Installing custom OpenWRT on an Inteno (DG301) router

Soon after getting an Inteno DG301 router from my ISP Telia, I poked around the firmware trying to find out more about its internals. It became apparent that the iopsys firmware running on the machine was a customised version of OpenWRT. The modifications by Inteno include making it more fool-proof for consumers, removing any easy access to its internal settings in the process. It's not possible access SSH without proper keys, and Telnet is disabled, even in OpenWRT's failsafe mode. In addition to the provided user account, there are also the support and admin accounts, but the passwords for these are not known. I did manage to dump most of the filesystem by abusing an insecure default option in the router's bundled Samba and found a couple of other exploitable bugs, however, I still didn't have proper shell access or a way to invoke opkg to install my own packages. So I decided to compile my own version of the iopsys router firmware. Using iopsys instead of regular OpenWRT as a base makes sense, because it's guaranteed to work on this hardware without many additional tweaks. Compiling my own version also had the benefits of TR69 being disabled, being able to add my own modules and remove the branding for a vanilla'ish experience.

Compiling is easy. These commands should successfully generate a build on Ubuntu 18.04:

$ sudo dpkg --add-architecture i386
$ sudo apt update
$ sudo apt -y install git curl zlib1g-dev file unzip python2.7 gawk libncurses5-dev
$ git clone
$ cd iopsyswrt
$ git checkout devel
$ ./iop setup_host
$ ./iop bootstrap
$ ./iop feeds_update
$ ./iop genconfig dg301

At this point, it might've complained about missing dependencies, which you should install using your distro's package manager. If you wish to modify your build, run make menuconfig before finally running make. You can have packages included in your firmware file by marking them with the y key. For example, I included essential packages like nano and bash, and finally compiled by running make. Compilation took me about 2 hours, including the toolchain. Future compile times should be much shorter as one doesn't have to re-compile everything. This generated a couple of files in the bin/ directory, but I was interested in the .y2 file. Excellent firmware analysis tool Binwalk confirmed that this was a proper firmware file. (2019 update: It now generates .y3 files as per the default configuration)

There was no easy way to flash custom firmware that I found. Manual updates were disabled in the settings panel and due to having no shell access, I was forced to prying it open (read: removing four screws) and seeing if there's another way in. There are 4 pins on the board, which I identified as, from the top down:

[   ]

On a newer generation board such as the DG400, the header is exposed through a tiny slot on the side of the casing - you need male jumper wires to connect to it. On the DG400 specifically, I've determined the pinout from top-to-bottom (or left-to-right if looking at it from the side) to be:


You can connect to these pins via a UART pin adapter of choice - a regular UART to USB adapter would work - just remember that RxD connects to TxD and vice versa. I decided to use my Raspberry Pi and screen for this:

screen /dev/ttyAMA0 115200

This gave me the ability to see boot messages, trigger OpenWRT's failsafe mode and most importantly access the built-in CFE bootloader menu by pressing a key right after booting up the router. The bootloader also has its own http server with the single option of uploading your own firmware.

I uploaded my own .y2 firmware to the router - it seemed to start flashing successfully. After about five minutes, the router rebooted itself and I was greeted with the JUCI login page. All of the accounts now had their passwords set to their usernames. I logged in as admin/admin, changed my passwords and added an SSH key in the settings. This allowed me to SSH into the router as root, being able to access it completely. As far as I can tell, all functionality is still the same, except for disabling ACS, TR69 and resetting all settings.

The admin user can also upload firmware files directly via the web interface, so I no longer need to access the router using a serial console.

2019 edit: The firmwares listed below are quite outdated - recommend building your own. However, they can still be used to, for example, unlock the firmware flashing feature on routers.

If you wish to use a custom firmware for your router, you can compile your own or download mine (DG301 .y2, DG301 .y3, DG400 .y3) and flash that instead - this WILL reset all of your settings, and in case they were stored on your ISP's server (Telia does that) they will not be re-applied.

Author | nns

Ethical Hacking and Cybersecurity professional with a special interest for hardware hacking, IoT and Linux/GNU.