JTAG

Joint Test Action Group

Enabling JTAG

Using Bootstrapping Pin

In some cases JTAG is disabled by default and multiplexed with another feature, in this case the EPHY LEDs. In order for us to enable it again we need to study the datasheet.

Datasheet, LED and JTAG is multiplexed through same pins
Showing bootstrap signal name "dbg_jtag_mode"
Pin ANT_TRN enables EPHY_LED or JTAG on boot

Digging deeper into the datasheet we find that on boot the pin ANT_TRN controls if JTAG should be enabled or disabled, after boot the pin returns to its normal purpose. Default ANT_TRN is set low (0V) enabling EPHY_LED, if we want to enable JTAG we need to pull this pin high (5V) on boot.


Interacting with JTAG

  1. Make sure Tigard switch is set to JTAG mode

  2. Supply 3.3V power from Tigard using the power switch

  3. Create OpenOCD Tigard configuration file, tigard-jtag.cfg.

  1. Connect using OpenOCD and Tigard configuration file

  1. Download / create board specific configuration file, mt7620n.cfg

  1. OpenOCD server is successfully running. Open a new terminal and connect to the server:


Debugging / Exploiting

Patching boot arguments (in memory)

Sometimes the boot arguments are hard-coded in the kernel:

Hard-coded boot arguments

Looking on line 0x020bcc0 and more specifically address 0x020bcc8 we have the hex data 0x324d0000. If we end the boot argument string with <space>1 (0x2031) it will tell the kernel to boot into single user mode, thus bypassing the login screen.

The kernel get loaded into the memory at address 0x80000000, making the interesting address to look on 0x8020bcc8, this is needed later.

To patch/exploit this start by opening three terminals.

NOTE: If the system is reboots (you see this in the 1:st terminal) it's because the system has a watchdog timer and it thinks something went wrong. Just keep halting the system until the rebooting stops.

Commands used
Action

mdw

Memory Display Word - display data on memory address

mww

Memory Write Word - edit data on memory address

wp

Watchpoint - halts when something tries to access memory address

rwp

Remove Watchpoint

Patching user privilege checks (in memory)

With an low privileged user we're not able to read files such as /etc/shadow. We can circumvent this by patching the permissions through JTAG directly in the memory, giving us full read access. This is just a simple PoC and can be used in many other similar ways.

NOTE: If you get all 0’s in GDB, the system might not be properly halted.

A call to a function that checks permission will either return a value that grants permission – in this case 0 – or another value that might be an error code – in this case -EACCES (represented as 0xfffffff3 or -13 ). In the example above, this result is stored in the register v0, and then the function returns to the caller.

We can patch/exploit this by putting a breakpoint on this li instruction, and when it tries to deny access by returning -13 or 0xfffffff3, we simply replace the value with 0.

Patching getty to bypass login (in memory)

The /bin/getty binary handles login to a system. Using the flag -f will force authentication without asking for a password, making it possible to simply login as root using login -f root. In some versions of getty, how they handle this is that they hard-coded -- at the end of the string, invalidating any other flags.

hex data of getty binary

What we can do using JTAG, is to find the bytes -- (2d 2d) and patch it to -f (2d 66) thus being able to bypass the login as any user. But how should we find 1 byte of data in the memory?

One way is to write a script to read 8 bytes of data at offset 0x7c9 and compare to the known signature 00 2d 2d 00 25 73 3a 20. If it's a match we can immediately patch it and hopefully gain access to the system.

Patch failed, it's possible that there are several copies of getty in memory, or even another bit of memory that contains the same string. Run the script again.

Script used can be found HERE.

This could also be accomplished by using forensics tools such as inception or PCILeech.

Last updated

Was this helpful?