About two weeks ago our local Toys'R'Us had a final closing sale with 90% off on all items. Knowing they had a few arcades in the store, I showed up early to get Street Fighter, but since they were all sold out I bought the Asteroids edition instead.
Assembling the game
Beer can for scale
This is the one I bought. Unassembled, flat-packed, IKEA style. Unfortunately I did not take any pictures of the build process, but the manuals were easy to follow, and I spent about half an hour setting it up. Got a little help from my 8 year old daughter, too.
After powering up the device, a menu popped up with a list of four games: Asteroids, Tempest, Major Havoc, and Lunar Lander. All games from the vector era, i.e. graphics composed of just lines.
Not quite my cup of tea to be honest, but it was a calculated risk. If it was too boring, I could do a switcheroo with a Raspberry Pi, or maybe one of those 60-in-1 boards. Either way, I wanted to explore the insides, so last night I decided to pop the lid and see how hackable it is. Spoiler alert: Oh, it is. Very much so.
Finding a serial console
I removed the game PCB, which is located behind the LCD screen. The first thing that caught my eye were the ICs: their surfaces has been etched away to hide the model numbering. This made me question my naïve approach, but I kept going and blindly probed around with the oscilloscope. After foolishly looking for some interesting test points, I stumbled across something interesting: right next to the flat flex cable, where it says "CON4", there's a 4-pin port. The signals were easily identified as: 3V3, TX, RX and GND. Yes, we have a UART.
I soldered a pin header and started looking around for USB-UART modules. Of course, all were gone and the ones I've ordered had not arrived yet. I settled using an Arduino as a temporary substitute. I simply set up a SoftwareSerial and monitored the activity using putty. The UART runs at 115200,8,N,1 and keeping an eye on it at power up shows a long boot log, and reveals that this arcade is running BuildRoot Linux!
Logging in, looking around
After the boot I was dumped at a login prompt. A user named "default" has no password, and spawns a BusyBox shell. The baudrate of 115200 caused a lot of errors, but slowing it down to a baudrate of 19200 (by issuing a
stty -F /dev/ttyS0 19200) fixed that. This would not be a problem with a proper UART-USB adapter.
After exploring the file system, the essentials boils down to:The arcade runs MAME. Basically all the files required by the emulator are located in /root.A directory called 565 contains all the menu graphics, which is dumped directly to the framebuffer on demand.Despite the menu only listing four available games, there are a total of seven games installed. The extra game ROMs are Gravitar, Asteroid Deluxe and Street Fighter!The /root directory contains a couple of scripts for mounting and unmounting external storage. I suspect there's a USB port on the board somewhere.A script called "mameload.sh" executes /root/mame with parameters from a file in /tmp.Without root privileges, the adventure appears to end here.
Getting root privileges
I started looking for BuildRoot exploits but couldn't find any easily accessible. The password file /etc/shadow was not readable by me at this point, so I couldn't crack the root password either.
But wait, hang on - look at that mameload.sh script again, and check out the file mode bits:
-rwxrwxrwx 2 root root 72 Jan 1 00:01 mameload.sh
This file belongs to root and all users have write privileges to it! The menu process is also run by root, could this be a loophole to gain root access? Another spoiler alert: Yes it is.
I added a few commands to the script which took a copy of /etc/shadow in /tmp. Starting a game confirmed that this worked, I had a readable copy in /tmp! Instead of cracking the password, which would probably be trivial, I removed it entirely. I then modified the mameload.sh script once again, this time to take a copy of /tmp/shadow back to /etc.
And now root no longer needs a password and we have full access!
"What, this ol' thing? Just my Asteroids arcade running Street Fighter, nothing special."
Importing a new game
Importing a game from the "outside" was a bit of a challenge through a serial connection. After some impatient finger drumming, I noticed that
uudecode was a part of the BusyBox. This means I can transfer a file as 7-bit text over the serial terminal, and turn it back to 8-bit binary on the arcade side.
And that worked too! Welcome to your new home, Mario.
I have to admit there's one thing left, and that's configuring the buttons to the new games. I need to read up a little on MAME cfg files, but I think this should be a pretty painless.
Also, while writing this blog entry, I found that someone has already found the USB port I was talking about earlier. I will attempt to solder a connector to it later today and see how it works out. This will make file transfer much easier.