第二届“长城杯”铁人三项赛 (防护赛)初赛WriteUP
字数 2008 2025-08-22 12:22:30
第二届“长城杯”铁人三项赛(防护赛)初赛WriteUP
Web安全部分
0x00 Safe_Proxy
题目分析
这是一个基于Flask的Web应用,主要功能包括:
- GET请求访问根路径会返回当前Python脚本源码
- POST请求可以提交模板代码进行渲染
- 实现了简单的HTTP代理功能
漏洞点
- SSTI(服务器端模板注入)漏洞存在于POST路由的
render_template_string函数 - 黑名单过滤不完善:
blacklist = ['__', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system', '\r', '\n']
利用方法
- 使用Fenjing工具自动构造绕过黑名单的SSTI payload
- 构造payload访问全局变量和内置函数:
{%print g.pop[' '\ 2+'globals'+' ' 2][' '\ 2+'builtins'+' ' 2] ' '\ 2+'i''mport'+' ' 2 'p''open' .read()%} - 通过URL编码后提交,成功读取flag
防御建议
- 避免直接使用用户输入渲染模板
- 使用更严格的白名单过滤
- 使用Jinja2的沙箱环境
0x01 hello_web
题目分析
- 存在文件包含漏洞,尝试访问
....//hackme.php - 发现PHP代码混淆,需要解码
解题步骤
- 通过双写绕过过滤:
....//hackme.php - 解码PHP混淆代码:
- 分析字符串拼接和变量构造
- 提取关键函数调用链
- 最终找到flag路径:
/var/run/log/13c448004444d2791e0661fa2f216b20/flag
关键代码
$lapUCm = urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
$YwzIst = $lapUCm{3}.$lapUCm{6}.$lapUCm{33}.$lapUCm{30};
密码学部分
0x00 rasnd
题目分析
- 分为两部分flag,使用RSA加密
- 第一部分给出两个线性方程作为hint:
hint1 = x1*p + y1*q - 0x114hint2 = x2*p + y2*q - 0x514
- 第二部分给出特殊hint:
hint = pow(514*p - 114*q, n - p - q, n)
解题步骤
-
第一部分:
- 爆破x1, x2, y1, y2的可能值
- 计算gcd(k-w, n)获取p或q
- 使用常规RSA解密方法获取flag1
-
第二部分:
- 利用欧拉定理和模运算性质
- 构造矩阵方程求解
- 使用BKZ算法寻找短向量解
关键代码
for i in trange(211):
for w in range(211):
k = (hint1 + 0x114) * i
w = (hint2 + 0x514) * w
l = gcd(k - w, n)
if l != 1 and isPrime(l):
p = l
q = n // p
d = inverse(65537, (p-1)*(q-1))
m = pow(c, d, n)
0x01 fffffhash
题目分析
自定义哈希函数:
def giaogiao(hex_string):
base_num = 0x6c62272e07bb014262b821756295c58d
x = 0x0000000001000000000000000000013b
MOD = 2**128
for i in hex_string:
base_num = (base_num * x) & (MOD - 1)
base_num ^= i
return base_num
解题步骤
- 使用线性代数和模运算逆向计算
- 构建矩阵方程并应用BKZ算法
- 通过位运算特性恢复原始输入
关键代码
M = Matrix.column([p_value^(n - i - 1) for i in range(n)] + [-(wpk_value - key * p_value^n), limit])
M = M.BKZ()
for row in M:
if row[0] == 0 and abs(row[-1]) == 1:
valid_solution = row[1:-1]
break
逆向工程部分
0x00 ezCsky
题目分析
- IDA无法正常反编译,需要尝试不同版本
- 发现RC4加密算法和密钥
- 密文存储在程序中
解题步骤
- 实现RC4解密算法
- 发现密文需要倒序按位异或
- 编写解密脚本获取flag
关键代码
class RC4:
def __init__(self, key):
self.S = list(range(256))
self.key = [ord(char) for char in key]
self.ksa()
def ksa(self):
j = 0
for i in range(256):
j = (j + self.S[i] + self.key[i % len(self.key)]) % 256
self.S[i], self.S[j] = self.S[j], self.S[i]
0x01 dump
题目分析
- 命令行程序,逐字符加密
- 通过动态调试发现加密逻辑
- 需要爆破每个字符
解题步骤
- 编写爆破脚本尝试所有可打印字符
- 通过比较输出结果与已知密文匹配
- 逐步构建完整flag
关键代码
for (int j = 0; printable[j] != '\0'; j++) {
snprintf(flag + strlen(flag), 2, "%c", printable[j]);
fp = popen(flag, "r");
fgets(output, MAX_OUTPUT_LEN, fp);
fclose(fp);
if (strcmp(hex_pair, enc[index]) == 0) {
printf("%c", printable[j]);
break;
}
}
PWN部分
0x00 anote
题目分析
- 没有开启PIE保护
- 提供add、edit、show功能,没有free
- 存在后门函数backdoor
漏洞利用
- 利用edit函数中的函数指针调用漏洞
- 构造特殊chunk布局覆盖函数指针
- 调用backdoor函数执行shellcode
EXP代码
backdoor_addr = 0x080489CE
add()
add()
edit(0, p32(backdoor_addr)+p32(0)*4+p32(0x21)+p32(gift_addr+8))
edit(1, b"aaaa")
威胁检测与网络流量分析
zeroshell系列题目
解题要点
-
zeroshell_1:
- 使用strings工具查找base64编码的flag
- 解码获取真实flag
-
zeroshell_2:
- 分析HTTP流量中的RCE payload
- 发现利用tar命令的checkpoint-action参数执行任意命令
- 通过curl下载并执行远程脚本
-
zeroshell_3/4:
- 分析.nginx恶意文件
- 使用IDA反编译发现外联IP和可疑字符串
- 确定恶意软件功能和外联地址
-
zeroshell_5:
- 从恶意文件中提取加密密钥
- 验证密钥有效性
-
zeroshell_6:
- 查找系统启动脚本
- 发现恶意文件被复制到/tmp并执行的流程
WinFT系列题目
解题要点
-
WinFT_1:
- 分析hosts文件发现可疑域名和IP
- 确定flag格式和端口信息
-
WinFT_2:
- 检查计划任务
- 解码base64和HTML编码的flag
-
WinFT_5:
- 使用随波逐流工具分析流量
- 提取隐藏的ZIP文件
- 从文件备注中获取解压密码
-
WinFT_9:
- 查找特定IP地址
- 将IP转换为flag格式
总结
本WriteUP涵盖了多种安全技术领域,包括:
- Web安全(SSTI、文件包含)
- 密码学(RSA、自定义哈希)
- 逆向工程(RC4、恶意软件分析)
- PWN(堆利用、函数指针覆盖)
- 威胁检测(流量分析、恶意行为识别)
每个题目都展示了不同的漏洞利用技术和分析方法,强调了全面安全评估的重要性。