【天问】PyPI 2023年Q3恶意包回顾(二)
/ / 点击 / 阅读耗时 26 分钟2023年第三季度,天问Python供应链威胁监测模块共捕捉到320个恶意包。在对某一家族的恶意包分析中,我们发现攻击者会不断尝试更新迭代攻击方式来规避安全检测,其恶意代码逐渐趋同于正常代码。这使得恶意代码监测的难度不断提升,给供应链安全带来了巨大的挑战。
天问供应链威胁监测模块是奇安信技术研究星图实验室研发的“天问”软件供应链安全分析平台的子模块,”天问“分析平台对Python、npm等主流的开发生态进行了长期、持续的监测,发现了大量的恶意包和攻击行为。
1. 网络请求
相关恶意特征: requests.get
, socket.socket
,urllib.request.urlopen
这种恶意包根据网络请求的目的可以分为三类,信息回传、恶意载荷下载和反向Shell。
1.1 信息回传
相关恶意特征: socket.gethostname
, os.getcwd
, getpass.getuser
,request.get
, platform.release
, platform.system
,https://api.ipify.org
, http://ifconfig.me
, https://geolocation-db.com/jsonp/{ip}
,socket.gethostname
我们在Q3的监测中,发现了一个恶意包家族,这些恶意包在setup.py
中设置的author
和author_email
完全一致。通过对这个恶意家族的演变分析,我们发现攻击者也在不断升级尝试不同的攻击手法,来逃避安全检测。
discord-api-requests-1.0.0/setup.py
1 | from setuptools import setup |
这是我们发现的这个恶意家族的第一个包,可以看到它向一个discord账号回传了一个字符串”Alguien ha instalado el paquete.”。这是一句西班牙语,含义是”有人已经安装了该软件包”,由此可以推断这是攻击者的一个测试包。
当天晚些时候,该攻击者又发布了另外一个恶意包。
simple-discord-api-1.0.1/setup.py
1 | from setuptools import setup |
从包内的内容,我们可以看到攻击者将恶意代码放在的第三方网站上,通过网络请求的方式获取恶意代码并加载到内存中执行。第三方网站的截图如下所示。
之后,该攻击者将PyPI的账号从benjskk
切换到了benjaprograms
,同时更新了恶意包的内容。将攻击代码变成字符串,写入文件中,然后通过执行文件的方式来发起攻击。这样可以避免静态检测中对于第三方库函数的检测,具体代码如下所示。
discord-simple-api-1.2.1/setup.py
1 | from setuptools import setup |
在discord-simple-api-1.3.1
中,攻击者取消了文件写入操作,直接使用exec
执行字符串,实现无文件攻击。
discord-simple-api-1.3.1/setup.py
1 | from setuptools import setup |
三天后,攻击者又使用bestprogrammer
这个账号发布了新的恶意包urtelib32-1.7.2
,这次攻击者将攻击代码使用base64编码写入一个文件,并将文件伪装成png。从第三方服务器下载到这个伪装png后,会对其解码运行。迷惑性更强,具体代码如下。
urtelib32-1.7.2/setup.py
1 | from setuptools import setup |
然后,攻击者bestprogrammer
又进一步隐藏了恶意代码,在urllitelib-1.0.1
中,其将恶意代码从setup.py
中移到的urllitelib/post_install.py
中,setup.py
中只保留启动命令,具体代码如下所示。
urllitelib-1.0.1/setup.py
1 | from setuptools import setup |
urllibtelib-1.0.1/urllitelib/post_install.py
1 | import requests |
为了进一步隐藏攻击代码,攻击者pyprograms
选择不在安装时执行恶意代码,而是将恶意代码放到模块的__init__.py
文件中,在import过程中执行。同时,其添加了其他正常代码企图干扰检测分析,具体代码如下。
pygraphql32-1.2.0/setup.py
1 | from setuptools import setup |
pygraphql32-1.2.0/pygraphql/__init__.py
1 | import requests, random, time |
通过对这个恶意家族的分析,我们不难发现攻击者对于逃避恶意检测的手段在不断迭代更新,而且他们的伪装使得恶意代码与正常代码相差无几。这对于恶意检测分析而言将是一个非常严峻的考验,未来如何能高效准确地分辨这些恶意包将会是非常重要的一个课题。
visumpy-2073.0.0/setup.py
1 | from setuptools import setup |
这个恶意包收集了用户主机名和用户名等信息进行了回传。经过分析,回传所使用的网址是通过GitHub一个开源工具interactsh
生成的,其可以将payload内容通过这个网址回传给攻击者。类似的网址还有https://oastify.com/
,其是Burp Suite用于测试web应用安全漏洞的,但被部分攻击者用于接收受害者的相关信息。
信息回传常见网址 oastify.com
,burpcollaborator.net
,pipedream.net
,oast.fun
, https://discord.com/api/webhooks/
1.2 恶意载荷下载
恶意载荷可以是一个恶意文件,也可以是一段代码。这些载荷通常放在第三方文件分享网站,常见的网站列表如下所示:
https://paste.fo
,https://transfer.sh/
,https://cdn.discordapp.com/attachments/
,https://dl.dropbox.com/
,https://www.mediafire.com/
,https://rentry.co/
,https://raw.githubusercontent.com/
,https://render.com/
adv2099m-1.0.0/setup.py
1 | import setuptools |
这个恶意包利用requests
下载了一个zip文件,并将其解压缩移动到了Windows的AppData
目录下。然后,其通过改写WindowsUpdater.bat
实现了系统启动时的自动运行。
pfadver05/setup.py
1 | ... |
这个恶意包的攻击代码与上面的基本一致,差别在于它将恶意代码从setup.py
文件中移动到了adv2099.py
中,并在setup参数中规定了模块名。这样模块被导入的时候,就会触发攻击。
1.3 反向Shell
相关恶意特征: socket.socket
,/bin/sh
nir-bb-test-0.6
1 | ... |
2. base64 payload
相关恶意特征: base64.b64decode
,setuptools.command.install.install
,tempfile.NamedTemporaryFile
pyJwtRequest-1.0.4/setup.py
1 | import base64 |
payload可以是一段代码,也可以是一个二进制文件。这个恶意包中包含了一个反向shell的代码。
1 | import os, socket, subprocess, threading |
feur-0.1/setup.py
1 | import base64 |
这个包中的内容相较于前一个包,添加了一个新的base64字符串code2。这个payload是一个二进制文件,在包安装过程中写入临时文件并执行。
3. 附录(恶意包列表)
网络请求
- 信息回传
包名 版本 作者 上传时间 visumpy 2073.0.0 prasiddha47 2023-07-06T09:05:59 min-jq 1.5 kotko 2023-07-12T04:30:46 diaossama-test2 0.0.3 PypiSecTest 2023-07-13T09:48:51 diaossama-test3 0.0.2 PypiSecTest 2023-07-14T11:13:10 diaossama-test3 0.0.3 PypiSecTest 2023-07-14T11:28:56 diaossama-test3 0.0.4 PypiSecTest 2023-07-14T11:38:36 thanos-gen 2.1.1 predator_97x1 2023-07-20T10:37:34 mypackage-for-demo-purposes 0.1 clear-test 2023-07-27T06:48:24 nferx 1.0.0 abradabra 2023-07-27T09:15:31 algokit-arc 10.0.1 nirajmodi 2023-08-05T05:07:47 dependencyrrr 1.0.0 Rooted0x01 2023-08-08T04:21:25 peloton-client123 0.8.10 y54586b0 2023-08-13T22:34:01 syns-knox-xss-allwhere 1.0.0 Rooted0x01 2023-08-13T22:38:30 kwxiaodian 9.1.10 LkBAUB 2023-09-03T15:10:39 openapi-ba 9.1.10 LkBAUB 2023-09-03T15:40:37 dsc-auth 1.1.1 index80999357 2023-09-03T15:44:52 vmc-reporter 1.99.103 Pinkyy 2023-09-06T08:53:02 appsec-utils 1.99.105 Pinkyy 2023-09-06T13:04:40 appsec-utils 1.99.106 Pinkyy 2023-09-06T15:02:33 aisi-od-training 1.99.106rc1 Pinkyy 2023-09-07T09:49:42 discord-api-requests 1.0.0 benjskk 2023-09-07T04:15:52 simple-discord-api.py 1.0.0 benjskk 2023-09-07T20:08:41 simple-discord-api.py 1.0.1 benjskk 2023-09-07T20:15:25 simple-api.py 1.0.2 johnprogrammer 2023-09-07T20:35:46 discord-simple-api.py 1.2.1 benjaprograms 2023-09-07T22:05:35 discord-simple-api.py 1.3.0 benjaprograms 2023-09-07T22:09:12 discord-simple-api.py 1.3.1 benjaprograms 2023-09-07T22:12:41 rtlibb32 1.2.1 benjashh 2023-09-08T00:26:21 urtelib32 1.7.2 bestprogrammer 2023-09-10T01:06:45 urtelib32 1.7.3 bestprogrammer 2023-09-10T01:10:51 urtelib32 1.7.5 bestprogrammer 2023-09-10T01:19:28 urllitelib 1.0.1 bestprogrammer 2023-09-10T02:33:10 pygraphql32 1.2.0 pyprograms 2023-09-10T18:50:15 litepygraphql 1.2.0 pyprograms 2023-09-10T19:12:05 pygraphql32 1.2.1 pyprograms 2023-09-10T19:18:23 graphql32 1.7.3 johnxx 2023-09-11T01:23:48 graphql32 1.8.0 johnxx 2023-09-11T02:18:05 secureit-a-tope 1.2 zer0ulsalamandy 2023-09-15T08:32:01 secureit-a-topev1 1.2 zer0ulsalamandy 2023-09-15T08:33:28 secureit-a-topev2 1.2 zer0ulsalamandy 2023-09-15T08:36:15 secureit-a-topev3 1.2 zer0ulsalamandy 2023-09-15T08:38:22 secureit-a-topev3 99.99 zer0ulsalamandy 2023-09-15T12:34:02 secureit-a-topev4 99.99 zer0ulsalamandy 2023-09-15T12:35:30 pytarlooko 1.0.0 vcdhgfg 2023-09-23T20:53:42 - 恶意载荷下载
包名 版本 作者 上传时间 adv2099m 1.0.0 adv2099 2023-07-02T16:49:27 adv2099m2 1.0.0 adv2099 2023-07-02T16:58:52 adv2099m3 1.0.0 adv2099 2023-07-02T17:02:29 adv2099m4 1.0.0 miguel2099 2023-07-02T17:14:02 adv2099m5 1.0.0 miguel2099 2023-07-02T17:17:51 adv2099m6 1.0.0 miguel2099 2023-07-02T17:21:26 adv2099m7 1.0.0 adv2099n2 2023-07-02T19:06:30 supra-style 0.6 Oxygen1337 2023-07-04T02:19:16 supra-style 0.7 Oxygen1337 2023-07-04T11:10:45 urz 0.1 SpookyCoder 2023-07-04T19:49:31 juk 0.1 SpookyCoder 2023-07-04T21:08:45 tjajsd 10.33 Tahg.py 2023-07-05T15:08:53 jas9do1 7.72 Tahg.py 2023-07-05T15:12:38 18923aa 4.96 Tahg.py 2023-07-05T15:13:32 pfadver05 1.0.0 pfadver05 2023-07-06T18:20:45 servantcord 1.0.0 servant666 2023-07-07T12:22:11 servantcord 1.0.1 servant666 2023-07-07T12:51:10 servantcord 1.0.2 servant666 2023-07-07T12:56:38 servantcord 1.0.3 servant666 2023-07-07T12:59:20 servantcord 1.0.4 servant666 2023-07-07T13:02:26 servantcord 1.0.6 servant666 2023-07-07T13:05:35 servantcord 1.0.8 servant666 2023-07-07T13:16:53 servantcord 1.0.9 servant666 2023-07-07T13:21:35 servantcordd 1.0.9 servant666 2023-07-07T14:10:00 servandcord 1.0.9 servant666 2023-07-07T15:10:24 testpackageforyoutube 1.0.0 killskids 2023-07-14T10:42:43 killskids-auth 1.0.5 killskids 2023-07-14T11:34:01 killskids-auth 2.0.0 killskids 2023-07-14T12:33:28 pyobfuscater 1.0.0 killskids 2023-07-17T17:59:55 pyobfuscater 1.0.1 killskids 2023-07-17T18:05:19 pyobfuscater 1.0.3 killskids 2023-07-17T18:11:54 pyobfuscater 1.0.7 killskids 2023-07-17T18:16:39 pyobfuscater 1.0.8 killskids 2023-07-17T18:19:14 pyobfuscater 1.1.0 killskids 2023-07-17T18:25:55 pyobfuscater 1.2.1 killskids 2023-07-17T18:29:53 wessycord 1.2.4 killskids 2023-07-17T18:37:21 wessycord 1.6.1 killskids 2023-07-17T18:46:08 nagie 1.1.0 DreamyOak 2023-07-19T13:35:21 nagie 1.13.0 DreamyOak 2023-07-19T13:39:37 nagie 2.32.0 DreamyOak 2023-07-19T13:46:35 nagiepy 3.422.0 nagie 2023-07-22T10:47:00 nageir 0.1.2 nagie 2023-07-22T10:55:47 dsicobotuser 0.0.1 True_Hell 2023-07-20T06:27:42 dicuser 0.0.1 True_Hell 2023-07-20T06:36:22 dicuser 0.0.2 True_Hell 2023-07-20T06:45:13 dicuser 0.0.3 True_Hell 2023-07-20T06:58:52 dicuser 0.0.4 True_Hell 2023-07-20T07:12:37 dicuser 0.0.5 True_Hell 2023-07-20T07:22:13 diuser 0.0.1 True_Hell 2023-07-20T07:31:17 genuser 0.0.1 True_Hell 2023-07-20T15:28:23 duck-test-pkg 1.99.0 pypi_sw_training 2023-07-24T18:59:34 duck-test-pkg 1.99.0 pypi_sw_training 2023-07-24T18:59:36 splite5 0.0.1 badsidev 2023-07-25T11:23:09 splite5 0.0.1 badsidev 2023-07-25T11:23:10 evil-pip 0.0.1 0xe2d0 2023-08-23T19:47:01 evil-pip 0.1.0 0xe2d0 2023-08-23T20:00:56 - 反向Shell
包名 版本 作者 上传时间 nir-bb-test 0.6 niroh 2023-07-03T14:51:55 base64 payload
包名 | 版本 | 作者 | 上传时间 |
---|---|---|---|
graphdata | 0.9.0 | j_ackerman | 2023-07-01T09:20:32 |
pyJwtRequest | 1.0.4 | ErwannTestOmg | 2023-07-01T14:44:02 |
EvannLeGoat | 1.0.4 | ErwannCacaOmg | 2023-07-01T15:38:30 |
SwiftyPy | 2.1 | SwiftFan | 2023-07-01T16:40:39 |
SwiftyPy | 3.1 | SwiftFan | 2023-07-01T22:47:45 |
SwiftyPy | 4.1 | SwiftFan | 2023-07-01T22:50:24 |
SwiftyPy | 5.1 | SwiftFan | 2023-07-02T00:46:56 |
SwiftyPy | 7.1 | SwiftFan | 2023-07-02T00:56:54 |
SwiftyPy | 8.1 | SwiftFan | 2023-07-02T01:03:18 |
SwiftyPy | 8.2 | SwiftFan | 2023-07-02T01:06:59 |
requests-toolbelt-2 | 0.0.0 | nexmo | 2023-07-20T02:02:44 |
requests-toolbelt-2 | 0.0.0 | nexmo | 2023-07-20T02:02:45 |
requests-toolbelt-v2 | 0.0.0 | jrich84 | 2023-07-20T02:09:25 |
requests-toolbelt-v2 | 0.0.0 | jrich84 | 2023-07-20T02:09:26 |
requests-toolbelt-v2 | 0.0.1 | jrich84 | 2023-07-20T02:12:47 |
requests-toolbelt-v2 | 0.0.1 | jrich84 | 2023-07-20T02:12:49 |
osinfopkg | 0.0.3 | marianacamelia | 2023-07-19T07:54:17 |
osinfopkg | 0.0.3 | marianacamelia | 2023-07-19T07:54:19 |
osinfopkg | 1.0.2 | marianacamelia | 2023-07-24T06:26:57 |
osinfopkg | 1.0.2 | marianacamelia | 2023-07-24T06:26:59 |
osinfopkg | 1.0.3 | marianacamelia | 2023-07-24T06:58:55 |
osinfopkg | 1.0.3 | marianacamelia | 2023-07-24T06:58:57 |
osinfopkg | 1.0.4 | marianacamelia | 2023-07-24T07:19:32 |
osinfopkg | 1.0.4 | marianacamelia | 2023-07-24T07:19:33 |
VMConnect | 1.1.7 | hushki502 | 2023-07-28T02:38:30 |
VMConnect | 1.1.7 | hushki502 | 2023-07-28T02:38:32 |
this-package-is-a-test-of-starjacking | 1.0.0 | allegrep | 2023-09-11T15:48:47 |
pystob | 1.0.0 | Hellka | 2023-09-17T11:12:51 |
pylioner | 1.0.0 | Histoll | 2023-09-17T21:23:42 |
pystallerer | 1.0.0 | J_nky | 2023-09-22T18:49:22 |
pyktrkatoo | 1.0.0 | J_nky | 2023-09-23T17:31:57 |