Skip to main content
SAP Pentest Playbook
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage
Edit page

Lateral Movement Across SAP Landscapes

Description

SAP landscapes are rarely a single isolated system. They are graphs of trust: SM59 RFC destinations carrying stored credentials or trusted-system flags, MYSAPSSO2/STRUSTSSO2 ticket-issuer trust, SAProuter route permissions, shared <sid>adm/DB-user OS credentials across DEV->QAS->PRD tiers, and - in hybrid landscapes - Cloud Connector/SM59 Type-G bridges into SAP BTP. A foothold on any one node of this graph routinely reaches others, often systems of a higher security classification than the one first compromised (sandbox/DEV RFC destinations pointing into PRD is the classic case). This page catalogs the SAP-specific trust-graph pivots; generic OS-level lateral movement (Windows credential reuse, general SSH tradecraft) is referenced out to standard sources rather than reproduced.

Risk

An attacker who compromises one low-classification system inherits reach across every system that system’s stored RFC credentials, trusted-system relationships, SSO-ticket trust, or shared OS credentials extend to - frequently including production. Because most of these pivots require no new exploit (only an already-configured trust relationship), lateral movement across an SAP landscape is typically the highest-leverage, lowest-effort step in an engagement once any single system is owned. Impact spans confidentiality, integrity, and availability of every system reached, compounding with each hop (see post-exploitation for end-state business impact once a hop lands).

Options

RFC Trust Chains (SM59 Stored Credentials / Trusted-System S_RFCACL)

  • Stored dialog/technical-user credentials - an SM59 Type-3 destination carrying a stored user (dialog or technical) grants direct Remote Logon or RFC-call access to the target system under that user’s authorizations. Especially critical when the source system has a lower security classification than the target (sandbox->PRD, DEV->PRD, QAS->PRD).
  • Trusted-system relationship (SMT1/RFCTRUST/RFCSYSACL, authorization object S_RFCACL) - a passwordless pivot: any user holding S_RFCACL in the trusting system can log on as themselves in the trusted system with no password check at all. Distinct from and not to be confused with the Message Server/Gateway “betrusted” trust described below - SAP’s own naming overlaps but the mechanisms are unrelated.
  • S_RFC field granularity - inbound RFC execution is gated by S_RFC on fields RFC_TYPE (function group vs. single module), RFC_NAME, and ACTVT = 16 (execute). SAP deliberately withholds RFC_READ_TABLE from standard technical-user roles (e.g. Solution Manager READ/TMW users) precisely because it can read almost any table - so a stored technical RFC user that does carry it, or a wildcard S_RFC, is an outsized find on the far side of a hop.
  • Graph analysis / chain discovery - SAPMAP modules/postex/sapmap_chain.py: bounded BFS over every RFC destination + STRUSTSSO2 trust pair a session has already discovered, ranking reachable targets by severity and rendering a human headline (e.g. “S4H -> BTP:a1b2c3d4 -> ECP - Production reached in 2 hops [trusted RFC]”). Traversal only continues past a hop that is SAP_ALL-bearing, trusted-RFC, or a forged-ticket edge - a plain tested logon proves reachability but not onward pivot.
  • Discovery of the destination table itself - schedule report RSRFCCHK over the XBP background-job interface to enumerate every SM59 destination with a stored password, or read RFCDES directly via RFC_READ_TABLE.
  • Payload once a hop lands - the critical RFC-enabled function modules page (RFC_READ_TABLE, SXPG_*, RFC_ABAP_INSTALL_AND_RUN, BAPI_USER_CREATE1) is the standard payload set on the far side of any RFC pivot.
  • Manual equivalent: SM59 destination review + Remote Logon; SE16/SE16N on RFCDES/RFCTRUST/RFCSYSACL.
  • Cross-ref: Message Server Trust Injection into Gateway ACL (10KBLAZE “betrusted”) is a network-level trust bypass unrelated to S_RFCACL despite similar terminology.

SSO Ticket Replay (MYSAPSSO2)

  • Prerequisite: a forged ticket - see Forging SAP Logon Tickets (MYSAPSSO2) for the PSE-theft/forge primitive.
  • Replay across the trust graph - SAPMAP modules/exploitation/sap_ticket_propagate.py: replays the forged ticket over the HTTP cookie channel (Cookie: MYSAPSSO2=<base64> against ICF/WebGUI endpoints, classified by login-form/Set-Cookie heuristics) and the RFC channel (pyrfc.Connection(mysapsso2=<cookie>) + RFC_PING). Candidate-receiver set = every node sharing the issuer’s SID (self-trust - always works, a system trusts its own signing cert) plus an operator-supplied list drawn from the issuer’s STRUSTSSO2/TWPSSO2ACL (the tool does not itself enumerate that table). A ticket forged as a pinned assertion ticket (RecipientSID/RecipientClient) collapses the candidate set to just that one receiver.
  • Manual equivalent: curl -b "MYSAPSSO2=<b64>" https://host:port/sap/bc/... per candidate system; pyrfc.Connection(mysapsso2=<b64>) + RFC_PING.
  • Blast radius beyond self-SID is entirely bounded by how well the STRUSTSSO2 trust graph is scoped - review it per target as part of any assessment.

SAProuter Pivoting

  • See SAProuter Route-Permission Table Abuse (Open Proxy / niroute Pivot) for the full technique: NI_ROUTE tunneling through a permissive saprouttab, an ACL-aware port-probe side channel that maps internal reachability without completing a tunnel, and the “Trusted Router Hack” (daisy-chaining a second attacker-controlled SAProuter through the target’s own permissive route table when hop limits aren’t configured).
  • Once a tunnel is established, any other SAP protocol runs over it unmodified - chain into RFC Gateway 10KBLAZE / SAPXPG or Message Server Trust Injection against systems behind the SAProuter that are not otherwise externally reachable.

Shared Service Accounts Across DEV->QAS->PRD Tiers

  • Generic or shared dialog/technical users configured identically (same password, same RFC destination pattern) across development, quality-assurance, and production tiers turn a single compromised credential into landscape-wide access, independent of any RFC-destination trust - the credential itself is the pivot.
  • Where the shared account holds excessive S_RFC scope, chain into BAPI_USER_CREATE1 -> BAPI_USER_PROFILES_ASSIGN to mint a persistent SAP_ALL user in the higher-tier target.
  • Manual equivalent: SM59/SU01 cross-system user/credential comparison; review of RFC destinations whose stored user is identical across tiers.

On-Prem <-> BTP via Cloud Connector

  • On-prem -> BTP (credential harvest + token mint) - SAPMAP modules/exploitation/sap_onprem_to_btp.py: mines already-captured on-prem credential material - SM59 HTTP destinations with a decrypted SecStore password, OA2C_CLIENT/OA2C_CLIENT_EXT OAuth2 client profiles joined against their SecStore secret, raw RSECTAB, and Java SecStoreFS - for anything resolving to a *.hana.ondemand.com host, then mints a live BTP token three ways: (1) mint_btp_token() - plain HTTP Basic-Auth client_credentials grant against XSUAA /oauth/token; (2) mint_btp_token_via_cert() - mTLS/RFC 8705 client_credentials, kernel-proxied through the on-prem system’s own SM59 destination via RFC_ABAP_INSTALL_AND_RUN (a generated ABAP report opens the destination with CL_HTTP_CLIENT=>CREATE_BY_DESTINATION, so the on-prem kernel performs the mTLS handshake using its own STRUST PSE - the private key never leaves the kernel); (3) mint_btp_token_via_local_cert() - the same RFC 8705 flow issued directly from the operator host with a local cert/key pair (a documented workaround for a kernel 7.53 HTTP/2->1.1 chunked-response body-loss bug).
  • BTP -> on-prem (Destination-service credential hijack) - see Destination Service Abuse and SM59 Destination SSRF: the Destination service returns on-prem technical-user credentials in clear text to any caller holding a token scoped to read destination configuration, letting a BTP-side foothold pivot back down into the on-prem backend the destination points at.
  • Principal propagation abuse - see SAP Cloud Connector Principal Propagation Impersonation for identity-forwarding abuse specific to the Cloud Connector bridge, and SAP Cloud Connector Admin Access & Keystore/SSFS Extraction for extracting the Connector’s own credential material.
  • Prerequisite for the harvest step: prior on-prem Secure Store decryption (RSECTAB/SSFS) to recover cleartext secrets.
  • Manual equivalent: SE16/SE16N on RSECTAB, SM59 destination inspection, SU01/SOA_MANAGER review of OA2C_CLIENT; curl -u client_id:client_secret <uaa_url> -d grant_type=client_credentials for the basic-auth mint.

SAP -> OS -> SSH

  • SAPMAP modules/postex/sap_ssh_lateral.py: from an existing OS command-execution foothold, harvests /etc/passwd plus ~/.ssh/{id_*,config,known_hosts,authorized_keys} from every home directory, tests harvested keys against known_hosts/already-discovered nodes to map new SSH pivots, and (optionally) plants a persistent public key into authorized_keys - a hardcoded, deterministic ed25519 key commented sapmap@pentest, a clean IOC by design.
  • The SAP-specific value is the entry point: <sid>adm and DB-user accounts frequently have broad, shared SSH reach across a landscape’s host estate, so a single SAP OS-exec foothold (OS command execution, RFC Gateway 10KBLAZE, virtual SAP*) often unlocks the whole host estate. The SSH mechanics themselves are generic OS-level tradecraft - reference standard SSH pentest guidance for execution detail rather than reproducing it here.

Mitigation

RFC Trust

  • Do not create RFC connections from lower-classification systems (sandbox, DEV, QAS) to higher-classification systems (PRD) without a documented business requirement and compensating controls.
  • Regularly review SM59 destinations for stored credentials; do not store dialog-user credentials in RFC destinations at all.
  • Restrict S_RFC per RFC user to the minimal function-group set required; never grant SAP_ALL to a stored RFC-destination user.
  • Review and minimize trusted-system relationships (SMT1) and S_RFCACL grants separately from ordinary S_RFC review; avoid trust from lower- to higher-classified systems.
  • Apply the message-server/gateway hardening set (SAP Notes 1421005, 821875, 1408081, 1444282) so the unrelated “betrusted” network-level trust bypass cannot seed an RFC-trust chain in the first place.

SSO Ticket Trust

  • Restrict OS-level access to $SECUDIR (SAPSYS.pse, cred_v2) so ticket-signing keys cannot be stolen in the first place - see MYSAPSSO2 ticket forgery mitigation.
  • Keep STRUSTSSO2 pruned to only necessary trusted-issuer certificates; remove stale entries.
  • Prefer SNC/X.509 client-certificate SSO over cookie tickets for high-value systems; use short ticket validity.

SAProuter

Shared Accounts

  • Use dedicated, per-tier technical users - never reuse the same account/password across DEV/QAS/PRD.
  • Rotate stored technical-user passwords on a schedule; restrict such users to minimum required authorizations.

Cloud Connector / On-Prem<->BTP

  • Treat every SM59 HTTP destination, OA2C_CLIENT profile, and SecStore entry pointing at *.hana.ondemand.com as Tier-0 material - rotate on any suspected on-prem compromise.
  • Prefer x509/PSE-bound destinations over static client-secret Basic-Auth OA2C bindings; a stolen PSE still requires the on-prem kernel (or a stolen private-key file) to exercise.
  • Apply least-privilege scoping to every OAuth2 client registered against a subaccount so a harvested credential grants minimum blast radius.
  • See Destination Service Abuse mitigation for the BTP->on-prem direction.

SAP -> OS -> SSH

  • Harden the upstream SAP OS-exec channels (Gateway ACLs, SXPG restriction) to deny the initial foothold this pivot depends on.
  • Do not share SSH keys across the landscape; scope <sid>adm/DB-user SSH reach per host; use bastions.
  • Monitor authorized_keys for unexpected entries.

Detection and Monitoring

  • RFC trust graph: an attacker who can read/test SM59 destinations across many systems in quick succession, or replay a forged ticket across multiple trusting systems in sequence, produces a distinctive multi-system access pattern - correlate SM59/STRUSTSSO2 reads and RFC logon attempts across systems in a SIEM rather than per-system only.
  • SSO replay: Security Audit Log (SM20/RSAU) SSO-ticket logons from unusual source IPs, especially SAP*/DDIC or production clients; ICM/ICF access logs for Cookie: MYSAPSSO2=... on unexpected endpoint/client combinations.
  • SAProuter: dev_rout/saprouter -G log - high volume of distinct destination host/port combinations from one source in a short window; see route_string_abuse.md Detection.
  • On-prem->BTP: RFC_ABAP_INSTALL_AND_RUN execution and dynamic report compilation (e.g. a generated ZHTTPDEST-style report) where ad-hoc report generation via RFC is not an expected admin workflow - audit via Security Audit Log; outbound CL_HTTP_CLIENT calls to *.hana.ondemand.com from an SM59 destination not normally exercised at that frequency.
  • BTP/XSUAA: anomalous client_credentials token-mint volume per client_id, especially x509-bound clients whose certificate thumbprint doesn’t match the expected calling system; repeated basic-auth failures followed by success (credential-iteration signature).
  • SAP->OS->SSH: authorized_keys containing the string sapmap@pentest is a direct tool IOC; more generally, anomalous reads of ~/.ssh/ private keys by an SAP work-process/<sid>adm context, or SSH logins originating from a SAP host to atypical targets.

References