rust免杀 – shellcode加载与混淆 | 宜武汇-ag真人国际厅网站

这是半年前我学习rust和免杀时的一些记录,最近打开知识库看到了这篇半年前的笔记,并且发现我常逛的安全社区都比较少有人分享rust以及rust免杀的帖子,于是想着将这篇笔记分享出来供大家参考和指正。由于我写这篇文章时也刚刚开始接触rust,所以文中所涉及的知识和代码都有可能出现错误,所以再次说明这篇文章仅供参考并希望大家指正。

shellcode加载方式

跟其他语言的shellcode加载器一样,要实现更多的shellcode加载方式,需要调用winapi。
执行shellcode的一般流程:

rust调用winapi需要先引入依赖,cargo是rust的一个包管理工具,要引入winapi依赖需要在cargo.toml添加:

winapi = {version="0.3.9",features=["winuser","processthreadsapi","memoryapi","errhandlingapi","synchapi"]}

这里以加载msf生成的弹计算器的shellcode为例,先使用msfvenom生成一段raw格式的shellcode,保存到calc.bin文件中,并复制到rust的项目目录下。

link_section是rust的一个,它用来将特定的函数或者变量放到程序的指定的区块中,.text区块通常用来存储程序的执行代码,它会被加载到内存中并由处理器执行。
然后通过std::mem::transmute*const u8 类型的指针转换为函数类型 fn(),最后执行shellcode。

该方式同样需要先引入依赖,在cargo.toml文件中添加如下依赖:

[dependencies] winapi = {version="0.3.9",features=["winuser","heapapi","errhandlingapi"]}

该方法通过heapcreate创建heap_create_enable_execute权限的内存堆,然后通过heapalloc来从堆中分配内存空间,最后通过函数指针的方式执行shellcode。

shellcode混淆方式

上面介绍了在rust中为shellcode申请内存空间和执行shellcode的几种常见的方式,接下来会介绍几种常见的编码和加密混淆方式在rust中的实现。在实际的shellcode免杀的时候经常需要结合几种混淆方式,或者是自己设计加密混淆方式。

在rust中实现base64编码同样需要引入依赖,在cargo.toml文件中添加如下依赖:

[dependencies] base64 = "0.20.0"

通过下面的代码即可将传入的切片类型的shellcode进行base64编码并返回一段字符串。

通过以下代码即可将得到的字符串解码,并返回vec数组类型的shellcode。

在rust中实现hex编码同样需要引入依赖,在cargo.toml文件中添加如下依赖:

[dependencies] hex = "0.4.3"

通过下面的代码即可将传入的切片类型的shellcode进行hex编码并返回一段字符串。

通过以下代码即可将得到的字符串解码,并返回vec数组类型的shellcode。

通过迭代器将shellcode与key逐个字符进行异或,然后进行base64编码返回一段字符串。

要进行解密,需要先进行base64解码,然后将异或加密后的shellcode再次与key进行逐个字符进行异或,即可还原shellcode。

rust要实现rc4加密与加密需要引入依赖,在cargo.toml文件中添加下面的依赖。

[dependencies] rust-crypto="0.2.36" base64="0.13.0" rustc-serialize = "0.3"

下面是实现rc4加解密的代码,在加密的函数中最终返回的是base64编码后的字符串,而解密函数最终返回的是vec数组,这是为了方便在shellcode loader中读取加密后的shellcode以及加载解密后的shellcode。

rust要实现aes加密与加密也需要引入依赖,在cargo.toml文件中添加下面的依赖。

[dependencies] aes="0.7.5" hex="0.4.3" block-modes="0.8.1" hex-literal="0.3.3"

下面是实现aes-cfb加解密的代码,在加密的函数中最终返回的是hex编码后的字符串,而解密函数最终返回的是vec数组,同样是为了方便在shellcode loader中读取加密后的shellcode以及加载解密后的shellcode。

同样先在cargo.toml文件中添加下面的依赖。

[dependencies] hex = "0.4.3"

下面是结合异或加密和添加随机字符的代码,xor_encrypt将对shellcode与key进行异或,使用hex::encode将异或结果转为十六进制字符串返回,方便后面添加随机字符。add_random迭代xor_encrypt返回的字符串的每个字符,并在每次迭代时添加一个随机字符。最后,使用 hex::encode 将结果转为十六进制字符串返回。xor_decryptrm_random是对应的二次异或和删除随机字符的函数。

rust的编译体积是非常小的,虽然比不上c/c ,但是和python和go相比优势还是非常大的,并且rust的热门程度也远小于python和go,所以杀软对rust的检出程度也是非常低的,这都是rust免杀的天然优势。结合本文章几种基础的加载方式和混淆方式还是可以轻松过一部分杀软的。以下链接是我半年前上传到virustotal的一个样本,半年过去了,目前的检出率为14/71:(刚上传时检出率为0/71)。
这篇文章的代码部分我也已经提交到github供大家参考:

原文链接:https://xz.aliyun.com/t/12618

网络摘文,本文作者:15h,如若转载,请注明出处:https://www.15cov.cn/2023/08/27/rust免杀-shellcode加载与混淆/

发表评论

邮箱地址不会被公开。 必填项已用*标注

网站地图