When I started looking for a winter break project, I was told that wifi router firmware was extremely easy to find your first “real” bug in- which turned out to be excellent advice. Not knowing anything about picking a target, I looked at the model number on the back of my router, and found a firmware dump. Checking it out with binwalk, there was a bunch of licensing and certificate data, along with a squashfs filesystem.
The SDB daemon
From what I found, the SDB daemon, contained in the /bin/sdb, /bin/sdb_helper, and /lib/libsdb.so binaries, is the central piece of software on the system. Although it’s not really relevant to the rest of this writeup, I’m going over it in case other people end up working with it (and because I wasted a lot of time reversing it). It handles logging, manages a database, handles commands sent from the web portal, and does what looks like a good portion of the initialization stuff after boot. It creates a linux socket at /var/tmp/sdb.server and listens for requests using its own custom protocol. Either emulating or writing a stub for it is basically mandatory if you plan to emulate something from the firmware dump, since even if a binary doesn’t rely on its database or commands, it will likely still use it for logging and refuse to run if it can’t connect to the socket.
The webpages
The webpages are served via cgi-bin using lighttpd, with a custom binary called /bin/webasp generating the HTML from some weird templated Lua. Confusingly, there’s actually code for three separate web interfaces in the /www directory, although /www/att is the only one served by default.
Inside of /www/wificert, one of the 2 web portals not enabled by default, however, there’s something very interesting.
if ENV.REQUEST_METHOD == "POST" then if FORM.Cancel ~= nil then if FORM.uploadfile ~= nil and FORM.uploadfile ~= "" then os.execute("rm -f "..FORM.uploadfile)Even though I couldn’t use it for my initial access, this is your run-of-the-mill command injection, and it seemed like it could be an easy way to set up persistence, although sadly it never ended up coming into play. (I think I can still count this as “found a command injection bug” though?)
UART and the BIOS
The BGW210 has some pins on the board which allow for direct access over a serial cable. So, after ordering a guinea pig BGW210 and a UART to USB adapter, I was able to solder the right pins and only burnt myself once. this writeup explains the disassembly pretty thoroughly, although the exploit it describes is no longer functioning, and you can’t downgrade anymore either.
^ my abysmal soldering job :/
My final setup was a cheap UART to USB adapter from temu connected to PuTTY (baud rate is 115200, and flow control needs to be set to None), and the USB drive mentioned in the writeup is unnecessary. After plugging in the power to the router, plugging in the UART adapter to my PC, and opening a serial connection, I was able to see the console output of the router booting.
Finding the password
Spoiler alert- this section’s gonna be short.
After extracting the UBoot image from the .bin file, I opened up Ghidra, and while I was waiting for it to start, I tried strings uboot.bin | grep password. Maybe that’ll give us some function names or error strings or…
$ strings uboot.bin | grep passwordEnter password ( attempting autoboot in %2ds )password12345
Surely there’s no way that’s it, right?
Right?
wrong.
The Grave Mistake
Unfortunately, my brave, brave lab-rat BGW210 from ebay has met with a tragic fate and is now in a vegetative state. After typing in password12345 at the login prompt during boot, I was dropped into the BIOS, which had, among other useful things like an option to boot from usb, commands for mounting, reading, and writing various filesystems & flash chips. Importantly, U-boot has you read files & other data directly to an address in physical memory, and then directly print out said physical memory. I found an interesting-looking file to read on one of the mountable filesystems, pasted in what I thought was some unused memory I could put it in for the address, and hit enter. And then it stopped responding to my inputs over PuTTY.

It turns out, due to Virtualbox’s janky shared clipboard, what Windows thought was on my clipboard wasn’t the scratch memory I’d copied inside virtualbox- it was the memory-mapped address of the flash chip containing the bootloader- specifically, the address of the interrupt vector table. Fuuuuuuuuck.
Conclusions
- Using the boot from USB functionality in the bootloader, the BGW210 can boot or install custom firmware like OpenWRT, which is pretty cool.
- If someone more careful than me used the available tools inside U-Boot, they could boot or install a patched or outdated image. This can be used to get a shell on the device and extract certificates, do further reversing, and generally get up to shenanigans and/or mischeif.
- Use EXTREME caution when dealing with U-Boot- you will pay dearly