|

Update: IconBurst NPM software supply chain attack grabs data from apps and websites

ReversingLabs researchers have uncovered a widespread campaign to install malicious NPM modules that are harvesting sensitive data from forms embedded in mobile applications and websites.

Karlo Zanki
Blog Author

Karlo Zanki, Reverse Engineer at ReversingLabs. Read More...

IconBurst

Executive Summary

Update: since publication of this blog, new, malicious packages attributable to the accounts identified in our original report appeared on npm. In addition, new CDN (content distribution network) infrastructure was identified being used for script inclusion. We have updated our blog post to include the latest information and will continue updating it as new threats or information become available. (July 6, 2022)

ReversingLabs researchers recently discovered evidence of a widespread software supply chain attack involving malicious Javascript packages offered via the NPM package manager. Researchers at ReversingLabs identified more than two dozen NPM packages, dating back six months, that contain obfuscated Javascript designed to steal form data from individuals using applications or websites where the malicious packages had been deployed.

Upon closer inspection, we discovered evidence of a coordinated supply chain attack, with a large number of NPM packages containing jQuery scripts designed to steal form data from deployed applications that include them. While the full extent of this attack isn’t yet known, the malicious packages we discovered are likely used by hundreds, if not thousands of downstream mobile and desktop applications as well as websites. In one case, a malicious package had been downloaded more than 17,000 times.

As with the recent (benign) dependency confusion attacks targeting German organizations, these clearly malicious attacks relied on typo-squatting, a technique in which attackers offer up packages via public repositories with names that are similar to — or common misspellings of — legitimate packages. Attackers impersonated high-traffic NPM modules like umbrellajs and packages published by ionic.io. However, it is the end users of software (and their data) rather than development organizations that are the real targets. That makes this attack more comparable to the infamous SolarWinds compromise than to other, more recent supply chain compromises. Furthermore, similarities between the domains used to exfiltrate data suggest that the various modules in this campaign are in the control of a single actor.

Here’s detailed information on this widespread software supply chain attack, including known indicators of compromise (IOCs) associated with the attacks — and recommendations for remediating the threat posed by these malicious NPM modules.

[ Watch Reverse Engineer Karlo Zanki's  a deep-dive discussion about his IconBurst research on ConversingLabs ]

Introduction

The ReversingLabs research team is continuously monitoring open-source package repositories for instances of malicious code planting and software supply chain attacks. This work involves both automated and human-led scanning and analysis of packages published in the most popular public package repositories like NPM, PyPI, Ruby and NuGet. During these scans, we leverage our proprietary Titanium platform, and our deep file repository of goodware and badware to spot malicious and even suspicious elements hiding in plain view. Our newly released ReversingLabs secure.software solution builds upon that past work. The platform provides a way for dev and SOC teams to deeply examine their CI/CD workflows, containers and release packages to spot nascent or active software supply chain compromises.

Frequently, our work turns up evidence of active software supply chain attacks. In April, we came across NPM packages that used a javascript obfuscator to hide their functionality. Our analysis of those packages produced proof of the simulated “dependency confusion” attacks on the software supply chain of leading German companies across a number of industries. We have been tracking NPM repositories for occurrences of packages that use the same obfuscator ever since.

Here’s how tracking the usage of this obfuscation technique resulted in discovering several NPM accounts, which were used to publish malicious code designed to steal form data entered by end users of infected web applications.

Discussion

The core capability of ReversingLabs’ secure.software solution is analyzing code intent while highlighting malicious behaviors. These indicators cover all kinds of software behavior, from network and file system activities to use of packers associated with malicious campaigns, and the use of evasion techniques.

Got obfuscation?

One technique we’re increasingly attuned to is the use of javascript obfuscator, a goodware component that is intended (mostly) to protect Javascript applications from the prying eyes of those who seek to steal or reverse engineer the code. Despite the respectable bona fides of javascript obfuscator and its laudable purpose, our past research revealed several instances of malicious packages using this tool to disguise malicious code. At this point, every encounter with such behavior requires a closer look.

The presence of a javascript obfuscator was the indicator that initially got our team looking at a wide range of NPM packages, mostly published in the last two months, all using the mentioned obfuscator. In total, we discovered more than two dozen NPM packages. When we looked at the names of those packages, we noticed some striking similarities. To show you what we mean, check out the following list of suspect packages.

Similarly named packages using javascript obfuscator

Figure 1: Similarly named packages using javascript obfuscator

Can you spot the pattern? A deeper investigation into these NPM modules reveals even more connections. All were connected to one of a handful of NPM accounts with names like ionic-io; arpanrizki; kbrstore; and aselole.

Obfuscated code found stealing form data

To figure out what was going on with these packages, our team started by de-obfuscating the package content using a javascript deobfuscator. We followed that with a detailed examination of the de-obfuscated samples, which revealed that all of them perform collection of form data using jQuery Ajax functions, and then exfiltrate that data to various domains controlled by malicious authors. In other words: This is clear evidence of malicious intent.

Clearly, the typo-squatting technique used to fool developers into confusing the malicious packages with their legitimate counterparts was working. Packages created by the NPM ionic-io author, for example, show that the author published 18 versions of an NPM package named icon-package containing the malicious form stealing code. That was a glaring attempt to mislead developers into using this package instead of ionicons, a popular, open-source icon set with more than 1,000 icons for web, iOS, Android, and desktop apps.

Version data related to icon-package

Figure 2: Version data related to icon-package

NPM download stats show that the malicious icon-package has over 17,000 downloads. Data exfiltrated using this package passes through a domain hxxps://ionicio.com, a play on the legitimate ionicons framework domain ionic.io that would be easy for application developers to overlook. The ruse extends beyond the NPM ecosystem, though. Note the visual similarity between the fake ionic web page seen in Figure 3 and the legitimate ionic page in Figure 4.

Fake ionic webpage


Figure 3: Fake ionic webpage

Legitimate ionic webpage


Figure 4: Legitimate ionic webpage

Under the hood, the malicious packages use a modified script that extends the behavior of the jQuery ajax() function to exfiltrate serialized form data to domains controlled by the attacker. Prior to sending the data, the function validates the URL content to perform target filtering checks.

The trail begins in December 2021

In the process of tracing the origin of the campaign, even older packages containing this type of malicious functionality were discovered. They were published in December 2021 by the author fontsawesome, and also targeted the already mentioned ionicons icon set. The domain used for data exfiltration in these packages is the same as the one used in the first two versions of the icon-package package: hxxps://graph-googleapis.com.

While the exact start of this campaign is unknown, the malicious package published from December 2021 all the way to the middle of May 2022 focused on mimicking the ionicons framework. At that point, the attackers switched to developing new NPM packages that reused the same functionality and also started targeting other popular UI frameworks.

One of those packages is called umbrellaks, which is an obvious attempt at a typosquatting attack on the quite popular umbrellajs javascript DOM (document object model) manipulation framework.

We also observed several packages published by the NPM account arpanrizki engaging in similar form data-grabbing. However, the exfiltration domain associated with these packages is different: hxxps://arpanrizki.my.id. The form identifier for exfiltrated data was quite specific: ValidateVerificationDataForm. So, as part of our investigation, we performed a GitHub search for this identifier, with some interesting results. (See Figure 5.)

GitHub search results

Figure 5: GitHub search results

As the results show, one of the GitHub repositories containing the string in question were maintained by arpantek, a nickname very similar to the one of the NPM author. The other result was related to a HackingTool repository belonging to the NPM author Woxruz.

Woxruz’s HackingTool

Figure 6: Woxruz’s HackingTool

The last commit’s description gives us a clue of the intended use for these software projects. These tools were designed for “Hacking PUBG i’d” [sic]. PUBG is a popular online-multiplayer video game with a large number of users. In other words, it seems the person behind the arpantek and arpanrizki accounts tried to port the login stealing script to the NPM ecosystem to expand the reach.

Names of the packages published by arpanrizki also suggest they are targeting popular Javascript frameworks like ionicons and sidr. In particular, the sidr NPM package hasn’t been maintained for 6 years, but still has more than 500 weekly downloads, which makes it a good target. Packages published by this author have since been removed from NPM and replaced with security placeholders. The sidr package description confirms that in this phase of the campaign, the main target of the actor behind arpanrizki account were PUBG users.

sidr package description and the content of the referenced website

Figure 7: sidr package description and the content of the referenced website

Hungry for data

While the malicious packages we initially observed took a conservative approach to harvesting form data, the more recently published malicious packages are taking a more aggressive approach to acquiring data. Another malicious package we identified, footericon, gathers data from all form elements with a defined “login-form” class.

Form data exfiltration code from footericon package

Figure 8: Form data exfiltration code from footericon package

Similarly, the swiper-bundIe package, a malicious NPM package targeting the popular Javascript framework swiper, uses the embedded jQuery approach, extending its end() function with functionality that gathers data from every form element on the page.

Form data exfiltration code from swiper-bundIe package

Figure 9: Form data exfiltration code from swiper-bundIe package

Clues hidden in code

While we can’t yet identify the actor(s) responsible for these attacks, clues as to the structure of the campaign abound in the deployed packages. For example, the swiper-bundIe package contains a Javascript header in the payload script with cleartext comments that name the author of the package as Alberto Varela, the author of the sidr package targeted by the arpanrizki author. Similarly, the long, commented Javascript one-liner also contains several references to the sidr package.

Comment header at the beginning of the payload from swiper-bundIe package


Figure 10: Comment header at the beginning of the payload from swiper-bundIe package

Finally, the malicious packages use exfiltration domains with a consistent naming pattern: <subdomain>.my.id. Together, these clues suggest a common actor behind the various malicious packages and a unified campaign.

List of malicious NPM modules

Author / Package name Download count
fontsawesome  
ionic-icon 108
ionicio 3,724
ionic-io  
icon-package 17,774
ajax-libs 2,440
umbrellaks 686
ajax-library 530
arpanrizki  
iconion-package 101
package-sidr 91
kbrstore 89
icons-package 380
subek 99
package-show 103
package-icon 122
kbrstore  
icons-packages 170
ionicon-package 64
icons-pack 49
pack-icons 468
ionicons-pack 89
aselole  
package-ionicons 144
package-ionicon 57
base64-javascript 40
ionicons-js 38
ionicons-json 39
footericon  
footericon 1,903
ajax-libz  
roar-01 40
roar-02 37
wkwk100 38
swiper-bundie 39
ajax-libz 40
swiper-bundle 185
atez 43
ajax-googleapis 38
tezdoank 69
ryucha  
ajaxapis 40
tescodek 38
atezzz 114
libz.jquery 160
ajax-libary 36
kabarstre  
icon-ionicon 384
icon-ionicons 65
arpan-package 109
ion-package 254
package-ion 98
ionpackages 67
ionpackagesa 96
ditznesiaa  
basencrypt 73
basecrypt 174
cdnpjs 87
cndpjs 42
pattern.json 44
rakaganz  
rochman 135
footericonfootericon 169
footericons 245
sdomino 96
codashop 78
freefire 64
true_id 66
rakaws  
logo-facebook 183
jubaa  
ajax-libss 48


Table 1: List of malicious packages with corresponding download count


Conclusion

ReversingLabs’ research uncovered an extensive software supply chain attack involving more than two dozen NPM modules used by thousands of downstream applications, as indicated by the package download counts.

Analysis of the modules reveals evidence of coordination, with malicious modules traceable to a small number of NPM publishers, and consistent patterns in supporting infrastructure such as exfiltration domains. ReversingLabs reached out to the NPM security team to report the findings on July 1st, 2022.

This attack marks a significant escalation in software supply chain attacks. Malicious code bundled within the NPM modules is running within an unknown number of mobile and desktop applications and web pages, harvesting untold amounts of user data. The NPM modules our team identified have been collectively downloaded more than 27,000 times. As very few development organizations have the ability to detect malicious code within open source libraries and modules, the attacks persisted for months before coming to our attention. While a few of the named packages have been removed from NPM, most are still available for download at the time of this report.

In publishing this report, we hope it serves as a resource for development organizations to assess their own exposure to these malicious NPM modules. We have prepared a list of affected modules and indicators of compromise that organizations can use to look for evidence of active attacks.

Looking beyond this specific incident, it is clear that software development organizations as well as their customers need new tools and processes for assessing supply chain risks like the ones posed by these malicious NPM packages. The decentralized and modular nature of application development means that applications and services are only as strong as their least secure component. The success of this attack — with more than two dozen malicious modules available for download on a popular package repository, and one of them with 17,000 downloads in a matter of weeks — underscores the freewheeling nature of application development, and the low barriers to malicious or even vulnerable code entering sensitive applications and IT environments.

Indicators of Compromise (IoC)

C2 domains extracted from the analyzed NPM packages:
graph-googleapis.com
ionicio.com
curls.safhosting.xyz
arpanrizki.my.id
dnster.my.id
okep.renznesia.xyz
ryucha.my.id
panelllgege.001www.com
nge.scrp.my.id
apiii-xyz.yogax.my.id
panel.archodex.xyz
panel.curlz.online
api.mlbb-x-02.ml

Package versions:

Package Name Package Version SHA1
ionic-icon 4.7.0 8ab228743d3fef5c89aa55c7d3a714361249eba8
ionicio 5.0.0 f0221e1707075e2976010d279494bb73f0b169c7
icon-package 5.0.0 9299a3eb1f11fcc090c7584bb9ce895ba38fd2cb
icon-package 5.1.0 6092606456adce8eb705ba33ad3e9536682d917f
icon-package 5.2.0 d106693abc732a93176085410c67c4581de28447
icon-package 5.3.0 5a631ab46373251dade6dca5bb460b55bf738a64
icon-package 5.4.0 c173de3d3ee1dd0920ee5a3a4f80d8c280ce2697
icon-package 5.5.0 49f2bc011d1beece62b7a4ed47818e288b71edb6
icon-package 5.9.0 cf8a7066865ab6d009e226096fa879867b8e61bc
icon-package 6.0.0 6e2b0d621bf6031beee18b897b2da5d93d3ce5e7
icon-package 6.0.1 164ff2295b63434e8b260a46041669c98eab4235
icon-package 6.0.2 96aca5e901bd8f1229683339766073e4e5d1de59
icon-package 6.6.6 6253324c1d741c1be3ae20fd8262adb54530ee8b
icon-package 6.6.7 c77eda629d2076663276bc48c7462ea07470dbdc
icon-package 6.6.8 b7dc23a51469574205b0691944f4120e2d92e64d
icon-package 7.7.7 83e5ebd7f355b1655778a37db6b6953042fb77c4
icon-package 7.7.8 123dad7d48c47486e9c226ad50b26b2ba5ec9fe2
icon-package 7.7.9 17fef01df47ceb87b2755f4a18db23d8f7276d30
icon-package 8.0.9 ae70ef4e5a0bb522179e5d488ed56efb9ae5b4d9
icon-package 9.0.0 e66609e433e5b51a148889ff128bd7182fe22d4b
ajax-libs 9.0.1 54549337e60eede3d4dc6b52662c582449b66c40
ajax-libs 9.0.2 fd72a461bb62dce8989f1c24bdcc6ae6d4eaabc5
ajax-libs 9.0.3 66c41baf38e29c4b0a979cff35df4a1eed11e13e
umbrellaks 1.0.0 81031febc2ed49bdd8c8f7ca810830df1b0d3476
ajax-library 1.0.0 326dab8f5d4dab461ca5fd14f136503d12227eae
ajax-library 1.0.1 2afd6730426166f061d96a8ccbfba8d8c7ed9e3e
iconion-package 1.0.0 73db956f7f752c4f71a8a8588604fa7d7af7de7e
package-sidr 2.2.2 87cb0505dbb141391103e2bd358f3aa774210a4a
kbrstore 1.0.0 7e14150502ee992fc8b1259de58261aeb2f58ae1
icons-package 4.4.4 fb672c0b982542eeacce66be67a5bc4ff9567596
icons-package 4.4.5 a386ddf8fb1d0846e01501f6fbac11e0389ef581
icons-package 2.2.2 a5ad7a0edda67b7267694898a82abbee1ec7a466
icons-package 3.0.9 20254c86209118144e6a25fb90abea6f7c903d8e
subek 1.0.0 68d1c1883cfab75fa933ab08189ba7abbd2625a8
package-show 5.5.9 def789dc6322255264703c00d4f4dd265a48b50e
package-icon 6.0.5 1a719f2efa398ef8659a401e6209377beab87105
icons-packages 7.4.0 a2d25c070750cbd20f0c327980a40c26f4ea47ec
ionicon-package 9.0.3 f78a57ab8e288c725e452787f3b070ec690f276b
icons-pack 7.8.3 6388e354433f8c608ab8a97ed9391b9dc44d2a99
pack-icons 2.4.3 cda4b444744196ae9b2753830f750bc5e4548061
package-ionicons 8.0.5 abb8ff44d224b23266769d0808ebe97c3838e484
package-ionicon 8.0.5 c11d9aa077207adeef30cfdd9df3fe979e114b06
footericon 1.0.0 067e42878df480c0d1ca45c268300c96a258be63
footericon 3.7.1 06dbd365e76e7cb593df86a80385e8c46ca05545
footericon 3.7.0 8562edf90e988f7ca556183c2f032bc307dfefdb
footericon 3.7.3 08bc77bb17b6a4ab365d0354683cbd912219becf
footericon 1.7.9 9f5f2f34f15a03c4528d6fa632899d0e3b6d1ceb
roar-01 1.0.0 8c128c3be9645582db2fee9e64e175149d51d92c
roar-02 1.0.0 a1e2cb98d2aa1b134b3be04d6a720393dcf6c072
wkwk100 3.4.5 9f2a2001a07b92adef023ca697e4febba073728e
swiper-bundie 10.5.3 b64a10493897c96feb6eda1d0c9fc7ec85506258
ajax-libz 1.0.0 dd01c6baadd1d79f29b3d69a300e82b860edc57d
swiper-bundle 1.0.0 05d2084e1b2ce1d28c3096f16694413ec480704e
swiper-bundle 3.7.1 1de14d6be4029aa7888f8fc83779b61c96c063da
swiper-bundle 10.52.3 06cb7b1810ca1485e15fa81d92bd92533ff8c001
swiper-bundle 10.22.3 fa234405c958a9ff22bac7debfbcde452294d73c
swiper-bundle 10.21.3 64cd1eda88f92b32323f9784aab6d1a0bdd7a38c
ionicons-pack 1.5.2 fe59a8d59f6764800ce5b85f2bfbc4db05840bae
base64-javascript 3.7.2 77170de7458ee81382efd7de2499694a459abee3
ionicons-js 5.0.2 069f9c723af8be981a3e6220b991b9c40320d8b5
ionicons-json 5.0.2 52a96612e3d2df0a7980de81d622da6c5ff84513
atez 1.0.0 c6569dc3fd94f642cad56cb7a950175ff7c2062f
ajax-googleapis 1.0.0 77a0f0cc89e98b9662b224b653a35895d3ac69fa
tezdoank 1.0.0 eec7e3769b4d8b23aeb00f81583750ed26fadc47
tezdoank 2.0.0 5ba35812337b3c7a0064accf17479a26de486951
ajaxapis 1.0.0. 2a8c46d643d3027b3815eecbbfd183a7dee9e91d
tescodek 6.0.0. 8304b8c9549d08e3c258ce22f99587843bb52c00
atezzz 1.0.0. bc494a3249ce95b7cea5a62e29ee3cc023e2b5b1
atezzz 2.0.0. e2bc4408cea300c0f852e16665e7279cf5d0cd69
atezzz 3.0.0. b5b8d49f302cfeee5cb4dcf134320861c9fdaa66
libz.jquery 1.0.0. 9a41b333143eb0ad75bb93288a988ec8387379ca
libz.jquery 3.6.1. fd7197e446107ba047a2fa43814cdecc794b3dae
libz.jquery 3.6.0. 1517b34ed31cf3f2815105d344dd0b845d48d092
libz.jquery 3.6.3. 4e30e0d1cf39cdaf5f03b7afda81aa2aed6a6d5d
ajax-libary 2.0.3. 50d681e5c016904b0080ad70f40abb86926849a0
icon-ionicon 2.4.3 6132a31838fa836aeadbbe39054de9fa702c8fbb
icon-ionicons 2.4.3 a28477cc116aa0de478014d6f4adb1603cdd6bb1
arpan-package 2.0.5 8dfd7a91308508b859bf464df375030e6231602f
ion-package 2.4.3-Base 5f66bb7a4df11b16238de0c1ad33dddafec779f4
package-ion 2.4.3-icons f7d09b4429f59e136796a70410b689754c355708
basencrypt 2.0.0 9c11c8512ae2f1ed0d4e7ece99e7aa42dd77d4e2
basecrypt 3.1.0 45162797b66a8ea41f530468bca09b5f783383f4
cdnpjs 4.5.0 a3c9595043120c3471c58d6fa43893f34c12b402
cndpjs 4.5.2 2b112481f4adba7b840a397bad7d00acb59ee256
cdnpjs 4.5.8 7e5228665b9396b60c3c7b7024bb948cc45c4a84
pattern.json 4.12.7 879699f620acf2b9c7d24a5fd89e008ac60f4b57
rochman 1.0.0 07280f0b4ec2db03143e1f7add5fd0a04f9b7f3b
rochman 3.6.0 dfbcb2e7e3fc7444415fc5575d8d2a793f9ae668
footericonfootericon 3.7.1 9b8b5fa9e36ed902045ca5de26c00ddd9a035d36
footericons 3.7.1 b38aa72b39fc015c0366e11d072de0947266e884
sdomino 7.9.0 ae603d5a3d8360d076a62d9622679d1a0c79b395
footericons 4.8.0 f0fff262a3dda9b8ca0e0cfedd1808ec0342be75
codashop 5.6.0 6353469679f07b8d6f5870c1e211b17bd575ea89
freefire 7.9.0 a6ef2f3538571db4119d5466b9a3d2a91a984bcc
true_id 8.3.0 e00999f831120a0fc5b37986c0e2d1af947caf0b
ionpackages 2.2.1-Base 925c585c1b1507bf29deb89a4db9fe1f90721140
ionpackagesa 2.4.5-icons 9b1d41d813067d16de7a77512cf205603cb555fa
logo-facebook 4.8.2 ec731509e1478decc6020f9dd57b196853f456c5
ajax-libss 3.6.0 ff862d407422fcca070f726e0aa477c9a93b270b

 

Complete affected package list:
https://blog.reversinglabs.com/hubfs/Blog/IconBurst/package_versions.tsv