sliver源码分析 | 植入物生成逻辑

2024-09-10 38 0

引言

  • 项目概述:对开源的C2框架sliver进行源码分析,意图学习其原理。本篇分析sliver生成植入物如windows可执行文件exe和windows平台下的shellcode。

  • 目标与读者:网络安全兴趣爱好者、红队选手

准备工作

git clone https://github.com/BishopFox/sliver.git

vscode debug配置

如果需要对sliver-server进行调试可按照下面的设置
.vscode/launch.json中写入

{
    "version": "0.2.0",
    "configurations": [
      {
        "name": "Debug Server",
        "type": "go",
        "request": "attach",
        "mode": "remote",
        "remotePath": "${workspaceFolder}",
        "port": 8844,
        "host": "127.0.0.1",
        "trace": "log"
      }
    ]
}

在项目根目录运行dlv进行调试

dlv debug \
    --build-flags="-tags osusergo,netgo,go_sqlite,server -ldflags='-X github.com/bishopfox/sliver/client/version.Version=1.1.2 -X github.com/bishopfox/sliver/client/version.CompiledAt=Never -X github.com/bishopfox/sliver/client/version.GithubReleasesURL=github.com -X github.com/bishopfox/sliver/client/version.GitCommit=aabbcc -X github.com/bishopfox/sliver/client/version.GitDirty=Dirty'" \
    --headless \
    --listen=:8844 \
    --api-version=2 \
    --log \
    github.com/bishopfox/sliver/server

定位generate

sliver终端构造https类型植入物exe的精简命令如下

generate beacon --http HOST:PORT --save beacon.exe

通过在vscode中搜索generate关键词,找到
client/command/generate/generate.go

func GenerateCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
	name, config := parseCompileFlags(cmd, con)
	if config == nil {
		return
	}
	save, _ := cmd.Flags().GetString("save")
	if save == "" {
		save, _ = os.Getwd()
	}
	if external, _ := cmd.Flags().GetBool("external-builder"); !external {
		compile(config, save, con)
	} else {
		_, err := externalBuild(name, config, save, con)
		if err != nil {
			if err == ErrNoExternalBuilder {
				con.PrintErrorf("There are no external builders currently connected to the server\n")
				con.PrintErrorf("See 'builders' command for more information\n")
			} else if err == ErrNoValidBuilders {
				con.PrintErrorf("There are external builders connected to the server, but none can build the target you specified\n")
				con.PrintErrorf("Invalid target %s\n", fmt.Sprintf("%s:%s/%s", config.Format, config.GOOS, config.GOARCH))
				con.PrintErrorf("See 'builders' command for more information\n")
			} else {
				con.PrintErrorf("%s\n", err)
			}
			return
		}
	}
}

可以看到如果不用external-builder默认执行的是compile(config, save, con)

分析compile

func compile(config *clientpb.ImplantConfig, save string, con *console.SliverClient) (*commonpb.File, error) {
	if config.IsBeacon {
		interval := time.Duration(config.BeaconInterval)
		con.PrintInfof("Generating new %s/%s beacon implant binary (%v)\n", config.GOOS, config.GOARCH, interval)
	} else {
		con.PrintInfof("Generating new %s/%s implant binary\n", config.GOOS, config.GOARCH)
	}
	if config.ObfuscateSymbols {
		con.PrintInfof("%sSymbol obfuscation is enabled%s\n", console.Bold, console.Normal)
	} else if !config.Debug {
		con.PrintErrorf("Symbol obfuscation is %sdisabled%s\n", console.Bold, console.Normal)
	}

	start := time.Now()
	ctrl := make(chan bool)
	con.SpinUntil("Compiling, please wait ...", ctrl)
	//con.r(θωθ)p(θωθ)c.Generate()重点在这个方法
	generated, err := con.r(θωθ)p(θωθ)c.Generate(context.Background(), &clientpb.GenerateReq{
		Config: config,
	})
	ctrl <- true
	<-ctrl
	if err != nil {
		con.PrintErrorf("%s\n", err)
		return nil, err
	}

	elapsed := time.Since(start)
	con.PrintInfof("Build completed in %s\n", elapsed.Round(time.Second))
	if len(generated.File.Data) == 0 {
		con.PrintErrorf("Build failed, no file data\n")
		return nil, errors.New("no file data")
	}

	fileData := generated.File.Data
	if config.IsShellcode {
		if !config.SGNEnabled {
			con.PrintErrorf("Shikata ga nai encoder is %sdisabled%s\n", console.Bold, console.Normal)
		} else {
			con.PrintInfof("Encoding shellcode with shikata ga nai ... ")
			resp, err := con.r(θωθ)p(θωθ)c.ShellcodeEncoder(context.Background(), &clientpb.ShellcodeEncodeReq{
				Encoder:      clientpb.ShellcodeEncoder_SHIKATA_GA_NAI,
				Architecture: config.GOARCH,
				Iterations:   1,
				BadChars:     []byte{},
				Data:         fileData,
			})
			if err != nil {
				con.PrintErrorf("%s\n", err)
			} else {
				con.Printf("success!\n")
				fileData = resp.GetData()
			}
		}
	}

	saveTo, err := saveLocation(save, generated.File.Name, con)
	if err != nil {
		return nil, err
	}

	err = os.WriteFile(saveTo, fileData, 0o700)
	if err != nil {
		con.PrintErrorf("Failed to write to: %s\n", saveTo)
		return nil, err
	}
	con.PrintInfof("Implant saved to %s\n", saveTo)
	return generated.File, err
}

可以看到整个方法进行了beacon判断、是否启用DEBUG、然后发送r(θωθ)p(θωθ)c请求,调用con.r(θωθ)p(θωθ)c.Generate()进行构造。构造完毕后根据构造结果是否是shellcode,进行SGNEnabled判断,从而决定是否使用Shikata ga nai encoder进行编码,最后将结果写入到--save指定的文件中,最后该函数返回文件名和错误信息。

那么分析重点就在下面的r(θωθ)p(θωθ)c调用中

generated, err := con.r(θωθ)p(θωθ)c.Generate(context.Background(), &clientpb.GenerateReq{
	Config: config,
})

分析r(θωθ)p(θωθ)c

这里直接使用vscode的CTRL+左键只能找到他的定义,不能找到实现。
定位到定义的位置是
protobuf/被干掉的词/services_gr(θωθ)p(θωθ)c.pb.go

package 被干掉的词

import (
	context "context"
	clientpb "github.com/bishopfox/sliver/protobuf/clientpb"
	commonpb "github.com/bishopfox/sliver/protobuf/commonpb"
	sliverpb "github.com/bishopfox/sliver/protobuf/sliverpb"
	gr(θωθ)p(θωθ)c "google.golang.org/gr(θωθ)p(θωθ)c"
	codes "google.golang.org/gr(θωθ)p(θωθ)c/codes"
	status "google.golang.org/gr(θωθ)p(θ

4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

苹果试图保护你的隐私,OpenAI可能做不到
Shuffle:一款完全自动化的安全栈增强平台
如何使用CODASM编码Payload并降低熵值
SessionExec:一款针对会话安全的安全命令测试工具
Arkime:一款大规模数据包捕获和索引数据库系统
从蓝队流量角度分析Shiro-550反序列化漏洞

发布评论