-
-
Save EspressoCake/7ba2371d9d6f7d3a6b0077563f819d36 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#################################################################################### | |
# Author(s): Justin Lucas (@the_bit_diddler) and Fletcher Davis (@gymR4T) # | |
# Date: January 6, 2022 # | |
#################################################################################### | |
#################################################################################### | |
# Notes: This script is meant to be headless via ./agscript .... # | |
# It will keep track of initial beacon metadata, in case # | |
# they are cleared from the UI. # | |
# # | |
# 1) To have the JSON metadata generated: # | |
# - From the "Event Log" window: !fetch_json_archive # | |
# # | |
# 2) To pull the JSON log: # | |
# - Retrieve the logfile from the teamserver, via the provided path # | |
#################################################################################### | |
global('%beaconHashmap'); | |
# Initialize to nothing, keeping it all tidy | |
%beaconHashmap = %(); | |
on beacon_initial { | |
$beacon = binfo($1); | |
if ($1 in keys(%beaconHashmap)) { | |
} else { | |
$beacon['initial_hit'] = ticks(); | |
$beacon['admin_session'] = fetchIsAdmin($1); | |
%beaconHashmap[$1] = $beacon; | |
} | |
} | |
sub enrichArchiveLog { | |
local('$logitem'); | |
local('@carray'); | |
local('$cTime'); | |
local('$attributeIndex'); | |
$attributeIndex = 1; | |
foreach $logitem (archives()) { | |
if ( ($logitem['type'] ne "checkin") && ($logitem['type'] ne "webhit") && ("bid" in keys($logitem)) ) { | |
local('$currentData'); | |
# Replace double quotes to keep JSON from breaking | |
$currentData = replace($logitem['data'], '"', "'"); | |
# Replace backslashes with forward-slashes to keep JSON from breaking | |
$currentData = replace($currentData, '\\\\', '/'); | |
$logitem['data'] = $currentData; | |
$cTime = $logitem['when']; | |
$logitem['when_friendly'] = dstamp($logitem['when']); | |
$logitem['index_value'] = $attributeIndex; | |
if ( strlen(binfo($logitem['bid'], "computer")) > 0 ) { | |
$logitem['host_context_admin'] = fetchIsAdmin($logitem['bid']); | |
$logitem['host_computername'] = binfo($logitem['bid'], "computer"); | |
$logitem['host_external'] = binfo($logitem['bid'], "external"); | |
$logitem['host_internal'] = binfo($logitem['bid'], "internal"); | |
$logitem['host_listener'] = binfo($logitem['bid'], "listener"); | |
$logitem['host_os_distribution'] = binfo($logitem['bid'], "os"); | |
$logitem['host_os_build_version'] = binfo($logitem['bid'], "build"); | |
$logitem['host_os_build_revision'] = binfo($logitem['bid'], "ver"); | |
$logitem['host_process_id'] = binfo($logitem['bid'], "pid"); | |
$logitem['host_process_name'] = binfo($logitem['bid'], "process"); | |
$logitem['host_session_type'] = binfo($logitem['bid'], "session"); | |
$logitem['host_username'] = binfo($logitem['bid'], "user"); | |
if ($logitem['bid'] in keys(%beaconHashmap)) { | |
if (($cTime - %beaconHashmap[$logitem['bid']]['initial_hit']) < 0) { | |
%beaconHashmap[$logitem['bid']]['initial_hit'] = $cTime; | |
} | |
$logitem['host_initial_compromise'] = %beaconHashmap[$logitem['bid']]['initial_hit']; | |
$logitem['host_initial_compromise_friendly'] = dstamp(%beaconHashmap[$logitem['bid']]['initial_hit']); | |
$logitem['host_action_delta'] = $cTime - %beaconHashmap[$logitem['bid']]['initial_hit']; | |
} | |
} else if ( $logitem['bid'] in keys(%beaconHashmap) ) { | |
$logitem['host_context_admin'] = %beaconHashmap[$logitem['bid']]['admin_session']; | |
$logitem['host_computername'] = %beaconHashmap[$logitem['bid']]['computer']; | |
$logitem['host_external'] = %beaconHashmap[$logitem['bid']]['external']; | |
$logitem['host_internal'] = %beaconHashmap[$logitem['bid']]['internal']; | |
$logitem['host_listener'] = %beaconHashmap[$logitem['bid']]['listener']; | |
$logitem['host_os_distribution'] = %beaconHashmap[$logitem['bid']]['os']; | |
$logitem['host_os_build_version'] = %beaconHashmap[$logitem['bid']]['build']; | |
$logitem['host_os_build_revision'] = %beaconHashmap[$logitem['bid']]['ver']; | |
$logitem['host_process_id'] = %beaconHashmap[$logitem['bid']]['pid']; | |
$logitem['host_process_name'] = %beaconHashmap[$logitem['bid']]['process']; | |
$logitem['host_session_type'] = %beaconHashmap[$logitem['bid']]['session']; | |
$logitem['host_username'] = %beaconHashmap[$logitem['bid']]['user']; | |
if (($cTime - %beaconHashmap[$logitem['bid']]['initial_hit']) < 0) { | |
%beaconHashmap[$logitem['bid']]['initial_hit'] = $cTime; | |
} | |
$logitem['host_initial_compromise'] = %beaconHashmap[$logitem['bid']]['initial_hit']; | |
$logitem['host_initial_compromise_friendly'] = dstamp(%beaconHashmap[$logitem['bid']]['initial_hit']); | |
$logitem['host_action_delta'] = $cTime - %beaconHashmap[$logitem['bid']]['initial_hit']; | |
} | |
$attributeIndex++; | |
add(@carray, $logitem, size(@carray)); | |
} | |
} | |
return @carray; | |
} | |
sub fetchIsAdmin { | |
if (-isadmin $1) { | |
return "1"; | |
} | |
return "0"; | |
} | |
sub writer { | |
local('$handle'); | |
local('$filename'); | |
local('$currentTick'); | |
$currentTick = ticks(); | |
$handle = openf(">" . script_resource("/") . $currentTick . "_output.json"); | |
println($handle, $1); | |
closef($handle); | |
return "JSON-formatted history written to: " . script_resource("/") . $currentTick . "_output.json"; | |
} | |
sub stringifyHashmap { | |
local('$individualItem'); | |
local('$individualKeys'); | |
local('$stringRepresentation'); | |
local('$endOfObject'); | |
local('$cindex'); | |
$endOfObject = size($1) - 1; | |
$cindex = 0; | |
$stringRepresentation = '[' . "\n"; | |
foreach $individualItem ($1) { | |
$stringRepresentation .= "\t" . '{' . "\n"; | |
local('$keylength'); | |
$keylength = size(keys($individualItem)); | |
foreach $individualKeys (keys($individualItem)) { | |
if ($individualKeys ne keys($individualItem)[$keylength - 1]) { | |
$stringRepresentation .= "\t\t" . '"' . $individualKeys . '": "' . $individualItem[$individualKeys] . '"' . ",\n"; | |
} else { | |
$stringRepresentation .= "\t\t" . '"' . $individualKeys . '": "' . $individualItem[$individualKeys] . '"' . "\n"; | |
} | |
} | |
if ($cindex == $endOfObject) { | |
$stringRepresentation .= "\t" . '}' . "\n"; | |
} else { | |
$stringRepresentation .= "\t" . '},' . "\n"; | |
} | |
$cindex++; | |
} | |
$stringRepresentation .= ']' . "\n"; | |
return $stringRepresentation; | |
} | |
sub orchestrateTransition { | |
local('$cval'); | |
$cval = enrichArchiveLog(); | |
return writer(stringifyHashmap($cval)); | |
} | |
on event_public { | |
local('$user $content $when'); | |
$user = $1; | |
$content = $2; | |
$when = $3; | |
if ($2 ismatch '!fetch_json_archive') { | |
say("Generating JSON archive for you now, " . $user); | |
privmsg($user, orchestrateTransition()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment