Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Powershell Improvements - Auto Arch Detection, Size Reduction #2557

Closed
wants to merge 130 commits into from

Conversation

Meatballs1
Copy link
Contributor

This is basically my PR to @sempervictus's branch #2075

It builds a better framework for performing Powershell command execution -> shellcode execution.

One of the main features I'm trying to do is that powershell will spawn the correct process for the payload architecture.

More and more modules are starting to poke at the powershell functionality so I would rather get these in earlier rather than later.

Specced

Some may not be the best specs ever written but at least they exercise most code paths

rspec spec/lib/rex/exploitation/powershell* spec/lib/msf/core/exploit/powershell_spec.rb 
Msf::Exploit::Powershell ...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Rex::Exploitation::Powershell::Function ..
Rex::Exploitation::Powershell::Obfu .........
Rex::Exploitation::Powershell::Output ..............
Rex::Exploitation::Powershell::Param .
Rex::Exploitation::Powershell::Parser ...........
Rex::Exploitation::Powershell::PshMethods .....
Rex::Exploitation::Powershell::Output ...
Rex::Exploitation::Powershell ...

Finished in 4.29 seconds
543 examples, 0 failures

capture

Features

  • The payload auto detects the architecture of the runtime environment that it is executed within. This allows it to spawn a new powershell process if the shellcode targets a different architecture. This means powershell exploits have an Automatic target rather than specifying x86/x64. Obviously this doesn't work with x64 shellcode on an x86 target but x86 shellcode should be properly universal.
  • It reduces the size of the final payload. This means we can execute a full meterpreter payload in a fully base64 encoded -e command around < 5700 chars. This makes the cmd exec a lot more usable as there are a lot less bad characters to worry about.
  • Unencoded payloads can be generated < 2200 characters which could be helpful if command injection is more limited in size. (By editing the source powershell we should be able to drop this further).
  • More flexible techniques for generating powershell command lines and arguments are used so these aren't hardcoded strings within modules. No more gsubbing of bad characters if possible!

Options

cmd_psh_payload options:

  • :use_single_quotes => Encapsulates the final -c command in single quotes. e.g. -c 'echo 1' (~2200)
  • :encode_inner_payload => b64 encodes the inner payload (~5230)
  • :encode_final_payload => b64 encodes the final payload e.g. -e blah. (~5700)
  • :remove_comspec => Remove %COMSPEC% and just rely on powershell.exe.
  • :no_full_stop => Remove .exe from powershell (incase . is a bad char)
  • :no_equals => Remove == from base64 encoded final payload (incase = is a bad char)
  • :shorten => Shorten command line args e.g. -Command -> -c

Update Modules

Current modules that need to be fixed up regarding these changes:

  • windows/http/oracle_endeca_exec
  • windows/local/current_user_psexec
  • windows/local/ms13_005_hwnd_broadcast
  • windows/local/wmi
  • windows/browser/ie_unsafe_scripting
  • windows/smb/psexec_psh
  • windows/misc/psh_web_delivery
  • windows/local/powershell_cmd_upgrade.rb
  • windows/misc/hp_dataprotector_exec_bar.rb

Potential PR conflicts:

#2551

#2307

#2468

#2402

Verification: Auto Arch Targeting using psh_web_delivery

  • x86 payload on x86 system
  • x86 payload on x64 Process
  • x86 payload on SYSWOW64 Process
  • x64 payload on x64 Process
  • x64 payload on SYSWOW64 Process

g0tmi1k and others added 30 commits July 4, 2013 13:27
If the regex fails then the entire moudle would too
Add Rex powershell parser:
 reads PSH, determines functions, variables, blocks
 compresses and cleans up the code it's read, obfuscates
 handles string literals and reserved variable names
 extracts code blocks and functions for reuse
  turns powersploit into a useful sub-component for MSF
Rewire Msf powershell modules
 Make use of Rex parser
 Handles payload generation, substituions
 Brings convenience methods - byte array generation and download
 Re-add .NET compiler
  Compiles .NET code (C#/VB.NET) in memory
  Can generate binary output file (dynamic persistence)
  Handles code-signing (steal cert with mimikatz, sign your bin)
  Not detected by AV (still...)
 Update payload generation
  GZip compression and decompression (see Rex module as well)
  msftidy violations for space efficiency - each char counts
Re-submit psexec-psh
 Makes use of updated Msf and Rex modules
 Runs shellcode in-memory (in a hidden PSH window)
 Completely bypasses all AVs tested for the last year...
@g0tm1lk: no clue, you must've pwned me in your sl33p. :)
Resolve conflicts from old code being pulled into master.

Conflicts:
	lib/msf/core/exploit/powershell.rb
	modules/exploits/windows/smb/psexec_psh.rb
Remove .NET compiler, post lib and modules.
This is temporary and rather messy. Since the internals for
dealing with PSH code have moved to Rex there may be a hiccup or
two here. This was my original attempt at basic PSH integration
and does not make use of the new libraries and namespaces in
this PR.

Will introduce the updated modules and libraries in separate PR.
Replace powershell lib which snuck in as psexec_psh.
Introduce psexec_psh module which uses the Rex and Msf PSH
methods provided in the lib import.
… psh_merge

Conflicts:
	modules/exploits/windows/smb/psexec_psh.rb
Looks good from here, though we may want to address the all caps opt names.
@sempervictus
Copy link
Contributor

@Meatballs1 check your repo, i think we got out of sync in Post. I've re-added my Post module to your branch with some fixup. I'll PR DotNet and associated Psh/DotNet modules once this lands, so as not to keep this held up any longer.

@Meatballs1
Copy link
Contributor Author

Will look to merge in your Post stuff when we get this landed :)

@sempervictus
Copy link
Contributor

Please whack me when we have a window? I should have some more code to push
in a bit.

On Fri, Jun 20, 2014 at 5:50 PM, Meatballs1 [email protected]
wrote:

Will look to merge in your Post stuff when we get this landed :)


Reply to this email directly or view it on GitHub
#2557 (comment)
.

@Meatballs1 Meatballs1 closed this Jul 15, 2014
@sempervictus
Copy link
Contributor

Did this die on the vine or are we rebasing somewhere? There's a lot of useful work in here...

@Meatballs1
Copy link
Contributor Author

I'm going to re-open it when other PR gets landed. I cant keep updating 19 PRs when they are just sat around gathering no love :(

@sempervictus
Copy link
Contributor

@Meatballs1 I feel your pain on the open PRs, though i've learned to see it as a sort of compliment that our work requires serious review. However, if we drop this out of the active queue it will never hit, and i assume you probably have derived work internally as well by now. I spend too much time merging upstream with my work, and have moved most of my really scandalous code into plugins, but if this doesnt merge then at least you and i will, again, be cleaning out interrim-submitted hackery to get around PSH idiosyncrasies to accomplish what we have here (without the "good practices").
I vote we re-open and nag @todb-r7 until its committed or @hmoore-r7 turns us into toads ;)
I can re-PR the thing if you want me to have stewardship over this, but TBH you've been invaluable in getting this work into upstream both in terms of code and diplomatic effort with the powers that be.

@r7 This is a healthy body of work with a ton of value. It comes up in almost every discussion i have with client security staff and AV vendors have asked about it after realizing it walks lazy circles around them. Moreover, since R7 bases the commercial offering on the framework, one could reason that the capabilities this exposes would be of significant value to paying customers.

@devs, aside from the need to sleep and eat on occasion, is there anything we can address which is holding up this PR?

end

vprint_status("Powershell command length: #{command.length}")
if command.length > 8191
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8191 or 8192? In the unlikely event that the command is exactly 8192 characters, this will incorrectly raise (or the error message is incorrect, depending on your POV)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CR space? I think the original code was 8192, but this actually makes more sense. I believe we can thank @Meatballs1 for catching that.

(sorry for the edit, original response was sent from mobile mail client)

On Jul 16, 2014 3:19 PM, "Jon Hart" [email protected] wrote:

In lib/msf/core/exploit/powershell.rb:

  •    final_payload = "'#{final_payload}'"
    
  •  end
    
  •  command_args[:command] = final_payload
    
  • end
  • psh_command = generate_psh_command_line(command_args)
  • if opts[:remove_comspec]
  •  command = psh_command
    
  • else
  •  command = "%COMSPEC% /b /c start /min #{psh_command}"
    
  • end
  • vprint_status("Powershell command length: #{command.length}")
  • if command.length > 8191

8191 or 8192? In the unlikely event that the command is exactly 8192
characters, this will incorrectly raise (or the error message is incorrect,
depending on your POV)


Reply to this email directly or view it on GitHub
https://github.com/rapid7/metasploit-framework/pull/2557/files#r15021129
.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was probably the case but I can't remember for sure now :)

@Meatballs1
Copy link
Contributor Author

@sempervictus My plan was to re-open this as my only PR except @scriptjunkie had some momentum on my other pull so was hoping for that to land. Then I can continue with just one PR at a time. Having this open was also making me not want to land any other Powershell stuff as it just meant more additional work and testing for me :(

This needs fixing up against:

modules/exploits/multi/script/web_delivery
exploits/windows/local/ms14_009_ie_dfsvc
exploits/windows/local/ms13_097_ie_registry_symlink

as well as potential conflicts with #2585

# @param target [String] Location to save the file
#
# @return [String] Powershell code to download a file
def self.download(src,target=nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the behavior when no location to save the file to? I'm assuming that it it just drops it in pwd much like most downloader-like tools, but it might be worth being explicit here in the documentation (since you took the time to write it and it is so nice)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should throw a 'WebException' if filename is null or Empty.

I will modify this so it doesn't take a default

@hdm
Copy link
Contributor

hdm commented Jul 16, 2014

Offhand, the use of str[start...end] versus str[start,length] seems wrong in a few places. It seems a few exploit modules are still broken or not compatible with this change based on the checkboxes above. As for why it is blocked @sempervictus , see @Meatballs1 comment above.

@hdm hdm reopened this Jul 16, 2014
@Meatballs1
Copy link
Contributor Author

Nb the unchecked modules above probably are compatible, just i havent had environment to test (a few I have tested in previous iterations but haven't got round to in latest commit). I dont forsee any issues with these

@Meatballs1
Copy link
Contributor Author

@hmoore-r7 Whats wrong with string[range]?

@Meatballs1
Copy link
Contributor Author

I have come to the conclusion this is just pre-commit fixes to @sempervictus's code originally submitted in January 2013 and there's no reason to delay any further.

@Meatballs1 Meatballs1 closed this Jul 30, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants