论坛首页 逆向工程技术区 阅读主题

[原创]KCTF2025 day6 wp

338 浏览 0 回复
#1 楼主 2026-06-01 21:08:55
以下分析都是做完题后进行的, 所以已经恢复了部分符号.先简单运行一下程序, 会发现是一个易语言写的GUI, 结合文件大小应该是静态编译的. 然后随意输入一些数据点击登录没有反应, 题目说明中提到验证失败没有弹窗或弹出错误提示, 再试了一下更长的输入发现有错误提示的图片了, 二分法可以快速定位到这个临界值是31字节, 说明要提交的答案大概率就是31字节长的.接下来开始分析, 既然是WindowsGUI程序, 获取输入框内容大概率要用到GetWindowTextW, 刚好题目也导入了这个函数, 为了避开一些初始化时的反调试(如果有的话), 下面的调试都是启动程序后附加调试的.在GetWindowTextW下好断点后点击登录成功断下, step out发现获取到了输入: 硬件断点跟踪数据流到某个地方发现反汇编失败了: 观察一下会发现一条陌生的指令bextr, 应该就是它导致了这个错误, 并且这个错误发生后IDA的反汇编器会直接摆烂不再可以进行反汇编.继续跟踪数据流发现了输入长度和一个熟悉的立即数进行了比较: 并且这个函数没有那条神必指令, 重启IDA来到这个函数进行反汇编, 若输入长度>= 0x1f就会把输入当参数进到do_check(12351552), 从f5结果来看输入只进到了这几个函数里进行处理: 调试可以发现前两个都是拷贝函数, 第三个函数真正进行了加密操作, 而为了确定加密的范围继续追踪这一步的密文, 下一次程序断下就来到了最后一个函数中, 并且和一段字节进行了比较: 在内存中搜索和加密结果比较的字节串可以在数据段找到: 修改比较结果发现可以弹出正确提示: 也就是说真正的加密逻辑只用看encrypt(12352547), 继续硬断追踪数据流, 第一步加密是将输入零扩展成DWORD: 再跟到下一步会发现在123533C6进行了写回: 在上面两个调用上下断点, 实际上callsm就是一个跳板函数, 用于调用放在EBX中的函数, 第一个跳板在每i次调用时从未被零扩展的ser取出ser[(4 - (i & 3)) * (i >> 2) : (i >> 2) << 2], 例如输入的是1234, 那么每次取出的就是:这里1替换成?是因为调试会发现每次取出一个DWORD时最高字节都会变化, 这个变化才是真正的第二步加密, 这里的两个跳板实际上执行的就是第二步加密完后再零扩展存入.取出的DWORD来自[ebp-30h], 向上溯源, 这个值来自: 跳板执行的do_xor实际上是将第二个参数和第五个参数进行异或: 再向上溯源, 这个异或的字节来自[ebp-0x64]: 是一个有意义的字节串, 应该就是异或的key, 到这里总结一下真正的第一步加密:继续跟踪数据流, 第二个字节的处理先是加了0x100: 这里用浮点数实现貌似是易语言特性, 接下来这个值被当作下标从一个表中取出一个字节存回.第三个字节的断点在12353581被触发, 准备通过跳板进行异或操作, 和它异或的字节就是上面加密完的第二个字节: 在这两个操作上下断点会发现它们是交替执行的, 总结一下这两步加密接下来要解决的问题就是执行轮次的问题, 从f5的结果来看大概是执行114514 * 0x20轮: 在那两个操作上下条件断点分析轮次问题:


登录后可查看完整内容

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-288237.htm

暂无回复,快来抢沙发吧!

请登录后参与讨论

立即登录 注册账号