Windows CE SuperH3 Exploit Development Part 2: Finding Buffer Overflows with the Embedded Visual Tools Debugger
Disclaimer: This information doesn’t have many practical uses unless you’ve got a Windows CE SH3 machine (some voting machines, lab equipment, barcode scanners, all early 2000’s IoT devices, etc) you’re looking to write exploits for. I’m mainly just trying out cool stuff for fun. If you want to write exploits for Linux arm or x86 Windows, see the sources section in my introduction. My series introduction, tool list, and some of the sources I’ll be using can be found here:
Windows CE SuperH3 Exploit Development Part 1: Tools and Sources of Information
An introduction to the tools required for Windows CE SuperH3 exploit development…
The program we will be testing is STweaker 2004. It’s a great set of utilities, some of which were never fully implemented by the developer. I use it all the time to clean out registry artifacts and weird messages left behind by partially-deleted software. There are features like a planned shell that weren’t finished but were given menu entries anyway. The fact that it was released in a partially finished state increases the likelihood that the developer made some errors that could lead to a successful overflow.
String analysis in IDA Pro also produced very few error strings, which indicated a lack of software error handling.
This is key knowledge, because Windows CE 2.11 does not enforce any sort of hardware error handling.
It must be downloaded and installed to the device before we begin. The cab file can be found here:
STweaker 1.33 (details view) - Windows CE Software Compatibility List - HPC Factor
Windows CE Software Compatibility for STweaker 1.33 (details view)
Before debugging, we want to get some sort of indication that STweaker may be vulnerable to this type of attack. An easy way to test this is to attack it with a few long strings of A’s. We can automate this task with M3cro, but doing it manually works just as well, and isn’t too tedious for this particular example. We’ll start using M3cro scripts when it comes time for exploitation.
The first thing we need to do is prepare a text file full of “A” strings of varying lengths. The test lengths I used were 50, 100, 250, 500, 1000, and 2500.
STweaker has a function called “New Name”. Normal behavior if a string is entered into “New Name” and no options are selected is to close the dialogue box and keep STweaker open. STweaker itself should not close.
To establish a baseline of normal behavior, let’s test this with a 10 character “A” string.
As we suspected, when we input the string, the dialogue box closes, and STweaker remains open.
Let’s move up to 50 characters and see what happens.
Wow, that was easier than I expected. The number of characters required to crash it is low enough that we can do some manual testing to determine what exact length the string needs to be for the program to crash.
It turns out the exact string length required was 50. Anything string length above 50 would cause an immediate crash, any string length below 50 would not do so. 49 A’s would not cause a crash, 51 A’s would.
Now that we have this information, it’s time to do some debugging!
Author’s Note: I don’t actually have a serial port on my laptop, but I do have a crazy setup that allows this to work.
This required a Jornada to serial adapter, a serial to USB adapter, and a virtual machine running the ActiveSync 3.5 software. It would have been much easier if I could use my other SuperH device, but it did not support STweaker.
Our first step after installing STweaker on the SH3 CE device will be to copy the program files to the virtual machine. This way we get an executable that we can feed into the Embedded Visual Tools debugger without extracting the cab.
Author’s Note: This is possible either with ActiveSync or a Compact Flash card. I’ll only be covering the Compact Flash card method.
STweaker only has one file, the executable. All we need to do is highlight and copy it from the program files directory.
After that, we can paste it in the Compact Flash drive and transfer that to the host.
Then we can transfer it to the Windows XP Virtual Machine by whatever means we prefer. I personally like packaging the file in an ISO and transferring it as if it were a CD.
Once it’s on the Windows XP guest, we can open up Embedded Visual C++ and go to the file menu.
We can open executables for debugging by selecting “Executable Files” in the “Open” options.
After we open the executable, we should see a blank screen and some executable specifications.
Now it’s time to set up the ActiveSync Connection.
In theory, if ActiveSync is installed correctly, all we need to do is open up our Jornada, connect it to the computer, and wait for it to start connecting.
After that, a partnership dialogue box will pop up. We will select all of the default options and press “Finish”.
Now it’s time to move over to Embedded Visual C++. We can open up the debugger by clicking on “Project > Settings” and selecting the “Debug” tab in settings.
We must select the directory we want the program to be transferred to. Even though it is already present on the device, this tool will resend it anyway. For that reason, we can choose our external storage card so it’s not just wasting space.
Author’s Note: The debugger just leaves it on the device after closing, I delete it every time. I don’t know what happens if you don’t delete it, probably weird conflicts.
Once this is done, we can press “F11” or find the “Step Into” button to start debugging. The program will then start connecting to the device using ActiveSync.
It will throw up a CPU Mismatch error. This is a known issue, but it was never fixed. We can just ignore this and press “Yes”.
Since this is our first time debugging, the device will be sent a debug monitor.
Once we start seeing the disassembled view of the program.
To run STweaker on the Windows CE device, we can scroll all the way to the bottom of the program, put the cursor on the last valid instruction, and click the “Run to Cursor” button. Once we’re there, we can start open the “Name” dialogue box in the program and input our 50 character test string.
We’ll see an exception pop up in the debug monitor.
We can press ok, and select the button from the “Debug” dialogue box named “Register View”. A view of the registers will then appear.
Success! We have an overflow! The program counter and procedure registers have both been overwritten by A’s. Not sure why they’re being separated by null characters, but we can worry about that later. For now, let’s quit debugging and formulate a strategy for further research.
Author’s Note: Unfortunately quitting the debugger also crashed the entire Windows CE device, but hey, that’s what backups are for. In this case we didn’t need one, but it’s a good idea to make some.
Now it’s time to figure out exactly where the PC register is overwritten. To do this, we must first hop into a Kali linux box to utilize the pattern_create.rb tool from the Metasploit framework.
Because we know the program crashes at 50, it would be a good idea to create a pattern of length 70, something to ensure we have enough characters to figure out exactly where the overflow occurs.
Now all we need to do is transfer the pattern text file to the device using our compact flash card.
Before we begin debugging again, we need to copy this pattern to the clipboard.
Now we can go through the steps to start debugging again and open up the program.
Back on the device, we can paste the pattern into the “Name” menu and wait for the exception to pop up.
Ok, now that we’re back in register view, we can see that we have a bit of a problem.
The buffer is overflowing right, and the characters are getting inserted, but there are null characters being inserted between every ASCII character.
To check the pattern and figure out where the overflow is occurring, we’ll need to remove the null separators. We get “4136”, which is “A6”. We can also see that r8 and fp, the two registers that were overflowed before, were changed. R8 was overwritten by “6241” or “bA”, and fp was overflowed by “4138”, which is “A8”. If we take a look at the pattern, we see that none of these occur, but we must remember that the SuperH is a bi-endian ISA. Keeping the endianess in mind, we can deduce that these bytes should be reversed. That means “6A”, ”Ab”, and “8A”. If we take a look at our pattern, we can see there’s an area with “6Ab7Ab8A” where all of these characters exist.
If we put this into Metasploit’s offset determination tool we can tell that the buffer is being overflowed at exactly 50 characters.
We’ve verified what we originally found without debugging, and have learned a bit about how the overflow effects not only the program counter and procedure register, but spills over into registers fp (refers to one of the two FPU registers that start with FP?) and r8 (a general purpose register).
Edit: Wow, I apologize, I was unfamiliar with the similarities between arm and SH3 before I started this. FP is just the stack frame pointer. This gives us the opportunity to take our overflow in a very different direction and have some stack based fun. I was able to determine that the frame pointer is overflowed at offset 56.
We now know where the buffer is being overflowed, but we’re left with the problem of the null characters being inserted. My knowledge of SH3 registers is limited, but I know from previous readouts that the pc and pr should both be pointing to valid program stack locations that are not null separated. I’m not sure how this will effect our payloads. Either way, my idea for an easy proof of concept is changing a registry key.
Hopefully we can figure all of this out in the next installment of this series!
Update: There’s a very good reason for the null characters that had to do with Unicode. All will be revealed in the next post…