Arsenal Aggressor Script
Aggressor script to automatically download and load an arsenal of open source and private tooling. Hopefully, this saves other teams time and helps the community!
TL;DR
Introduction
Sleep
Download Artifacts via Aggressor Script
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;
# ===== 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++) {
downloadRepo(@repositories[$i][1],@repositories[$i][0]);
}
}
# createDir($path, $type);
sub createDir {
$path = $1;
$type = $2;
mkdir($path)
if (checkError($error)) {
warn("Unable to create $type directory: $error");
$eMsg = "true";
}
}
# createFile($path);
sub createFile {
$path = $1;
createNewFile($path);
}
# writeFile($handle, $path);
sub writeFile {
$handle = $1;
$path = $2;
$outFile = openf(">" . $path);
writeb($outFile, readb($handle, -1));
closef($outFile);
}
# 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 {
# 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 "";
}
}
# Create Cobalt Strike menu to download Arsenal
popup Arsenal {
item("&Download", { loadArsenal() });
}
menubar("Arsenal", "Arsenal");



Challenge 1: Root CA Trust in Sleep
Truststore Creation



Dynamic Truststore Load


Challenge 2: Unzip Repositories


Challenge 3: Nested Aggressor Script Load
importer.cna
importee.cna


Decompiling Cobalt Strike


Find The Loader




Implement Loader In Sleep


Locate Script Settings



Save (Scripts) Yourself

Bringing Everything Together



Conclusion
Potential improvements
Last updated
