The Approximately Monthly Zoomer


Hardware Hacking 2: Electric Boogaloo

2024-05-10

After dabbling in hardware hacking last time, I think I might have found my most recent passion. I’m switching to an ISP that allows you to have any router of your choosing attached, so I thought I could find one with OpenWrt support and install it for maximum customization. The router should support the IEEE standards 802.11ax and ac for the newer clients on the network and also n for internet of shit and legacy devices from hell (also known as “printers”). Also, it should be somewhat future-proof, support the latest stable branch of OpenWrt, and not break the bank. This lead me to the Asus RT-AX59U, which received OpenWrt support in November of 2023.

Git Blame

At the time of writing the OpenWrt wiki page for this router was lacking to say the least - the only information as to how to install OpenWrt onto the router was the commit message of the commit that added support for it. The general idea was this:

  1. Set up a TFTP server with the intramfs firmware that is reachable by the router.Section 4
  2. Connect to the router via UART.
  3. Interrupt the boot sequence to get to a shell.
  4. Download the intramfs image over TFTP and boot it.
  5. Use sysupgrade to install OpenWrt permanently.

Sounds a little complicated but more than doable, so I went ahead and bought the router for 100 gold, fully confident I could do it. It all worked out fine in the end but I did encounter some unexpected problems.

Is this thing glued?

There are only two screws that are visible from the outside - they are located on the underside of the device, holding the base attached to the device. So I went ahead and unscrewed them. I expected the base to fall off or at least be easy to remove, but the amount of force I had to use to remove it lead me to believe I missed some pin I had to push down or some hidden button I had to press. Sure, breaking the base would have been suboptimal, but I could have easily 3D-printed some sort of base if I broke it, so I went ahead and pulled like a maniac. The next two screws were somewhat hidden deep inside the enclosure, but nothing you can’t reach with a regular screwdriver. With those removed, I again tried to pry away another layer. It was so hard to pull away that I had to ask someone else for help - both grasping the router with both hands and pulling it apart. A rather cartoonish scene, but it worked. I wasn’t sure how to proceed from here and pull away even more of its plastic casing but I didn’t need to since I already found what I needed.

UART

After removing the plastic, you immediately get greeted by four unpopulated pins. On the other side, that is visible through a small window, we can see that the pins are labelled “RX, TX, GND, VCC”. Before plugging in a USB TTL adapter, I quickly checked the baud rate with my oscilloscope. This step wasn’t really necessary since modern devices are pretty much always™ communicating at 115200 baud with 8 data bits, no parity bits and 1 stop bit - you’ll also see this referred to as 115200,8N1. Now that we know where to plug in and which parameters to use we can go ahead and attach the cables to the router, plug in the USB cable into a computer on one end, on the other end we enthusiastically plug into a micro USB port and…

…break it.

Enshittification of Local Business

I try to have all tools I need ready when starting with a project, because when I start, I really don’t want to stop. Unfortunately there weren’t any local businesses that sell USB TTL converters for a reasonable price. 30 gold for a CH340-based adapter? No thank you! Suddenly I became very creative and remembered that I have a raspberry pi somewhere, so I bought a coffee instead and headed home. The raspberry pi has a lot of GPIO pins, surely some of them can be used for UART. Checking some docs we can see that this is indeed the case. Pins 14 and 15 can be used after running raspi-config and enabling the serial console in the interfaces section (disable login shell, enable serial port).

Intermediate Egyptology 201

After waiting for what felt like an eternity for the raspberry pi to boot I was greeted by the minimal raspberry pi os desktop environment. The first thing I did was enable ssh and connect it to my network, so I wouldn’t have to directly interact with it. Within ssh I ran picocom -b 115200 -r -l /dev/serial0, started the router, and got nothing but garbled output with the occasional readable text. So garbled in fact, that it messed with my shell and turned it into a display of ancient Egyptian linguistics. It couldn’t have been the wrong baud rate, I checked with my oscilloscope and there wouldn’t have been entire blocks of text that are readable. I double and triple checked that all pins were properly connected and had good contact and thought that maybe the ssh connection was wonky. Maybe it works on the raspi but doesn’t get sent over ssh properly. When I entered the command on the raspi it was still garbled - but it was less garbled! Success! When I saw it was still garbled, but less so, it immediately clicked. The raspberry pi is overloaded and can’t keep up with Wi-Fi, bluetooth, ssh, a desktop environment, and UART at the same time! I disabled Wi-Fi and bluetooth, dropped down to the login shell with Ctrl + Alt + F2 (or was it F3? I don’t remember) and finally got ungarbled output.

Inspecting the Shell

We can interrupt the boot sequece by pressing the number (1|2|3|4|7|9) at the right time.

Please choose the operation: 
   1: Load System code to SDRAM via TFTP.
   2: Load System code then write to Flash via TFTP.
   3: Boot System code via Flash (default).
   4: Entr boot command line interface.
   7WAN Show April 19, 2024: Load Boot Loader code then write to Flash via Serial.
   9: Load Boot Loader code then write to Flash via TFTP.

You choosed 4

   4: Entr boot command line interface.

U-Boot 2022.04-rc1 (Aug 02 2023 - 10:59:04 +0800)
MT7986>

I choosed [sic] 4 to enter the U-Boot shell and then proceeded to download the OpenWrt intramfs image.

MT7986> setenv ipaddr 192.168.1.1
MT7986> setenv serverip 192.168.1.70
MT7986> tftpboot 0x46000000 rtax59u.bin
switch prereq:0
Using ethernet0@15100000 device
TFTP from server 192.168.1.70; our IP address is 192.168.1.1
Filename 'rtax59u.bin'.
Load address: 0x46000000
Loading: Got ARP REPLY, set eth addr (e1:ee:78:00:81:e5)
#################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #################################################################
     #########################################
     12.6 MiB/s
done
Bytes transferred = 7278084 (6f0e04 hex)
MT7986>

Now we should be able to boot the downloaded image.

MT7986> bootm 0x46000000
## Loading kernel from FIT Image at 46000000 ...

And after a while, we are greeted with this beautiful ascii art:

BusyBox v1.36.1 (2024-03-22 22:09:42 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 23.05.3, r23809-234f1a2efa
 -----------------------------------------------------
root@OpenWrt:/#

Now we can login to the webinterface, install the sysupgrade image, reboot, bob’s your uncle.

No Screwing Around

Usually these kinds of products have some sort of tamper evident warranty sticker somewhere. I only realized where it was when I was reassembling it - it was on one of the screws of the second set removed.

But don’t worry about these stickers because in most countries the manufacturers can’t actually weasel their way out of a warranty replacement unless they can prove that you broke the device. Funnily enough, I didn’t even put these screws back in since they are not in contact with any metal (so are not used for grounding) and the clips of the plastic case are strong enough to hold up a person, let alone the case itself.




A Giant Leap-S1 for Mankind

2024-04-08

Hardware hacking has always been a little scary for me. Mostly because opening and disassembling hardware would sometimes render it unusable due to my low dexterity stat - much to the dismay of those who still wanted to use the device and couldn’t appreciate the immeasurable amount of invaluable knowledge that stands to be gained from dissection. Nonetheless I’ve recently decided to dip my toe into some hardware hacking again.

The Target

The Leap-S1 is an android tv box which uses the Amlogic S905X2 SoC with an ARM Cortex-A53, can output in 4k60Hz, has 2GB of RAM and 8GB of flash. Like all android tv boxes it comes with a lot of Goolag bloat that is neither necessary nor privacy-friendly. So how about we install something else on it, like coreelec, since android is basically linux anyway. The adb shell on the box doesn’t really have lots of permissions to poke around. Maybe there is a uart connector somewhere that we could use to get a shell with more privileges.

What’s in the Booox?

Warranty void stickers are a meme anyway so let’s open the box and see what’s inside.

No obvious uart connections. Let’s check the bottom.

Bingpot! That’s as clear a uart as you can get but let’s make sure by identifying the pins.

UART

The GND pin is unsurprisingly connected to the ground, as can easily be checked with a multimeter in continuity mode. Again with a multimeter we can check the other pins while the box is booting and we’ll see that while 3.3V and RX stay at the same voltage throughout the boot process, the voltage on the TX pin fluctuates around 2V. Realistically, there is no way this is anything other than uart, but just to double-check and find out the baud rate, we can connect the TX pin to an oscilloscope and see what’s going on there.

We can see that the shortest pulse is around 8.7μs and if we want to be a little more precise we can measure the length of a few pulses and divide by how many of those shortest pulses fit inside the whole. Here I measured the length of ten bits - from left to right we can see that the bits are 0110110001. The cursors of the oscilloscope are positioned at the beginning and at the end of the sequence and the oscilloscope tells us, that it takes 86.8μs for all ten bits - which is 8.68μs per bit. We can now take the reciprocal 1/(8.68*10^-6) and this gives us a frequency of 115207Hz, which we also get by multiplying the 11.52kHz displayed underneath the time measurement on the oscilloscope by ten. Baud rates are not arbitrary, there is only a set of predefined speeds for serial communication, so even if your oscilloscope is not the most precise, we can still get an idea of what baud rate is being used by looking at the closest possible rates. Our calculated speed is too fast for 76800 and too slow for 128000 and pretty much dead-on for 115200.

Chinesium Arduinos

If you short the reset and ground pin of an arduino, you can use it as a “dumb” USB to TTL converter. Just hook up RX to RX and TX to TX and you have yourself an adapter. This should also work with the arduino clones that use a CH340 series chip but it didn’t work for me. Before buying some sort of UART to USB adapter, I thought I’d check if I have some other microcontrollers and as it turned out I had an ESP8266-based NodeMCU (not sure if knockoff or not) which also used a CH340 chip. Not giving it much thought I tried the same thing - short reset to ground, TX to TX, RX to RX, ground to ground.

I plugged in the NodeMCU, started my serial communication program with picocom -b 115200 -r -l /dev/ttyUSB0, powered on the android tv box, and to my sheer delight there was a bootlog flying across my terminal!

Field Programmable Google AndroidTV

To make it a little easier to connect to the uart interface I wanted to solder some sort of cables or connector to the exposed pads. Luckily I have a drawer with Assorted Lengths of Wire™ for just such occasions!

I soldered the wires to the TX and RX pins, wrapped them around the board and made a hole in the case with a soldering iron.

Slap the bottom of the case back on that bad boy and we can access the uart “in the field” any time we want.

I forgor 💀

Since I just used some exposed metal as ground when I was investigating the board with my oscilloscope, I totally forgot to add a ground wire as well. Luckily ground is shared by all components and connectors so I just used an old 3.5mm audio cable and cut it open so I can use its ground when connecting using uart.

No Shell? 🥺

Starting kernel ...

uboot time: 7182164 us

It seemed like the boot process was completed and the kernel was loaded, surely that means we have an interactive shell now, right? Not really. It didn’t look like I could interact with the box over uart while it was booting at all - so what do we do now?

Inspecting the Bootlog

One section in particular caught my eye.

USB0:   USB3.0 XHCI init start
Register 3000140 NbrPorts 2
Starting the controller
USB XHCI 1.10
scanning bus 0 for devices... 1 USB Device(s) found
    scanning usb for storage devices... 0 Storage Device(s) found
** Bad device usb 0 **
[sk_usb_cfg_init,422]load file "/skyworth/factory_mode/uboot/check_udisk.cfg" from u disk failed!
[sk_boot,182]general boot.

It caught my eye because the file path was literally red! Apparently the bootloader looks for a specific file on a USB drive. Poor bootloader, let’s give him the file. If we add boot_mode="boot flash recovery" to the file we can even make it boot into recovery mode.

Pop Pop!

It looks like the bootloader liked our file.

USB0:   USB3.0 XHCI init start
Register 3000140 NbrPorts 2
Starting the controller
USB XHCI 1.10
scanning bus 0 for devices... 2 USB Device(s) found
       scanning usb for storage devices... init_part() 282: PART_TYPE_DOS
1 Storage Device(s) found
33 bytes read in 36 ms (0 Bytes/s)
[sk_boot,220]boot recovery from flash.

We’ve successfully booted into recovery mode and we even have a shell with a nice looking number sign.

# id
uid=0(root) gid=0(root) groups=0(root) context=u:r:shell:s0

Indeed, we are root and found a good place to start our recon and here’s what I’ve found after a very uncoordinated and brief attempt:

I’m sure I’ll find the motivation to keep digging soon. It can only be a matter of months.




Proxmox is not that hard

2023-02-12

As it turns out, having a single server run a host (no pun intended) of different things on the same operating system can lead to some weirdness. Having some form of separation between the processes can be helpful - many choose containers and virtual machines and so did I.

Proxmox

For me, the decision to install proxmox came about when I realized, that I experimented less and less on my server for fear of breaking something and causing downtime to the services I want to be locally available all the time. Being able to experiment inside a VM and restore it from a backup or throw it away should the need arise has definitely had a very positive impact on my peace of mind.

With regular snapshots of my minecraft server, I don’t have to worry about my so-called friend playing a practical joke on my meticulously constructed mob grinder.

By using proxmox’s potent klickibunti for managing drives, I was able to combine all the old vintage SSDs lying around my house into a single ZFS pool for the less important stuff on my server. While proxmox does have a nice way of viewing S.M.A.R.T. data and creating snapshots and backups of VMs, I’d rather not put my precious minecraft world saves that pool specifically.

One of the programs running on my server leaks RAM. Even though I love going through other people’s spaghetti and fixing RAM leaks, periodically restarting the program’s container seems to be a more pragmatic solution. And with proxmox I can even see its RAM usage over time.

Even if you don’t feel like using any kind of orchestration tool for your containers or config management for your VMs (yet), proxmox is a powerful tool. New VMs and Containers can be set up very easily, the snapshot and backup system is very versatile, and if you’re ready to spend some money you can use its HA tools to migrate VMs to a different node while they’re running. Installing it is as easy as it is to install debian, if not easier. 10/10 would recommend.




Can we please go back to paper menus?

2023-01-06

My brother in Christ, I do not need assistance with scanning a QR code, just give me the frickin’ paper menu!!!!11!1!

Recently I’ve let a restaurant ruin my mood by using a buggy menu behind a QR code instead of handing me a proper menu and that made me think, so here are all the reasons I could come up with in the shower about why we should reject modernity, embrace tradition, and use good old-fashioned paper menus.

  1. Why would I want to look at a tiny screen smaller than my hand instead of a large (paper) menu with a large font with godlike contrast that can display more than a few lines at a time?

  2. SoMeBoDy tHiNk oF tHe cHiLdReN - but unironically. Not all children who are capable readers posess a smartphone or should be encouraged to use one during a meal.

  3. I don’t want to be advertised to on a restaurant menu you greedy fucks. Louis Rossmann had a similar experience where the first thing he saw after loading the site were three advertisements that blocked nearly all of the page.

  4. Cookies - but not the kind you want at a restaurant. Clicking through dark-pattern cookie dialogues just to order food in a restaurant. Welcome to the world of tomorrow!

  5. Security - If someone on the street handed you a QR code to scan and said “trust me bro, it’s 100% safe and legit” I’m sure you’d do exactly as asked. Bonus points if the site allows you to directly pay by credit card. Also, what about exploits in the QR scanning software or just regular browser exploits? What if some non tech-savvy senior gets tricked into downloading the offishal™ restaurant app? Or someone leaves a fake QR code at the table?

  6. Tracking scripts. Why do goolag and friends need to know where I’ve been eating?

  7. Poor web design - Clicking back and forth through categories/menus just so you can see the appetizers, main courses, side dishes and desserts separately. And god forbid you want to see the ingredients, that’s another click on the item and scroll down. Then you have to click the back button which doesn’t bring you back to the same place on the page but all the way to the top.

  8. It distracts. Looking at your phone there will certainly be some other things that may disctract you, your friend texting you, a missed call from your coworker, a calendar reminder, any notification really. I for one don’t have the mental fortitude to block out all those stimuli and focus solely on looking at the menu in my browser, and neither do some of my friends, who ended up spending a large amount time checking other notifications every time they went to take a look at the menu.

  9. We’re inside, in a large building. Large buildings have lots of walls, lots of thick walls. Mostly from reinforced concrete, which has a pretty high linear attenuation coefficient. An internet connection is needed to load all the fancy 4K pictures of the food. Do you see where I’m going with this? They already have reception problems with their GSM credit card reader, waving it around trying to catch some bytes floating around the ether, let alone downloading high res pictures.

  10. Public WiFi. That fancy new speakeasy you can only enter with a password is in a basement? No need to worry about reception, just use their free WiFi! Yeah, sure. Even if you’re so inebriated that connecting to a public and unencrypted WiFi seems like a good idea, what do you think will happen when everyone tries to open the menu at once using their shit-tier ISP-provided 54mbps dsl 802.11g router? What about the couple sitting in the other corner away from the router?

The Good Things

Not everything about those QR menus is bad, there are some small benefits, but most have one thing in common: only the restaurant benefits from it.

  1. You can change prices on a whim! No more reprinting menus, just a few clicks in your POS (both meanings) system and you can adjust for real-time inflation should you live in Argentina. Someone with gucci crocs and a rolex just walked in? Have the QR code on their table link to a more suitable “premium” menu!

  2. You save money and trees by not printing paper menus. Well yes, but actually no. Most of the time they still have good old-fashioned cellulose menus as a backup, so those trees are already dead.

  3. When combined with an ordering system, you can fire some of the staff and keep more of the profits to yourself.

  4. That’s it?

Unless you completely dread social interaction with waiters and holding menus other people have held before you (why are you at a reastaurant then?), I fail to see how menus behind QR codes benefit you, the customer, in any way.




© Dominik Odrljin

1   Older