第二届AliyunCTF官方writeup
字数 1815 2025-08-05 08:18:25

AliyunCTF 2024 Writeup 技术解析文档

Web 安全挑战解析

Web 签到题

  • 漏洞类型: 命令参数注入
  • 利用方法: 通过 dig 命令的 -f 参数读取文件
  • 攻击载荷:
curl -H "Content-Type:application/json" -X POST --data '{"type":"-f/flag", "domain":"www.aliyunctf.com"}' http://localhost:23000/digHandler

chain17 (Java 反序列化)

  • 环境特点: JDK17 下的两条反序列化链(Hessian和原生)
  • 攻击流程:
    1. 通过 agent 端实现 RCE
    2. 通过 agent 访问 server
    3. 最终 RCE server 读取 flag

Agent 端利用

  • 依赖组件: hutool, h2
  • 利用链:
    JSONObject.put -> AtomicReference.toString -> POJONode.toString -> Bean.getObject -> DSFactory.getDataSource -> Driver.connect
    
  • 关键点: 使用 H2 SQL 执行实现 RCE

Server 端利用

  • 依赖组件: jooq
  • 利用链:
    EventListenerList.readObject -> POJONode.toString -> ConvertedVal.getValue -> ClassPathXmlApplicationContext.<init>
    
  • 关键点: 通过 SpEL 表达式执行实现 RCE

Pastbin (竞争条件)

  • 漏洞类型: 文件访问竞争条件
  • 利用方法: 并发访问 /flag/about 端点
  • Python 实现:
import asyncio
import aiohttp

async def send_request(session, url):
    while True:
        async with session.get(url) as resp:
            text = await resp.text()
            if "aliyunctf" in text:
                print(f"Found 'aliyunctf' in URL: {url}")
                print(text)
                exit()

async def main():
    urls = ["http://localhost:28080/about", "http://localhost:28080/flag"]
    async with aiohttp.ClientSession() as session:
        tasks = [send_request(session, url) for url in urls for _ in range(20)]
        await asyncio.gather(*tasks)

asyncio.run(main())

easyCAS (认证绕过)

  • 默认凭证: casuser/Mellon
  • 利用步骤:
    1. 访问 Dashboard 获取内存转储
    2. 使用 MAT 分析内存获取加密密钥
    3. 构造恶意请求绕过认证
  • 关键点: 通过内存分析获取 execution 参数加密细节

Pwn 挑战解析

Pwn 签到题

  • 漏洞类型: 堆利用 + 栈溢出
  • 利用步骤:
    1. 从 unsortbin 泄露 libc 地址
    2. 通过有漏洞的 scanf 函数进行栈溢出
    3. 构造 ROP 链实现任意代码执行

BadApple (JSC 漏洞)

  • 漏洞根源: 缺少 purifyNaN 调用,直接调用 boxDouble
  • 利用原语:
    1. 构造 fakeobj 原语
    2. 通过爆破实现 addrof 原语
    3. 伪造对象实现任意地址读写
    4. 写 JIT RWX 内存实现代码执行

klang (编译器漏洞)

  • 漏洞类型: 寄存器分配逻辑错误
  • 利用方法:
    1. 利用 backedge 情况下的错误处理
    2. 混淆 array 和 string 类型变量
  • 示例利用代码:
function hack() : array a, int b, array c, array d, array e, array f, array g, string h, string i -> array {
    a := array_new(4);
    b := 1;
    c := array_new(4); 
    // ... 其他变量初始化
    do {
        b := inputi();
        if(b == 1234) {
            c := array_new(c[0]); // 利用漏洞
            // ... 其他操作
        };
        b := b - 1;
        i := inputs();
        h := inputs();
    } while(b > 0);
    return d;
}

逆向工程挑战

欧拉路径问题

  • 解题思路:
    1. 分析邻接表确定存在欧拉路径
    2. 确定起点(0)和终点(4)
    3. 使用 DFS 搜索所有欧拉路径
    4. 根据约束条件过滤有效路径

RDTMA (RDMA 分析)

  • 分析步骤:
    1. 识别使用 Soft RoCEv2 实现
    2. 分析 WQE 结构体
    3. 利用 IBV_WR_ATOMIC_FETCH_AND_ADD 自修改操作
  • 投机解法: 在内存中直接搜索明文 flag

密码学挑战

BabyDH 1 (椭圆曲线低比特泄露)

  • 解题方法:
    1. 构造多项式方程
    2. 使用 Coppersmith 方法求解
    3. 利用 flatter 工具加速格归约

BabyDH 2 (椭圆曲线隐藏数问题)

  • 解题方法:
    1. 复现 ECHNP 研究成果
    2. 修改格构造适应低比特泄露场景
    3. 使用 flatter 工具加速求解

Doctored Dobbertin v2 (可调分组密码)

  • 后门利用:
    1. 寻找特定 tweak 使轮常数抵消
    2. 发送全0明文获取密钥信息
    3. 枚举剩余密钥字节

杂项挑战

字 (隐写术)

  • 解题步骤:
    1. 提取康熙部首替换模式获取二进制串
    2. 按7位分组转换为区位码
    3. 解码 GB2312 获取 flag

帕鲁情绪管理 (朴素贝叶斯分类)

  • 解题方法:
    1. 构建训练数据集
    2. 使用词袋模型特征提取
    3. 训练朴素贝叶斯分类器
    4. 迭代优化模型准确率

系统安全挑战

netatalk (权限提升)

  • 漏洞根源: AppleDouble 元数据验证缺失
  • 利用链:
    1. 泄露内存布局信息
    2. 覆盖函数指针
    3. 构造 ROP 链执行特权命令

SYSTEM (Windows 驱动漏洞)

  • 漏洞类型: MDL 双重释放
  • 利用方法:
    1. 将 double free 转化为 UAF
    2. 使用特定对象堆喷占位
    3. 修改 _KTHREAD.PreviousMode 构造读写原语

alibus (D-Bus 配置错误)

  • 利用方法:
    1. 实现恶意 PolicyKit 服务
    2. 绕过认证创建特权账户
    3. 通过新账户提升权限

总结

本CTF涵盖了广泛的安全领域技术,从传统的Web漏洞到新兴的RDMA安全研究,展示了现代系统安全防护与攻击的多样性。特别值得注意的是JDK17下的新型反序列化链构造、可调分组密码的后门利用以及RDMA领域的新型攻击面,这些都为安全研究人员提供了宝贵的学习素材。

AliyunCTF 2024 Writeup 技术解析文档 Web 安全挑战解析 Web 签到题 漏洞类型 : 命令参数注入 利用方法 : 通过 dig 命令的 -f 参数读取文件 攻击载荷 : chain17 (Java 反序列化) 环境特点 : JDK17 下的两条反序列化链(Hessian和原生) 攻击流程 : 通过 agent 端实现 RCE 通过 agent 访问 server 最终 RCE server 读取 flag Agent 端利用 依赖组件 : hutool, h2 利用链 : 关键点 : 使用 H2 SQL 执行实现 RCE Server 端利用 依赖组件 : jooq 利用链 : 关键点 : 通过 SpEL 表达式执行实现 RCE Pastbin (竞争条件) 漏洞类型 : 文件访问竞争条件 利用方法 : 并发访问 /flag 与 /about 端点 Python 实现 : easyCAS (认证绕过) 默认凭证 : casuser/Mellon 利用步骤 : 访问 Dashboard 获取内存转储 使用 MAT 分析内存获取加密密钥 构造恶意请求绕过认证 关键点 : 通过内存分析获取 execution 参数加密细节 Pwn 挑战解析 Pwn 签到题 漏洞类型 : 堆利用 + 栈溢出 利用步骤 : 从 unsortbin 泄露 libc 地址 通过有漏洞的 scanf 函数进行栈溢出 构造 ROP 链实现任意代码执行 BadApple (JSC 漏洞) 漏洞根源 : 缺少 purifyNaN 调用,直接调用 boxDouble 利用原语 : 构造 fakeobj 原语 通过爆破实现 addrof 原语 伪造对象实现任意地址读写 写 JIT RWX 内存实现代码执行 klang (编译器漏洞) 漏洞类型 : 寄存器分配逻辑错误 利用方法 : 利用 backedge 情况下的错误处理 混淆 array 和 string 类型变量 示例利用代码 : 逆向工程挑战 欧拉路径问题 解题思路 : 分析邻接表确定存在欧拉路径 确定起点(0)和终点(4) 使用 DFS 搜索所有欧拉路径 根据约束条件过滤有效路径 RDTMA (RDMA 分析) 分析步骤 : 识别使用 Soft RoCEv2 实现 分析 WQE 结构体 利用 IBV_ WR_ ATOMIC_ FETCH_ AND_ ADD 自修改操作 投机解法 : 在内存中直接搜索明文 flag 密码学挑战 BabyDH 1 (椭圆曲线低比特泄露) 解题方法 : 构造多项式方程 使用 Coppersmith 方法求解 利用 flatter 工具加速格归约 BabyDH 2 (椭圆曲线隐藏数问题) 解题方法 : 复现 ECHNP 研究成果 修改格构造适应低比特泄露场景 使用 flatter 工具加速求解 Doctored Dobbertin v2 (可调分组密码) 后门利用 : 寻找特定 tweak 使轮常数抵消 发送全0明文获取密钥信息 枚举剩余密钥字节 杂项挑战 字 (隐写术) 解题步骤 : 提取康熙部首替换模式获取二进制串 按7位分组转换为区位码 解码 GB2312 获取 flag 帕鲁情绪管理 (朴素贝叶斯分类) 解题方法 : 构建训练数据集 使用词袋模型特征提取 训练朴素贝叶斯分类器 迭代优化模型准确率 系统安全挑战 netatalk (权限提升) 漏洞根源 : AppleDouble 元数据验证缺失 利用链 : 泄露内存布局信息 覆盖函数指针 构造 ROP 链执行特权命令 SYSTEM (Windows 驱动漏洞) 漏洞类型 : MDL 双重释放 利用方法 : 将 double free 转化为 UAF 使用特定对象堆喷占位 修改 _ KTHREAD.PreviousMode 构造读写原语 alibus (D-Bus 配置错误) 利用方法 : 实现恶意 PolicyKit 服务 绕过认证创建特权账户 通过新账户提升权限 总结 本CTF涵盖了广泛的安全领域技术,从传统的Web漏洞到新兴的RDMA安全研究,展示了现代系统安全防护与攻击的多样性。特别值得注意的是JDK17下的新型反序列化链构造、可调分组密码的后门利用以及RDMA领域的新型攻击面,这些都为安全研究人员提供了宝贵的学习素材。