-
-
[原创]cython逆向之CTF实战(1)
-
发表于:
2025-1-23 21:49
6301
-
最近cython的CTF题目越出越多,要学会手撕cython才能ak逆向了
题目是ciscn中的一道题:rand0m,题目给了一个py文件和pyd文件。其中pyd文件相当于dll,可以在同目录下给py文件直接导入。需要注意的是如果python版本不对会报错,如下图:

我们需要一个个版本进行尝试,这里建议使用conda环境,可以快速建立python环境和切换。这里使用3.12.5版本可以运行。

进入正题,我们用IDA打开pyd文件,然后使用shift+F12
查看字符串界面:

注意到这里有几个rand0m开头的字符串,在题目给的py脚本中我们可以发现调用了rand0m.check函数,那么我们对rand0m.check按x
进行交叉引用。

注意到这里有几个rand0m开头的字符串,在题目给的py脚本中我们可以发现调用了rand0m.check函数,那么我们对rand0m.check按x进行交叉引用。
这里一般会出现两行,第一行引用是这个函数的包装函数,第二行才是这函数的内部实现,我们看到第二行所在的函数。函数如下:

我们下面进行调试,首先编写一个python文件去调用函数。这里注意要使用input,方便我们使用ida attach。
用python调用后,使用ida attach,直接搜索python,这里这个python.exe就是我们attach的目标,记得要在函数开头先下一个断点。

attach之后会停止,我们需要让他运行起来

然后在命令行的input这里随便输入一些东西,然后回车,发现断在了我们下的断点处

我们看到下面,一个PyList_New是创建一个新的列表,参数是8就代表创建8个。第二个关于off_7FFE92BAB688[40]
这类指针里面会储存python中的硬编码数据。

上图中硬编码数据可以通过ida的交叉引用查看,例如这里的v10=off_7FFE92BAB688[40]
那么v10里面存的就是304643896

接下来往下分析的话主要是看ida中粉色的函数,其他函数可以暂时忽略,关于粉色的函数可以看对于cython的基础逆向分析(1) - 先知社区的一些分析。这个程序主要是在rand0m.rand0m
中进行处理,我们在rand0m.rand0m
里的开头下断点。

可以查看参数a2,参数a2是个结构体,进入是数据,可以使用快捷键d
将db转为dp

就可以查看到相关的结构

里面的结构体大概如下
看到rand0m中第一个对数据操作的api,这里是PyNumber_Xor也就是异或

查看v12可以发现是我们的输入,转为了16进制


然后查看off_7FFE9DAEB688[44]
是2654435769
,那么我们可以开始手动还原函数

下一个是右移函数,可以进去查看,这里可以看第二个参数也可以看第三个参数,那么这里可以还原为tmp2 = tmp >> 5


再往下走可以看见一个左移,这里依旧是查看off_7FFE9DAEB688[32]
,那么可以还原为tmp3 = tmp << 4
,可以查看v12里面的内容确定是哪个变量


然后是一个按位与,这里的v16就是off_7FFE9DAEB688
,查看是4198170623
,那么可以还原为tmp4 = tmp3 & 4198170623


接下来一个右移一个相加,这里不多赘述,可以这两行可以还原为tmp5 = tmp2 >> 23
,tmp6 = tmp4 + tmp5

再往后一个右移一个幂和求模,还原为tmp7 = ((tmp1 >> 11) ** 65537) % 4294967293


总结以上为
然后我们可以通过返回值来验证结果,可以发现我们还原的结果与题目相同

注意在取值的时候要看静态中的off_7FFE9DAEB688[32]
,cython在动态中的数据值长度32位中只有30位是有效的,所以有可能会出现数值高位与实际值不一样的情况。
import
rand0m
tmp
=
input
()
gu
=
rand0m.check(tmp)
print
(gu)
import
rand0m
tmp
=
input
()
gu
=
rand0m.check(tmp)
print
(gu)
dq 标志
dq 数据类型
dq 未知 (我猜测是数据长度)
dq 数据 (如果是列表或者元组可能会有多个)
dq 标志
dq 数据类型
dq 未知 (我猜测是数据长度)
dq 数据 (如果是列表或者元组可能会有多个)
[注意]看雪招聘,专注安全领域的专业人才平台!