Started booting fwbl1

This commit is contained in:
Eljakim Herrewijnen 2024-08-05 19:37:13 +02:00
parent 934bebe0c5
commit a8cc6b3f39
18 changed files with 124 additions and 34 deletions

View File

@ -0,0 +1,13 @@
=======
Booting
=======
After exploitation the goal is to fully boot the device.
debugger
========
Some other information about the debugger and it's current state.
ROM
---

View File

@ -9,6 +9,8 @@ Protections
-----------
There are no stack canaries or guard pages, and no ASLR. Meaning there are almost no protections in place.
Rom is at address 0x0 and is unwritable(Sometimes this is writeable due to MMU caching).
Samsung Firmware
----------------
Samsung releases firmware files for their devices. These files contain the bootloader, modem, and other firmware files.

View File

@ -12,5 +12,6 @@ Documentation on Samsung devices, currently mainly the Samsung S7.
:caption: BootROMs:
BootROM_8890/index.rst
BootROM_8890/boot_chain.rst

View File

@ -1,9 +1,9 @@
#Ghidra Lock File
#Wed Jul 31 20:30:18 CEST 2024
#Sat Aug 03 17:14:04 CEST 2024
OS\ Name=Linux
OS\ Version=6.5.0-41-generic
OS\ Version=6.5.0-44-generic
Username=eljakim
Hostname=levith
<META>\ Supports\ File\ Channel\ Locking=Channel Lock
OS\ Architecture=amd64
Timestamp=7/31/24, 8\:30 PM
Timestamp=8/3/24, 5\:14 PM

View File

@ -2,14 +2,14 @@
<FILE_INFO>
<BASIC_INFO>
<STATE NAME="EXCLUSIVE" TYPE="boolean" VALUE="false" />
<STATE NAME="CHECKOUT_VERSION" TYPE="int" VALUE="1" />
<STATE NAME="CHECKOUT_VERSION" TYPE="int" VALUE="-1" />
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="Program" />
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
<STATE NAME="FILE_ID" TYPE="string" VALUE="7f0119bc3142241939494339" />
<STATE NAME="FILE_ID" TYPE="string" VALUE="7f011889d240069673442230" />
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
<STATE NAME="LOCAL_CHECKOUT_VERSION" TYPE="int" VALUE="1" />
<STATE NAME="LOCAL_CHECKOUT_VERSION" TYPE="int" VALUE="-1" />
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
<STATE NAME="CHECKOUT_ID" TYPE="long" VALUE="2" />
<STATE NAME="NAME" TYPE="string" VALUE="8890_bootrom.bin" />
<STATE NAME="CHECKOUT_ID" TYPE="long" VALUE="-1" />
<STATE NAME="NAME" TYPE="string" VALUE="8890_bootrom.bin.keep" />
</BASIC_INFO>
</FILE_INFO>

View File

@ -1,4 +1,11 @@
VERSION=1
/
NEXT-ID:0
00000002:8890_bootrom.bin:7f0119bc3142241939494339
/mib3
00000000:full_boot:7f0118059140616855428589
/s7
00000003:sboot.bin.2.bin:7f011ab837995028720085
00000004:sboot.bin.3.bin:7f011872b8163836628792
00000005:sboot.bin.4.bin:7f011842b8231996037592
NEXT-ID:6
MD5:d41d8cd98f00b204e9800998ecf8427e

View File

@ -3,5 +3,9 @@ VERSION=1
00000002:8890_bootrom.bin:7f0119bc3142241939494339
/mib3
00000000:full_boot:7f0118059140616855428589
NEXT-ID:3
/s7
00000003:sboot.bin.2.bin:7f011ab837995028720085
00000004:sboot.bin.3.bin:7f011872b8163836628792
00000005:sboot.bin.4.bin:7f011842b8231996037592
NEXT-ID:6
MD5:d41d8cd98f00b204e9800998ecf8427e

View File

@ -1,10 +0,0 @@
FADD:/NewFolder
FMV:/NewFolder:/mib3
IADD:00000000:/mib3/fwbl1_a.bin
IDSET:/mib3/fwbl1_a.bin:7f0118059140616855428589
IMV:/mib3/fwbl1_a.bin:/mib3/full_boot
IADD:00000001:/mib3/8890_bootrom.bin
IDSET:/mib3/8890_bootrom.bin:7f011974d142238523757581
IADD:00000002:/8890_bootrom.bin
IDSET:/8890_bootrom.bin:7f0119bc3142241939494339
IDEL:/mib3/8890_bootrom.bin

View File

@ -1,4 +1,8 @@
VERSION=1
/
NEXT-ID:0
00000000:udf_7f0118059140616855428589:7f0118d0b142268235940037
00000003:udf_7f011872b8163836628792:7f011a9478217161533597
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
NEXT-ID:4
MD5:d41d8cd98f00b204e9800998ecf8427e

View File

@ -1,5 +1,9 @@
VERSION=1
/
00000000:udf_7f0118059140616855428589:7f0118d0b142268235940037
NEXT-ID:1
00000004:udf_7f011842b8231996037592:7f01190f112184430945139
00000003:udf_7f011872b8163836628792:7f011a9478217161533597
00000001:udf_7f0119bc3142241939494339:7f011abb7142807435236045
00000002:udf_7f011ab837995028720085:7f0118cdd8148515697603
NEXT-ID:5
MD5:d41d8cd98f00b204e9800998ecf8427e

View File

@ -1,2 +1,2 @@
IADD:00000000:/udf_7f0118059140616855428589
IDSET:/udf_7f0118059140616855428589:7f0118d0b142268235940037
IADD:00000004:/udf_7f011842b8231996037592
IDSET:/udf_7f011842b8231996037592:7f01190f112184430945139

View File

@ -1,2 +0,0 @@
IADD:00000001:/udf_7f0119bc3142241939494339
IDSET:/udf_7f0119bc3142241939494339:7f011abb7142807435236045

View File

@ -1,2 +1,4 @@
*.elf
*.o
*.bin
venv/

View File

@ -18,6 +18,7 @@
"request": "launch",
"program": "exploit.py",
"console": "integratedTerminal",
"justMyCode": false,
"args": []
}
]

View File

@ -4,6 +4,8 @@ from keystone import *
from capstone import *
from ghidra_assistant.utils.utils import *
from ghidra_assistant.concrete_device import *
from ghidra_assistant.utils.debugger.debugger_archs.ga_arm64 import GA_arm64_debugger
from qiling.const import QL_ARCH
def p32(x):
return struct.pack("<I", x)
@ -17,6 +19,9 @@ def p16(x):
def p64(x):
return struct.pack("<Q", x)
logger = setup_logger("") #Leave empty to get root logger
logger.setLevel(logging.DEBUG)
BLOCK_SIZE = 512
CHUNK_SIZE = 0xfffe00
MAX_PAYLOAD_SIZE = (BLOCK_SIZE - 10)
@ -174,18 +179,71 @@ class ExynosDevice():
def usb_write(self, data):
assert len(data) <= 0x200, "Data too big"
transferred = ctypes.c_int()
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, data, len(data), ctypes.byref(transferred), 0)
assert res == 0, "Error sending data"
assert transferred.value == len(data), "Invalid transfered size"
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, data, len(data), ctypes.byref(transferred), 300)
assert res == 0, f"Error sending data {res}"
assert transferred.value == len(data), f"Invalid transfered size {transferred.value} != {len(data)}"
return transferred.value
def usb_read(self, size):
transferred = ctypes.c_int()
buf = ctypes.c_buffer(b"", size)
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_IN, buf, len(buf), ctypes.byref(transferred), 0)
assert res == 0, "Error receiving data"
res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_IN, buf, len(buf), ctypes.byref(transferred), 300)
assert res == 0, f"Error receiving data {res}"
return buf.raw[:transferred.value]
def setup_concrete_device(self, concrete_device : ConcreteDevice):
#Setup architecture
concrete_device.arch = QL_ARCH.ARM64
concrete_device.ga_debugger_location = 0x2069000 # TODO, not used yet
concrete_device.ga_vbar_location = 0x206d000 + 0x1000
concrete_device.ga_storage_location = 0x206d000
concrete_device.ga_stack_location = 0x206b000
concrete_device.arch_dbg = GA_arm64_debugger(concrete_device.ga_vbar_location, concrete_device.ga_debugger_location, concrete_device.ga_storage_location)
concrete_device.arch_dbg.read = self.usb_read
concrete_device.arch_dbg.write = self.usb_write
#Overwrite all calls to make the concrete target function properly
concrete_device.copy_functions()
def setup_debugger(self):
'''
Setup the debugger as a concrete device
'''
self.cd = ConcreteDevice(None, False)
self.cd.dev = self.setup_concrete_device(self.cd)
self.cd.test_connection()
def dumb_interact(self):
'''
Room for playing around with the debugger
'''
self.cd.arch_dbg.state.auto_sync = False
self.cd.arch_dbg.state.print_ctx()
AUTH_BL1 = 0x00012848
def memdump_try():
dumped = b""
for block in range(0x2020000, 0x2200000, 0x200):
print(hex(block))
dumped += self.cd.memdump_region(block, 0x200)
def auth_bl1():
# Load the firmware
self.cd.arch_dbg.state.X0 = 1
self.cd.arch_dbg.state.X1 = 1
self.cd.arch_dbg.state.LR = 0x2069000 #jump back to debugger when finished
self.cd.restore_stack_and_jump(AUTH_BL1)
fwbl1 = open("../S7/fwbl1.bin", "rb").read()
self.cd.memwrite_region(0x02021800, fwbl1)
memdump_try()
auth_bl1()
self.cd.arch_dbg.state.print_ctx()
#authenticate it
pass
def run_boot_chain(self):
stage1 = open("stage1/stage1.bin", "rb").read()
self.exploit(stage1)
@ -197,6 +255,7 @@ class ExynosDevice():
assert len(debugger) == 0x2000, "Invalid debugger size, stage1 requires 0x2000 size"
for block in range(0, len(debugger), 0x200):
self.usb_write(debugger[block:block+0x200])
# time.sleep(.5) # Wait a little bit
assert self.usb_read(0x200) == b"GiAs", "No response from debugger"
# Test basic functionality
@ -205,6 +264,9 @@ class ExynosDevice():
assert r == b"PONG", f"Invalid response from device: {r}"
run_debugger()
self.setup_debugger()
self.dumb_interact()

View File

@ -1,9 +1,11 @@
from ghidra_assistant.ghidra_assistant import GhidraAssistant
if __name__ == "__main__":
rom = open("S7/rom.bin", 'rb').read()
# rom = open("S7/rom.bin", 'rb').read()
imem = open("exynos_imem_0x02020000_0x2070000.bin", 'rb').read()
ga = GhidraAssistant()
ga.ghidra.add_memory(rom, 0x0, True, "ROM")
# ga.ghidra.add_memory(rom, 0x0, True, "ROM")
ga.ghidra.add_memory(imem, 0x02020000, True, "IMEM")
pass