GoClipC2:基于Windows剪贴板的隐蔽C2通道实现

本文详细介绍了GoClipC2工具的实现原理,这是一种利用Windows剪贴板作为命令控制通道的创新技术。文章涵盖Base64编码、AES-GCM加密、剪贴板API操作等技术细节,并提供了检测方法和未来改进方向。

GoClipC2:基于Windows剪贴板的隐蔽C2通道实现

背景与动机

一年多前,我在VDI实验环境中发现了一个有趣的现象:虽然剪贴板功能被启用,但无法直接复制粘贴二进制文件或脚本到环境中。然而,可以通过浏览器将内容粘贴为文本。这让我开始思考如何将所需内容转换为文本格式传输到环境中——Base64编码成为了解决方案。

最初的版本只是简单地将内容分段复制,但考虑到人为错误和操作繁琐性,我决定根据剪贴板缓冲区大小自动分块处理。

ChunkyIngress工具解析

ChunkyIngress的工作原理很简单:接收输入文件作为变量,将其分割成指定大小的块,并将这些块复制到剪贴板:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
if ($mode -eq 'encode') {
    $fileBytes = [IO.File]::ReadAllBytes($inputPath)
    $base64String = [Convert]::ToBase64String($fileBytes)
    $chunkSize = 68KB  # 可根据需要修改块大小
    $chunkCount = [math]::Ceiling($base64String.Length / $chunkSize)
    
    Write-Output "准备传输 ${chunkCount} 个数据块"
    Write-Output "将每个块粘贴到环境中后,按回车键复制下一个块"

    for ($i = 0; $i -lt $chunkCount; $i++) {
        $startIndex = $i * $chunkSize
        $chunk = $base64String.Substring($startIndex, [math]::Min($chunkSize, $base64String.Length - $startIndex))
        Set-Clipboard -Value $chunk
        Write-Output "块 $i 已复制到剪贴板。按Enter复制下一个块或Ctrl+C退出。"
        Read-Host
    }

    Write-Output "总共创建了 $chunkCount 个块"
}

在默认代码中,工具会将数据分割成68KB的块,计算所需块数,然后将块复制到剪贴板,以便在另一端使用类似以下代码解码还原文件:

1
2
$BuildMahFile = [Convert]::FromBase64String("")
[IO.File]::WriteAllBytes('ChunkyIngress.7z', $BuildMahFile)

这种方法在有PowerShell可用时非常适合数据渗透/渗出,但同样可以考虑将剪贴板用作命令控制通道。

剪贴板API层级分析

在深入实现细节之前,了解Windows剪贴板的API机制很重要:

打开/关闭操作:

  • OpenClipboard(hwnd) - 打开剪贴板进行读写
  • CloseClipboard() - 关闭剪贴板访问
  • EmptyClipboard() - 清空剪贴板内容

数据操作:

  • SetClipboardData(format, handle) - 将数据放置到剪贴板
  • GetClipboardData(format) - 从剪贴板检索数据
  • IsClipboardFormatAvailable(format) - 检查格式是否存在
  • EnumClipboardFormats(format) - 枚举可用格式

常见格式:

  • CF_TEXT - ANSI文本
  • CF_UNICODETEXT - Unicode文本
  • CF_BITMAP - 位图图像
  • CF_DIB - 设备无关位图

Windows剪贴板历史演变

Windows XP及更早版本

  • 有限格式支持:主要支持基本格式如CF_TEXT、CF_BITMAP、CF_DIB
  • 无剪贴板历史记录

Windows Vista/7

  • 增强格式支持
  • UAC集成:影响剪贴板访问
  • 应用程序隔离:首次引入剪贴板应用程序隔离

Windows 8/8.1

  • 不同应用类型间的复制控制更严格
  • 应用开发者可防止数据从其应用中复制

Windows 10

  • 引入剪贴板历史记录(最多25个项目)
  • 跨设备同步功能
  • 增加元数据记录,便于防御方调查

Windows 11

  • 扩展剪贴板历史记录
  • 改进格式检测
  • 增加剪贴板历史搜索功能
  • 更精细的隐私控制

C2通道探索

基于ChunkyIngress的成功,我开始探索利用剪贴板作为C2通道的其他途径。虽然已有基于PowerShell的Invoke-Clipboard工具,但我希望创建一个更全面的解决方案。

于是诞生了GoClipC2——一个相当全面的概念验证工具,包含客户端和服务器设置。服务器部署在控制器上,客户端二进制文件部署在目标VDI/RDP主机上。

由于使用剪贴板且这些是 technically 本地操作,该设置没有任何出站端口连接,从而提高了操作安全性。唯一的考虑因素是剪贴板上的内存痕迹和磁盘上的客户端二进制文件。

工具构建过程

v0.0.1:核心通信

  • 使用500ms轮询循环监控剪贴板变化作为C2
  • 调整为几秒轮询以减少噪音
  • 添加AES-GCM加密包装所有流量
  • 构建基于JSON的消息结构,包含唯一ID以区分不同客户端
  • 添加心跳功能

v0.0.2:实际C2操作

当前版本支持以下C2操作:

VDI/RDP环境检测 - 使用进程的多向量检测

文件上传/下载 - 具有进度跟踪和错误恢复的分块传输架构

命令队列系统 - 支持同时运行多个命令

后台持久性控制 - 在后台运行进程而非传统持久性

睡眠/唤醒功能 - 模拟合法信标操作,具有可配置休眠时间

进程列表枚举 - 使用隐藏窗口执行tasklist:

1
2
3
4
cmd := exec.Command("tasklist", "/fo", "table", "/v")
cmd.SysProcAttr = &syscall.SysProcAttr{
    HideWindow: true,  
}

心跳定制 - 具有健康监控的自适应心跳系统

工作原理

C2通道通过Windows剪贴板操作,服务器核心发送多种消息类型到客户端二进制文件以执行特定命令或操作:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 消息类型
const (
    MSG_HEARTBEAT     = "HB"
    MSG_COMMAND       = "CMD"
    MSG_RESPONSE      = "RESP"
    MSG_DATA          = "DATA"
    MSG_ERROR         = "ERR"
    MSG_SHELL         = "SHELL"
    MSG_SLEEP         = "SLEEP"
    MSG_WAKE          = "WAKE"
    MSG_SET_HEARTBEAT = "SET_HB"
    MSG_STATUS        = "STATUS"
    MSG_QUEUE         = "QUEUE"
    MSG_QUEUE_STATUS  = "QUEUE_STATUS"
    MSG_DOWNLOAD      = "DOWNLOAD"
    MSG_UPLOAD        = "UPLOAD"
    MSG_FILE_CHUNK    = "FILE_CHUNK"
    MSG_FILE_COMPLETE = "FILE_COMPLETE"
    MSG_FILE_ERROR    = "FILE_ERROR"
    MSG_PERSIST       = "PERSIST"
    MSG_ENV_INFO      = "ENV_INFO"
    MSG_SCREENSHOT    = "SCREENSHOT"
    MSG_KEYLOG        = "KEYLOG"
    MSG_PROC_LIST     = "PROC_LIST"
)

C2消息系统构建围绕处理从基本命令执行到分块文件传输的所有通信模式。核心功能消息类型如MSG_HEARTBEAT维持连接,MSG_COMMAND和MSG_RESPONSE处理端点上的命令执行流。

文件操作使用分块方法,通过MSG_FILE_CHUNK和MSG_FILE_COMPLETE消息确保在剪贴板介质上的可靠传输。

客户端状态管理通过MSG_SLEEP和MSG_WAKE等消息处理操作安全,而MSG_QUEUE支持批处理命令处理。系统还通过MSG_ENV_INFO和MSG_PROC_LIST支持高级侦察。

示例输出

所有消息都以加密的Base64 blob形式发送,前缀为SYUPD,以与合法系统剪贴板活动混合。这种编码确保随意的剪贴板监控或自动化安全工具不太可能检测到C2流量(除非专门搜索),因为消息显示为良性的系统更新数据,而不是结构化的命令控制通信。

示例块:

1
SYSUPD:cwOXba5E9tldKP8xwdLy7LatBk6IMTs26u/i3JUTK3PanCvGivcvw80CJSCh6jkTymGg+qzzRxsB3E+W9Xh7uJFOSDuIk+AVRmOwt5e+NC2T5HRdz48CjeFDs4r+1RIFNXtu0X1+UsZDhxcEXBr/R2piJIai4x9jfixOavp+W/UD6es4bLJgxXbvwh6DNjTHuaEbbCj2jtjBva+Q09UXENTOwa1ftJKBxt3CpQzb

检测机会

Sysmon事件ID用于GoClipC2检测

事件ID 1(进程创建):

  • 检测初始GoClipC2客户端执行
  • 捕获隐藏窗口执行(HideWindow标志)
  • 识别cmd.exe/powershell.exe子进程的快速生成
  • 监控从临时目录执行的进程

事件ID 7(映像/DLL加载):

  • 检测user32.dll加载以访问剪贴板API
  • 识别非GUI进程加载kernel32.dll
  • 捕获可疑可执行文件加载剪贴板相关库

事件ID 10(进程访问):

  • 识别GoClipC2访问其他进程进行侦察
  • 检测环境检测尝试
  • 监控跨进程剪贴板服务交互
  • 捕获潜在的权限提升活动

事件ID 11(文件创建):

  • 监控通过剪贴板分块进行的文件传输
  • 检测操作期间创建的临时文件
  • 跟踪带有"downloaded_“前缀的下载文件

未来计划

我有一个半功能性的COFFLoader端口,可用于进程内执行,可能会作为GoClipC2的附加组件发布。还可能从反取证角度探索更多改进操作安全性的方法,使用更多原生Go函数而非子进程。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计