【CTF对抗-cython逆向之CTF实战(1)】此文章归类为:CTF对抗。
前言
最近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。
1 2 3 4 | import rand0m
tmp = input ()
gu = rand0m.check(tmp)
print (gu)
|
用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
就可以查看到相关的结构
里面的结构体大概如下
1 2 3 4 | dq 标志
dq 数据类型
dq 未知 (我猜测是数据长度)
dq 数据 (如果是列表或者元组可能会有多个)
|
看到rand0m中第一个对数据操作的api,这里是PyNumber_Xor也就是异或
查看v12可以发现是我们的输入,转为了16进制
然后查看off_7FFE9DAEB688[44]
是2654435769
,那么我们可以开始手动还原函数
1 2 | def rand0m(tmp):
tmp1 = tmp ^ 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
总结以上为
1 2 3 4 5 6 7 8 9 | def rand0m_by_gh(tmp):
tmp1 = tmp ^ 2654435769
tmp2 = tmp >> 5
tmp3 = tmp << 4
tmp4 = tmp3 & 4198170623
tmp5 = tmp2 >> 23
tmp6 = tmp4 + tmp5
tmp7 = ((tmp1 >> 11 ) * * 65537 ) % 4294967293
return (tmp7, tmp6)
|
然后我们可以通过返回值来验证结果,可以发现我们还原的结果与题目相同
备注
注意在取值的时候要看静态中的off_7FFE9DAEB688[32]
,cython在动态中的数据值长度32位中只有30位是有效的,所以有可能会出现数值高位与实际值不一样的情况。
更多【CTF对抗-cython逆向之CTF实战(1)】相关视频教程:www.yxfzedu.com