Forging SAP Logon Tickets (MYSAPSSO2)
A SAP Logon Ticket (MYSAPSSO2) is a digitally signed token - carried as an HTTP cookie or RFC logon parameter - that asserts an authenticated username. Receiving systems accept it when login/accept_sso2_ticket = 1 and the certificate that signed it is present in their STRUSTSSO2 trust list. The ticket is a simple TLV structure (user, client, SID, validity, …) followed by a PKCS#7/CMS signature over the preceding bytes.
An attacker who obtains a system’s signing key - the private key + certificate inside its system PSE (SAPSYS.pse) - can forge a valid ticket for any username (including SAP* or any dialog user), and replay it against every system that trusts that certificate: at minimum the issuing system itself (self-trust), and potentially every system with that cert in its STRUSTSSO2/TWPSSO2ACL.
This is a post-compromise technique. There is no network-only path to a valid signature - forging requires first stealing SAPSYS.pse and recovering its PIN (see Secure Store / PSE extraction and OS-level access below). It is a privilege-consolidation / lateral-movement step, not initial access.
Once an attacker holds a system’s PSE signing key, they can impersonate any user across the entire SSO trust domain without any password, entirely offline - defeating authentication and enabling lateral movement to every STRUSTSSO2-trusting system. Because the ticket verifies correctly against a legitimately-possessed key, this is not a signature-verification bug but a consequence of key compromise: the controls are protecting the PSE and pruning trust, not “patching” the mechanism. Impact spans confidentiality, integrity, and availability across the trusted landscape.
The forge itself is offline once the key is held; the work is obtaining the key.
- Obtain the signing key (prerequisite) - read
SAPSYS.pse+cred_v2from$SECUDIRas<sid>adm(or via an OS-exec foothold - GWSAPXPG,SXPG_STEP_XPG_START, OS command execution, virtual SAP*), recover the PIN (fromcred_v2, empty, legacy default, SID, or<sid>admname), and extract the private key + cert. Automated by SAPMAPmodules/postex/sap_pse_loot.py. - Forge, sign, deliver - build the ticket for the chosen user, PKCS#7-sign it with the stolen key (RSA/EC/DSA), base64-encode as a
MYSAPSSO2cookie / RFC parameter. Automated by SAPMAPmodules/exploitation/sap_mysapsso2.py; the end-to-end chain (exfil -> PIN -> key -> forge) issapmap_exploit.py::extract_and_forge_ticket. - Replay - present the cookie to ICF/Fiori endpoints or use it for RFC logon against any system trusting the certificate.
NoteAn assertion ticket can be pinned to a single receiver (RecipientSID/RecipientClient), and older NetWeaver stacks usingSAPSECULIBmay sign with DSA keys - both are handled by the tooling but do not change the prerequisite (stolen PSE + PIN).
- Restrict OS-level access to
$SECUDIR(SAPSYS.pse,cred_v2) to<sid>admonly - no world-readable PSE files. This is the real root control; the forge cannot be prevented once the key is out. - Harden the upstream OS-exec primitive (RFC Gateway
secinfo/reginfoACLs,gw/rem_start = DISABLED) soSAPXPG-class channels aren’t reachable - see OS command execution. - Keep
STRUSTSSO2pruned to only necessary certificates; remove stale trust relationships. - Use short ticket validity; prefer SNC / X.509 client-certificate SSO over cookie tickets for high-value systems.
- If PSE compromise is suspected, re-issue
SAPSYS.pseand revoke the old certificate from allSTRUSTSSO2ACLs; rotate downstream trust.
STRUSTSSO2review: unexpected/unpruned trust entries.- Security Audit Log (
SM20/RSAU): SSO-ticket logons from unusual source IPs, especially forSAP*/DDICor in production clients. - ICM/ICF access logs:
Cookie: MYSAPSSO2=...on unexpected endpoints/client combinations. - File-integrity monitoring on
$SECUDIRfor unauthorized reads ofSAPSYS.pse/cred_v2- the prerequisite the whole chain depends on.
