go-shellcode 是一个 Windows Shellcode 运行器及支持工具的仓库。这些应用程序使用各种 API 调用或技术来加载和执行 Shellcode。
可用的 Shellcode 运行器包括:
此应用程序利用 Windows 的 CreateFiber 函数(来自 Kernel32.dll)在该应用程序的进程内执行 shellcode。当您希望避免远程进程注入并避免调用 CreateThread 时,这很有用。此应用程序不使用 golang.org/x/sys/windows 包中的函数。最显著的区别是,此应用程序自行加载所有必要的 DLL 和过程,并使用过程的 Call() 函数。
注意: 我尚未找到让进程退出的方法,您必须手动终止它。
可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o CreateFiber.exe .\cmd\CreateFiber\main.go
此应用程序利用 Windows 的 CreateProcess 函数(来自 Kernel32.dll)。进程以挂起状态创建,更新 IMAGE_OPTIONAL_HEADER 结构中的 AddressOfEntryPoint 以在子进程中执行 shellcode,然后恢复进程。这是一种进程镂空技术,但现有的 PE 没有被取消映射,且 ThreadContext 没有被更新。提供的 shellcode 架构(即 x86 或 x64)必须与子进程的架构匹配。
可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o CreateProcess.exe .\cmd\CreateProcess\main.go
此应用程序利用 Windows 的 CreateProcess 函数(来自 Kernel32.dll)。进程以挂起状态创建,更新 IMAGE_OPTIONAL_HEADER 结构中的 AddressOfEntryPoint 以在子进程中执行 shellcode,然后恢复进程。这是一种进程镂空技术,但现有的 PE 没有被取消映射,且 ThreadContext 没有被更新。提供的 shellcode 架构(即 x86 或 x64)必须与子进程的架构匹配。
此应用程序与 CreateProcess 的不同之处在于,它会收集子进程中写入 STDOUT 或 STDERR 的任何数据,并将其返回给父进程。通过使用 CreatePipe 函数创建匿名管道,父进程和子进程通过该管道进行通信来收集数据。当使用像 Donut 这样的工具在子进程中以 shellcode 形式执行 .NET 程序集并检索执行程序的输出时,这很有用。以下命令可用于生成位置无关的 shellcode,以使用 Donut v0.9.3 运行 Seatbelt:
.\donut.exe -o donut_v0.9.3_Seatbelt.bin -x 2 -c Seatbelt.Program -m Main -p "ARPTable" Seatbelt.exe
可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o CreateProcessWithPipe.exe .\cmd\CreateProcessWithPipe\main.go
此应用程序利用 Windows 的 CreateRemoteThread 函数(来自 Kernel32.dll)在远程进程中执行 shellcode。该应用程序要求目标注入进程必须已运行。可以使用 -pid 命令行参数在运行时提供目标进程 ID (PID) 以进行测试。在实际使用中,通过将以下代码行中的 0 替换为目标 PID 来硬编码 PID:
pid := flag.Int("pid", 0, "要注入 shellcode 的进程 ID")
此应用程序在可行的情况下使用 golang.org/x/sys/windows 包中的函数,例如 windows.OpenProcess()。可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o CreateRemoteThread.exe .\cmd\CreateRemoteThread\main.go
此应用程序利用 Windows 的 CreateRemoteThread 函数(来自 Kernel32.dll)在远程进程中执行 shellcode。该应用程序要求目标注入进程必须已运行。可以使用 -pid 命令行参数在运行时提供目标进程 ID (PID) 以进行测试。在实际使用中,通过将以下代码行中的 0 替换为目标 PID 来硬编码 PID:
pid := flag.Int("pid", 0, "要注入 shellcode 的进程 ID")
此应用程序不使用 golang.org/x/sys/windows 包中的函数。最显著的区别是,此应用程序自行加载所有必要的 DLL 和过程,并使用过程的 Call() 函数。可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o CreateRemoteThreadNative.exe .\cmd\CreateRemoteThreadNative\main.go
此应用程序利用 Windows 的 CreateThread 函数(来自 Kernel32.dll)在该应用程序的进程内执行 shellcode。当您希望避免远程进程注入时,这很有用。此应用程序在可行的情况下使用 golang.org/x/sys/windows 包中的函数,例如 windows.VirtualAlloc()。可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o CreateThread.exe .\cmd\CreateThread\main.go
此应用程序利用 Windows 的 CreateThread 函数(来自 Kernel32.dll)在该应用程序的进程内执行 shellcode。当您希望避免远程进程注入时,这很有用。此应用程序不使用 golang.org/x/sys/windows 包中的函数。最显著的区别是,此应用程序自行加载所有必要的 DLL 和过程,并使用过程的 Call() 函数。可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o CreateThreadNative.exe .\cmd\CreateThreadNative\main.go
该应用程序利用 Windows 的 CreateProcess 函数以挂起状态创建一个进程。子进程挂起后,使用 Windows 的 QueueUserAPC 函数向子进程添加一个指向已分配 shellcode 的用户 APC。接下来,调用 ResumeThread,它会依次调用未文档化的 NtTestAlert 函数,该函数将执行创建的 UserAPC 并进而执行 shellcode。这很有用,因为 shellcode 将在 AV/EDR 能够挂钩函数以支持检测之前执行。参考 发现新的 'Early Bird' 代码注入技术。可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
export GOOS=windows GOARCH=amd64;go build -o goEarlyBird.exe cmd\EarlyBird\main.go
此应用程序利用 Windows 的 EtwpCreateEtwThread 函数(来自 ntdll.dll)在该应用程序的进程内执行 shellcode。原始工作由 TheWover 完成。当您希望避免远程进程注入时,这很有用。此应用程序不使用 golang.org/x/sys/windows 包中的函数。最显著的区别是,此应用程序自行加载所有必要的 DLL 和过程,并使用过程的 Call() 函数。可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o EtwpCreateEtwThread.exe .\cmd\EtwpCreateEtwThread\main.go
此应用程序使用未文档化的 NtQueueApcThreadEx 在当前进程的当前线程中创建一个“特殊用户 APC”以执行 shellcode。由于 shellcode 在当前进程中加载并执行,因此是“本地”的。同样的技术也可以用于远程进程。注意: 这仅在 Windows 7 或更高版本上有效。参考 APC 系列:用户 APC API。
export GOOS=windows GOARCH=amd64;go build -o goNtQueueApcThreadEx-Local.exe cmd\NtQueueApcThreadEx-Local\main.go
此应用程序利用 Windows 的 RtlCreateUserThread 函数(来自 ntdll.dll)在远程进程中执行 shellcode。该应用程序要求目标注入进程必须已运行。可以使用 -pid 命令行参数在运行时提供目标进程 ID (PID) 以进行测试。在实际使用中,通过将以下代码行中的 0 替换为目标 PID 来硬编码 PID:
pid := flag.Int("pid", 0, "要注入 shellcode 的进程 ID")
此应用程序不使用 golang.org/x/sys/windows 包中的函数。最显著的区别是,此应用程序自行加载所有必要的 DLL 和过程,并使用过程的 Call() 函数。可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o RtlCreateUserThread.exe .\cmd\RtlCreateUserThread\main.go
此应用程序通过直接对 Shellcode 的入口点进行系统调用来在当前运行进程中执行 Shellcode。此应用程序不使用 golang.org/x/sys/windows 包中的函数。可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o Syscall.exe .\cmd\Syscall\main.go
此应用程序利用 Windows 的 UuidFromStringA 函数将 shellcode 加载到内存地址,然后调用 EnumSystemLocalesA 函数来执行 shellcode。这种加载和执行 shellcode 的方法源自 nccgroup 的 RIFT:分析 Lazarus Shellcode 执行方法。对于此应用程序,内存在堆上分配,不涉及 VirtualAlloc。可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o UuidFromString.exe .\cmd\UuidFromString\main.go
此应用程序用于转换 shellcode 二进制文件。该程序要求输入文件是一个包含 shellcode 十六进制字节的二进制文件(.bin)。ShellcodeUtils 可以对输入文件进行 base64 编码,也可以使用 XOR、RC4 或 AES256-GCM 加密。该工具还可用于解密文件。
ShellcodeUtils 帮助菜单:
-base64
对输出进行 Base64 编码。可以与加密一起使用或单独使用
-i string
输入二进制文件的路径
-key string
加密密钥
-mode string
对输入文件执行的操作模式 [encrypt,decrypt] (默认 "encrypt")
-nonce string
用于解密 AES256 输入文件的 nonce(十六进制)。仅在解密时使用
-o string
输出文件路径
-salt string
用于通过 Argon2 生成 AES256 32 字节密钥的 salt(十六进制)。仅在解密时使用
-type string
要使用的加密类型 [xor, aes256, rc4, null]
-v
启用详细输出
仅对输入文件进行 Base64 编码并保存为文本文件的示例:
PS C:\Users\bob> .\ShellcodeUtils.exe -i C:\Users\bob\calc.bin -o C:\Users\bob\calc.b64.txt -base64 -v
[-]输出目录: C:\Users\bob\
[-]输出文件名: calc.b64.txt
[-]文件内容(十六进制): 505152535657556a605a6863616c6354594883ec2865488b32488b7618488b761048ad488b30488b7e3003573c8b5c17288b741f204801fe8b541f240fb72c178d5202ad813c0757696e4575ef8b741f1c4801fe8b34ae4801f799ffd74883c4305d5f5e5b5a5958c3
[-]未提供加密类型,继续执行...
[+]输出(字符串):
UFFSU1ZXVWpgWmhjYWxjVFlIg+woZUiLMkiLdhhIi3YQSK1IizBIi34wA1c8i1wXKIt0HyBIAf6LVB8kD7csF41SAq2BPAdXaW5Fde+LdB8cSAH+izSuSAH3mf/XSIPEMF1fXltaWVjD
[+] 加密输入并将 140 字节写入: C:\Users\bob\calc.b64.txt
使用密钥 Sh3!1z 对输入文件进行 XOR 加密并对输出进行 base64 编码的示例:
PS C:\Users\bob> .\ShellcodeUtils.exe -i C:\Users\bob\calc.bin -o C:\Users\bob\calc.xor.b64.txt -mode encrypt -type xor -key Sh3!1z -v
[-]输出目录: C:\Users\bob\
[-]输出文件名: calc.xor.b64.txt
[-]文件内容(十六进制): 505152535657556a605a6863616c6354594883ec2865488b32488b7618488b761048ad488b30488b7e3003573c8b5c17288b741f204801fe8b541f240fb72c178d5202ad813c0757696e4575ef8b741f1c4801fe8b34ae4801f799ffd74883c4305d5f5e5b5a5958c3
[-]使用密钥对输入文件进行 XOR 加密: Sh3!1z
[+]输出(十六进制):
03396172672d0602537b5919320450756832d0841b4479f16120b8572932d81e23699c32d8587baa4f4a503f0faa6d6d7be3473e11325296b8752e5e5cdf1f36bc2851c5b21d362d3a067654def127772f693084d85c9d69308dca97e469b2be63356c7f6a200a30f0
[+]xor 加密输入并将 105 字节写入: C:\Users\bob\calc.xor.b64.txt
使用密码 Sh3!1z 对输入文件进行 AES256-GCM 加密而不进行 base64 编码的示例:
PS C:\Users\bob> .\ShellcodeUtils.exe -i C:\Users\bob\calc.bin -o C:\Users\bob\calc.aes.bin -mode encrypt -type aes256 -key Sh3!1z -v
[-]输出目录: C:\Users\bob\
[-]输出文件名: calc.aes.bin
[-]文件内容(十六进制): 505152535657556a605a6863616c6354594883ec2865488b32488b7618488b761048ad488b30488b7e3003573c8b5c17288b741f204801fe8b541f240fb72c178d5202ad813c0757696e4575ef8b741f1c4801fe8b34ae4801f799ffd74883c4305d5f5e5b5a5958c3
[-]AES256 加密输入文件
[+]Argon2 salt(十六进制): db6126d3ac640f8aaa67cda74b8cf1d2c54513db7bf4fbe3422d1b276af1367e
[+]AES256 密钥(32 字节)从输入密码 Sh3!1z 派生(十六进制): 096a40f1aef38dd9b5d63284acc19727c4420dd98f21ea052112bef63eb7d94a
[+]AES256 nonce(十六进制): 13802153c4b2fb6a3e545ff4
[+]输出(十六进制):
44a974233e37b460dc2181b16846f265e8e3a07959abf9c8760f7d0ac8029575e67571ea5b313bc8b011739db57c690ec156a4b0bba4e4d632c35c1490aeaac24f5ae05e90934adf57798ee3c702a3c27073fe976fbcc6ee5db355da186c1add58913e41a8c5716a0fcfc27371f0cae906e50e680366496a00
[+]aes256 加密输入并将 121 字节写入: C:\Users\bob\calc.aes.bin
AES256 需要 32 字节的密钥。此程序使用 Argon2 ID 算法,从通过 -key 输入参数提供的密码派生出一个 32 字节密钥,同时使用随机生成的 salt。要成功解密文件,您需要相同的输入密码、在 Argon2 算法中使用的 salt,以及 AES256 算法中使用的同一个 nonce。或者,解密函数_可以_更新为直接使用 32 字节的 Argon2 密钥,而不是输入密码和 salt。
注意: 由操作者决定是仅使用生成的 Argon2 密钥,还是使用用于生成该密钥的密码和 salt。
解密输入文件的 AES256 示例:
PS C:\Users\bob> .\ShellcodeUtils.exe -i C:\Users\bob\calc.aes.bin -o C:\Users\bob\calc.aes.decrypted.bin -mode decrypt -type aes256 -key Sh3!1z -nonce 13802153c4b2fb6a3e545ff4 -salt db6126d3ac640f8aaa67cda74b8cf1d2c54513db7bf4fbe3422d1b276af1367e -v
[-]输出目录: C:\Users\bob\
[-]输出文件名: calc.aes.decrypted.bin
[-]文件内容(十六进制): 44a974233e37b460dc2181b16846f265e8e3a07959abf9c8760f7d0ac8029575e67571ea5b313bc8b011739db57c690ec156a4b0bba4e4d632c35c1490aeaac24f5ae05e90934adf57798ee3c702a3c27073fe976fbcc6ee5db355da186c1add58913e41a8c5716a0fcfc27371f0cae906e50e680366496a00
[-]AES256 解密输入文件
[-]Argon2 salt(十六进制): db6126d3ac640f8aaa67cda74b8cf1d2c54513db7bf4fbe3422d1b276af1367e
[-]AES256 密钥(十六进制): 096a40f1aef38dd9b5d63284acc19727c4420dd98f21ea052112bef63eb7d94a
[-]AES256 nonce(十六进制): 13802153c4b2fb6a3e545ff4
[+]输出(十六进制):
505152535657556a605a6863616c6354594883ec2865488b32488b7618488b761048ad488b30488b7e3003573c8b5c17288b741f204801fe8b541f240fb72c178d5202ad813c0757696e4575ef8b741f1c4801fe8b34ae4801f799ffd74883c4305d5f5e5b5a5958c3
[+]aes256 解密输入并将 105 字节写入: C:\Users\bob\calc.aes.decrypted.bin
可以使用以下命令在 Windows 主机上从项目根目录编译该应用程序:
set GOOS=windows GOARCH=amd64;go build -o ShellcodeUtils.exe .\cmd\ShellcodeUtils\main.go