将一个加密的对象解密到char []的char []



我试图使用加密 来加密和解密unsigned char对象。迄今为止,加密很好。但是,我需要在字节数组或字符阵列中保存最终解密的内容,以便我可以正确地将其交给Memcpy。

我正在使用Visual Studio 19,其中包括Crypto 的最新版本。

HexEncoder encoder(new FileSink(cout));
ByteQueue plain, cipher, recover;
unsigned char shellcode[] = "xfcxe8x89x00x00x00x60";
unsigned char enc_shellcode[] ="x6Dx30xEBx18xF2x01x16";
plain.Put(reinterpret_cast<const byte*>(shellcode), sizeof(shellcode));
//Encryption:
CBC_Mode<AES>::Encryption enc;
enc.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
StreamTransformationFilter f1(enc, new Redirector(cipher));
plain.CopyTo(f1);
f1.MessageEnd();
cout << "Cipher text: ";
cipher.CopyTo(encoder);
encoder.MessageEnd();
cout << endl;
// Decryption
CBC_Mode<AES>::Decryption dec;
dec.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
StreamTransformationFilter f2(dec, new Redirector(recover));
cipher.CopyTo(f2);
f2.MessageEnd();
recover.CopyAllTo(encoder);
encoder.MessageEnd();
cout << endl;
// Allocating memory with EXECUTE writes
void* exec = VirtualAlloc(0, sizeof test, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// Copying deciphered shellcode into memory as a function
memcpy(exec, /*Decrypted Shellcode..*/, sizeof test);

我永远无法以十六进制形式将数据回到其原始的unsigned char,以便我可以将数据加载到内存中...我不是很精通C ,我敢肯定,这对你们中的某些人来说是相当的对象还是一个简单的修复...?

我永远无法以十六进制形式将数据回到其原始的未符号字符中,以便我可以将数据加载到内存中...

ByteQueueMessageQueue是高级加密 管道对象。当数据从源流向水槽时,它们是一个很好的选择。但是当您不使用水槽时,它们可能会有些尴尬,例如使用memcpy

以下是做您想做的事的两个示例。

还要注意这不是很正确。由于CBC模式和PKCS填充,密文的大小必须是块的倍数。在您的情况下,加密的外壳应为16个字节。

const byte enc_shellcode[] ="x6Dx30xEBx18xF2x01x16";

管道

@zett42有正确的想法 - 使用ArraySink,加密 管道将为您完成memcpy。实际上,您甚至不需要plainrecover。因此,它看起来像下面。(我在Linux上工作,所以我需要伪造VirtualAlloc(。

$ cat test.cxx
#include "cryptlib.h"
#include "filters.h"
#include "modes.h"
#include "files.h"
#include "aes.h"
#include "hex.h"
#include <iostream>
int main(int argc, char* argv[])
{
    using namespace CryptoPP;
    HexEncoder encoder(new FileSink(std::cout));
    ByteQueue cipher;
    const byte shellcode[] = "xfcxe8x89x00x00x00x60";       
    const byte key[16] = {1,2,3,4, 1,2,3,4, 1,2,3,4, 1,2,3,4};
    const byte  iv[16] = {8,7,6,5, 8,7,6,5, 8,7,6,5, 8,7,6,5};
    //Encryption
    CBC_Mode<AES>::Encryption enc;
    enc.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
    ArraySource plain(shellcode, 7, true);
    StreamTransformationFilter f1(enc, new Redirector(cipher));
    plain.CopyTo(f1);
    f1.MessageEnd();
    std::cout << "Cipher text: ";
    cipher.CopyTo(encoder);
    encoder.MessageEnd();
    std::cout << std::endl;
    // Allocating memory with EXECUTE writes
    // void* exec = VirtualAlloc(0, sizeof test, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    // Proxy for VirtualAlloc
    byte x[7];
    void* exec = reinterpret_cast<void*>(x);
    // Decryption
    CBC_Mode<AES>::Decryption dec;
    dec.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
    ArraySink recover(reinterpret_cast<byte*>(exec), 7);
    StreamTransformationFilter f2(dec, new Redirector(recover));
    cipher.CopyTo(f2);
    f2.MessageEnd();
    // Can't use recover.CopyTo() here. ArraySink is not a source;
    // and the internal pointer is at the end of the array, not
    // the beginning of the array.
    std::cout << "Recover text: ";
    encoder.Put(reinterpret_cast<byte*>(exec), 7);
    encoder.MessageEnd();
    std::cout << std::endl;
    return 0;
}

运行代码会产生下面的输出。

$ g++ test.cxx ./libcryptopp.a -o test.exe
$ ./test.exe
Cipher text: 88BFA35C6ABF2EDF1FDCDC354721C72C
Recover text: FCE88900000060

C 对象

您也可以使用C 对象,而不是加密 ByteQueue。这更容易使用。

$ cat test.cxx
#include "cryptlib.h"
#include "filters.h"
#include "osrng.h"
#include "modes.h"
#include "files.h"
#include "aes.h"
#include "hex.h"
#include <string>
#include <iostream>
int main(int argc, char* argv[])
{
    using namespace CryptoPP;
    HexEncoder encoder(new FileSink(std::cout));
    // The embedded NULLs mean we need to use this ctor
    const std::string shellcode("xfcxe8x89x00x00x00x60", 7);
    std::string cipher;
    const byte key[16] = {1,2,3,4, 1,2,3,4, 1,2,3,4, 1,2,3,4};
    const byte  iv[16] = {8,7,6,5, 8,7,6,5, 8,7,6,5, 8,7,6,5};
    //Encryption
    CBC_Mode<AES>::Encryption enc;
    enc.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
    StreamTransformationFilter f1(enc, new StringSink(cipher));
    StringSource(shellcode, true, new Redirector(f1));
    std::cout << "Cipher text: ";
    StringSource(cipher, true, new Redirector(encoder));
    std::cout << std::endl;
    // Allocating memory with EXECUTE writes
    // void* exec = VirtualAlloc(0, sizeof test, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    // Proxy for VirtualAlloc
    byte x[7];
    void* exec = reinterpret_cast<void*>(x);
    // Decryption
    CBC_Mode<AES>::Decryption dec;
    dec.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
    ArraySink recover(reinterpret_cast<byte*>(exec), 7);
    StreamTransformationFilter f2(dec, new Redirector(recover));
    StringSource(cipher, true, new Redirector(f2));
    // Can't use recover.CopyTo() here. ArraySink is not a source;
    // and the internal pointer is at the end of the array, not
    // the beginning of the array.
    std::cout << "Recover text: ";
    encoder.Put(reinterpret_cast<byte*>(exec), 7);
    encoder.MessageEnd();
    std::cout << std::endl;
    return 0;
}

以及使用std::string的相同结果:

$ g++ test.cxx ./libcryptopp.a -o test.exe
$ ./test.exe
Cipher text: 88BFA35C6ABF2EDF1FDCDC354721C72C
Recover text: FCE8899B7F0000

最新更新