基于剪贴板的隐蔽C2通道:GoClipC2技术解析

本文详细介绍了GoClipC2工具,这是一种利用Windows剪贴板作为隐蔽命令控制通道的创新技术,适用于VDI/RDP环境,通过加密Base64消息绕过网络监控,包含完整的技术架构和实现细节。

Clippy Goes Rogue (GoClipC2)

概述

GoClipC2:一种基于Windows剪贴板的隐蔽C2通道,专为VDI/RDP环境设计。通过加密的Base64消息传递绕过网络监控。

ChunkyIngress解构

一年前在基于VDI的实验室环境中,我发现剪贴板功能已启用,但无法直接复制粘贴二进制文件或脚本到环境中。然而,可以通过浏览器将内容粘贴为文本。这引发了我的思考:如何将所需内容转换为文本形式传入环境?Base64编码成为解决方案。

初始版本只是简单地将内容传输过去,但考虑到人为错误和可能的问题,我决定根据剪贴板缓冲区大小将其自动分块处理。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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)

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

  • Metro应用引入剪贴板相关变更
  • 不同应用类型间的复制控制更严格

Windows 10

  • 剪贴板历史:最多保留25个最近项目
  • 跨设备同步功能
  • 时间线集成:记录剪贴板活动时间线

Windows 11

  • 扩展剪贴板历史
  • 更好的格式检测
  • 剪贴板历史搜索功能
  • 更精细的隐私控制

C2探索

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

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

工具构建

项目从基本的剪贴板命令执行概念验证开始,逐步发展为功能完整的工具:

v0.0.1:核心通信

  • 使用500毫秒轮询循环监控剪贴板变化
  • 添加AES-GCM加密包装
  • 构建基于JSON的消息结构
  • 实现心跳功能

v0.0.2:实际C2操作

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

  • VDI/RDP环境检测 - 多向量进程检测
  • 文件上传/下载 - 分块传输架构
  • 命令队列系统 - 批量命令执行
  • 后台持久性控制 - 进程后台运行
  • 睡眠/唤醒功能 - 模拟合法信标操作
  • 进程列表枚举 - 隐藏窗口执行
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"
)

所有消息都以加密的Base64数据块形式发送,前缀为"SYUPD",以混入合法的系统剪贴板活动。

检测机会

Sysmon事件ID检测

  • 事件ID 1(进程创建):检测初始GoClipC2客户端执行
  • 事件ID 7(镜像/DLL加载):检测user32.dll加载用于剪贴板API访问
  • 事件ID 10(进程访问):识别GoClipC2访问其他进程进行侦察
  • 事件ID 11(文件创建):监控通过剪贴板分块的文件传输

未来计划

  • 发布半功能性的COFFLoader端口用于进程内执行
  • 从反取证角度改进操作安全性
  • 更多使用原生Go函数而非子进程
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计