Skip to content

Commit

Permalink
v2.2
Browse files Browse the repository at this point in the history
Multiple custom profile fixes and features
  • Loading branch information
Tylous authored Feb 19, 2022
2 parents 2dfd3e4 + 4a723d8 commit c890b3c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 18 deletions.
51 changes: 42 additions & 9 deletions Loader/Loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type Beacon_SSL struct {
var num_Profile int
var Post bool

func GenerateOptions(stage, sleeptime, jitter, useragent, uri, customuri, beacon_PE, processinject_min_alloc, Post_EX_Process_Name, metadata, injector, ansible, Host, Profile, ProfilePath, outFile, custom_cert, cert_password, CDN, CDN_Value, datajitter, Keylogger string, Forwarder bool) {
func GenerateOptions(stage, sleeptime, jitter, useragent, uri, customuri, customuriGET, customuriPOST, beacon_PE, processinject_min_alloc, Post_EX_Process_Name, metadata, injector, ansible, Host, Profile, ProfilePath, outFile, custom_cert, cert_password, CDN, CDN_Value, datajitter, Keylogger string, Forwarder bool) {
Beacon_Com := &Beacon_Com{}
Beacon_Stage_p1 := &Beacon_Stage_p1{}
Beacon_Stage_p2 := &Beacon_Stage_p2{}
Expand All @@ -80,7 +80,7 @@ func GenerateOptions(stage, sleeptime, jitter, useragent, uri, customuri, beacon
fmt.Println("[*] Preparing Varibles...")
HostStageMessage, Beacon_Com.Variables = GenerateComunication(stage, sleeptime, jitter, useragent, datajitter)
Beacon_PostEX.Variables = GeneratePostProcessName(Post_EX_Process_Name, Keylogger)
Beacon_GETPOST.Variables = GenerateHTTPVaribles(Host, metadata, uri, customuri, CDN, CDN_Value, Profile, Forwarder)
Beacon_GETPOST.Variables = GenerateHTTPVaribles(Host, metadata, uri, customuri, customuriGET, customuriPOST, CDN, CDN_Value, Profile, Forwarder)
Beacon_Stage_p2.Variables = GeneratePE(beacon_PE)
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)
Expand Down Expand Up @@ -166,7 +166,7 @@ func GenerateComunication(stage, sleeptime, jitter, useragent, datajitter string
num_agent, _ := strconv.Atoi(Utils.GenerateNumer(51, 65))
Beacon_Com.Variables["useragent"] = Struct.Useragent_list[num_agent]
} else {
log.Fatal("Error: Please provide a Useragent option")
Beacon_Com.Variables["useragent"] = useragent
}
}
if useragent == "" {
Expand Down Expand Up @@ -199,7 +199,7 @@ func GeneratePostProcessName(Post_EX_Process_Name, Keylogger string) map[string]
return Beacon_PostEX.Variables
}

func GenerateHTTPVaribles(Host, metadata, uri, customuri, CDN, CDN_Value, Profile string, Forwarder bool) map[string]string {
func GenerateHTTPVaribles(Host, metadata, uri, customuri, customuriGET, customuriPOST, CDN, CDN_Value, Profile string, Forwarder bool) map[string]string {
Beacon_GETPOST := &Beacon_GETPOST{}
Beacon_GETPOST.Variables = make(map[string]string)
Beacon_GETPOST.Variables["Host"] = Host
Expand All @@ -221,20 +221,46 @@ func GenerateHTTPVaribles(Host, metadata, uri, customuri, CDN, CDN_Value, Profil
} else {
log.Fatal("Error: Please provide a valid metadata option")
}
if customuri != "0" {
if customuriGET != "0" || customuriPOST != "0" {
log.Fatal("Error: Using customuri with either of customuriGET or customuriPOST is not supported")
}
}
if (customuriGET != "0" && customuriPOST == "0") || (customuriGET == "0" && customuriPOST != "0") {
log.Fatal("Error: When using CustomuriGET/CustomuriPOST, both must be sepecified")
}
if uri == "" {
Post = false
uri := customuri
if customuriGET != "0" && customuriPOST != "0" {
uri = customuriGET
fmt.Println("[*] GET URI base: " + uri)
}

Beacon_GETPOST.Variables["HTTP_GET_URI"] = Utils.GenerateURIValues(1, num_Profile, Post, uri)
Post = true
if customuriGET != "0" && customuriPOST != "0" {
uri = customuriPOST
fmt.Println("[*] POST URI base: " + uri)
}

Beacon_GETPOST.Variables["HTTP_POST_URI"] = Utils.GenerateURIValues(1, num_Profile, Post, uri)

}
if uri != "" {
num_uri, _ := strconv.Atoi(uri)
Post = false
uri := customuri
if customuriGET != "0" && customuriPOST != "0" {
uri = customuriGET
fmt.Println("[*] GET URI base: " + uri)
}
Beacon_GETPOST.Variables["HTTP_GET_URI"] = Utils.GenerateURIValues(num_uri, num_Profile, Post, uri)
Post = true
if customuriGET != "0" && customuriPOST != "0" {
uri = customuriPOST
fmt.Println("[*] POST URI base: " + uri)
}
Beacon_GETPOST.Variables["HTTP_POST_URI"] = Utils.GenerateURIValues(num_uri, num_Profile, Post, uri)
}
if CDN != "" {
Expand Down Expand Up @@ -323,6 +349,7 @@ func GenerateProfile(Profile, CDN, CDN_Value, cert_password, custom_cert, Profil
CNAME := "\rhttps-certificate {\rset CN \"" + hostname + "\"; #Common Name"
Beacon_SSL.Variables["Cert"] = CNAME + Struct.Cert[num_Profile-1]
Beacon_GETPOST_Profile.Variables["Profile"] = Struct.HTTP_GET_POST_list[(num_Profile - 1)]
fmt.Println("[!] Self Signed SSL Cerificate Used")
} else if num_Profile == 6 {
if CDN == "" {
log.Fatal("Error: Please provide a CDN value in order to use AzureEdge profiles")
Expand All @@ -335,7 +362,6 @@ func GenerateProfile(Profile, CDN, CDN_Value, cert_password, custom_cert, Profil
}
Beacon_SSL.Variables["Cert"] = Struct.Cert[4]
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")
Expand All @@ -346,16 +372,23 @@ func GenerateProfile(Profile, CDN, CDN_Value, cert_password, custom_cert, Profil
Beacon_SSL.Variables["Cert"] = Struct.Cert[4]
Beacon_GETPOST_Profile.Variables["Profile"] = Struct.HTTP_GET_POST_list[(num_Profile - 1)]
} else if num_Profile == 8 {
if cert_password == "" {
if cert_password == "" && custom_cert == "" {
CNAME := "\rhttps-certificate {\rset CN \"" + hostname + "\"; #Common Name"
Beacon_SSL.Variables["Cert"] = CNAME + Struct.Cert[0]
fmt.Println("[!] Self Signed SSL Cerificate Used")
}
if cert_password == "" && custom_cert != "" {
log.Fatal("Error: Please provide a Password value to use this profile")
}
if custom_cert == "" {
if custom_cert == "" && cert_password != "" {
log.Fatal("Error: Please provide a Keystore value to use this profile")
}
Beacon_SSL.Variables["Cert"] = Struct.Cert[4]
if cert_password != "" && custom_cert != "" {
Beacon_SSL.Variables["Cert"] = Struct.Cert[4]
}
Beacon_GETPOST_Profile.Variables["Profile"] = Utils.Readfile(ProfilePath)
} else {
log.Fatal("Error: Please provide a Profile number less the 7 option")
log.Fatal("Error: Please provide a Profile number of 8 or less")
}
}
if custom_cert != "" && cert_password != "" {
Expand Down
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ Usage of ./SourcePoint:
-CDN-Value string
CDN cookie value (typically used for AzureEdge profiles)
-Customuri string
The base URI for custom HTTP GET/POST profile (default "0")
The base URI for custom HTTP GET/POST profile (default "0") - Cannot be used with CustomuriGET or CustomuriPOST
-CustomuriGET string
The base URI for custom HTTP GET profile (default "0") - Must be used with CustomuriPOST
-CustomuriPOST string
The base URI for custom HTTP POST profile (default "0") - Must be used with CustomuriGET
-Datajitter string
Appends a value to HTTP-Get and HTTP-Post server output (default "50")
-Forwarder
Expand Down Expand Up @@ -148,6 +152,7 @@ Usage of ./SourcePoint:
[*] Win6.3
[*] Linux
[*] Mac
[*] Custom - Whatever string you specify will be used as the user agent
-Yaml string
Path to the Yaml config file
```
Expand Down Expand Up @@ -209,23 +214,23 @@ This part of your profile controls how the beacon handles post-exploitation modu


### Profiles
Currently SourcePoint provides you with 6 baked in options for HTTP/HTTPS traffic profiles, based on existing profiles. Of these 6, 4 of them are influenced by and based on:
Currently SourcePoint provides you with 7 baked in options for HTTP/HTTPS traffic profiles, based on existing profiles. Of these 6, 4 of them are influenced by and based on:
* Microsoft Window's Update Communication
* Slack's Message Communication
* Gotomeeting's Active Meeting Communication
* Microsoft Outlook's Email Communication

2 of the profile options (5, 6 and 7) are designed specifically for:
3 of the profile options (5, 6 and 7) are designed specifically for:
* Cloudfront.net
* AzureEdge.net

The last option (7) is designed to input a custom profile. This option is designed to allow an operator to utilize a completely custom traffic profile. There are many cases where a completely unique traffic profile will yield high success rather than one of these. This also allows operators to still utilize SourcePoint's malleability features with their go-to or favorite traffic profile. As this allows for unique profiles it’s important to ensure you tweak and adjust the profile for SourcePoint to work. At a minimum:
The last option (8) is designed to input a custom profile. This option is designed to allow an operator to utilize a completely custom traffic profile. There are many cases where a completely unique traffic profile will yield high success rather than one of these. This also allows operators to still utilize SourcePoint's malleability features with their go-to or favorite traffic profile. As this allows for unique profiles it’s important to ensure you tweak and adjust the profile for SourcePoint to work. At a minimum:
* Replace - `header "Host" "acme.com";` with `header "Host" "{{.Variables.Host}}";`
* Replace - `/pathtolegitpage/` under the GET field with `{{.Variables.HTTP_GET_URI}}`
* Replace - `/pathtolegitpage/` under the POST field with `{{.Variables.HTTP_POST_URI}}`


To do so, use the following options `-CustomURI` and `-ProfilePath` along with `-Profile 7`. While developing a profile, it’s highly recommended to use the native ./c2lint to verify everything is working.
To do so, use the following options `-Customuri` and `-ProfilePath` along with `-Profile 8`. To use a different URI base for GET and POST, `-CustomuriGET` and `-CustomuriPOST` should be used in place of `-Customuri`. While developing a profile, it’s highly recommended to use the native ./c2lint to verify everything is working.


## Sample Yaml Configs
Expand Down
14 changes: 11 additions & 3 deletions SourcePoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ type FlagOptions struct {
useragent string
uri string
customuri string
customuriGET string
customuriPOST string
beacon_PE string
processinject_min_alloc string
Post_EX_Process_Name string
Expand Down Expand Up @@ -56,6 +58,8 @@ type conf struct {
Sleep string `yaml:"Sleep"`
Uri string `yaml:"Uri"`
Customuri string `yaml:"Customuri"`
CustomuriGET string `yaml:"CustomuriGET"`
CustomuriPOST string `yaml:"CustomuriPOST"`
CDN string `yaml:"CDN"`
CDN_Value string `yaml:"CDN_Value"`
Useragent string `yaml:"Useragent"`
Expand Down Expand Up @@ -91,7 +95,9 @@ func options() *FlagOptions {
[*] Linux
[*] Mac`)
uri := flag.String("Uri", "", "The number URIs a profile for beacons to choose from")
customuri := flag.String("Customuri", "0", "The base URI for custom HTTP GET/POST profile")
customuri := flag.String("Customuri", "0", "The base URI for custom HTTP GET/POST profile - Cannot be used with CustomuriGET or CustomuriPOST")
customuriGET := flag.String("CustomuriGET", "0", "The base URI for custom HTTP GET profile - Must be used with CustomuriPOST")
customuriPOST := flag.String("CustomuriPOST", "0", "The base URI for custom HTTP POST profile - Must be used with CustomuriGET")
beacon_PE := flag.String("PE_Clone", "", `PE file beacon will mimic (Use the number):
[1] srv.dll
[2] ActivationManager.dll
Expand Down Expand Up @@ -174,7 +180,7 @@ func options() *FlagOptions {
Forwarder := flag.Bool("Forwarder", false, "Enabled the X-forwarded-For header (Good for when your C2 is behind a redirector)")
Yaml := flag.String("Yaml", "", "Path to the Yaml config file")
flag.Parse()
return &FlagOptions{stage: *stage, sleeptime: *sleeptime, jitter: *jitter, useragent: *useragent, uri: *uri, customuri: *customuri, 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}
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}

}

Expand Down Expand Up @@ -209,6 +215,8 @@ func main() {
opt.sleeptime = c.Sleep
opt.uri = c.Uri
opt.customuri = c.Customuri
opt.customuri = c.CustomuriGET
opt.customuri = c.CustomuriPOST
opt.CDN = c.CDN
opt.useragent = c.Useragent
opt.ProfilePath = c.ProfilePath
Expand All @@ -224,6 +232,6 @@ func main() {
log.Fatal("Error: Please provide the hostname, IP or enable ansible mode")
}

Loader.GenerateOptions(opt.stage, opt.sleeptime, opt.jitter, opt.useragent, opt.uri, opt.customuri, opt.beacon_PE, opt.processinject_min_alloc, opt.Post_EX_Process_Name, opt.metadata, opt.injector, opt.ansible, 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)
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.ansible, 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)

}
2 changes: 1 addition & 1 deletion Utils/Utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func GenerateURIValues(numb int, profile_type int, Post bool, customuri string)
}
}
if profile_type == 8 {
baseuri = "//"
baseuri = "" + customuri + ""
}
if profile_type == 9 {
baseuri = "" + customuri + ""
Expand Down

0 comments on commit c890b3c

Please sign in to comment.