一、前言

根据“天问”平台的监测分析,在2023年2月份,共发现了261个npm恶意包。这些恶意包中,依赖混淆攻击仍然持续不断,攻击者利用简单的npm包来窃取和收集可被攻击对象的敏感信息。此外,还有一些攻击者针对Windows平台精心构造了木马病毒。通过一个伪装的程序崩溃页面,诱导用户下载安装包含木马后门的flash安装包。一旦安装运行后,攻击者可以持续地控制受害者主机。

二、分析

2.1 持续的依赖混淆攻击

在2023年2月,针对npm生态的依赖混淆攻击屡屡发生。例如恶意npm包micro-username在package.json的scripts字段中直接嵌入恶意代码。这种做法在npm生态的软件供应链攻击中已经是非常常见且频繁的。scripts字段中定义的preinstall内容会在安装时自动以shell环境执行,攻击者滥用了npm的这一点特性来进行攻击。而在这个恶意包中,攻击者将受害者主机的名称和用户名称发送至远程接收服务器。

除此之外,这一类的恶意包中往往还包含了攻击者的一些描述声明,表明自己是进行所谓的“安全测试”或者“安全研究”。例如在包micro-username中就包含了一串描述字符:“Simple PoC package for testing for dependency confusion vulnerabilities.”,攻击者试图表明该包是用来证明和测试依赖混淆漏洞的。

然而,出于安全研究的道德考量,这种行为是不被认可的。因此,在分析过程中,只要npm包中包含了可能会危及用户机器的行为(比如收集敏感信息等),都被认为是恶意的。

image-20230324164400840

随着依赖混淆攻击的持续进行,不同的攻击者会使用不同的域名来进行信息的收集,除了以往常见的域名外,在本月的恶意包分析中还发现了以下几个新增的域名:

1
2
3
4
5
6
7
8
9
curetosec.online
oast.live
oast.site
oast.me
ident.me
vabch.org
lupin.monster
tirvax.com
bind9-or-callback-server.com

2.2 针对Windows平台的恶意攻击

2023年2月3日,攻击者cq0km9hu上传了一个名为aabquerys的恶意包,在该恶意包仅有一个被严重混淆后名为jquery.js文件。

image-20230324170148711

经过反混淆分析后,发现该JavaScript文件会伪装出一个程序崩溃后的crash页面,诱使用户点击“安装兼容程序”按钮,实际上会从攻击者的远程服务器下载木马后门,并将其执行。此外,该文件还会检测用户的操作系统平台,只有在PC端才会执行,否则会弹出错误提示信息“此插件仅支持在电脑端安装”。从上述行为可以看出,该恶意程序具有明确的目的性和针对性。

image-20230324171418284

根据分析,从远程服务器下载的恶意样本为Windows PE文件,其伪装成flash安装包并在受害者主机上执行一系列恶意操作。经过天穹沙箱分析平台的深入分析,发现该恶意样本采用Inno Setup Module工具进行打包伪装。执行后,该样本将再次下载一个名为demon.bin的远程控制木马。据分析,该木马是基于一个开源远程控制开发框架Havoc开发而成。通过该木马,受害者主机会连接到远程C2,并进一步受到恶意指令的攻击。更为详细的分析结果可以参考天穹沙箱报告

image-20230324175351322

需要注意的是,恶意包中并没有自动执行混淆的JavaScript脚本。根据天问供应链依赖分析平台的查询结果,在整个npm生态中也没有任何依赖使用该恶意包,该恶意包的名称aabquerys和一个正常包的名称abquery较为相似,这是一个在JQuery基础上再次开发的第三方库。恶意包内唯一一个文件以jquery.js命名并导出,我们推测,攻击者可能利用了一些jQuery开发人员的输入错误,从而引入该npm包,并触发其恶意行为。

image-20230327105953672

此外,通过分析该npm包上传者的帐号,我们发现攻击者使用了一个@bestdefinitions.com的匿名邮箱。进一步检索使用该邮箱发布的npm包,我们发现其他两个疑似相同作者的恶意包,分别是aabquerynvm_jquery。这两个包使用了相同的混淆方式,但攻击逻辑略有不同,我们猜测这可能是攻击者在本地测试用的包。

附录

2023年2月恶意包名称汇总如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
hellosign-embedded-cla@8.0.2
bykea_node_boilerplate@2.0.1
mypy-action@6.0.2
mypy-action@8.0.2
swisspost@99.99.99
buildin@99.99.1
nayduck@99.99.97
nayduck@99.99.96
dwolla-algolia-search@50.50.50
dwolla-algolia-search@50.50.60
browser-abc@99.99.99
browser-main@99.99.99
browser-main-obj-redirect@99.99.99
browser-main-unmodified@99.99.99
common-dep-required@99.99.99
bundle-dep@99.99.99
mk1@99.99.99
nested-export@99.99.99
typecommon@99.99.99
nested-file@99.99.99
symlink-peer@99.99.99
erc1400@99.99.99
abacus-cmdline@99.99.99
buildin@99.99.2
zsbpwebsdktest@9999.99.9
zsbpwebsdktest@9999.99.91
zsbpwebsdktest@9999.99.92
zsbpwebsdktest@9999.99.93
zsbpwebsdktest@9999.99.94
eslint-plugin-indeed@99.99.9
texture-allocator@99.99.99
editor-layer-index@99.99.99
jumflot@99.99.99
compositionupdate@88.8.8
rb-web-info-component@99.99.99
zsbpwebsdktest3@9999.999.99
zsbpwebsdktest3@9999.999.990
zsbpwebsdk@9999.99.1
zsbpsdk@9999.99.1
zsbpsdk@9999.999.100
zsbpwebsdk@9999.999.100
editor-layer-index@99.99.80
texture-allocator@99.99.80
use-sync-external-store-shim@1.0.0
use-sync-external-store-shim@1.0.1
flp_all@1.0.0
micro-username@2.0.6
micro-username@2.0.9
micro-username@2.1.0
micro-username@2.1.1
micro-username@2.1.2
micro-username@2.1.3
commentrating@99.9.1
twinmotion@99.1.1
diesel-site@99.9.1
dist-web@99.1.1
plain-function@20.1.1
egs-trusted-domains@99.2.1
allianz-icons@7.999.9
allianz-icons@8.999.7
egstore-carousel@99.2.1
allianz-icons@8.999.4
allianz-icons@8.999.3
allianz-icons@8.999.6
allianz-icons@8.999.5
proton-account@99.99.999
proton-pack@99.99.9999
allianz-icons@9.999.2
allianz-icons@8.999.8
vpro-dev@1.0.0
minify_flp@1.0.0
@gumtree/ui-library@10.0.0
@gumtree/ui-library@0.5.0
@gumtree/ui-library@5.0.0
@gumtree/ui-library@30.0.0
@gumtree/ui-library@20.0.0
@gumtree/ui-library@0.4.0
@gumtree/ui-library@0.2.0
@gumtree/ui-library@0.1.0
@gumtree/ui-library@1.0.0
@gumtree/ui-library@0.3.0
ftvi-meteo-frontend@0.21.0
ftvi-meteo-frontend@0.20.0
ftvi-meteo-frontend@0.20.1
testneb@1.0.1
action-destinations@70.0.2
action-destinations@70.0.3
instantsearch-web@3.2.15
testnebb@1.0.1
micro-username@2.1.4
recurly-dev@6.0.5
apache2@1.1.9
micro-username@2.1.5
micro-username@2.1.6
micro-username@2.1.7
micro-username@2.1.8
micro-username@2.1.9
micro-username@2.2.0
jquery-impromtu@1.0.0
smart-commons@19.6.1
smart-commons@9.6.1
egstore-carousel@99.2.2
commentrating@99.9.3
twinmotion@99.1.2
dist-web@99.1.2
plain-function@20.1.2
diesel-site@99.9.2
@chegg/wtai-upload-widget@9.999.2
reporter-app-dist@1.0.0
reporter-app-dist@1.0.1
reporter-app-dist@1.1.1
@chegg/wtai-upload-widget@9.999.8
@chegg/wtai-upload-widget@9.999.7
saddlebag-event-logger@5.0.0
skyscanner-themes@5.0.0
testingforbug855@1.1.1
capacity-planning-projection@9.1.3
eslint-config-bayzat@50.1.1
virgil-spring-boot-starter@20.0.0
another-dev-dependency2@3.0.0
fusion-cli-tests@0.0.0-monorepo
not-a-real-project@0.0.0
not-a-real-dep@0.0.0
proton-account@99.99.9999
proton-pack@99.9999.9999
hackerone2222@1.0.0
azure-rest-api-specs-tests@1.0.0
fe-core-components-vuejs@0.15.0
fe-core-components-vuejs@0.14.1
jquery-mask@99.0.0
jquery-mask@1.7.7
mobile-kohana@68.0.0
nokia-smp@1.0.2
prize-market@1.999.0
prize-market@2.999.0
prize-market@3.999.0
prize-market@4.999.0
prize-market@5.999.0
prize-market@6.999.0
flow-faucet@5.999.0
flow-faucet@1.999.0
flow-faucet@2.999.0
flow-faucet@3.999.0
flow-faucet@4.999.0
flow-faucet@6.999.0
flow-faucet@7.999.0
flow-faucet@8.999.0
flow-faucet@9.999.0
flow-faucet@10.999.0
prize-market@7.999.0
prize-market@8.999.0
prize-market@9.999.0
prize-market@10.999.0
transparent-proxy@1.11.0
bnjuilopjhgthtyi@99.99.99
kuna-chart-header@1.999.0
kuna-chart-header@2.999.0
kuna-chart-header@3.999.0
kuna-chart-header@4.999.0
kuna-chart-header@5.999.0
kuna-chart-header@6.999.0
kuna-chart-header@7.999.0
kuna-chart-header@8.999.0
kuna-chart-header@9.999.0
kuna-chart-header@10.999.0
asc-deps@0.0.1
ban-notifier4@1.0.0
dc-preview-utils@99.0.0
dc-preview-utils@99.0.1
azure-sp@3.0.0
xsstesttttttttt@1.0.1
zsbpwebsdktest2@9999.9.9
xsstesttttttttt@1.0.3
ban-notifier6@1.0.1
seaport_v1_2@99.0.0
seaport_v1_2@1.0.0
@pagseguro/pagseguro-utils-test@1.999.1
@pagseguro/pagseguro-utils@9.99.9
@pagseguro/pagseguro-utils@3.10.9
@pagseguro/pagseguro-utils@3.99.9
idcs-dialog@1.0.0
idcs-dialog@1.2.0
notebooklanguageserver@3.0.0
kiosk-util@9999.9999.9998
legal-footer@9999.9999.9998
multivariate-experiments@9999.9999.9998
privacy-mask@9999.9999.9998
theme-next@9999.9999.9998
theme-next@9999.9999.9999
privacy-mask@9999.9999.9999
multivariate-experiments@9999.9999.9999
legal-footer@9999.9999.9999
kiosk-util@9999.9999.9999
spectra-ui-commons@35.0.0
transparent-proxy@1.11.1
transparent-proxy@1.11.2
transparent-proxy@1.11.3
miro-api-clients@8.0.5
transparent-proxy@1.11.4
transparent-proxy@1.11.5
transparent-proxy@1.11.6
transparent-proxy@1.11.7
eg-affiliates-common@1.0.2
eg-affiliates-common-test@0.0.2
confusedatma@4.0.0
confusedatma@6.0.0
vmw-atk@1.0.0
zsbpwebsdktest3@9999.9.9
zsbpwebsdk@9999.9.1
zsbpwebsdk@9999.9.2
@doccledev/pattern-library@5.0.99
tempomati-omega-3@1.0.0
tempomati-omega-5-emcuf31@1.0.0
tempomati-omega-5-emcuf31@1.0.1
tempomati-omega-5-emcuf311@1.0.1
tempomati-omega-5-emcuf2@1.0.1
tempomati-omega-5-emcuf5@1.0.1
tempomati-omega-69-emcuf8@1.0.0
tempomati-omega-69-emcuf7@1.0.0
apomakqyr3@1.0.0
stateful-fastclick@1.0.0
sapling-output-plugin@1.0.0
piercing-library@1.0.0
tempomatrce3@1.0.0
common-dep-target@1.0.0
hackity@1.0.0
myattenuator@1.0.0
typeparsers@1.0.0
react-test-renderer-17@1.0.0
webpack-dev-server.legacy@1.0.0
webpack-cli.legacy@1.0.0
spectra-ui-commons@16.3.8
micro-username@1.0.5
micro-username@1.0.9
micro-username@1.4.0
micro-username@1.5.0
@appdirect/public-custom-app-ui@0.0.9
micro-username@2.0.4
micro-username@2.0.5
wf-extract-text-in-image2@1.0.0
wf-extract-text-in-image2@1.0.1
wf-extract-text-in-image2@1.0.2
wf-extract-text-in-image2@1.0.3
@nobixe9651/ng-fds@1.0.2
eslint-plugin-dropbox-sign@99999.1.0
eslint-plugin-dropbox-sign@99999.1.1
eslint-plugin-dropbox-sign@99999.1.2
opbox-web@99.0.0
opbox@99.0.0
opbox-seller-shop-service@99.0.0
fkletbbpoc@0.0.1
staging-opbox-web-browser@99.0.0
ifoodshop-react-ui@99.0.0
eslint-plugin-dropbox-sign@999999999999999.0.0
nvm_jquery@1.0.0
nvm_jquery@1.0.1
nvm_jquery@1.0.2
aabquery@1.0.0
aabquerv@1.0.1
aabquerys@1.0.0
aabauervs@1.0.1