-
Notifications
You must be signed in to change notification settings - Fork 4
/
OffSecOpsArsenal.cna
301 lines (253 loc) · 8.64 KB
/
OffSecOpsArsenal.cna
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.File;
import java.net.URL;
import java.net.URLConnection;
import java.io.IOException;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.security.KeyStore;
import aggressor.Prefs;
import java.util.LinkedList;
# ===== Global Variables =====
$saveFilePath = script_resource() . "/downloads"; # Location to store downloaded zips
$destPath = script_resource(); # Unzipped repositories destination folder is relative to this scripts location
# ============================
# ==== Git Repositories ====
# Name, repository ID, branch, [CNA script paths to load]
# Name => repository will be downloaded into this folder, the name has to match the path that is used to load the bofs! (see the modified cna script)
# URL to download zip from => GitLab repository ID
# Paths => relative path from root directory to the cna script to load
@repositories = @(
@("CS-Situational-Awareness-BOF", "https://github.com/trustedsec/CS-Situational-Awareness-BOF/archive/refs/heads/master.zip", "CS-Situational-Awareness-BOF-master/SA/SA.cna"),
@("CS-Remote-OPs-BOF", "https://github.com/trustedsec/CS-Remote-OPs-BOF/archive/refs/heads/main.zip", "CS-Remote-OPs-BOF-main/Remote/Remote.cna", "CS-Remote-OPs-BOF-main/Injection/Injection.cna"),
# add other entries here as well
);
# ============================
# ==== Functions ====
# Download all repository zip files one by one
sub loadArsenal {
for($i = 0; $i < size(@repositories); $i++) {
$name = @repositories[$i][0];
$url = @repositories[$i][1];
$size = size(@repositories[$i]);
downloadRepo($url, $name);
unzip($name, $name); # need to find out if and why this errors
if ($size <= 2) {
println("No scripts to load");
}
else {
for ($y = 2; $y < $size; $y++) {
$cnaScriptPath = script_resource($name . "/" . @repositories[$i][$y]);
println($cnaScriptPath);
betterLoadScript($cnaScriptPath);
}
println("> Scripts loaded.");
}
println("> Completed " . $name);
}
# Open the script manager again since we don't know how to call refresh() from this script
# Shows all scripts are loaded
openScriptManager();
}
# createFile($path);
sub createFile {
$path = $1;
createNewFile($path);
if (checkError($error)) {
warn("Cannot create file $path: $error");
$eMsg = "true";
}
}
# writeFile($handle, $path);
sub writeFile {
$handle = $1;
$path = $2;
$outFile = openf(">" . $path);
writeb($outFile, readb($handle, -1));
closef($outFile);
if (checkError($error)) {
warn("Error while writing to file: $error");
$eMsg = "true";
}
}
# createDir($path, $type);
sub createDir {
$path = $1;
$type = $2;
mkdir($path)
if (checkError($error)) {
warn("Unable to create $type directory: $error");
$eMsg = "true";
}
}
# Unzips the downloaded zipfile and puts the folder in the main project directory
# unzip($name, $folderName);
sub unzip {
$zipFileName = $1 . ".zip";
$folderName = $2;
$zipFile = $saveFilePath . "/" . $zipFileName;
$destPathProper = $destPath . "/" . $folderName;
$currDir = cwd();
# load and unzip zipfile
$fis = [new java.io.FileInputStream: $zipFile];
$zis = [new java.util.zip.ZipInputStream: $fis];
if ([$fis available] == 0) {
println("Archive is empty. Aborting.");
[$zis closeEntry];
[$fis close];
exit();
}
#Create and go to the destination directory
createDir($destPathProper, "zip destination");
chdir($destPathProper);
# Write all zip contents to the directory
$entry = [$zis getNextEntry];
while ($entry) {
# Check if $entry is an empty directory
if ([$entry isDirectory]) {
createDir(getFileProper($entry), "empty"); # Create empty directory
}
# Else $entry is a file
else {
$fullPath = getFileProper($destPathProper, $entry);
createDir(getFileProper(getFileParent($entry)), "parent"); # Create the parent directory
createFile($fullPath); # Create the file
$zipHandle = [SleepUtils getIOHandle: $zis, $null];
writeFile($zipHandle, $fullPath);
}
$entry = [$zis getNextEntry];
}
[$zis closeEntry];
[$fis close];
# Change directory back to initial
chdir($currDir);
println("> Files unzipped");
}
# Download a single repository and write the contents to downloads/repositoryname.zip
sub downloadRepo {
$downloadUrl = $1;
$fileName = $2 . ".zip";
# Create downloads dir if it does not exist
if (!-exists $saveFilePath) {
createDir($saveFilePath);
}
println("> Downloading " . $fileName . "...");
println("\tDownload url: $downloadUrl");
# Check if the zip file can be created
$saveFilePathProper = $saveFilePath . "/" . $fileName;
createFile($saveFilePathProper);
# Obtain the content and write to file
$handle = httpGet($downloadUrl);
writeFile($handle, $saveFilePathProper);
}
# httpGet($url);
# Adapted from https://gist.github.com/mgeeky/2d7f8c2a6ffbfd23301e1e2de0312087
sub httpGet {
$method = "GET";
$url = $1;
$n = 0;
if(size(@_) == 2) { $n = $2; }
$maxRedirectsAllowed = 10;
if ($n > $maxRedirectsAllowed) {
warn("Exceeded maximum number of redirects: $method $url ");
return "";
}
$USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0";
try {
# When using private git server, load the truststore with the custom root CA or self-signed CA from the current directory
$filepath = script_resource("truststore-public.jks");
# The trust store file and optional password to unlock it
$trustStoreFile = [new File: $filepath];
$trustStorePassword = "changeit";
# Load the trust store from file into an object, the type is "jks"
$trustStore = [KeyStore getInstance: "JKS"];
[$trustStore load: [new FileInputStream: $trustStoreFile], $trustStorePassword];
# init TrustManagerFactory with truststore containing root CA
$tmf = [TrustManagerFactory getInstance: [TrustManagerFactory getDefaultAlgorithm]];
[$tmf init: $trustStore];
# Set the SSLContext of the HTTP requests to ensure the root CA certificate is trusted
$sslContext = [SSLContext getInstance: "TLS"];
[$sslContext init: $null, [$tmf getTrustManagers], $null];
[javax.net.ssl.HttpsURLConnection setDefaultSSLSocketFactory: [$sslContext getSocketFactory]];
# Build the HTTP Request
$urlobj = [new java.net.URL: $url];
if (checkError($error)) {
warn("1: $error");
}
$con = $null;
$con = [$urlobj openConnection];
[$con setRequestMethod: $method];
[$con setInstanceFollowRedirects: true];
[$con setRequestProperty: "Accept", "*/*"];
[$con setRequestProperty: "Cache-Control", "max-age=0"];
[$con setRequestProperty: "Connection", "keep-alive"];
[$con setRequestProperty: "User-Agent", $USER_AGENT];
# Send the request and obtain the content
$inputstream = [$con getInputStream];
$handle = [SleepUtils getIOHandle: $inputstream, $null];
$responseCode = [$con getResponseCode];
# If a redirect is returned, try again with the redirect target (max 10 times)
if (($responseCode >= 301) && ($responseCode <= 304)) {
warn("Redirect");
$loc = [$con getHeaderField: "Location"];
httpRequest($loc, $n + 1);
}
# return the handle with the content
return $handle;
}
catch $message {
warn("HTTP Request failed: $method $url : $message ");
printAll(getStackTrace());
return "";
}
}
# Iterate the config list of loaded scripts
# If a script is already present, it should not be loaded for a second time
sub checkUnique
{
$unique = 1;
for ($z = 0; $z < [$1 size]; $z++)
{
if([$1 get: $z] eq $2)
{
$unique = 0;
}
}
return $unique;
}
# betterLoadScript($pathtoscript);
sub betterLoadScript
{
# Load prefs
$scriptpath = $1; # Full path to script as arg, e.g.
$list = [[Prefs getPreferences] getList: "cortana.scripts"];
$result = checkUnique($list, $scriptpath);
# Only add if it was not yet in the list
# Avoids loading scripts twice
if($result == 1)
{
# Save the script to the cortana.scripts list
[$list add: $scriptpath];
[[Prefs getPreferences] setList: "cortana.scripts", $list];
[[Prefs getPreferences] save];
# Actually Loading the script
# https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics_aggressor-scripts/as-resources_functions.htm#getAggressorClient
$client = getAggressorClient();
[[$client getScriptEngine] loadScript: $scriptpath];
println("\tLoaded $scriptpath");
}
}
# Create Cobalt Strike menu to download Arsenal
popup Arsenal {
item("&Download", { loadArsenal() });
}
menubar("Arsenal", "Arsenal");