Skip to content

Conversation

sempervictus
Copy link
Contributor

This pull request incorporates prior work submitted in
various PRs including 701 and 705. Since several PRs
never made it into trunk, SVIT's in-house framework
has diverged in a few places and modules making use
of those changes suffer in trunk.

Given the interest shown by viewers of the
thelightcosine's webcast in powershell techniques, i
believe it appropriate to re-submit the changes and sync
the core libs used in-house with R7 master, as well
as providing some of the modules derived from the
changes in lib.

I believe we still have some localization issues and other
kinks to work out with the modules and PSH code
therein, so testing and commentary are very welcome.

Powershell commentary and TODO:

Its been over a year since we started adding Powershell to
framework and at this point the argument of "its not widely
used" no longer carries as much weight. Ideally some of
the work stubbed out in Post would move in Rex itself in
the same manner we handle other languages we modify.

Syntax parsing will lead to better obfuscation as the current
approach is going to be pretty easy to unwrap once they
get their heads around it. A PSH native shell set would
also be a good idea, although work i've seen so far is not
there yet (its been a while, i shall re-check). Native use of
SSL sockets to pull stage2 would be preferable to
the standard rev_tcp stage1, and with cert validation can
provide a much more secure transfer method.
Darkoperator and others have written PSH cryptors,
which coupled with the currently used obfuscation
techniques provide a higher level of evasion...

Technically speaking, the post execution method only requires
meterpeter to read the channel, so PSH is a good way to
get a meterpreter session out of command line execution
(see PR 1343). I welcome discussion and suggestions for
updating the post libs to handle command sessions as well.

@kernelsmith
Copy link
Contributor

What is SVIT?

@sempervictus
Copy link
Contributor Author

SVIT is Semper Victus, the two commits are mass imports from an internal repo to GH. Its basically for review and alteration for framework acceptance - i expect this will be broken up into separate PRs per devs and each piece will change to conform to standards, fix bugs i missed, etc, before hitting trunk.

sempervictus pushed a commit to sempervictus/metasploit-framework that referenced this pull request Jan 30, 2013
@sempervictus
Copy link
Contributor Author

I've removed all modules and cleaned up the libraries into Post and Exploit as sensible. I've also updated the psexec_psh PR, #1343 to reflect these changes.

@dmaloney-r7 - the compression trick discussed on the webcast is now in Exploit::Powershell, and i've updated the cmd payload generation to work with psh 1.0 (see #1343 for example) out of the box.

sempervictus pushed a commit to sempervictus/metasploit-framework that referenced this pull request Feb 5, 2013
The original module suffered from a small problem - interactive
process notification from Desktop 0 for users currently logged in.
Although acheiving full AV evasion, we were setting off UserAlert.
This commit updates the module itself to match rapid7#1379 in R7's repo.
The size of powershell payloads has been reduced, and a wrapper
added to hide the actual payload process entirely.
@darkoperator
Copy link
Contributor

I believe that for clean up it would be better for you to track the PID of the original PoweShell process and use that to look for other powershell processes that have that one as the PPID and kill only those so as to not impact any other running PowerShell process in the target box.

# pid is the pid of the powershell.exe that launched the script or command.
# Finding PIDs of processes created
  session.sys.process.processes.each do |proc|
      pids << proc['pid'] if (proc["ppid"] == pid.to_i)
   end
   if pids.length >> 0
       # add original process pid to the list
       pids << pid

       # terminating processes
       pids.each do |p|
           session.sys.process.kill(p)
       end
   else
        session.sys.process.processes.each do |proc|
             if (proc["pid"] == pid.to_i)
                 session.sys.process.kill(pid)
             end
         end
   end

@sempervictus
Copy link
Contributor Author

Would be a more concise cleanup method, but IIRC, it leaves behind pids which dont register the original psh process as the parent ID. This tends to happen when you create new powershell instances from unmanaged memory, or with a different runtime (take a look at the .net compiler). WMI based invocations also fall off the kill list, etc etc. There's nothing like having a runaway psh process hogging system resources to ruin your pentest and get someone's attention.

@darkoperator
Copy link
Contributor

There is also nothing like killing the wrong PowerShell process and messing up something for the client on the box that he is running, that would be worst that a process hugging 100% CPU or something similar, specially now that so much of the MS enterprise products depend on it. also WMI runs under comhost under the PowerShell process that initiated it, same for jobs, same for runspaces and same for workflows, what you mention is the least common scenario. I really do not like the scorch earth approach of killing all powershell.exe processes those one created or not, there has to be a better way to track what you have launched for clean up.

@sempervictus
Copy link
Contributor Author

Powershell is not so often used by most Windows users that they are likely to instantiate a PID during the runtime of most of our scripts (because we only kill pids which are not present in the list of powershells already running at exec time). Moreover, you can modulate how much killing occurs :).

Grab a diff and try it, it shouldnt kill existing powershell PIDs. Two potential problems exist with my approach - long running scripts on a development environment where powershell is often used, and the low probability chance that someone starts a powershell script while we run our powershell post-exploitation abuses. All that can be avoided by running psh stand-alone with output to files in those environments.

Post libs like this are a stop-gap, we need a powershell-xml-parsing meterpreter extension to perform our PSH I/O instead of this hackery.

@darkoperator
Copy link
Contributor

Yep that would work :) right now backing up Hyper-V machines is done via PowerShell so is Exchange managements tasks and maintenance, same for System Center Operations Manager so not killing existing ones would save from messing those up.

end
psh << lines.join("") + "\r\n\r\n"
# Set up the payload string, see psh_net for formatting reason
psh << "[Byte[]]$#{var_code} = #{Rex::Text.to_hex(code).gsub('\x',',0x')[1..-1]}\r\n"
Copy link
Contributor

Choose a reason for hiding this comment

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

Rex::Text.to_hex() expects a string but code is unpacked to an array on line 1138 causing a NoMethodError undefined method `unpack' for #Array:0xb38ca510

RageLtMan added 11 commits April 2, 2013 20:23
Revert "import SVIT powershell post modules"

This reverts commit ce48f13.
This commit separates out the core powershell mechanisms for working
with the platform from those required to work in a post-exploitation
setting. Msf::Exploit::Powershell namespace now carries everything
required for psexec_psh, and adds the DotNet namespace to generate
powershell for building .NET code ( C# works currently, VB not yet
tested). The Post namespace has been modified accordingly, and
there are no modules depending on this code in Framework as of yet.

The idea behind this separation comes from Exploit::PDF which is a
staging ground for the data format, without communication protocols
or anything network related.
@sempervictus
Copy link
Contributor Author

@Meatballs1 you sir are entirely correct, resolved, thank you.
@devs rebased off of current master

@Meatballs1
Copy link
Contributor

Closing this in favour of more recent PR: #2075

@Meatballs1 Meatballs1 closed this Sep 16, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants