From my experience the RFC Gateway security is for many SAP Administrators still a not well understood topic. As a result many SAP systems lack for example of proper defined ACLs to prevent malicious use.
After an attack vector was published in the talk “SAP Gateway to Heaven” from Mathieu Geli and Dmitry Chastuhin at OPDCA 2019 Dubai (https://github.com/gelim/sap_ms) the RFC Gateway security is even more important than ever. This publication got considerable public attention as 10KBLAZE.
With this blogpost series i try to give a comprehensive explanation of the RFC Gateway Security:
Part 5: ACLs and the RFC Gateway security.
ACLs and RFC Gateway security
In the previous parts we had a look at the different ACLs and the scenarios in which they are applied. Maybe some security concerns regarding the one or the other scenario raised already in you head. So let’s shine a light on security.
Please make sure you have read part 1 to part 4 of this series to be familiar with the basics of the RFC Gateway and the terms i use to describe things.
Which rules are activated by default?
The default rules in reginfo and secinfo ACL mentioned in part 2 and part 3 are enabled if either profile parameter ‘gw/acl_mode = 1’ is set or if ‘gw/reg_no_conn_info’ includes the value ’16’ in its bit mask and if no custom ACLs are defined.
If these profile parameters are not set the default rules would be the following allow all rules:
P TP=* USER=* USER-HOST=* HOST=*
The default rule in prxyinfo ACL mentioned in part 4 is enabled if no custom ACL is defined. This is an allow all rule. At time of writing this can not be influenced by any profile parameter.
What about the syntax of the reginfo, secinfo ACL?
The syntax used in the reginfo, secinfo and prxyinfo changed over time. It is strongly recommended to use syntax of Version 2, indicated by
#VERSION=2in the first line of the files.
Furthermore the means of some security checks have been changed or even fixed over time. To use all capabilities it is necessary to set the profile parameter ‘gw/reg_no_conn_info = 255’.
What is the keyword ‘local’ about?
The keyword ‘local’ will be substituted at evaluation time by a list of ip-addresses belonging to the host of the RFC Gateway. This also includes the loopback address 127.0.0.1 as well as its IPv6 equivalent “::1”.
What is the keyword ‘internal’ about?
The keyword ‘internal’ will be substituted at evaluation time by a list of hostnames of application servers in status ‘ACTIVE’ which is periodically sent to all connected RFC Gateways. This list is gathered from the Message Server every 5 minutes by the report ‘RSMONGWY_SEND_NILIST’. In addition to these hosts it also covers the hosts defined in the profile parameters ‘SAPDBHOST’ and ‘rdisp/mshost’.
Since this keyword is relying on a kernel feature as well as an ABAP report it is not available in the internal RFC Gateway of SAP NW AS Java.
A Stand-alone Gateway could utilise this keyword only after it was attached to the Message Server of AS ABAP and the profile parameter ‘gw/activate_keyword_internal’ was set.
To prevent the list of application servers from tampering we have to take care which servers are allowed to register themselves at the Message Server as an application server.
The message server port which accepts registrations is defined by profile parameter ‘rdisp/msserv_internal’.
Limiting access to this port would be one mitigation. In addition to proper network separation, access to the message server ports can be controlled on network level either in general by the ACL file specified by profile parameter ‘ms/acl_file’ or more specific to the internal port by the ACL file specified by profile parameter ‘ms/acl_file_int’.
It also could be restricted on the application level by the ACL file specified by profile parameter ‘ms/acl_info’.
Another mitigation would be to switch the internal server communication to TLS by setting the profile parameter ‘system/secure_communication = ON’. This makes sure application servers must have a trust relation in order to take part of the internal server communication. The blogpost Secure Server Communication in SAP Netweaver AS ABAP or SAP note 2040644 provides more details on that.
A combination of these mitigations should be considered in general.
What to consider in general when maintaining reginfo, secinfo or prxyinfo ACL?
When editing these ACLs we always have to think from the perspective of each RFC Gateway the ACLs are applied to.
Pretend as if you would maintain the ACLs of a stand-alone RFC Gateway. Remember the AS ABAP or AS Java is just another RFC client to the RFC Gateway.
Should a custom reginfo or secinfo ACL contain a deny all rule at the end?
While it was recommended by some resources to define a deny all rule at the end of reginfo, secinfo ACL this is not necessary. There is a hardcoded implicit deny all rule which can be controlled by the parameter ‘gw/sim_mode’. The simulation mode is a feature which could help to initially create the ACLs.
Is the default rule of reginfo ACL safe for use?
As we learned in part 2 SAP introduced the following internal rule in the in the reginfo ACL:
P TP=* HOST=internal,local ACCESS=internal,local CANCEL=internal,local
While it is common and recommended by many resources to define this rule also in a custom reginfo ACL as the last rule, from a security perspective it is not an optimal approach.
With this rule applied any RFC enabled program on any of the servers covered by the keyword ‘internal’ is able to register itself at the RFC Gateway independent from which user started the corresponding executable on OS level (again refer to 10KBLAZE). With this rule applied you should properly secure access to the OS (e.g., verify if all existing OS users are indeed necessary, SSH with public key instead of user+pw).
In an ideal world each program alias of the relevant ‘Registered Server Programs’ would be listed in a separate rule, even for registering from one of the hosts of ‘internal’.
What to consider especially when maintaining custom rules in the reginfo ACL?
All of our custom rules should bee allow rules.
Every attribute should be maintained as specific as possible. The wildcard should be strongly avoided. In case of ‘TP Name’ this may not be applicable in some scenarios. There we should look for patterns which can be used with an ending wildcard in order to reduce the effective values, e.g., for the ‘TP Name’ of SAP Trex this could be
Please note: The wildcard ‘*’ is per se supported at the end of a string only.
Is the default rule of secinfo ACL safe for use?
As we learned in part 3 SAP introduced the following internal rule in the in the secinfo ACL:
P USER=* USER-HOST=internal,local HOST=internal,local TP=*
While it is common and recommended by many resources to define this rule also in a custom secinfo ACL as the last rule, from a security perspective it is not an optimal approach.
With this rule applied for example any user with permissions to create or edit TCP/IP connections in transaction SM59 would be able to call any executable or script at OS level on the RFC Gateway server in the context of the user running the RFC gateway process.
Depending on the settings of the reginfo ACL she could also misuse this permissions to start a program which registers itself on the local RFC Gateway, e.g.,:
the program still will be started and will be running on the OS level, and furthermore it could register itself at the local RFC Gateway:
There are also other scenarios imaginable in which no previous access along with critical permission in SAP would be necessary to execute commands via the RFC Gateway. In the slides of the talk “SAP Gateway to Heaven” for example a scenario is outlined in which a SAProuter installed on the same server as the RFC Gateway could be utilized to proxy a connection to ‘local’.
Benign programs to be started by the local RFC Gateway of a SAP NetWeaver AS are typically part of the SAP Kernel and located in the $(DIR_EXE) of the application server. Unfortunately, in this directory are also the Kernel programs ‘saphttp’ and ‘sapftp’ which could be utilized to retrieve or exfiltrate data. So
TP=/usr/sap/<SAPSID>/<Instance>/exe/* might not be a good solution for high security systems, but still better than the default rules.
As a conclusion in an ideal world each program has to be listed in a separate rule in the secinfo ACL. Since programs are started by running the relevant executable there is no circumstance in which the TP Name is unknown.
What to consider especially when maintaining custom rules in the secinfo ACL?
All of our custom rules should bee allow rules.
Every attribute should be maintained as specific as possible. The wildcard ‘*’ should not be used at all.
Is the default rule of prxyinfo ACL safe for use?
As we learned in part 4 SAP introduced the following internal rule in the in the prxyinfo ACL:
P SOURCE=* DEST=*
Since proxying to circumvent network level restrictions is a bad practice or even very dangerous if unnoticed the following rule should be defined in a custom prxyinfo:
D SOURCE=* DEST=*
If there is a scenario where proxying is inevitable this should be covered then by a specific rule in the prxyinfo ACL of the proxying RFC Gateway above the rule mentioned before, e.g.,:
P SOURCE=<hosts-SRC> DEST=<hosts-TGT>
What to consider when maintaining custom rules in the secinfo ACL?
All of our custom rules should bee allow rules.
Every attribute should be maintained as specific as possible. The wildcard ‘*’ should be avoided wherever possible.
A custom allow rule has to be maintained on the proxying RFC Gateway only.
Please note: The proxying RFC Gateway will additionally check its reginfo and secinfo ACL if the request is permitted. In secinfo for example if a rule like the following exists:
P USER=<username> USER-HOST=<SOURCE> HOST=<DEST> TP=<TP-Name>
What about starting executables on remote servers?
If we do not have any scenarios which relay on this use-case we are should disable this functionality to prevent from misuse by setting profile parameter
gw/rem_start = DISABLED otherwise we should consider to enforce the usage of SSH by setting
gw/rem_start = SSH_SHELL.