Revert changes in exploit.py
This commit is contained in:
parent
34ca995109
commit
416521c8c7
@ -12,7 +12,9 @@ pages:
|
|||||||
- python -m venv venv
|
- python -m venv venv
|
||||||
- source venv/bin/activate
|
- source venv/bin/activate
|
||||||
- pip install -r <(head -n -1 requirements.txt)
|
- pip install -r <(head -n -1 requirements.txt)
|
||||||
- documentation/make html
|
- cd documentation
|
||||||
|
- make html
|
||||||
|
- cd ..
|
||||||
- cp -r documentation/build/* .public
|
- cp -r documentation/build/* .public
|
||||||
- mv .public public
|
- mv .public public
|
||||||
artifacts:
|
artifacts:
|
||||||
|
@ -17,8 +17,6 @@ After exploitation the goal is to fully boot the device. The following part desc
|
|||||||
|
|
||||||
This is under development and will still change.
|
This is under development and will still change.
|
||||||
|
|
||||||
BL1
|
|
||||||
---
|
|
||||||
The first stage is downloading BL1, authenticating it and patching it after authentication.
|
The first stage is downloading BL1, authenticating it and patching it after authentication.
|
||||||
This is done by overwriting the USB return address pointer and jumping back to the debugger.
|
This is done by overwriting the USB return address pointer and jumping back to the debugger.
|
||||||
In the debugger we can authenticate BL1, patch it and boot it. An overview of this process is shown below:
|
In the debugger we can authenticate BL1, patch it and boot it. An overview of this process is shown below:
|
||||||
@ -36,8 +34,6 @@ Booting an authenticated and patched BL1:
|
|||||||
|
|
||||||
Next up is BL31, which is loaded by BL1.
|
Next up is BL31, which is loaded by BL1.
|
||||||
|
|
||||||
BL31
|
|
||||||
----
|
|
||||||
``BL31`` is the secure monitor. The monitor uses memory that is also being used by the debugger, so we will have to relocate it to keep code exeuction.
|
``BL31`` is the secure monitor. The monitor uses memory that is also being used by the debugger, so we will have to relocate it to keep code exeuction.
|
||||||
|
|
||||||
.. figure:: images/bl31_debugger_memory_example.png
|
.. figure:: images/bl31_debugger_memory_example.png
|
||||||
@ -127,8 +123,9 @@ The processor state reported then is:
|
|||||||
X21 : 0x0 | X22 : 0x0 | X23 : 0x0 | X24 : 0x0 | X25 : 0x0 | X26 : 0x0 | X27 : 0x1 |
|
X21 : 0x0 | X22 : 0x0 | X23 : 0x0 | X24 : 0x0 | X25 : 0x0 | X26 : 0x0 | X27 : 0x1 |
|
||||||
X28 : 0x0 | X29 : 0x2020f00 | LR/X30 : 0x20c0000 | SP/X31 : 0x2020ef0
|
X28 : 0x0 | X29 : 0x2020f00 | LR/X30 : 0x20c0000 | SP/X31 : 0x2020ef0
|
||||||
|
|
||||||
Initial boot function
|
Initial boot function (BL1)
|
||||||
---
|
---------------------
|
||||||
|
|
||||||
.. figure:: images/initial_boot_function.png
|
.. figure:: images/initial_boot_function.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
@ -186,9 +183,79 @@ BL1 is laoded at the download buffer and self copies to ``0x02024000`` and resum
|
|||||||
|
|
||||||
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).
|
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. (How is this done in Ghidra?). We seem to lose control of our debugger once we step into the `some_weird_brom_function`.
|
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:: dtsi
|
||||||
|
|
||||||
|
/* 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.
|
||||||
|
|
||||||
|
BL31
|
||||||
|
----
|
||||||
|
|
||||||
|
BL31 is written at 0x02024000 with the entry point at 0x02024010.
|
||||||
|
|
||||||
|
BL2
|
||||||
|
---
|
||||||
|
|
||||||
|
0x02e8dc mentions 'Onyx-OPR6-8511R1', which is likely sboot.
|
||||||
|
|
||||||
|
OLD
|
||||||
|
---
|
||||||
|
|
||||||
TODO TODO TODO
|
|
||||||
The reason for this is the following code in bl1:
|
The reason for this is the following code in bl1:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
@ -238,52 +305,3 @@ Replacing this function with our debugger makes us jump back:
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
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:: dtsi
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
|
@ -39,7 +39,13 @@ TODO make memory layout of ROM, IMEM and some devices @JONHE
|
|||||||
.. figure:: images/memory_layout.drawio.svg
|
.. figure:: images/memory_layout.drawio.svg
|
||||||
|
|
||||||
The memory layout of the Exynos 8890
|
The memory layout of the Exynos 8890
|
||||||
|
|
||||||
|
- 0x00000000 to 0x00020000: BootROM
|
||||||
|
- 0x000002c0: BL1 boot entry point
|
||||||
|
- 0x00012848: bootrom authentication function
|
||||||
|
- 0x00019310: BL1 boot function
|
||||||
|
- 0x02069000: First debugger location
|
||||||
|
|
||||||
|
|
||||||
Download protocol
|
Download protocol
|
||||||
-----------------
|
-----------------
|
||||||
|
1380
documentation/source/_ignore/draw_boot.ipynb
Normal file
1380
documentation/source/_ignore/draw_boot.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,8 @@ extensions = [ 'myst_parser',
|
|||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
exclude_patterns = []
|
exclude_patterns = []
|
||||||
|
|
||||||
|
# Ignore
|
||||||
|
exclude_patterns = ['_ignore']
|
||||||
|
|
||||||
# select the theme
|
# select the theme
|
||||||
html_theme = 'sphinx_wagtail_theme'
|
html_theme = 'sphinx_wagtail_theme'
|
||||||
|
@ -12,4 +12,7 @@ pyhidra
|
|||||||
sphinxcontrib.confluencebuilder
|
sphinxcontrib.confluencebuilder
|
||||||
sphinxcontrib.drawio
|
sphinxcontrib.drawio
|
||||||
sphinx_wagtail_theme
|
sphinx_wagtail_theme
|
||||||
|
plotly
|
||||||
|
numpy
|
||||||
|
nbformat>4.2.0
|
||||||
source/ghidra_assistant/ghidra_assistant-0.0.1-py3-none-any.whl
|
source/ghidra_assistant/ghidra_assistant-0.0.1-py3-none-any.whl
|
@ -625,18 +625,6 @@ class ExynosDevice():
|
|||||||
|
|
||||||
self.cd.memwrite_region(0x02021880, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br"))
|
self.cd.memwrite_region(0x02021880, self.cd.arch_dbg.sc.branch_absolute(DEBUGGER_ADDR, branch_ins="br"))
|
||||||
|
|
||||||
# self.cd.memwrite_region(0x020200a0, p32(DEBUGGER_ADDR))
|
|
||||||
# self.cd.memwrite_region(0x020200d0, p32(DEBUGGER_ADDR))
|
|
||||||
# self.cd.memwrite_region(0x020200b4, p32(DEBUGGER_ADDR))
|
|
||||||
# self.cd.memwrite_region(0x020200a4, p32(DEBUGGER_ADDR))
|
|
||||||
|
|
||||||
# self.cd.memwrite_region(0x0202297c, self.cd.arch_dbg.sc.mov_0_w0_ins + self.cd.arch_dbg.sc.ret_ins)
|
|
||||||
|
|
||||||
|
|
||||||
GADGET_RET0 = 0x00000d58
|
|
||||||
# self.cd.memwrite_region(0x20296da , p32(GADGET_RET0))
|
|
||||||
# self.cd.memwrite_region(0x20296da + 4, p32(GADGET_RET0))
|
|
||||||
|
|
||||||
# END
|
# END
|
||||||
jump_bl1(DEBUGGER_ADDR)
|
jump_bl1(DEBUGGER_ADDR)
|
||||||
|
|
||||||
@ -655,7 +643,9 @@ class ExynosDevice():
|
|||||||
|
|
||||||
self.usb_read(0x200) # GiAs
|
self.usb_read(0x200) # GiAs
|
||||||
# lr = self.cd.arch_dbg.state.LR
|
# lr = self.cd.arch_dbg.state.LR
|
||||||
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # Resore oginal boot flow
|
|
||||||
|
|
||||||
|
# self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) # Resore oginal boot flow
|
||||||
|
|
||||||
# TODO patch verification
|
# TODO patch verification
|
||||||
|
|
||||||
@ -677,13 +667,22 @@ class ExynosDevice():
|
|||||||
# ====== PATCHES TO BL31 here! ======
|
# ====== PATCHES TO BL31 here! ======
|
||||||
|
|
||||||
|
|
||||||
# Jump BL31
|
# Jump entry BL31
|
||||||
self.cd.restore_stack_and_jump(0x02024010)
|
self.cd.restore_stack_and_jump(0x02024010)
|
||||||
|
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
self.connect_device()
|
self.connect_device()
|
||||||
|
|
||||||
|
# WORKING
|
||||||
|
assert self.usb_read(0x200) == b"GiAs", "Failed to jump back to debugger"
|
||||||
|
self.cd.memwrite_region(0x020200dc, p32(hijacked_fun)) #Sets jump/X1 address at X0 0x2048000 -> Entry point of BL2
|
||||||
|
|
||||||
|
self.cd.memwrite_region(0x02020, p32(DEBUGGER_ADDR)) # Restore original boot flow
|
||||||
|
|
||||||
|
# Jump into BL2
|
||||||
|
self.cd.restore_stack_and_jump(hijacked_fun)
|
||||||
|
# END
|
||||||
|
|
||||||
# self.usb_read(0x200) # GiAs
|
# self.usb_read(0x200) # GiAs
|
||||||
# self.cd.restore_stack_and_jump(hijacked_fun)
|
# self.cd.restore_stack_and_jump(hijacked_fun)
|
||||||
@ -697,12 +696,12 @@ class ExynosDevice():
|
|||||||
# ==== Stage 4 ====
|
# ==== Stage 4 ====
|
||||||
stage4 = open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read()
|
stage4 = open("../S7/g930f_latest/g930f_sboot.bin.4.bin", "rb").read()
|
||||||
# Patching
|
# Patching
|
||||||
stage4_len = len(stage4)
|
# stage4_len = len(stage4)
|
||||||
patch_len = len(b"USB RECOVERY MODE")
|
# patch_len = len(b"USB RECOVERY MODE")
|
||||||
patch = b"ELHER HERE" + (b"\x00" * (patch_len - len(b"ELHER HERE")))
|
# patch = b"ELHER HERE" + (b"\x00" * (patch_len - len(b"ELHER HERE")))
|
||||||
patch_offset = stage4.find(b"USB RECOVERY MODE")
|
# patch_offset = stage4.find(b"USB RECOVERY MODE")
|
||||||
stage4 = stage4[:patch_offset] + patch + stage4[patch_len + patch_offset:]
|
# stage4 = stage4[:patch_offset] + patch + stage4[patch_len + patch_offset:]
|
||||||
assert len(stage4) == stage4_len, "Invalid stage4 length"
|
# assert len(stage4) == stage4_len, "Invalid stage4 length"
|
||||||
self.send_normal_stage(stage4)
|
self.send_normal_stage(stage4)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user