红队行动中的Rust武器化。
我在武器化 Rust 用于植入开发及一般攻击性操作方面的实验。
mingw 工具链,不过某些库可能无法在其他操作系统上成功编译。本仓库不提供二进制文件,你需要自行编译。
安装 Rust
下载二进制文件并安装即可。
本仓库在 Windows 10 下编译,建议使用该系统。如前所述,OpenSSL 二进制文件将存在依赖问题,需要安装 OpenSSL 和 perl。
对于 TCP SSL 客户端/服务端,建议使用静态编译,以避免目标主机上的依赖问题。
创建项目,执行:
cargo new <name>
这将自动创建以下结构化项目文件夹:```bash
project
├── Cargo.toml
└── src
└── main.rs
Cargo.toml 是包含依赖项和编译配置的文件。
main.rs 是主文件,将与任何包含库的潜在目录一起编译。
要编译项目,进入项目目录并执行:
`cargo build`
这将使用你的默认工具链。
如果你想构建最终的“发布”版本,执行:
`cargo build --release`
对于静态二进制文件,在构建命令之前在终端中执行:
`"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"`
`set RUSTFLAGS=-C target-feature=+crt-static`
如果你觉得阅读我的代码不方便,你也可以在项目目录下使用以下命令,以更好的方式格式化它:
`cargo fmt`
某些示例可能无法编译并报错,因为它可能需要 Rust 的夜间构建版本及最新特性。要安装它,只需执行:
`rustup default nightly`
查找依赖项或所谓 [Crates](https://crates.io/) 的最简单地方。
## 交叉编译
交叉编译需要遵循 [这里](https://rust-lang.github.io/rustup/cross-compilation.html) 的说明。
通过安装不同的工具链,你可以使用以下命令进行交叉编译:
`cargo build --target <toolchain>`
要查看系统上已安装的工具链,执行:
`rustup toolchain list`
要检查系统中所有可安装的工具链,执行:
`rustup target list`
要安装新的工具链,执行:
`rustup target add <toolchain_name>`
## 优化可执行文件体积
这个 [仓库](https://github.com/johnthagen/min-sized-rust) 包含了许多关于减小文件大小的配置选项和思路。
静态二进制文件通常相当大。
## 我自己陷入过的陷阱
注意 \0 字节,不要在内存中的字符串中忘记它们。我花了很多时间,但 windbg 总是帮助解决。
## 有趣的 Rust 库
- WINAPI
- [WINAPI2](https://github.com/MauriceKayser/rs-winapi2)
- Windows - 这是微软官方提供的,我还没怎么用过
## OPSEC
- 尽管 Rust 有很好的优势,但很难适应它,而且它不是很直观。
- 由于 LLVM,Shellcode 生成是另一个问题。我找到了一些处理方式。
[Donut](https://github.com/TheWover/donut) 有时确实能生成可用的 shellcode,但这取决于项目的实现方式,可能不行。
通常,对于 shellcode 生成,所制作的工具应让所有代码位于 .text 段中,
这就引出了这个很棒的 [仓库](https://github.com/b1tg/rust-windows-shellcode)。
这个项目中有一个 shellcode 示例,可以向你展示如何组织代码以成功生成 shellcode。
此外,这个项目还有一个 shellcode 生成器,它抓取二进制文件的 .text 段,
并在执行一些补丁后转储 shellcode。
该项目从特定位置抓取二进制文件,所以我做了一个分支,可以接收二进制文件路径作为参数,见 [这里](https://github.com/trickster0/rust-windows-shellcode-custom)。
- 即使你删除了所有调试符号,Rust 仍可能在二进制文件中保留对你的主目录的引用。我发现唯一的方法是传递以下标志:`--remap-path-prefix {你的主目录}={某个随机标识符}`。你可以使用 bash 变量获取你的主目录并生成随机占位符:`--remap-path-prefix "$HOME"="$RANDOM"`。(由 [Yamakadi](https://github.com/yamakadi) 提供)
- 虽然对于上述问题,还有另一种方法可以删除关于主目录的信息,即在 Cargo.toml 顶部添加:
`cargo-features = ["strip"]`。
由于 Rust 默认会在二进制文件中留下大量字符串信息,我主要使用这个 [cargo.toml](https://github.com/trickster0/offensiverust/blob/master/cargo.toml) 来避免它们并减少体积,
配合构建命令:
`cargo build --release -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target x86_64-pc-windows-msvc`
- [Yamakadi] 还指出,根据导入的库不同,strip 在隐藏主目录方面并不总是有效,因此结合他的路径重映射方案和上述 cargo.toml 会是最好的做法。尽量注意并在进行实际任务前检查你的二进制文件,看是否有未正确去除的潜在字符串。
## 我用 Rust 编写的其他项目
- [UDPlant](https://github.com/trickster0/UDPlant) - 基本上是一个 UDP 反向 shell
- [EDR Detector](https://github.com/trickster0/EDR_Detector) - 根据安装的 .sys 文件检测系统中的 EDR
- [Lenum](https://github.com/trickster0/Lenum) - 一个简单的 Unix 枚举工具
## 可能有帮助的 Rust 项目
- [houdini](https://github.com/yamakadi/houdini) - 帮助使可执行文件自删除
| 文件 | 描述 |
|---|
| Allocate_With_Syscalls | 直接使用 ntapi 库中的 NTDLL 函数 |
| Create_DLL | 创建 DLL 并弹出一个消息框,Rust 对 DLL 的支持并不完整,由于 Rust DLL 没有 main 函数,可能出现异常情况 |
| DeviceIoControl | 打开驱动句柄并执行 DeviceIoControl |
| EnableDebugPrivileges | 在当前进程中启用 SeDebugPrivilege |
| Shellcode_Local_inject | 通过指针强制转换,直接在本进程中执行 Shellcode |
| Execute_With_CMD | 通过 Rust 传递命令来执行 cmd |
| ImportedFunctionCall | 从 dbghelp 导入 minidump 并执行 |
| Kernel_Driver_Exploit | 针对简单缓冲区溢出的内核驱动漏洞利用 |
| Named_Pipe_Client | 命名管道客户端 |
| Named_Pipe_Server | 命名管道服务端 |
| PEB_Walk | 动态解析和调用 Windows API |
| Process_Injection_CreateThread | 使用 CreateThread 向运行中的进程注入 |
| Process_Injection_CreateRemoteThread | 使用 CreateRemoteThread 向远程进程注入 |
| Process_Injection_Self_EnumSystemGeoID | 使用 EnumSystemsGeoID API 调用来运行 shellcode 的自注入器。 |
| Unhooking | 挂钩解除 |
| asm_syscall | 通过汇编获取 PEB 地址 |
| base64_system_enum | Base64 编解码字符串 |
| http-https-requests | 忽略证书检查的 HTTP/S GET/POST 请求 |
| patch_etw | 修补 ETW |
| ppid_spoof | 伪造创建进程的父进程 |
| tcp_ssl_client | 忽略证书检查的 SSL TCP 客户端(编译需要安装 openssl 和 perl) |
| tcp_ssl_server | TCP 服务端,带端口参数(编译需要安装 openssl 和 perl) |
| wmi_execute | 执行 WMI 查询以获取主机上的 AV/EDR |
| Windows.h+ Bindings | 该文件包含 Windows.h 的结构体,以及完整的自定义 LDR、PEB 等(微软未正式文档化)。在文件顶部添加 include!("../bindings.rs"); |
| UUID_Shellcode_Execution | 将 UUID 数组中的 shellcode 放入堆空间,并使用 EnumSystemLocalesA 回调来执行 shellcode。 |
| AMSI Bypass | 本地进程的 AMSI 绕过 |
| Injection_AES_Loader | NtTestAlert 注入配合 AES 解密 |
| Litcrypt_String_Encryption | 使用 Litcrypt crate 对静态字符串进行加密,在内存和存储中以防止静态 AV 检测。 |
| Api Hooking | 使用 detour 库进行 API 挂钩 |
| memfd_create | 使用 memfd_create 技术从内存执行载荷(适用于 Linux) |
| RC4_Encryption | RC4 解密的 shellcode |
| Steal Token | 从进程中窃取令牌 |
| Keyboard Hooking | 使用 SetWindowsHookEx 挂钩键盘进行键盘记录 |
| memN0ps arsenal: shellcode_runner_classic-rs | 使用 ntapi 的经典 shellcode 运行器/注入器 |
| memN0ps arsenal: dll_injector_classic-rs | 使用 windows-sys 的经典 DLL 注入 |
| memN0ps arsenal: module_stomping-rs | 使用 windows-sys 的模块踩踏 / 模块重载 / DLL 空心化 |
| memN0ps arsenal: obfuscate_shellcode-rs | 简单的 shellcode XOR 和 AES 混淆器 |
| memN0ps arsenal: process_hollowing-rs | 使用 ntapi 的进程空心化 |
| memN0ps arsenal: rdi-rs | 使用 windows-sys 的反射式 DLL 注入 |
| memN0ps: eagle-rs | Rusty Rootkit:面向红队人员的 Rust Windows 内核驱动,使用 winapi 和 ntapi |
| memN0ps: psyscalls-rs | 使用 winapi 的 Rusty 并行系统调用库 |
| memN0ps: mmapper-rs | 使用 winapi 的 Rusty 手动映射器 |
| memN0ps: srdi-rs | 使用 windows-sys 的 Rusty Shellcode 反射式 DLL 注入 |
| memN0ps: mordor-rs - freshycalls_syswhispers | 使用 windows-sys 的 Rusty FreshyCalls / SysWhispers1 / SysWhispers2 / SysWhispers3 库 |
| memN0ps: mordor-rs - hells_halos_tartarus_gate | 使用 windows-sys 的 Rusty Hell's Gate / Halo's Gate / Tartarus' Gate 库 |
| memN0ps: pemadness-rs | 使用 windows-sys 的 Rusty 可移植执行文件解析库(PE 解析库) |
| memN0ps: mimiRust | 由 @ThottySploit 用 Rust 编写的 Mimikatz。原作者已删除其 GitHub 账号,因此上传供社区使用。 |
| memN0ps and trickster0: ekko-rs | Rusty Ekko - 使用 windows-sys 的 Rust 睡眠混淆。 |