越来越多的PYTHON恶意软件Part①作者:Gabriel Wong(MoonLightGW)前言在过去的30年中,绝大多数严重的恶意软件都是用Assembly或编译语言(例如C,C ++和Delphi)编写的。但是,在过去的十年中,这种恶意软件的数量一直在不断增长,以解释性语言(例如Python)编写。低进入门槛,易用性,快速开发过程以及庞大的库集合使Python对数百万开发人员(包括恶意软件作者)具有吸引力。Python已迅速成为威胁者创建远程访问特洛伊木马(RAT),信息窃取者和漏洞利用工具的标准语言。随着Python的普及和C恶意软件单一文化的持续快速增长 继续受到挑战,似乎只能确定Python将越来越多地被用作网络攻击中的恶意软件。他们是时代的改变与C之类的标准编译语言相比,用Python编写恶意软件会带来很多困难。首先是需要在操作系统上安装Python才能解释和执行Python代码。但是,正如我们将在下一节中看到的那样,可以使用多种不同的方法将Python程序轻松转换为本地可执行文件。用Python编写的恶意软件也会对文件大小,内存占用量和处理能力产生不利影响。严重的恶意软件通常被设计为小巧,隐蔽,内存占用量少并且使用有限的处理能力。用C编写的已编译恶意软件样本可能为200 KB,而用Python编写的类似恶意软件样本在转换为可执行文件后可能为20 MB。使用解释语言时,CPU和RAM的使用率也会大大提高。但是,现在是2020年,数字化格局已不再是过去。互联网比以往任何时候都快,我们的计算机拥有比以往更大的内存和存储容量,并且CPU的速度每年都在提高。Python也比以往任何时候都更加普及,默认情况下已预装在macOS和大多数所有Linux发行版中。没有编译器?没问题!Microsoft Windows仍然是大多数恶意活动的主要目标,并且默认情况下未安装Python。因此,为了使威胁参与者能够有效地分发其恶意软件,他们必须将其Python代码转换为可执行格式。有很多方法可以将Python“编译”为本地可执行文件。让我们来看看几种最流行的方法…… PyInstaller 通过“编译” Python代码,PyInstaller能够将Python应用程序构建为适用于Windows,Linux,macOS等的独立可执行文件。它是将Python代码转换为可执行格式的最受欢迎的方法之一,已被广泛用于合法和恶意目的。让我们创建一个简单的“你好,世界!” 使用Python编写程序,并使用PyInstaller将其冻结为独立的可执行文件:[Python] 纯文本查看 复制代码 $ cat hello.py
print('Hello, world!')
$ pyinstaller --onefile hello.py
...
$ ./dist/hello
Hello, world!
$ file dist/hello
dist/hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=294d1f19a085a730da19a6c55788ec08c2187039, stripped
$ du -sh dist/hello
7.0M dist/hello 此过程创建了可移植的独立Linux ELF(可执行和可链接格式),等效于Windows上的EXE。现在,让我们创建并编译一个“ Hello,world!” Linux上的C中的程序进行比较:[Python] 纯文本查看 复制代码 $ cat hello.c
#include <stdio.h>
int main() {
printf("Hello, world!");
}
$ gcc hello.c -o hello
$ ./hello
Hello, world!
$ file hello
hello: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=480c7c75e09c169ab25d1b81bd28f66fde08da7c, for GNU/Linux 3.2.0, not stripped
$ du -sh hello
20K hello 请注意,文件大小要大得多:7 MB(Python)对20 KB(C)!这证明了我们先前讨论的关于文件大小和内存使用的主要缺点。Python可执行文件之所以大得多,是因为它必须将Python解释器(在Linux上作为共享对象文件)捆绑在可执行文件本身中才能运行。py2exePy2exe 是将Python代码转换为可以本地运行的Windows EXE(可执行)格式的另一种流行方法。与PyInstaller相似,它将Python解释器与您的Python代码捆绑在一起,以生成可移植的可执行文件。Py2exe可能会随着时间的流逝而过时,因为在Python 3.4之前尚不支持Py2exe,这是由于 CPython中的字节码在Python 3.6及更高版本中已发生重大变化。Py2exe利用distutils并需要setup.py 创建一个小的脚本来生成可执行文件。让我们创建一个示例“你好,世界!” 使用py2exe可执行文件:在hello.exe由py2exe创建的大小与PyInstaller 6.83 MB在未来类似。 [Python] 纯文本查看 复制代码 > type hello.pyprint('Hello, world!')
> type setup.py
import py2exe
from distutils.core import setup
setup(
console=['hello.py'],
options={'py2exe': {'bundle_files': 1, 'compressed': True}},
zipfile=None
)
> python setup.py py2exe
...
> dist\hello.exe
Hello, world!
Nuitka
Nuitka可能是最未充分利用的方法,但它是将Python代码编译为可执行文件的更高级的方法。它将Python代码转换为C程序,然后与libpython链接以执行与CPython相同的代码。Nuitka可以使用各种C编译器,包括gcc,clang,MinGW64,Visual Studio 2019+和clang-cl,将Python代码转换为C.让我们创建一个“hello,word” Linux上的Python程序,并使用Nuitka进行编译:[Asm] 纯文本查看 复制代码 $ cat hello.pyprint('Hello, world!')
$ nuitka3 hello.py
...
$ ./hello.bin
Hello, world!
$ file hello.bin
hello.bin: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=eb6a504e8922f8983b23ce6e82c45a907c6ebadf, for GNU/Linux 3.2.0, stripped
$ du -sh hello.bin
432K hello.bin
Nuitka非常简单地生成了一个可移植的二进制文件,它的432 KB大小只是PyInstaller或py2exe可以生成的大小的一小部分!Nuitka如何做到这一点?让我们看一下build文件夹:[Asm] 纯文本查看 复制代码 $ cloc hello.build/
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C 11 2263 709 8109
C/C++ Header 1 1 0 7
-------------------------------------------------------------------------------
SUM: 12 2264 709 8116
------------------------------------------------------------------------------- Nuitka从我们的1行Python程序中产生了8,000行以上的C代码。Nuitka的工作方式是实际上将Python模块转换为C代码,然后使用libpython和自己的静态C文件以与CPython相同的方式执行。这非常令人印象深刻,并且随着时间的流逝,Nuitka“ Python编译器”很有可能会被进一步采用。稍后我们将看到,Nuitka在防止逆向工程(RE)方面可能具有进一步的内置优势。已经有几种工具可以轻松分析PyInstaller和py2exe生成的二进制文件以恢复Python源代码。但是,通过Nuitka将Python代码转换为C,进行逆向工程要困难得多。 Python恶意软件可以利用庞大的开源Python软件包和存储库生态系统。您几乎可以想到的任何东西,已经有人使用Python构建了它。对于恶意软件作者来说,这是一个巨大的优势,因为可以从开放的网络中挑选出简单的功能,而不必从头开始编写更复杂的功能。 让我们看一下三个简单但功能强大的工具示例:代码混淆截屏执行网络请求工具示例1 –混淆使用Python的恶意软件作者拥有许多库,他们可以使用这些库来模糊化Python代码以使代码的可读性变得更加困难,例如: pyminifier 和 pyarmor。这是一个如何pyarmor 混淆Python代码的小例子 :[Asm] 纯文本查看 复制代码 $ cat hello.py
print('Hello, world!')
$ pyarmor obfuscate hello.py
...
$ cat dist/hello.py
from pytransform import pyarmor_runtime
pyarmor_runtime()
__pyarmor__(__name__, __file__, b'\x50\x59\x41\x52\x4d\x4f\x52\x00\x00\x03\x08\x00\x55\x0d\x0d\x0a\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x40\x00\x00\x00\xd5\x00\x00\x00\x00\x00\x00\x18\xf4\x63\x79\xf6\xaa\xd7\xbd\xc8\x85\x25\x4e\x4f\xa6\x80\x72\x9f\x00\x00\x00\x00\x00\x00\x00\x00\xec\x50\x8c\x64\x26\x42\xd6\x01\x10\x54\xca\x9c\xb6\x30\x82\x05\xb8\x63\x3f\xb0\x96\xb1\x97\x0b\xc1\x49\xc9\x47\x86\x55\x61\x93\x75\xa2\xc2\x8c\xb7\x13\x87\xff\x31\x46\xa5\x29\x41\x9d\xdf\x32\xed\x7a\xb9\xa0\xe1\x9a\x50\x4a\x65\x25\xdb\xbe\x1b\xb6\xcd\xd4\xe7\xc2\x97\x35\xd3\x3e\xd3\xd0\x74\xb8\xd5\xab\x48\xd3\x05\x29\x5e\x31\xcf\x3f\xd3\x51\x78\x13\xbc\xb3\x3e\x63\x62\xca\x05\xfb\xac\xed\xfa\xc1\xe3\xb8\xa2\xaa\xfb\xaa\xbb\xb5\x92\x19\x73\xf0\x78\xe4\x9f\xb0\x1c\x7a\x1c\x0c\x6a\xa7\x8b\x19\x38\x37\x7f\x16\xe8\x61\x41\x68\xef\x6a\x96\x3f\x68\x2b\xb7\xec\x60\x39\x51\xa3\xfc\xbd\x65\xdb\xb8\xff\x39\xfe\xc0\x3d\x16\x51\x7f\xc9\x7f\x8b\xbd\x88\x80\x92\xfe\xe1\x23\x61\xd0\xf1\xd3\xf8\xfa\xce\x86\x92\x6d\x4d\xd7\x69\x50\x8b\xf1\x09\x31\xcc\x19\x15\xef\x37\x12\xd4\xbd\x3d\x0d\x6e\xbb\x28\x3e\xac\xbb\xc4\xdb\x98\xb5\x85\xa6\x19\x11\x74\xe9\xab\xdf', 1)
$ python dist/hello.py
Hello, world! 工具示例2 –屏幕截图信息窃取恶意软件通常具有捕获用户桌面截图以窃取敏感信息的功能。使用Python太容易了,有几个库可以做到这一点,包括: pyscreenshot 和 python-mss。屏幕截图可以很容易地python-mss 像这样拍摄 :[Asm] 纯文本查看 复制代码 from mss import mss
with mss() as sct:
sct.shot() 工具示例3 – Web请求恶意软件通常会发出Web请求,以在受感染的端点上执行各种不同的操作,包括:基于Web的命令和控制(C2),获取外部IP地址,下载第二阶段有效负载等。使用Python,发出Web请求非常简单,可以使用标准库或开源库(例如: requests 和 httpx)来完成。可以使用以下方式轻松获取受感染端点的外部IP地址 requests :[Asm] 纯文本查看 复制代码 import requests
external_ip = requests.get('http://whatismyip.akamai.com/').text EVAL()的力量 通常,Python的eval()内置函数被视为非常危险,因为在生产代码中使用它会带来严重的安全风险。但是, eval()在Python恶意软件中使用时具有巨大的优势。该 eval()功能非常强大,可用于从Python程序本身内部执行Python代码字符串。单个功能通常被视为已编译恶意软件的高级功能。如果使用得当,它可以即时运行高级脚本或“插件”。这类似于C恶意软件包括Lua脚本引擎以使恶意软件能够执行Lua脚本的情况。在诸如Flame之类的知名恶意软件中已经看到了这一点 。假设一个假想的APT组正在与某些基于Python的恶意软件进行远程交互。如果该小组遇到了需要快速反应的意外情况,那么能够在最终目标上直接执行Python代码将非常有益。此外,可以将Python恶意软件有效地“毫无特征”地放置在目标上,并且可以根据需要在目标上执行功能以保持隐身状态。到野外好吧,让我们看一些真实世界中的Python恶意软件样本!海公爵SeaDuke恶意软件可能是涉及基于Python的恶意软件的最引人注目的危害。Palo Alto的Unit 42对SeaDuke 进行了一些奇妙的分析 。可以在此处找到揭露的 反编译Python源代码单元42。此外,F-Secure还发布了有关Duke恶意软件的精彩 白皮书, 其中涵盖了SeaDuke和相关的恶意软件。SeaDuke恶意软件是Python木马,使用PyInstaller制成Windows可执行文件,并与UPX打包在一起 。混淆了Python源代码,使分析人员更难以阅读该代码。该恶意软件具有多种功能,包括在Windows上建立持久性的几种方法,运行跨平台以及执行Web命令和控制请求的能力。 PWOBOTPWOBot是基于Python的恶意软件,类似于SeaDuke,它是使用PyInstaller编译成Windows可执行文件的。它在2013-2015年期间很普遍,并影响了几个欧洲组织,其中大多数在波兰。该恶意软件功能非常强大,并且具有记录按键,在Windows上建立持久性,下载和执行文件,执行Python代码,创建Web请求以及挖掘加密货币的功能。Palo Alto的Unit 42对PWOBot 进行了一些出色的分析。PyLockyPyLocky是基于Python的勒索软件,使用PyInstaller编译成Windows独立可执行文件。它针对几个不同的国家,包括美国,法国,意大利和韩国。它包括防沙盒功能,命令和控制以及使用3DES(三重DES)密码的加密文件。趋势科技对PyLocky 进行了一些出色的分析 。Talos Intelligence的分析师对PyLocky进行了逆向工程,并能够为受害者创建文件解密器,以恢复其加密文件。PoetRATPoetRAT是基于Python的木马,该木马枚入侵了某国政府并枚举了系统并窃取了与控制风力涡轮机的ICS / SCADA系统有关的信息。该恶意软件是使用恶意Microsoft Word文档删除的。RAT提供了许多用于窃取信息的功能,包括通过FTP提取文件,使用网络摄像头拍摄图像,上传其他工具,键盘记录,浏览器枚举和凭据盗用。Talos Intelligence报告了该威胁参与者,并针对使用该恶意软件的未知参与者撰写了 精彩的文章。威胁参与者使用此简短脚本来捕获网络摄像头图像:开源病毒Python RAT, pupy 和 Stitch。这些开放源代码的Python木马展示了复杂和功能丰富的Python恶意软件有多复杂。pupy RAT是跨平台的,具有全内存执行准则,占用空间非常小,可以结合多种C2加密方法,使用反射注入迁移到进程中,并且可以从内存中加载远程python代码。PYTHON恶意软件分析工具有许多工具可用来分析Python恶意软件,即使是已编译的形式。让我们粗略地看一下恶意软件分析师可以使用哪些工具来破解Python恶意软件。uncompyle6decompyle,uncompyle和uncompyle2- uncompyle6的后继者 是本机Python交叉版本反编译器和片段反编译器。它可用于将Python字节码转换回Python源代码。例如,以我们的“你好,世界!” 之前的脚本,并将其作为模块执行,然后为我提供pyc文件(字节码)。我们可以使用uncompyle恢复脚本的源代码。[Asm] 纯文本查看 复制代码 $ xxd hello.cpython-38.pyc
00000000: 550d 0d0a 0000 0000 16f3 075f 1700 0000 U.........._....
00000010: e300 0000 0000 0000 0000 0000 0000 0000 ................
00000020: 0002 0000 0040 0000 0073 0c00 0000 6500 [email].....@...s....e[/email].
00000030: 6400 8301 0100 6401 5300 2902 7a0d 4865 d.....d.S.).z.He
00000040: 6c6c 6f2c 2077 6f72 6c64 214e 2901 da05 llo, world!N)...
00000050: 7072 696e 74a9 0072 0200 0000 7202 0000 print..r....r...
00000060: 00fa 2d2f 686f 6d65 2f75 7365 722f 746d ..-/home/user/tm
00000070: 702f 7079 7468 6f6e 5f61 7274 6963 6c65 p/python_article
00000080: 2f6e 2f74 6573 742f 6865 6c6c 6f2e 7079 /n/test/hello.py
00000090: da08 3c6d 6f64 756c 653e 0100 0000 f300 ..<module>......
000000a0: 0000 00
$ uncompyle6 hello.cpython-38.pyc | grep -v '#'
print('Hello, world!') pyinstxtractor.py(PyInstaller提取器)该 PyInstaller提取 可以提取PyInstaller编译的可执行文件的Python数据。运行非常简单:[Asm] 纯文本查看 复制代码 > python pyinstxtractor.py hello.exe
... 这将生成pyc文件,然后可将其与uncompyle6反编译器一起使用以恢复源代码。python-exe-unpacker该 EXE unpack.py脚本 可以用来解压和反编译了与py2exe生成的可执行文件。可以这样使用:[Asm] 纯文本查看 复制代码 > python python_exe_unpack.py -i hello.exe
... 检测PYTHON编译的可执行文件在Windows上编译时,PyInstaller和py2exe都会在其二进制可执行文件中放置唯一的字符串。这意味着可以使用简单的YARA规则检测到它们。PyInstaller在可执行文件的末尾写入字符串“pyi-windows-manifest-filename”,您可以在十六进制编辑器(HxD)中看到它: 这是用于检测PyInstaller编译的可执行文件的YARA规则(Source):[Asm] 纯文本查看 复制代码 import "pe"
rule PE_File_pyinstaller
{
meta:
author = "Didier Stevens (https://DidierStevens.com)"
description = "Detect PE file produced by pyinstaller"
strings:
$a = "pyi-windows-manifest-filename"
condition:
pe.number_of_resources > 0 and $a
} 这是用于检测py2exe编译的可执行文件的第二条YARA规则(Source):[Asm] 纯文本查看 复制代码 import "pe"
rule py2exe
{
meta:
author = "Didier Stevens (https://www.nviso.be)"
description = "Detect PE file produced by py2exe"
condition:
for any i in (0 .. pe.number_of_resources - 1):
(pe.resources[i].type_string == "P\x00Y\x00T\x00H\x00O\x00N\x00S\x00C\x00R\x00I\x00P\x00T\x00")
} 结论从Python恶意软件的世界来看,现在就这些了。有趣的是,随着计算机系统变得越来越快,更容易操作,恶意软件趋势也发生了变化。 |