近期工作中需要逆向分析一个神奇的木马,文件看起来是一个linux下面的elf文件,但是通过常规手段用ida或者ghidra分析完全没有头绪(主要是因为菜>_<),但是通过ida的分析可以看出明显的python痕迹,后来通过万能的谷歌学习到,还有另一种途径可以完美的逆向python打包的可执行程序。本文简要记录一下逆向python打包的elf/exe程序的逆向分析方法。
python打包的可执行程序
将python脚本打包成可执行程序可以更方便的在目标平台上执行,打包工具有很多,其中最常用的当数pyinstaller
了,在Linux/Windows平台上可以通过pip安装:
pip install pyinstaller
打包方法很简单,直接对写好的python程序demo.py
执行:
pyinstaller -F demo.py
打包好的exe程序会在dist目录中,elf需要在Linux下打包,方法是一样的
pyinstaller打包可执行程序的特征
接下来分析一下用ida打开打包好的elf/exe有什么特征,将exe拖到ida中分析。
- main函数特征
首先在函数窗口可以找到main
方法,双击打开然后上F5
大法
下图中标注了几条main中比较明显的特征,猜测应该是pyinstaller打包的一种固定模式代码
- 字符串特征
按shift+F12
查看变量(本例中,想在这里找到程序中的密码是不可能的),可以看到很多Py
开头的文件,这也是为什么我开始猜测这个elf文件是由python打包的
反编译可执行文件
从ida的内容分析似乎很难找到真正的程序逻辑入口在哪里,后来在谷歌一番搜索终于找到的正确方向。反编译首先要用python(我用python3.7)自带的archive_viewer.py
将elf/exe程序提取出pyc
文件,然后再从pyc
反编译成py
- 提取pyc文件
windows下的archive_viewer.py
文件目录在{Python_Home}\Lib\site-packages\PyInstaller\utils\cliutils
,将这个文件复制到工作目录下,执行如下命令:
python archive_viewer.py demo
这里看到分析出目标程序的模块,其中唯一一个不带前缀后缀的就是我们要找的模块
接下来提取该模块x client-update
,提取后的文件如下图所示:
- 修改文件头
使用pyinstaller打包的文件,文件头的数据会被抹消掉。再还原的过程中,我们需要手动进行修补。文件头的格式为:magic(4字节,编译器标志) + 时间戳(4字节)。在实际修补时,需要添加的数据可能不止是8个字节。(笔者python版本为3.7,需要填充16个字节)以下为修补的步骤
承接上面的步骤,除了要提取目标文件.pyc以外,还需要再提一个struct
文件:
使用二进制编辑工具打开这两个文件,对比发现,提取出的目标文件头部比struct.pyc
少了8个字节
[图片上传失败...(image-bb5cab-1626878121733)]
接下来需要将缺失的部分补全,将struct.pyc
头部的8个字节内容拷贝到目标文件头部,然后保存文件
-
反编译pyc文件
这里需要安装
uncompyle6
pip install uncompyle6
安装后的可执行程序在
{Python_Home}/Scripts}
下,可以直接执行:uncompyle6.exe client-update.pyc > client-update.py
可以看到最后反编译的结果非常清晰可读
原文链接: 反编译Python打包的可执行程序