逆向分析Python Pickle与r2pickledec工具
2023年6月1日 - 作者:Dennis Goodlett
R2pickledec是首个支持所有协议5(当前最新)指令的Pickle反编译器。本文将介绍Python Pickle的基本概念、工作原理,以及如何使用Radare2和r2pickledec进行逆向分析。后续博文将深入探讨Pickle的高级混淆技术。
什么是Pickle?
Pickle是Python内置的序列化算法,能够将任何Python对象转换为字节流以便存储或网络传输。Pickle因其危险性而闻名——永远不要从不可信源反序列化Pickle数据,否则可能导致远程代码执行。详情请参阅官方文档。
Pickle基础
Pickle实现为简单的汇编语言,仅包含68条指令,主要基于栈操作。指令名称直观易懂,例如empty_dict
会将空字典压入栈中。
栈通常只允许访问顶部项(某些情况下可访问多项)。如需访问其他项,必须使用memo(备忘录)。memo是实现为正整数索引的字典,常见memoize
指令会将栈顶项复制到memo的下一个索引中。之后如需使用该对象,可通过binget n
获取索引n处的对象。
建议通过实际操作学习Pickle:在Radare2中启用描述功能(e asm.describe = true
)查看指令说明,反编译自己构建的简单Pickle并理解指令含义。
安装Radare2和r2pickledec
推荐使用Radare2(简称r2)进行Pickle逆向。包管理器提供的r2版本可能较旧,但通常不影响使用(Pickle架构支持已添加多年)。如遇问题,建议从源码安装。
本教程主要使用r2pickledec反编译器插件,该插件仅依赖r2库,因此只要r2正常运行,r2pickledec即可工作。通过r2pm安装:
|
|
验证安装成功:
|
|
使用Radare2和r2pickledec逆向真实Pickle
假设您入侵了一台Web服务器,该服务器允许公司员工对客户账户执行特权操作。在探查过程中,发现服务器使用Pickle文件恢复状态。以下Base64编码的Pickle文件可能包含有趣信息:
(Base64编码内容省略)
解码后保存为test.pickle,使用r2打开文件。执行x
查看十六进制内容,pd
显示反汇编(附加?
可查看命令帮助,如pd?
):
|
|
从反汇编可知这是有效的Pickle文件,包含requests.sessions
和Session
字符串,表明可能导入了requests库并使用会话功能。
使用pdPf @0 ~..
命令进行反编译:
pdPf
:r2pickledec的反编译命令(pdP?
查看详情),f
参数让反编译器为每个变量名设置r2标志,便于重命名和跳转@0
:指定从偏移量0开始执行命令(避免寻址错误)~..
:使用r2内置分页器(也可使用|less
)
反编译结果生成类Python代码(以下为片段,注释由反编译器添加):
|
|
建议从返回语句开始分析(即Pickle的最终输出)。跳转到文件末尾(G
命令)可见:
|
|
返回的what_x616
变量是g_Api_x1c.__new__
调用的结果。g_
前缀表示反编译器识别为全局导入(此处提示为Api类)。x1c
和x616
表示对象在Pickle中的创建偏移量(后续修补时使用)。
使用标志重命名变量:fr pick.g_Api_x1c pick.api
(标志可tab补全,f
命令列出所有标志)。
搜索auth
字段发现认证信息:
|
|
这表明auth元素设置为元组("admin", "Pickles are fun")
——我们刚刚窃取了管理员凭证!
修补操作
虽然真实渗透测试中不推荐此操作,但我们可以修改Pickle以指向恶意服务器。首先查找当前URL:
|
|
通过变量名中的x5fe
定位或直接跳转到pick.str_x5fe
标志:
|
|
使用以下r2命令将URL修改为https://doyensec.com/
:
|
|
JSON与自动化
如需批量处理100个文件,可使用r2pipe进行脚本化。大多数r2命令添加j
后缀可输出JSON格式(如pdPj
生成包含偏移量的AST)。利用此功能可编写自动解析器定位并修补baseurl元素。
r2内置JSON处理功能:~{}
美化输出,~{=}
输出gron格式便于搜索。例如:
|
|
还可通过外部命令处理:pdPj |jq
可搜索AST模式(如返回所有PY_GLOBAL
类型对象)。
结论
r2pickledec插件简化了Pickle逆向过程,并充分利用r2的强大功能。本文仅浅尝辄止,更多功能请参阅r2手册。敬请关注后续关于Python Pickle混淆技术的博文。