August 13, 2017

SHA2017 writeups: Forensics : Samsung S4 (300)

Last weekend I participated in the SHA2017 CTF https://ctf.sha2017.org/ with my team HackingForSoju. We ended up at third place. Here are the writeups for the levels I solved.

Forensics: Samsung S4 (300)

A forensic investigator was wondering how hacker boxes like RIFF and Z3X use JTAG on a Samsung S4 phone while the main cores have debugging disabled.
The attached file was an archive with the file CTF_SamsungS4.csv, the contents of that file looked like:

Time, tms, tck, tdi, tdo 
0.000000250, 1, 0, 1, 1
0.000000500, 1, 1, 1, 1
0.000000750, 1, 1, 1, 1
0.000001000, 1, 0, 1, 1
0.000001250, 1, 0, 1, 1
0.000001500, 1, 1, 1, 1
0.000001750, 1, 1, 1, 1
...

TMS, TCK, TDI and TDO are the four mandatory signals in the JTAG protocol, and the logfile gives their logical levels over time. There are many tools to analyze logical signals, but I used sigrok and the GUI PulseView. https://sigrok.org/wiki/PulseView

The CSV-file could not be imported to sigrok right away, I had to remove the headers and timestamps:

grep -o ' .*' CTF_SamsungS4.csv | tail -n+2  > stripped.csv

When imported into pulseview, the data looks like this after naming the signals:



The data line TDI shows data going into the device, and TDO holds data that comes out of the device. Note that there is data at TDO between the samples 2500 and 4000. This seems to be an intresting point to look at.

I added a JTAG-decoder to decode what was going on.



The magenta bits indicate that the JTAG state machine is doing SHIFT-DR, the text labels don't show at this zoom level. The data on TDO is the previous content of the data register, we probably want to have a look!

There might be a more elegant solution to get the data out, but as CTFs are under time pressure I just added an extra SPI decoder with TMS as chip select to get the bitstream. Note that there are 35 bits in the SHIFT-DR section, so this width must be changed in the SPI decoder.



This CTF has made me recognize 'FLAG' when written in hex, but the byte order had to be changed:

>>> s = '67616c66 3061397b 39633565 33636134 37383365 33313931 31626130 66633333 31656662 7d38'
>>> ''.join([e.decode('hex')[::-1] for e in s.split()])
'flag{9a0e5c94ac3e38719130ab133cfbfe18}'
>>> 

No comments:

Post a Comment