0xGame2024Week1WP

文章发布时间:

最后更新时间:

页面浏览:加载中...

Web

[Week 1] hello_http

image-20241006170558875

1
0xgame{1cd6a904-725f-11ef-aafb-d4d8533ec05c}

[Week 1] hello_web

1
2
<!-- 看看f14g.php -->
<!-- 此乃flag的第一段:0xGame{ee7f2040-1987-4e0a -->

image-20241006170750385

1
0xGame{ee7f2040-1987-4e0a-872d-68589c4ab3d3}

[Week 1] ez_rce

源码稍有改动(输出的源码语法有错误)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from flask import Flask, request
import subprocess

app = Flask(__name__)

@app.route("/")
def index():
return open(file).read()

@app.route("/calc", methods=['POST'])
def calculator():
expression = request.form.get('expression') or "114 1000 * 514 + p"
result = subprocess.run(["dc", "-e", expression], capture_output=True, text=True)
return result.stdout

if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)

GPT秒了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
这个 Flask 应用程序存在一个 命令注入 漏洞,因为它直接将用户输入 (expression) 传递给了 dc 计算器程序,而没有进行任何输入验证或过滤。用户可以通过构造恶意输入,执行任意命令,从而读取或操作系统文件。

漏洞原理:
dc 是一个命令行计算器,可以解释输入的数学表达式,但是如果用户在传入的表达式中嵌入其他命令,就可以利用这个漏洞执行任意代码。

漏洞利用示例:
通过 POST 请求发送特殊的表达式,注入恶意命令来读取系统文件,例如 /etc/passwd。

例子:
bash
复制代码
curl -X POST http://your-server-address:8000/calc -d "expression=114 514 + !cat /etc/passwd p"
在这个例子中:

!cat /etc/passwd 是执行命令的方式,dc 允许通过 ! 来执行 shell 命令。
p 是 dc 的一个指令,表示打印输出。
结果:
如果成功,服务器会返回 /etc/passwd 文件的内容。
防御措施:
输入验证:对用户的输入进行严格的验证和过滤,确保只允许合法的表达式被传入 dc。
禁用危险字符:过滤掉像 ! 这样的危险字符,防止通过 dc 执行 shell 命令。
使用沙箱执行:可以通过容器或沙箱来隔离执行环境,避免命令注入导致的系统破坏。

image-20241006203114231

1
0xGame{Do_You_Know_gtfobins?Try_To_Use_It!}

Misc

[Week 1] 关注 DK 盾谢谢喵

image-20241006135211987

[Week 1] 0xGame2048

1
2
3
通过一点也不可靠的途径,我们提前截获了0xGame2048的题目,据说这就是那时候的base编码(?

出题人:St4rr

安装base2048的python包

1
pip install base2048 

使用代码解不知道为什么报错

1
2
3
4
5
6
7
import base2048
print(base2048.decode('Жఱ൲ඌיય೬ࢶЖۍךะtঋළม۹ρԊҽඹ'))

File "C:\Users\Administrator\Documents\VScodeFiles\算法\main.py", line 5, in <module>
print(base2048.decode('Жఱ൲ඌיય೬ࢶЖۍךะtঋළม۹ρԊҽඹ'))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
base2048.DecodeError: Unexpected character 5: ['ય'] after termination sequence 4: ['י']

使用在线解密

1
https://nerdmosis.com/tools/encode-and-decode-base2048
1
0xGame{W3lc0me_t0_0xG4me!!!}

[Week 1] 一明一暗

1
2
3
糟糕!St4rr忘记了自己设的压缩包密码,被压缩的三个文件在清理电脑时又误删了两个。。。这该怎么办?

出题人:St4rr

Bandzip压缩给的图片然后使用ARCHPR明文爆破

image-20241006151341425

得到密钥解密之后解压压缩包

image-20241006151425340

查看提示

1
Emmmmmmmmm,seems like there's a watermark in the picture, but i can't see it directly......

使用水印工具提取

image-20241006152643251

1
0xGame{N0w_st4rt_uR_j0urn3y!!}

[Week 1] 加密的压缩包?

1
2
3
压缩包看起来好像没加密啊,怎么会解压不了呢?怎么注释里还给了个密码?

出题人:w8nn9z

这里改成0F即可,使用压缩包底部的密码解压0xGame2024

image-20241006140926278

1
0xGame{M@ybe_y0u_ar2_t4e_mAsTer_0f_Z1p}

Crypto

[Week 1] Caesar Cipher

1
2
3
4
5
密文:0yHbnf{Uif_Cfhjoojoh_Pg_Dszqup}

提示:凯撒加密。

若无特殊说明,FLAG格式均为0xGame{...}。

image-20241006141336536

1
0xGame{The_Beginning_Of_Crypto}

Reverse

[Week 1] BabyBase

使用IDA打开按F5转伪代码

image-20241006160947173

查看这里base64解码得到flag

image-20241006161012582

image-20241006160923198

1
0xGame{N0w_y0u_kn0w_B4se64_Enc0d1ng_w3ll!}

[Week 1] BinaryMaster

IDA打开F5转伪代码即可获取flag

image-20241006161214018

1
0xGame{114514cc-a3a7-4e36-8db1-5f224b776271}

[Week 1] SignSign

IDA打开F5转伪代码获取一半flag

1
_b3g1n_Reversing_n0w}

shift+F12查看字符串找到另一半

image-20241006161558989

1
0xGame{S1gn1n_h3r3_4nd_b3g1n_Reversing_n0w}

[Week 1] Xor-Beginning

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
int __fastcall main(int argc, const char **argv, const char **envp)
{
char v4[64]; // [rsp+20h] [rbp-70h] BYREF
char v5[40]; // [rsp+60h] [rbp-30h] BYREF
int v6; // [rsp+88h] [rbp-8h]
int v7; // [rsp+8Ch] [rbp-4h]

_main(argc, argv, envp);
v7 = 0;
v6 = 0;
qmemcpy(v5, "~5\v*',3", 7);
v5[7] = 0x1F;
v5[8] = 0x76;
v5[9] = 55;
v5[10] = 27;
v5[11] = 114;
v5[12] = 49;
v5[13] = 30;
v5[14] = 54;
v5[15] = 12;
v5[16] = 76;
v5[17] = 68;
v5[18] = 99;
v5[19] = 114;
v5[20] = 87;
v5[21] = 73;
v5[22] = 8;
v5[23] = 69;
v5[24] = 66;
v5[25] = 1;
v5[26] = 90;
v5[27] = 4;
v5[28] = 19;
v5[29] = 76;
printf("你的flag是什么? \n请在这里输入:");
scanf("%s", v4);
while ( v4[v7] )
{
v4[v7] ^= 78 - (_BYTE)v7;
++v7;
}
while ( v6 < v7 )
{
if ( v4[v6] != (unsigned __int8)v5[v6] || v7 != 30 )
{
printf("\n错误, 请重试! ");
system("pause");
exit(0);
}
++v6;
}
puts("\n正确!");
system("pause");
return 0;
}
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
# 预设的比较值
v5 = [
0x7E, 0x35, 0x0B, 0x2A, 0x27, 0x2C, 0x33, 0x1F, 0x76, 0x37,
0x1B, 0x72, 0x31, 0x1E, 0x36, 0x0C, 0x4C, 0x44, 0x63, 0x72,
0x57, 0x49, 0x08, 0x45, 0x42, 0x01, 0x5A, 0x04, 0x13, 0x4C
]
# 当代码中写 v5[7] = 31; 时:

# 31 是一个十进制数。
# 在计算机中,这个数字以二进制形式存储:00011111
# 用十六进制表示就是 0x1F
# 这就是为什么 v5[7] = 31; 对应 0x1F 的原因。

# 同样的原理适用于其他的赋值:

# v5[8] = 118; 对应 0x76,因为 118 的十六进制表示就是 76
# v5[9] = 55; 对应 0x37,因为 55 的十六进制表示就是 37
# 以此类推...

# 反向操作获取flag
flag = ""
for i in range(30): # v7 应该等于30
flag += chr(v5[i] ^ (78 - i))

print("Flag:", flag)
1
0xGame{X0r_1s_v3ry_Imp0rt4n7!}

[Week 1] Xor-Endian

1
2
3
刚开始就end了吗?

不对!这明明是endian
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
import ctypes

def decrypt(encrypted, key, length, key_length):
result = bytearray(length)
for i in range(length):
result[i] = encrypted[i] ^ key[i % key_length]
return result

# 预设的加密值
v6 = [
1363025275, 253370901, 1448151638, 1415391232,
91507463, 139743552, 1450318164, 1985283101,
1465125718, 1934953223, 84430593, 0
]

# 转换为字节数组
encrypted = b''.join(ctypes.c_uint32(x).value.to_bytes(4, 'little') for x in v6)

key = b"Key0xGame2024"
length = 44
key_length = 13

decrypted = decrypt(encrypted, key, length, key_length)

print("Decrypted flag:", decrypted.decode('ascii', errors='ignore'))

AI写脚本

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
这段代码看起来是一个加密验证程序。我们需要找出正确的输入,使得加密后的结果与预设的值相匹配。让我们来分析一下:

程序读取输入到 v7 数组。
v6 数组包含了预设的值。
输入通过 encrypt 函数进行加密,使用的密钥是 "Key0xGame2024"。
加密后的结果与 v6 数组比较。
要解密这个,我们需要逆向 encrypt 函数。但是,我们没有 encrypt 函数的具体实现。不过,我们可以尝试使用已知的信息来推断原始输入。

这里是一个可能的解决方案:

python

复制
import ctypes

def decrypt(encrypted, key, length, key_length):
result = bytearray(length)
for i in range(length):
result[i] = encrypted[i] ^ key[i % key_length]
return result

# 预设的加密值
v6 = [
1363025275, 253370901, 1448151638, 1415391232,
91507463, 139743552, 1450318164, 1985283101,
1465125718, 1934953223, 84430593, 0
]

# 转换为字节数组
encrypted = b''.join(ctypes.c_uint32(x).value.to_bytes(4, 'little') for x in v6)

key = b"Key0xGame2024"
length = 44
key_length = 13

decrypted = decrypt(encrypted, key, length, key_length)

print("Decrypted flag:", decrypted.decode('ascii', errors='ignore'))
这个脚本做了以下几件事:

定义了一个 decrypt 函数,它实际上就是 encrypt 函数的逆操作(假设 encrypt 使用了简单的 XOR 加密)。
我们将 v6 数组中的 32 位整数转换为字节序列。
使用给定的密钥 "Key0xGame2024"、长度 44 和密钥长度 13 来解密数据。
最后,我们尝试将解密后的数据解码为 ASCII 字符串。
请注意,这个解决方案基于一些假设,特别是关于 encrypt 函数的实现。如果 encrypt 函数使用了更复杂的加密方法,这个简单的 XOR 解密可能无法正确工作。

另外,解密后的结果可能包含一些不可打印的字符,所以我们使用 errors='ignore' 来忽略这些字符。

运行这个脚本后,如果我们的假设正确,你应该能看到解密后的 flag 或者至少是部分可读的文本。如果结果看起来不对,那么我们可能需要更多关于 encrypt 函数的信息来正确地解密数据。
1
0xGame{X0r_1s_v3ry_Imp0rt4n7!}

Pwn

[Week 1] 0. test your nc

1
2
3
4
5
Prepare your netcat.

Connect to server then you will get your first flag.

nc 47.97.58.52 40000

image-20241006170114218

1
0xGame{928bb261-0a63-4389-b629-4d1f2f449848}