本帖最后由 末日不孤单 于 2016-12-28 19:16 编辑
1. 概述第一次分析这种python exe程序,最开始还比较懵逼,直接对exe就开始下手了,发现它竟然会去释放并运行python dll,一直没想明白,结果浪费了不少时间,最后终于找到了正确的分析思路,所以,觉得挺有意思的,就分享给大家看看。 样本很大,有3.16MB,一般的exe程序不会这么大,所以用了压缩壳UPX。 1.1. 基本信息文件名称:LogonUI.exe 文件大小:3314728 字节(3.16MB) MD5 :A25EC7749B2DE12C2A86167AFA88A4DD SHA1 :BB71254FBD41855E8E70F05231CE77FEE6F00388 CRC32 :1D62CAB1 壳信息 :UPX 1.2. 文件说明LogonUI.exe.bak:样本源文件 LogonUI.exe.bak_upx -d :脱壳后文件Vbni7:反编译后文件 code.txt:Vbni7解码后文件 code.py.bak:code.txt源码修改后文件 decompiled.py.bak:网上下载的参考文件 1.3. 相关文档【原创】用 Python 反编译 Python 软件 http://bbs.pediy.com/showthread.php?t=111428 從PYTHON INSTALLER打包程式拖出PYTHON程式碼 http://adr.xxxxx.im/?p=467 反编译py2exe程序 http://www.qiaoyue.net/blog/2016/05/%E5%8F%8D%E7%BC%96%E8%AF%91py2exe%E7%A8%8B%E5%BA%8F.html 2.LogonUI.exe分析2.1 脱壳 使用PEID查壳,发现样本是UPX压缩壳,壳信息如下: “UPX -> www.upx.sourceforge.net [Overlay] *” 必须使用“upx -d”命令脱壳才行,手工脱壳不行(样本是用pyinstaller打包的程序,手工脱壳的程序无法反编译) 2.2. 将exe反编译成py文件使用PyInstxtractor.py反编译出py文件,具体操作如下: 查看反编译目录,文件“Vbni7”即为python脚本文件; 2.3. 解码python脚本打开python 脚本,发现大量的乱码,最开始还以为解码出错了,然后还又找了其他的方式去解码,直到后面发现文件中有一个exec()函数,才确定原来解码正确的。 最后整理文档时,才发现网上这篇 從PYTHON INSTALLER打包程式拖出PYTHON程式碼(“http://adr.xxxxx.im/?p=467”)。。。。 文件内容如下: 将exec()函数修改为print()函数,把代码保存为文件; 查看code.txt代码,又发现所有的变量名和类名都使用唯一字符串处理过,猜测这应该是木马作者使用的代码混淆; 分析人员可以将代码替换为原来的代码,例如:将字符串“pSsWAYdKJqgPHbRoVCwjkvMcmtuxInGEhaFfLBXUOrNlTyQzDe”全部替换为“base64.b64encode”,也可以写一个自动化脚本去替换,不过应该比较麻烦。。。。 在分析过程中,发现了几个特殊字符串,通过google,在github上找到了类似代码“https://github.com/pan-unit42/iocs/blob/master/seaduke/decompiled.py” 可将github上代码下载查看,按照github上代码进行代码修改,但具体分析不能使用github上分析,因为不确定两个样本是否完全一样,一般都是不一样的。。。。。。 2.4. python反编译说明在分析过程中,由于自己也对相关的python exe程序进行了相应的测试,故在这里和大家一起分享一下; 将python程序打包为exe,可以使用pyinstaller和py2exe; 2.4.1. pyinstaller打包程序本篇报告中分析的样本就是一个pyinstaller 打包程序,将样本脱壳后,使用IDA查看字符串,可以查看到大量的关于python的字符串: 针对pyinstaller打包程序,可以使用“pyinstxtractor.py”脚本工具反编译,查考從PYTHON INSTALLER打包程式拖出PYTHON程式碼(“http://adr.xxxxx.im/?p=467”) 2.4.2. py2exe打包程序使用py2exe打包的程序,脱壳后使用IDA查看字符串可直接看到字符串“PY2EXE_VERBOSE”: 针对py2exe打包程序可以使用unpy2exe和uncompyle2两个脚本工具进行反编译,查考反编译py2exe程序(“http://www.qiaoyue.net/blog/2016/05/%E5%8F%8D%E7%BC%96%E8%AF%91py2exe%E7%A8%8B%E5%BA%8F.html”) 3. code.txt分析
3.1. 源码修改由于代码中存在大量的唯一字符串,因此我在分析过程中参照decompiled.py对其进行了相应的代码修改,使代码方便查看调试; 由于通过print()函数打印出来的代码格式很紧凑,也不方便查看调试,因此,我又用pycharm编辑器对代码格式进行了调整; pycharm:Ctrl + Alt + L代码格式化 代码相对比较好阅读查看了,将代码保存为“code.py.bak”。 后续分析我也是使用pycharm编辑器进行代码调试,调试前需要安装相应的包,分析者可自行下载安装; 4. code.py.bak
4.1. 配置信息样本将解码相应的配置信息,将配置信息保存在bot_settings中; 相关代码截图如下: 解码代码如下:(配置信息与decompiled.py 一样,很可能两个样本是一样的,但为了以防万一,我还是没有使用decompiled.py 进行分析) { 'first_run_delay': 0, 'keys': { 'aes': 'KIjbzZ/ZxdE5KD2XosXqIbEdrCxy3mqDSSLWJ7BFk3o=', 'aes_iv': 'cleUKIi+mAVSKL27O4J/UQ==' }, 'autoload_settings': { 'exe_name': 'LogonUI.exe', 'app_name': 'LogonUI.exe', 'delete_after': False }, 'host_scripts': ['http://monitor.syn.cn/rss.php'], 'referer': 'https://www.facebook.com/', 'user_agent': 'SiteBar/3.3.8 (Bookmark Server; http://sitebar.org/)', 'key_id': 'P4BNZR0', 'enable_autoload': False } 4.2. 程序初始化在进入”__main__”函数前,样本将创建BotKlass实例对象,并调用BotKlass构造函数; 相关代码截图如下: 在构造函数中: - 初始化self.__settings信息,根据bot_settings[‘key_id’]生成配置文件名“tmpp4bnzr0”;查找配置文件“C:\Users\admin\AppData\Local\tmpp4bnzr0”是否存在;如果不存在,表明这是样本第一次运行,样本将直接获取4.1节中的配置信息;如果存在,则直接读取配置文件,并解密得到上一次运行的配置信息;
- 得到配置信息后,样本将把配置信息加密保存于“C:\Users\admin\AppData\Local\tmpp4bnzr0”文件中;
- 样本还将获取当前目录路径
- 样本将生成随机密钥,保存于self.__broker_key中,用于确定是哪一个客户端;
4.3. 主函数在主函数中,样本将判断当前系统是“windows”还是“Linux”系统,并执行相应的代码; 4.4. 获取任务在main函数中,样本调用networkHandleKlass.get_tasks()函数获取控制端分发的任务信息: 调用self.__send_request(id=botKlass.bot_id)函数,并传递当前客户端的bot_id; 在__send_request函数中,样本将bot_id加密为COOKIE进行请求; 如果样本请求数据成功,样本将调用decode_data函数对请求数据进行解密,并根据解密数据进行相应的远程命令; 4.5. 远程命令样本根据解密数据进行相应的远程命令,由于都是python源码,阅读起来也应该比较简单,就不详细讲解功能了,把功能列举如下: - cd命令:更改工作目录
- pwd命令:显示当前工作目录
- cdt命令:改变工作目录到TEMP目录
- :autoload:在指定的位置安装样本
- :migrate:迁移进程文件
- :clone_time:修改文件属性时间
- :download:下载文件
- :execw:执行命令
- :get:上传文件(加密)
- :upload_to:上传文件(不加密)
- :b64encode:加密文件内容并返回
- :eval:执行代码
- :set_update_interval:设置请求时间间隔
- :self_exit:停止运行样本
- :seppuku:卸载安装样本
样本下载链接:链接: http://pan.baidu.com/s/1kUEOIHL 密码: a6fr 密码:52pojie
|