d9d9ae332a
Boots BL2 and returns to debugger. BL2 is not yet patcheable.
208 lines
8.4 KiB
ReStructuredText
208 lines
8.4 KiB
ReStructuredText
=====
|
|
Notes
|
|
=====
|
|
General notes on interesting/peculiar things found on the S7 USB recovery boot process
|
|
|
|
Emulator
|
|
--------
|
|
What is interesting about the ROM is that it starts by checking MPIDR_EL1 register and doing a conditional branch to 0x20e0000.
|
|
|
|
.. code-block:: bash
|
|
|
|
undefined w0:1 <RETURN>
|
|
Reset XREF[1]: Entry Point(*)
|
|
00000000 bb 00 38 d5 mrs x27,mpidr_el1
|
|
00000004 7b 0f 78 92 and x27,x27,#0xf00
|
|
00000008 7f 03 00 f1 cmp x27,#0x0
|
|
0000000c 41 00 00 54 b.ne LAB_00000014
|
|
00000010 fc 7f 83 14 b LAB_020e0000
|
|
|
|
BL1 peculiarities
|
|
-----------------
|
|
|
|
.. figure:: images/bl1_auth_references.png
|
|
:align: center
|
|
|
|
BL1 authentication
|
|
|
|
At this point, we assumed that the authentication was succesful, and the bootROM would jump back to the debugger after loading, but this was not the case. After running this function, we were able to send a single packet, but never received a response. Indicating that the function we were executing never returned on us.
|
|
|
|
If authentication at auth_bl1 is succesful, the returns a value from a function at ``1230c``. This function does some things, but eventually jumps to a function at:
|
|
|
|
.. figure:: images/bl1_auth_follow-up_1230c.png
|
|
:align: center
|
|
|
|
BL1 authentication
|
|
|
|
After authentication the bootROM jumps to this function at, we can execute this function with the debugger.
|
|
|
|
.. code-block:: python
|
|
|
|
self.cd.memwrite_region(0x02020f60, p32(0x020c0000))
|
|
BOOT_BL1 = 0x00019310
|
|
def jump_bl1(lr):
|
|
self.cd.arch_dbg.state.LR = lr
|
|
self.cd.restore_stack_and_jump(BOOT_BL1)
|
|
|
|
jump_bl1(0x020c0000)
|
|
|
|
jump_fwbl1()
|
|
|
|
BL1 is loaded at the download buffer and self copies to ``0x02022000`` and resumes execution there, with a size of 0x2000 (``0x02022000`` to ``0x02024000``).
|
|
|
|
However, this does not result in a jump back to the debugger. But the ROM still allows receival of one data package from the USB host (this is likely the system 'waiting' to receive the bootloader).
|
|
|
|
By adding the IMEM to ghidra, we can have a look at what is going here. After having modified the LR to jump back to the debugger and jumping into auth_bl1 at ``0x00012848`` we jump back to the debugger. Jumping into BL1 at ``2c0`` does not return us to the debugger. Here we need to hijack ``020200dc`` and ``02021880`` we're able to boot into BL1. We store the address of the hijacked function, to restore it later for a proper boot flow.
|
|
|
|
.. code:: python
|
|
auth_bl1(DEBUGGER_ADDR)
|
|
self.usb_write(b"FLSH") # Flush cache
|
|
hijacked_fun = u32(self.cd.memdump_region(0x020200dc, 4))
|
|
|
|
# BL1 patches
|
|
self.cd.memwrite_region(0x020200dc, p32(DEBUGGER_ADDR)) # hijack ROM_DOWNLOAD_USB for BL31
|
|
self.cd.memwrite_region(0x02021880, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br"))
|
|
|
|
Authentication of BL1 seems to be done at ``0x0012848``. With return value '0' expected when this function is executed, to execute other functions.
|
|
|
|
.. figure:: images/bl1_auth_references.png
|
|
:align: center
|
|
|
|
BL1 authentication.
|
|
|
|
purpose
|
|
^^^^^^^
|
|
bl1 interacts with several pheriperals, from the DTB these are:
|
|
|
|
.. code-block:: bash
|
|
|
|
/* FSYS0 */
|
|
pinctrl_5: pinctrl@10E60000 {
|
|
compatible = "samsung,exynos8890-pinctrl";
|
|
reg = <0x0 0x10E60000 0x1000>;
|
|
interrupts = <0 212 0>;
|
|
};
|
|
|
|
/* FSYS1 */
|
|
pinctrl_6: pinctrl@15690000 {
|
|
compatible = "samsung,exynos8890-pinctrl";
|
|
reg = <0x0 0x15690000 0x1000>;
|
|
interrupts = <0 202 0>;
|
|
};
|
|
|
|
/* PERIC1 */
|
|
pinctrl_9: pinctrl@14CC0000 {
|
|
compatible = "samsung,exynos8890-pinctrl";
|
|
reg = <0x0 0x14CC0000 0x1000>;
|
|
interrupts = <0 460 0>;
|
|
};
|
|
|
|
pmu_system_controller: system-controller@105C0000 {
|
|
compatible = "samsung,exynos8890-pmu", "syscon";
|
|
reg = <0x0 0x105C0000 0x10000>;
|
|
};
|
|
|
|
rtc@10070000 {
|
|
compatible = "samsung,s3c6410-rtc";
|
|
reg = <0x0 0x10070000 0x100>;
|
|
interrupts = <0 73 0>, <0 74 0>;
|
|
clocks = <&clock 157>;
|
|
clock-names = "gate_rtc";
|
|
};
|
|
|
|
Probably the only thing it does is set some clocks and prepare for BL31.
|
|
|
|
The reason for this is the following code in bl1:
|
|
|
|
.. code-block:: c
|
|
|
|
iVar3 = FUN_02024320();
|
|
if (iVar3 == 1) {
|
|
(*(code *)(ulong)uRam0000000002020108)(0,1);
|
|
}
|
|
|
|
This code uses a predefined ROM function(I was looking for it) and jumps back to that function when it's done.
|
|
This function is at address ``0x020200e8``, looking in our IMEM dump we can see where in the ROM this points to:
|
|
|
|
.. code-block:: c
|
|
|
|
DAT_02020108 XREF[2]: FUN_00001708:000018b4(W),
|
|
FUN_02021970:02021a40(R)
|
|
02020108 90 57 00 00 undefined4 00005790h
|
|
|
|
Replacing this function with our debugger makes us jump back:
|
|
|
|
.. code-block:: python
|
|
|
|
# Overwrite jump back
|
|
self.cd.memwrite_region(0x02020108, p32(0x2069000))
|
|
self.cd.memwrite_region(0x020200e8, p32(0x2069000))
|
|
|
|
def jump_bl1():
|
|
self.cd.arch_dbg.state.LR = 0x2069000
|
|
self.cd.restore_stack_and_jump(0x02024010)
|
|
# self.cd.restore_stack_and_jump(0x02021810)
|
|
|
|
bl1 = open("../S7/bl1.bin", "rb").read()
|
|
self.cd.memwrite_region(0x02024000, bl1)
|
|
self.usb_write(b"FLSH")
|
|
|
|
# auth_bl1()
|
|
jump_bl1()
|
|
assert self.usb_read(0x200) == b"GiAs", "not jumped back to debugger?"
|
|
self.cd.arch_dbg.state.print_ctx()
|
|
|
|
root | DEBUG |
|
|
X0 : 0xc00000 | X1 : 0x2069000 | X2 : 0x0 | X3 : 0x2023114 | X4 : 0x4 | X5 : 0x0 | X6 : 0x0 |
|
|
X7 : 0x136c0008 | X8 : 0x2069000 | X9 : 0x0 | X10 : 0x2070000 | X11 : 0x0 | X12 : 0x0 | X13 : 0x0 |
|
|
X14 : 0xf | X15 : 0x206d000 | X16 : 0x9 | X17 : 0x0 | X18 : 0x1 | X19 : 0x20200e8 | X20 : 0x0 |
|
|
X21 : 0x80000000 | X22 : 0x0 | X23 : 0x0 | X24 : 0x0 | X25 : 0x0 | X26 : 0x0 | X27 : 0x1 |
|
|
X28 : 0x0 | X29 : 0x2020ed8 | LR/X30 : 0x202419c | SP/X31 : 0x2020ec0
|
|
|
|
However this does not fully run bl1, so we will have to dig a bit deeper to see the puropose and when to jump back to the debugger.
|
|
|
|
|
|
Week 35 - 2024
|
|
--------------
|
|
After booting BL31, the MMU seems to be set up, and we're unable to do get any data off of spaces we're not 'allowed' to access. Patching the if-statement at 0x020244e8, disables the bit that says that the MMU is setup, but booting into recovery is possible (meaning the MMU is setup). Additionally, the memory at 0x02035600 is still not dumpable. At 0x02048000 is still accessible.
|
|
|
|
Weird space found at 0x105c2400. Seems to contain references to usb buffer (about 48-64 bytes). Also space at 0x020307f0, but I lose access to this after booting
|
|
|
|
.. code-block:: python
|
|
|
|
self.cd.memdump_region(0x105c2400, 0x40).hex()
|
|
'0f0f00000f0008002100000000000000ffffffffffffffffffffffffffffffff0f0f00000f0008002101000000000000ffffffffffffffffffffffffffffffff'
|
|
|
|
Week 36 - 2024
|
|
--------------
|
|
Interesting links:
|
|
- `Heap overflow <https://highaltitudehacks.com/2020/09/05/arm64-reversing-and-exploitation-part-1-arm-instruction-set-heap-overflow.html>`_
|
|
- `UART on S8 <https://grimler.se/posts/exynos-uart/>`_
|
|
|
|
By accident found space at 0x11207010. Seems to be a memory read/write space. Not executable however, unless the MMU is turned off.
|
|
|
|
We can use this space to store our debugger, and patch the boot process. After loading BL2, we're now indeed loading VBAR's for EL1.
|
|
|
|
bl31
|
|
MMU is 0x0 (0x1=enabled, 0x0=disabled)
|
|
TTBR0_EL3: 0xbc4640892f1460, TTBR1_EL2: 0x854d39cb76f0, TTBR0_EL1: 0xa5c20f408c581142
|
|
VBAR_EL3: 0x18800, VBAR_EL2: 0x0, VBAR_EL1: 0x0
|
|
TCR_EL3: 0x0, TCR_EL2: 0x80800000, TCR_EL1: 0x0
|
|
SCTLR_EL3: 0xc5183a, SCTLR_EL2: 0x30c5083a, SCTLR_EL1: 0xc5083a
|
|
MAIR_EL3: 0x44e048e000098aa4, MAIR_EL2: 0x9e42bf572931240b, MAIR_EL1: 0x44e048e000098aa4
|
|
Current EL: 0xc
|
|
|
|
Jumped to 0x11207010 and back
|
|
|
|
bL2
|
|
[+] Sent stage
|
|
Connected device! 0x4e8 0x1234
|
|
MMU is 0x0 (0x1=enabled, 0x0=disabled)
|
|
TTBR0_EL3: 0xbc4640892f1460, TTBR1_EL2: 0x854d39cb76f0, TTBR0_EL1: 0xa5c20f408c581142
|
|
VBAR_EL3: 0x2031800, VBAR_EL2: 0x0, VBAR_EL1: 0x2053800
|
|
TCR_EL3: 0x0, TCR_EL2: 0x80800000, TCR_EL1: 0x0
|
|
SCTLR_EL3: 0xc5183a, SCTLR_EL2: 0x30c5083a, SCTLR_EL1: 0x30c5083a
|
|
MAIR_EL3: 0x44e048e000098aa4, MAIR_EL2: 0x9e42bf572931240b, MAIR_EL1: 0x44e048e000098aa4
|
|
Current EL: 0xc
|
|
|