Skip to content

Instantly share code, notes, and snippets.

@Und3rf10w
Last active July 8, 2022 01:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Und3rf10w/c890d3c6638a41f6f7e3d5b26c84a682 to your computer and use it in GitHub Desktop.
Save Und3rf10w/c890d3c6638a41f6f7e3d5b26c84a682 to your computer and use it in GitHub Desktop.
Send Cobalt Strike notifications to your Matrix Server via matrix-hookshot
# This script adds matrix-hookshot support via generic webhooks to Cobalt Strike
# Ensure that you configure the variables necessary at the beginning
# @Und3rf10w
# Modified from @vysecurity 's pushover-ng.cna
$version = "0.1a";
##########################
# MODIFY THESE VARIABLES #
##########################
$location = "https://<MATRIX WEBHOOK LOCATION>";
$uri = "/URI";
##########################
# END USER VARIABLES #
##########################
import java.net.URLEncoder;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
# Based off of byt3bl33d3r's implementation
sub sendpost{
$method = "POST";
$url = $1;
$body = $2 . "\r\n";
$USER_AGENT = "Mozilla/5.0";
$CONTENT_TYPE = "application/json; charset=UTF-8";
$urlobj = [new URL: $url];
$con = [$urlobj openConnection];
[$con setRequestMethod: $method];
[$con setRequestProperty: "User-Agent", $USER_AGENT];
[$con setRequestProperty: "Content-Type", $CONTENT_TYPE];
[$con setDoOutput: true];
$wr = [new DataOutputStream: [$con getOutputStream]];
[$wr writeBytes: $body];
[$wr flush];
[$wr close];
$responseCode = [$con getResponseCode];
$in = [new BufferedReader: [new InputStreamReader: [$con getInputStream]]];
$inputLine = "";
$response = "";
$inputLine = [$in readLine];
$response = $response . $inputLine . "\r\n";
while ($inputLine ne ""){
$inputLine = [$in readLine];
$response = $response . $inputLine . "\r\n";
}
[$in close];
return $response;
}
# Based off of mgeeky's implementation
# sub sendpost {
# $url = $1;
# $body = $2;
# $method = "POST";
# $n = 0;
#
# # If a 3rd argument is given, set $n to represent MAX_REDIRECTS
# # if(size(@_) == 3){ $n = $3; }
#
# $bodyLen = strlen($body);
# $maxRedirectsAllowed = 10;
# if ($n > $maxRedirectsAllowed) {
# warn("Exceeded maximum allowed redirects: $method $url");
# return "";
# }
#
# try{
# $urlobj = [new URL: $url];
# $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": "Mozilla/5.0 matrix-hookshot-cs/$version"];
#
# if ($bodyLen > 0) {
# [$con setDoOutput: true];
# [$con setRequestProperty: "Content-Type", "application/json; charset=UTF-8"];
# }
#
# # $outstream = [$con getOutputStream];
# # if($bodyLen > 0){
# # [$outstream write: [$body getBytes]];
# # }
#
# if($bodyLen > 0) {
# $wr = [new DataOutputStream: [$con getOutputStream]];
# [$wr writeBytes: $body];
# [$wr flush];
# [$wr close];
# }
# elog($outstream);
#
# $inputstream = [$con getInputStream];
# $handle = [SleepUtils getIOHandle: $inputstream, $outstream];
# $responseCode = [$con getResponseCode];
#
# if(($responseCode >= 301) && ($responseCode <= 304)) {
# elog($responseCode);
# $loc = [$con getHeaderField: "Location"];
# return httpRequest($method, $loc, $body, $n + 1);
# }
#
# @content = readAll($handle);
# $response = "";
# foreach $line (@content) {
# $response .= $line . "\r\n";
# }
#
# if((strlen($response) > 2) && (right($response, 2) eq "\r\n")) {
# $response = substr($resposne, 0, strlen($response) - 2);
# }
# elog($response);
#
# return $response;
#
# }
# catch $message
# {
# warn("HTTP Request failed: $method $url : $message");
# printAll(getStackTrace());
# return "";
# }
# }
# sub sendpost{
#
# $url = $1;
# $body = $2 . "\r\n";
#
# $USER_AGENT = "Mozilla/5.0 cs-matrix-hookshot/$version";
#
#
# $urlobj = [new URL: $url];
#
# $con = [$urlobj openConnection];
#
# [$con setRequestProperty: "User-Agent", $USER_AGENT];
#
# [$con setRequestMethod: "POST"];
#
# [$con setDoOutput: false];
#
# # [$con setRequestMethod: $method];
#
# [$con setDoOutput: true];
#
# [$con connect];
#
# $wr = [new DataOutputStream: [$con getOutputStream]];
# [$wr writeBytes: $body];
# [$wr flush];
# [$wr close];
#
# $responseCode = [$con getResponseCode];
#
# $in = [new BufferedReader: [new InputStreamReader: [$con getInputStream]]];
#
# $inputLine = [new String];
#
# $response = "";
#
# # $inputLine = [$in readLine];
# # $response = $response . $inputLine . "\r\n";
#
# while ($inputLine ne ""){
# $inputLine = [$in readLine];
# $response = $response . $inputLine . "\r\n";
# }
#
# [$in close];
#
# elog("POST" . ": " . $url . ": " . $responseCode);
# elog($response);
#
# return $response;
#
#
# }
# sub sendget{
#
# $url = $1;
#
# $USER_AGENT = "Mozilla/5.0 cs-matrix-hookshot/$version";
#
#
# $urlobj = [new URL: $url];
#
# $con = [$urlobj openConnection];
#
# [$con setRequestProperty: "User-Agent", $USER_AGENT];
#
# [$con setRequestMethod: "GET"];
#
# $responseCode = [$con getResponseCode];
#
# $in = [new BufferedReader: [new InputStreamReader: [$con getInputStream]]];
#
# $inputLine = "";
#
# $response = "";
#
# $inputLine = [$in readLine];
# $response = $response . $inputLine . "\r\n";
#
# while ($inputLine ne ""){
# $inputLine = [$in readLine];
# $response = $response . $inputLine . "\r\n";
# }
#
# [$in close];
#
# #elog($method . ": " . $url . ": " . $responseCode);
# #elog($response);
#
# return $response;
#
#
# }
on ready {
elog("Matrix-hookshot notifications are now configured!");
webhook("Cobalt Strike: Notification Configuration Status","matrix-hookshot notifications now configured");
}
#on event_notify {
# $time = formatDate($2, "yyyy.MM.dd 'at' HH:mm:ss z");
# webhook("Cobalt Strike: System Event","$time $+ : $1");
#}
on event_join {
$time = formatDate($2, "yyyy.MM.dd 'at' HH:mm:ss z");
webhook("Cobalt Strike: User Joined","$time $+ : $1 has joined");
}
on event_action {
$time = formatDate($2, "yyyy.MM.dd 'at' HH:mm:ss z");
webhook("Cobalt Strike: Action Performed","$time $+ : < $+ $3 $+ >: $1 ");
}
on event_public {
$time = formatDate($3, "yyyy.MM.dd 'at' HH:mm:ss z");
webhook("Cobalt Strike: New Message","$time $+ : [" . $1 . "]: " . $2 );
}
on event_quit {
$time = formatDate($2, "yyyy.MM.dd 'at' HH:mm:ss z");
webhook("Cobalt Strike: User Exit","$time $+ : $1 has quit");
}
on ssh_initial {
webhook("Cobalt Strike: New SSH Session", "New SSH Session Received - ID: $1 | Hostname " . binfo($1, "computer"));
}
on profiler_hit {
webhook("Cobalt Strike: Profiler Hit","Profiler Hit Received - External: $1 | Internal: $2 | UA: $3 | Email: " . tokenToEmail($5));
}
on web_hit {
# elog($1);
if ($1 == "POST" && $5 == "404 Not Found"){
$time = formatDate($9, "yyyy.MM.dd 'at' HH:mm:ss z");
$vuri = $2;
$eval = strrep($vuri, $uri, "");
# eval contains final bid number to exit
bexit($eval);
}
}
on beacon_initial {
if (-isadmin $1){
webhook("Cobalt Strike: New Beacon","New Beacon Received - ID: $1 | User: " . binfo($1, "user") . " | Hostname: " . binfo($1, "computer") . " | PID: " . binfo($1,"pid") . " | HOST: " . binfo($1,"host") . " | ADMIN BEACON | " . " | IP: " . binfo($1, "external"), $1);
$elog = "New Beacon Received - ID: $1 | User: " . binfo($1, "user") . " | Hostname: " . binfo($1, "computer") . " | PID: " . binfo($1,"pid") . " | HOST: " . binfo($1,"host") . " | ADMIN BEACON | " . " IP: " . binfo($1, "external");
}
else {
webhook("Cobalt Strike: New Beacon","New Beacon Received - ID: $1 | User: " . binfo($1, "user") . " | Hostname: " . binfo($1, "computer") . " | PID: " . binfo($1,"pid") . " | HOST: " . binfo($1,"host") . " | " . " | IP: " . binfo($1, "external"), $1);
$elog = "New Beacon Received - ID: $1 | User: " . binfo($1, "user") . " | Hostname: " . binfo($1, "computer") . " | PID: " . binfo($1,"pid") . " | HOST: " . binfo($1,"host") . " | IP: " . binfo($1, "external");
}
elog("\x039".$elog);
}
sub webhook {
$title = $1;
$message = $2;
# $body = "token=" . $token . "&user=" . $user . "&title=" . $title . "&message=" . $message;
# {"username": "matrix-hookshot-cs", "html": "\"<h2>$title</h2><br><p>$message<\p>\"", "text": "$title\r\n$message"}
$body = '{"html":' . "\"<h4>" . $title . "</h4><code>" . $message . "</code>\"," . '"text": ' . "\"". $title . "%0a%0d" . $message . "\"}";
# We'll use fork so we won't be blocking. Now it can work nicely in either the UI or loaded with agscript
fork(&sendpost, $1 => $location, $2 => $body);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment