上周末独自尝试了阿里云2024的CTF,只做出了Reverse的第一题,记录一下。
题目
是一个cmd exe可执行文件,需要input一个字符串。
解题工具
解题需要用到的工具包括
- x64dbg:Windows平台的程序动态调试工具
- IDA64:可执行文件、动态链接库的程序静态分析工具
- 通义千问:用于分析反编译生成的伪代码,并根据逻辑生成解题的脚本
解题记录
首先使用x64dbg,执行程序到等待输入处。打开字符串常量表,可以看到和flag相关的内容:aliyunctf{
和Right
、Wrong
。
追踪一下用到aliyunctf{
的代码处,发现这里主要是判定输入的内容是否以aliyunctf{
开始并以}
结束。
打开IDA64,找到引用到该常量的代码,如下图所示:
此时把代码拿去问问通义千问,程序逻辑基本清晰,主要分解为以下几个逻辑:
- 判断字符串长度是否为29
- 判定除了前缀和后缀的每个字符是否在0~8之间(48是字符串0的ASCii码),说明这是个数字,减去前缀和后缀11位,这是个18位的整数。
- 判定这个18位整数是否满足一些约束条件。
- 设相邻的两位为a和b,需要满足9a+b和9b+a的值在指定范围内,并且34个值不重复。(由代码
if ( dword_149994G4[u17] != 1 )
看出,这里可以看到这里的内容是个数组,并且其中的元素有80个(9a+b的最大值),其中有34个1(18个内容,共有17对相邻数字,刚好是34个))
以上条件需要全部满足,否则输出Wrong。
把内存中的这个bitmap拿出来
值为1的索引列表如下:
json
1 | [2, 5, 8, 12, 13, 14, 17, 18, 21, 24, 25, 28, 29, 31, 35, 37, 39, 42, 45, 46, 51, 53, 56, 58, 59, 62, 65, 71, 72, 73, 75, 77, 78, 79] |
通过输入一串满足前两个条件的随机数字,在x64dbg在if语句中打断点,观察内存和寄存器,可以进一步得出这串18位数字的约束条件。
- 第2位大于第3位
- 第4位小于第5位
- 第1位和第9位相同
- 第16位和第12位相同
- 第6位小于第11位
- 第14位大于第4位
- 第8位小于等于第5位
- 第15位是7
- 第18位是4
这个数字让人来找肯定是不行的,约束条件过多,只能写程序来找。
不使用框架,考虑裸解的思路主要是dfs打表+减枝优化。于是梳理一下思路:由于最后一位是固定的,所以从最后一位开始向前进行深度优先搜索,前面的数字基于后面的数字作为约束条件,减少判断条件。
写一段promote给通义千问:
Code
1 | 写一串python代码,查找满足条件的18位以下10进制数字。该数字需要满足以下条件(位数是10进制的位数从左边开始为1): |
通义千问生成的代码并没有考虑剪枝,而且还有点bug
python
1 | 根据您的描述,这是一个复杂的约束问题,需要使用回溯算法解决。但是由于问题的复杂性以及Python实现的限制(如运行时间、内存消耗等),直接在这里编写完整代码可能不太实际。下面是一个简化的框架示例,您可以基于此进行扩展和优化: |
于是我们改优化一下,最终的解题代码是:
python
1 | allowed_sums = set([2, 5, 8, 12, 13, 14, 17, 18, 21, 24, 25, 28, 29, 31, 35, 37, 39, 42, 45, 46, 51, 53, 56, 58, 59, 62, 65, 71, 72, 73, 75, 77, 78, 79]) |
最终计算出的18位数字只有一个
085134620568327814
题解为
aliyunctf{085134620568327814}
Bingo!