Added BeaconGate Option - CS 4.10

Added default beacon-gate option for cobalt strike 4.10

stage.beacon_gate

stage {
 beacon_gate {
    All;
 }
}

Default/None specified - None;
All Generic Options allowed
API Specification Allowed:
-BeaconGate UnmapViewOfFile,VirtualAlloc,etc

Mistyped API's will be removed - not cancel profile generation

Modified Readme

https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/beacon-gate.htm?cshid=1007
This commit is contained in:
Ed
2024-08-29 09:35:04 -07:00
parent b1d7bd7f43
commit ea1cdf4839
6 changed files with 55 additions and 7 deletions
+42 -4
View File
@@ -34,6 +34,7 @@ type FlagOptions struct {
tasks_max_size string
tasks_proxy_max_size string
tasks_dns_proxy_max_size string
beacongate string
}
type Beacon_Com struct {
@@ -67,7 +68,7 @@ type Beacon_SSL struct {
var num_Profile int
var Post bool
func GenerateOptions(stage, sleeptime, jitter, useragent, uri, customuri, customuriGET, customuriPOST, beacon_PE, processinject_min_alloc, Post_EX_Process_Name, metadata, injector, Host, Profile, ProfilePath, outFile, custom_cert, cert_password, CDN, CDN_Value, datajitter, Keylogger string, Forwarder bool, tasks_max_size string, tasks_proxy_max_size string, tasks_dns_proxy_max_size string, syscall_method string, httplib string, ThreadSpoof bool) {
func GenerateOptions(stage, sleeptime, jitter, useragent, uri, customuri, customuriGET, customuriPOST, beacon_PE, processinject_min_alloc, Post_EX_Process_Name, metadata, injector, Host, Profile, ProfilePath, outFile, custom_cert, cert_password, CDN, CDN_Value, datajitter, Keylogger string, Forwarder bool, tasks_max_size string, tasks_proxy_max_size string, tasks_dns_proxy_max_size string, syscall_method string, httplib string, ThreadSpoof bool, beacongate string) {
Beacon_Com := &Beacon_Com{}
Beacon_Stage_p1 := &Beacon_Stage_p1{}
Beacon_Stage_p2 := &Beacon_Stage_p2{}
@@ -83,7 +84,7 @@ func GenerateOptions(stage, sleeptime, jitter, useragent, uri, customuri, custom
HostStageMessage, Beacon_Com.Variables = GenerateComunication(stage, sleeptime, jitter, useragent, datajitter, tasks_max_size, tasks_proxy_max_size, tasks_dns_proxy_max_size, httplib)
Beacon_PostEX.Variables = GeneratePostProcessName(Post_EX_Process_Name, Keylogger, ThreadSpoof)
Beacon_GETPOST.Variables = GenerateHTTPVaribles(Host, metadata, uri, customuri, customuriGET, customuriPOST, CDN, CDN_Value, Profile, Forwarder)
Beacon_Stage_p1.Variables, Beacon_Stage_p2.Variables, syscall_method = GeneratePE(beacon_PE, syscall_method)
Beacon_Stage_p1.Variables, Beacon_Stage_p2.Variables, syscall_method = GeneratePE(beacon_PE, syscall_method, beacongate)
Process_Inject.Variables = GenerateProcessInject(processinject_min_alloc, injector)
Beacon_GETPOST_Profile.Variables, Beacon_SSL.Variables = GenerateProfile(Profile, CDN, CDN_Value, cert_password, custom_cert, ProfilePath, Host)
fmt.Println("[*] Building Profile...")
@@ -321,7 +322,7 @@ func GenerateHTTPVaribles(Host, metadata, uri, customuri, customuriGET, customur
return Beacon_GETPOST.Variables
}
func GeneratePE(beacon_PE string, syscall_method string) (map[string]string, map[string]string, string) {
func GeneratePE(beacon_PE string, syscall_method string, beacongate string) (map[string]string, map[string]string, string) {
Beacon_Stage_p1 := &Beacon_Stage_p1{}
Beacon_Stage_p1.Variables = make(map[string]string)
@@ -356,6 +357,43 @@ func GeneratePE(beacon_PE string, syscall_method string) (map[string]string, map
}
Beacon_Stage_p2.Variables["pe"] = Struct.Peclone_list[(PE_Num - 1)]
}
if beacongate == "" {
Beacon_Stage_p1.Variables["beacongate"] = "None;"
} else if beacongate == "All" || beacongate == "Comms" || beacongate == "Core" || beacongate == "Cleanup" {
Beacon_Stage_p1.Variables["beacongate"] = beacongate + ";"
} else {
// Handle specific APIs
apis := strings.Split(beacongate, ",")
validAPIs := map[string]bool{
"InternetOpenA": true, "InternetConnectA": true, "CloseHandle": true,
"CreateFileMapping": true, "CreateRemoteThread": true, "CreateThread": true,
"DuplicateHandle": true, "GetThreadContext": true, "MapViewOfFile": true,
"OpenProcess": true, "OpenThread": true, "ReadProcessMemory": true,
"ResumeThread": true, "SetThreadContext": true, "UnmapViewOfFile": true,
"VirtualAlloc": true, "VirtualAllocEx": true, "VirtualFree": true,
"VirtualProtect": true, "VirtualProtectEx": true, "VirtualQuery": true,
"WriteProcessMemory": true, "ExitThread": true,
}
var validatedAPIs []string
for _, api := range apis {
api = strings.TrimSpace(api)
if validAPIs[api] {
validatedAPIs = append(validatedAPIs, api)
} else {
fmt.Printf("[!] Warning: Invalid API '%s' will not be included in beacongate.\n", api)
}
}
if len(validatedAPIs) > 0 {
Beacon_Stage_p1.Variables["beacongate"] = strings.Join(validatedAPIs, ";\n ") + ";"
} else {
fmt.Println("[!] Warning: Invalid beacongate input. Reverting to 'None'.")
Beacon_Stage_p1.Variables["beacongate"] = "None;"
}
}
return Beacon_Stage_p1.Variables, Beacon_Stage_p2.Variables, syscall_method
}
@@ -415,7 +453,7 @@ func GenerateProfile(Profile, CDN, CDN_Value, cert_password, custom_cert, Profil
log.Fatal("Error: Please provide a Keystore value to use this profile")
}
Beacon_SSL.Variables["Cert"] = Struct.Cert[4]
Beacon_GETPOST_Profile.Variables["Profile"] = Struct.HTTP_GET_POST_list[(num_Profile - 1)]
Beacon_GETPOST_Profile.Variables["Profile"] = Struct.HTTP_GET_POST_list[num_Profile-1]
} else if num_Profile == 5 || num_Profile == 7 {
if cert_password == "" {
log.Fatal("Error: Please provide a Password value to use this profile")
+2
View File
@@ -35,6 +35,8 @@ $go build SourcePoint.go
Usage of ./SourcePoint:
-Allocation string
Minimum amount of memory to request for injected content (must be higher than 4096)
-BeaconGate string
Specify beacon gate options (All, Comms, Core, Cleanup) or specific APIs
-CDN string
CDN cookie name (typically used for AzureEdge profiles)
-CDN-Value string
BIN
View File
Binary file not shown.
+6 -2
View File
@@ -43,6 +43,7 @@ type FlagOptions struct {
httplib string
threadspoof bool
Yaml string
beacongate string
}
type conf struct {
@@ -77,6 +78,7 @@ type conf struct {
Syscall_method string `yaml:"Syscall_method"`
Httplib string `yaml:"Httplib"`
Threadspoof bool `yaml:"ThreadSpoof"`
BeaconGate string `yaml:"BeaconGate"`
}
func (c *conf) getConf(yamlfile string) *conf {
@@ -198,8 +200,9 @@ func options() *FlagOptions {
[*] winhttp'`)
threadspoof := flag.Bool("ThreadSpoof", true, "Sets post-ex DLLs to spawn threads with a spoofed start address. These are generated randomly")
Yaml := flag.String("Yaml", "", "Path to the Yaml config file")
beacongate := flag.String("BeaconGate", "", "Specify beacon gate options (All, Comms, Core, Cleanup) or specific APIs")
flag.Parse()
return &FlagOptions{stage: *stage, sleeptime: *sleeptime, jitter: *jitter, useragent: *useragent, uri: *uri, customuri: *customuri, customuriGET: *customuriGET, customuriPOST: *customuriPOST, beacon_PE: *beacon_PE, processinject_min_alloc: *processinject_min_alloc, Post_EX_Process_Name: *Post_EX_Process_Name, metadata: *metadata, injector: *injector, Host: *Host, Profile: *Profile, ProfilePath: *ProfilePath, outFile: *outFile, custom_cert: *custom_cert, cert_password: *cert_password, CDN: *CDN, CDN_Value: *CDN_Value, Yaml: *Yaml, Datajitter: *Datajitter, Keylogger: *Keylogger, Forwarder: *Forwarder, tasks_max_size: *tasks_max_size, tasks_proxy_max_size: *tasks_proxy_max_size, tasks_dns_proxy_max_size: *tasks_dns_proxy_max_size, syscall_method: *syscall_method, httplib: *httplib, threadspoof: *threadspoof}
return &FlagOptions{stage: *stage, sleeptime: *sleeptime, jitter: *jitter, useragent: *useragent, uri: *uri, customuri: *customuri, customuriGET: *customuriGET, customuriPOST: *customuriPOST, beacon_PE: *beacon_PE, processinject_min_alloc: *processinject_min_alloc, Post_EX_Process_Name: *Post_EX_Process_Name, metadata: *metadata, injector: *injector, Host: *Host, Profile: *Profile, ProfilePath: *ProfilePath, outFile: *outFile, custom_cert: *custom_cert, cert_password: *cert_password, CDN: *CDN, CDN_Value: *CDN_Value, Yaml: *Yaml, Datajitter: *Datajitter, Keylogger: *Keylogger, Forwarder: *Forwarder, tasks_max_size: *tasks_max_size, tasks_proxy_max_size: *tasks_proxy_max_size, tasks_dns_proxy_max_size: *tasks_dns_proxy_max_size, syscall_method: *syscall_method, httplib: *httplib, threadspoof: *threadspoof, beacongate: *beacongate}
}
@@ -249,6 +252,7 @@ func main() {
opt.syscall_method = c.Syscall_method
opt.httplib = c.Httplib
opt.threadspoof = c.Threadspoof
opt.beacongate = c.BeaconGate
}
if opt.outFile == "" {
log.Fatal("Error: Please provide a file name to save the profile into")
@@ -263,5 +267,5 @@ func main() {
log.Fatal("Error: When using CustomuriGET/CustomuriPOST, both must be sepecified")
}
fmt.Println(c.TasksMaxSize)
Loader.GenerateOptions(opt.stage, opt.sleeptime, opt.jitter, opt.useragent, opt.uri, opt.customuri, opt.customuriGET, opt.customuriPOST, opt.beacon_PE, opt.processinject_min_alloc, opt.Post_EX_Process_Name, opt.metadata, opt.injector, opt.Host, opt.Profile, opt.ProfilePath, opt.outFile, opt.custom_cert, opt.cert_password, opt.CDN, opt.CDN_Value, opt.Datajitter, opt.Keylogger, opt.Forwarder, opt.tasks_max_size, opt.tasks_proxy_max_size, opt.tasks_dns_proxy_max_size, opt.syscall_method, opt.httplib, opt.threadspoof)
Loader.GenerateOptions(opt.stage, opt.sleeptime, opt.jitter, opt.useragent, opt.uri, opt.customuri, opt.customuriGET, opt.customuriPOST, opt.beacon_PE, opt.processinject_min_alloc, opt.Post_EX_Process_Name, opt.metadata, opt.injector, opt.Host, opt.Profile, opt.ProfilePath, opt.outFile, opt.custom_cert, opt.cert_password, opt.CDN, opt.CDN_Value, opt.Datajitter, opt.Keylogger, opt.Forwarder, opt.tasks_max_size, opt.tasks_proxy_max_size, opt.tasks_dns_proxy_max_size, opt.syscall_method, opt.httplib, opt.threadspoof, opt.beacongate)
}
+4 -1
View File
@@ -1322,7 +1322,9 @@ stage {
set cleanup "true";
set userwx "false";
set smartinject "true";
beacon_gate {
{{.Variables.beacongate}}
}
set syscall_method "{{.Variables.syscall_method}}"; #### needs a varible
###will change down the road but 32-bit shouldn't be used that much
set magic_mz_x86 "MZRE";
@@ -1339,6 +1341,7 @@ func Beacon_Stage_p2_Stuct() string {
{{.Variables.pe}}
`
}
func Beacon_GETPOST_Profile_Struct() string {
return `
{{.Variables.Profile}}
+1
View File
@@ -1,3 +1,4 @@
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=