免杀思路

编写进度

杀毒软件常见检测方法:

通常分为静态特征查杀和动态行为检测(包括沙箱)

  • 静态特征查杀,基于匹配特征码,与病毒库里面的md5进行比较。

     做法:模糊哈希算法,机器学习跑模型 , 

    绕过:利用myccl工具查找定位复合特征码 或手工(单步查杀找到特征码)对特征码进行混淆处理

  • 动态行为检测 ,沙箱执行可以程序

     做法:hook关键api,监控注册表启动项,系统文件,防止对其修改   
     绕过: 沙箱检测(检测线程数),文件重命名检测 延时(类似cobaltstrike的睡眠机制,用钩子在睡眠时间内存权限设置读写,在非睡眠时改回可执行。)

熟悉各个杀软的查杀特性

  • 火绒: 重点基于字符串去查杀,
    做法:重点针对函数如regMovememory进行字符串混淆或更换函数

  • 360: 重点基于函数具体触发的行为去查杀 
    做法: 延时,沙箱检测,文件重命名检测

  • WinDefender: 重点基于特定位置,特征码去查杀   
    做法:找特征码去混淆

针对各个杀软的特点进行自定义加载器

免杀处理思路:

  1. 源码免杀,(有源码时) 定位特征码,进行混淆
    a)如内嵌汇编加载、内存免杀(渐进式申请一块内存,最后改为可执行)、分离免杀、二次编译、
    b)隐藏IAT、强制类型转换、加花指令、多层跳转、加无效指令、替换/重写API、API伪调用等
    c)shellcode进行异或 编码base64,AES加密等

  2. 无源码免杀,在源码不好修改时,
    a)resourceHacker资源修改、
    b)vmp加壳、加签名、PE优化等组合使用

  3. 白名单exe/dll免杀-如rundll32、msbuild、mshta、cscript等

  4. Powershell混淆绕过  – 根据powershell语言特性,字符串转换,变量转换,编码,压缩等

  5. 偏僻语言编写shellcode

  6. 加载器分离免杀

简述远程加载器分离免杀的思路比较好,实现代码逻辑

  规避网络测绘->shellcode混淆->beacon去特征
大体思路:
Winhttp库或window sockets实现http请求(cs使用winInet库) –> 存在问题:容易暴露自己C2和文件服务器地址(域前置解决)
对shellcode进行AES动态加密

  • 服务器
    用netty框架,采用select多客户端模型 写一个web服务器,获取请求发过来的key值,用key对shellcode进行加密,响应给客户端
  • 客户端(C++加载器)
  1. 每次请求shellcode时随机生成一个key值,通过http请求将key发送到服务器
  2. 服务器使用key对shellcode进行AES加密或shellcode每一位与key进行异或操作,响应给客户端
  3. 用cryptopp库进行AES解密shellcode,virtualAlloc采用渐进式申请内存空间,使用memcpy拷贝shellcode到内存中,最后调用这个内存地址

甚至可以将loader是否也可以尝试一下,客户端仅保留下载loader和shellcode的功能

shellcode生成工具-donut,对Execute-Assembly进一步利用,将exe,dll,vbs,js转成shellcode
shellcode混淆器-Obfuscator
修改加载器特征
加载器特征= A「shellcode+硬编码字符串」 + B 「virtualAlloc,virtualProtect函数」

修改方法:
          对A进行 base64编码+加密(如xor)(更安全),   
         对B插入花指令(无意义代码), 可以使用HeapAlloc替换virtualAlloc函数
修改加载器的特征

func_get_delegate_typefunc_get_proc_address两个函数重命名替换,对函数里面的一些变量进行重新定义

分离免杀

shellcode加载器=S_0「shellcode_downloader」+ S_1「donwlod+run_shellcode」
通常杀软只检测一个进程的行为,
做法: 使用windows管道,socket通道
分离免杀,将shellcode写入到文件中和加载器分离开,在加载器启动执行时再将shellcode从文件当中读取进来。

修改资源

杀软会检测文件的描述,版本号,创建日期作为特征检测
做法: 使用restorator对目标修改资源文件

隐藏IAT

杀软检测导入表中是否存在可疑函数
做法: opt1 调用getProcessAddress获取所需函数地址
opt2  用汇编从Teb里找到kernel32.dll地址,再从其导出表中获取所需系统函数

msf与cs的stager对比分析

相同点: 通过WinInet系列函数远程加载stage并使用VirtualAlloc为其分配一块rwx的内存空间,最后转去执行stage
不同点: cs比msf多调用几个函数 InternetErrorDlg, GetDesktopWindow, GetLastError

payload加载方式基本一致(cs参考msf,都支持stager和stageless方式加载)

meterpreter加载顺序:stager->metsrv.dll->stdapi.dll
cs-beacon加载顺序: stgaer->beacon.dll

C2实现方式:

   meterpreter的handler实现:TCPServer结合resources实现的简易HTTP服务
   Beacon的Listener实现:基于NanoHTTPD实现(成熟稳定)

通信协议上差异:

cs和msf均使用http/s进行数据通信,但具体传输方式上有差异
    meterpreter使用HTTP 1.1 ,默认使用keep-alive功能,且不能关闭 (不稳定)
    Beacon使用HTTP 1.1 ,但默认不开启keep-alive功能 且支持抖动特性

具体的表现为在实际使用过程中,Meterpreter与C2服务器始终保持一条TCP连接,且对TCP连接的状态没有监控. 相对应的Beacon在请求任务/返回结果时会与C2建立连接,而在sleep阶段与C2没有网络连接.


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 askding@qq.com

💰

×

Help us with donation