前言:
 继《Xbash部分样本分析》一篇博客之后,研究了关于pyinstaller与pyc字节码格式。虽然相关资料比较少,但是不影响去接触新的知识。
 不得不说pyinstaller是Xbash系列恶意软件跨平台执行的罪魁祸首,PyInstaller支持Linux、Windows、Apple macOS等多平台可执行文件转换。意味着病毒可以在多平台上兼容运行。虽然python开发维护病毒难度较小,周期短,对于分析人员来说也是件好事,比如把可执行文件提取成python源码。

pyinstaller pyc 恶意代码分析
环境搭建及使用 pyc格式解析(部分) Python恶意代码

  
一、Pyinstaller:
 ☛介绍一下pyinstaller,如前言所说pyinstaller将会读取您编写得python脚本,它会自行分析,当然是根据导出得与执行所需要得模块与库。收集这些文件包括活动得解释器,把他们放在一个文件夹中。

 This section covers the basic ideas of PyInstaller. These ideas apply to all platforms. Options and special cases are covered below, under Using PyInstaller.
 PyInstaller reads a Python script written by you. It analyzes your code to discover every other module and library your script needs in order to execute. Then it collects copies of all those files – including the active Python interpreter! – and puts them with your script in a single folder, or optionally in a single executable file.

 上述参考源于pyinstaller手册:https://pyinstaller.readthedocs.io/en/stable/index.html
也就是说当使用pyinstaller得时候,会自动检索我们代码中所需要得库与模块与解释器,将他们打包到一起,根据不同得参数生成可执行得文件。当然我们并不是研究如何实现转换成pe格式与elf格式得,因为这需要很漫长得过程。
但是我们需要了解,pyinstaller打包到一个文件夹后,如何执行得?首先pyinstaller会加载myscript.exe,这是核心文件,然后会引导加载程序得活动平台二进制可执行程序。会引导加载程序,加载python环境,方便python解释器在myscript中导入模块和库。
启动时候会在操作系统对应得文件夹创建一个临时得文件夹名称_MEIxxxxxx, 引导加载程序与临时文件夹的上下文中的单文件夹包完全相同。当捆绑代码终止时,引导加载程序将删除临时文件夹,详细得参考请看官方文档。


✍关于pyinstaller的一些参数,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片一:pyinstaller参数

    1、-F, --onefile         创建一个文件捆绑的可执行文件
    2、-w, --windowed, --noconsole       pe格式窗口程序GUI
    3、-c, --console, --nowindowed         pe格式控制台程序
    4、-a, --ascii不包含unicode支持
    5、-D, --onedir 创建包含可执行文件的单文件夹包


如和安装pyinstaller呢?很简单,命令如下所示:

系统Centos
如果你没有安装pip,参考如下:
    1、安装epel扩展:yum -y install epel-release
    2、安装pip:yum -y install python-pip
安装pyinstaller:
    pip install pyinstaller
Windows下参考也一样


如何使用pyinstaller?分为以下几大步,如下所示:
1、首先你需要编写一个py文件,当然你可以分成多个文件进行代码得编写,除了特殊模块需要告诉pyinstaller位置之外,其余会自定帮你分析模块与库,这里用测试代码如下:
关于pyinstaller与Xbash系列分析(续)
                    图片二:python测试代码
2、使用pyinstaller命令进行打包,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片三:pyinstaller打包
3、查看生成得数据,如下所示:
关于pyinstaller与Xbash系列分析(续)
关于pyinstaller与Xbash系列分析(续)
                    图片四:dist/xxx
生成的elf程序运行正常,而且pyinstaller维护了如上图所示得PYZ格式的数据文件,附加到了可执行文件的末尾,然后最前面是PYZ开头的格式。
 官方提供了对应的脚本来提取pyc,名字叫archive_viewer.py代码下载:https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/utils/cliutils/archive_viewer.py

4、从上述网站中把代码粘贴下来,touch一个文件,+x权限后,复制即可使用,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片五:archive_viewer.py
5、我们发现下面有很多数据,我们需要关注的s标志段中name是我们本身文件名:
关于pyinstaller与Xbash系列分析(续)
                    图片六:S段标志数据
6、archive_viewer.py都有什参数呢?很简单分析一下源码,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片七:命令分析
我们需要用到X的命令去提取pyc,上图中为标记的命令U是go Up one level的含义。
7、开始提取pyc,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片八:提取命令
8、这时候我们来看一看提取的pyc,widnows下用010就可以了,linux下用xxd可以观察,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片九:提取pyc数据观察
9、pyc提取的到底对不对呢?怎样来确认?这时候我们需要利用python中的py_compile模块,这个模块中方法compile可以将py生成pyc,这样我们对比观察,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片十:py_compile

代码:
            import py_compile
            py_compile.compile(r'路径')
注意:
            有时候会生成一个__pycompile__文件夹,里面会是pyc,有时候会在输入的路径下生成pyc,小心覆盖elf中提取的pyc。

10、我们看一下python原生态编译生成的字节码pyc如下:
关于pyinstaller与Xbash系列分析(续)
                    图片十一:compile编译pyc
图片九与图片十一做比对,你一定会开头少了8个字节的数据,注意当前编译环境使用的python2.7.5,缺少了8个字节的数据,python3前面的字节编码字节也是不同的。
 所以在当前环境下测试观察,那么使用pyinstaller中archive_viewer.py抽取的pyc比正常编译的字节码缺少了8个字节的数据,缺少的是什么?下面我们来看一看pyc格式解析。

  
二、pyc格式解析:
关于pyinstaller与Xbash系列分析(续)
                    图片十二:部分pyc格式数据分析
当然pyc的格式不只上述那么多,只是罗列出了一部分,详细的去介绍参数不是一篇文章或者短时间内能够研究学习明白的,那么我们来看一些重要的数据。

1、MAGIC,魔术头,注意版本区分不同所以魔术头的数值不同,比如python2一般是03f30d0a,python3.6一般是33790d0a,占用4个字节,前两个字节是版本,后两个字节是0d0a两个标志位.
 2、紧跟着Magic的是MTIME,是时间也占四个字节。
 3、TYPE_CODE, 表示了一个PyCodeObject对象,占用了一个字节大小,这个标志位是c,其实就是Pyton中编译过程生成code对象PyCodeObject。将PyCodeObject写入二进制文件,即.pyc。
 4、我们发现图片中co_code的数值,其实就是PyCodeObject结构体中的各个域,每一个属性占用一个long字节。
 5、下面三个属性Type_string与size values数值,是对应着PyCodeObject的co_code。
 6、Type_List,占用一个字节,是类型链表。
 7、co_consts size 表示元素个数,占用四个字节。
 8、Type_INT与co_consts[0]是一个×××。
 还有很多的属性,详细的数据还可以参考:https://www.2cto.com/kf/201504/395067.html


 ✉通过上面的描述,对pyc的数据格式有一个基础的认识,简单的知道了那些字节的含义与基础的作用。
 这样我们就可以很轻易的知道在pyinstaller打包的时候,解压Pyc缺失了8个字节,分别是Magic与MTIME两个字段属性,MTIME字段我们可以填充为0(无关紧要)。
 所以根据当前环境来判定魔术头的格式(pyinstaller在打包的时候,应该会抽取魔术头来作为版本的判定方式,所以会缺少字节)。我们尝试将确实的数据添加到c也就PyCodeObject对象之前补齐8个字节的数据,如下所示:

关于pyinstaller与Xbash系列分析(续)
                    图片十三:补齐数据
 注意:是在PyCodeObject对象之前补齐数据,而不是在原来的数据上修改!否则转换py的时候会报错的。
 补齐数据之后我们需要做的是用工具去反编译成py文件,wdinows下推荐一款为EasyPythonDecompiler.exe的软件,而linux下更是数不胜数,那么这里使用linux下名为uncompyle2, decompyle2很多都可以。下面演示就使用EasyPythonDecompiler.exe来转换py,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片十四:Decompile Success
 转换完成之后将会生成mypy.pyc_dis文件,如果pyc的格式不对就会失败,生成mypy.pyc_dis.failure,这时候我们拉入到IDE看一看python源码是否与图二中源码相同,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片十五:匹配成功
 上述一已经能成功的将pyinstaller打包elf格式的文件成功的转换成py,有何用呢?还记着Xbash系列病毒其中便有pyinstaller打包的病毒,如下所示:
关于pyinstaller与Xbash系列分析(续)
                    图片十六:提取恶意代码

三、Python恶意代码分析:
➀弱用户与密码字典:
关于pyinstaller与Xbash系列分析(续)
                    图片十七:弱用户与弱密码
➁公网请求及初始化扫IP及描端口:
关于pyinstaller与Xbash系列分析(续)
                    图片十八:请求及端口初始化
➂初始化恶意线程环境及启动线程:

关于pyinstaller与Xbash系列分析(续)
                    图片十九:创建启动线程
➃线程回调分析:
关于pyinstaller与Xbash系列分析(续)
                    图片二十:线程回调分析
➄WEB扫描及数据库扫描:
关于pyinstaller与Xbash系列分析(续)
                    图片二十一:pass_crack
关于pyinstaller与Xbash系列分析(续)
                    图片二十二:check_pass
关于pyinstaller与Xbash系列分析(续)
                    图片二十三:check_pass
关于pyinstaller与Xbash系列分析(续)
                    图片二十四:mysql
关于pyinstaller与Xbash系列分析(续)
关于pyinstaller与Xbash系列分析(续)
关于pyinstaller与Xbash系列分析(续)
                    图片二十五:mysql删库勒索

关于pyinstaller与Xbash系列分析(续)
                    图片二十六:postgresql删库勒索
关于pyinstaller与Xbash系列分析(续)
关于pyinstaller与Xbash系列分析(续)
关于pyinstaller与Xbash系列分析(续)
                    图片二十七:mongodb删库勒索
关于pyinstaller与Xbash系列分析(续)
                    图片二十八:redis删库勒索
关于pyinstaller与Xbash系列分析(续)
                    图片二十九:hadoop Yarn Rm执行命令
关于pyinstaller与Xbash系列分析(续)
                    图片三十:MQ利用执行put
⑥内网扫描:
关于pyinstaller与Xbash系列分析(续)
                    图片三十一:内网扫描
关于pyinstaller与Xbash系列分析(续)
                    图片三十二:内网扫描
通过上述恶意代码的分析,最可恶的是没有任何备份的情况下删库,且欺0.02BTC,即使给对方支付了费用,抱歉你的数据库仍无法恢复,对方会利用你的心性索要更多的BTC。
 服务器中大量的弱账户与弱密码,给病毒带来了福利。扫描web、内网创建线程,一经发现字典匹配成功,那么会对数据库进行毁灭的操作。
 如何防范?如果你服务器与数据库账户名,密码规范化管理(复杂程度及长度),经常更换,不使用这些弱密码弱账户,即使突破了安全防护,在字典扫描与破解的时候,也不能胡作非为,那么XbashY样本分析告一段落。