Decrypting SAP Secure Storage (SECSTORE / RSECTAB / SSFS)
SAP’s “Secure Storage” holds the passwords and keys an ABAP system needs to operate without re-prompting: database connect passwords, RFC and HTTP destination passwords (SM59), OAuth 2.0 client secrets, trusted-system HMAC keys, and PSE PINs. It exists in two representations, both recoverable to plaintext once an attacker has a foothold on the system:
- Secure Storage in the Database (
RSECTAB) - a database table where each row has anIDENT(e.g./RFC/<DEST>,/DBCON/DEFAULT,/HMAC_INDEP/...) and an encryptedRAW(184)DATAblob. Unless the administrator configured an individual key via transactionSECSTORE, the blob is encrypted with a default, hardcoded/derivable 3DES key. SAP itself states in SAP Note 1902611 that the default key “only provides obfuscation”. - Secure Storage in the File System (SSFS) - the OS file pair
SSFS_<SID>.KEY/SSFS_<SID>.DATunder/usr/sap/<SID>/SYS/global/security/rsecssfs/, encrypted with SAP’s proprietaryRSECCipherusing a hardcoded key-encryption key.
Recovering these secrets typically yields immediate authenticated pivots to every system the compromised system trusts via RFC/HTTP destinations.
Weak, default, or hardcoded key protection of SAP Secure Storage allows an attacker who has already obtained a foothold (a low-privileged RFC/HTTP logon with code-execution rights, OS access, or database read access) to decrypt stored credentials in plaintext. Because these secrets include RFC/HTTP destination passwords and DB connect credentials, their disclosure enables lateral movement across the SAP landscape and access to business-critical data - compromising confidentiality, integrity, and availability well beyond the initially compromised system. SAP Note 1902611 confirms the default RSECTAB key is obfuscation only.
Recovery is two stages: obtain the ciphertext, then decrypt it (the decryption is short and mechanical - always lead with an existing tool rather than re-implementing the cipher).
Obtaining the ciphertext (any one is sufficient):
- ABAP
OPEN DATASETread of theSSFS_<SID>.KEY/.DATfiles viaRFC_ABAP_INSTALL_AND_RUN(or/SAPDS/RFC_ABAP_INSTALL_RUNon hardened kernels) - ABAP
SELECT * FROM RSECTAB - OS command execution (
SXPG_STEP_XPG_START/SM49/SM69) tobase64/certutilthe SSFS files, or to queryRSECTABvia the DB CLI (hdbsql -U DEFAULT,sqlcmd,sqlplus / as sysdba,db2) RFC_READ_TABLEonRSECTAB(last resort - mangles binaryRAWfields)- Direct
<sid>admfilesystem access to/usr/sap/<SID>/SYS/global/security/rsecssfs/(bypasses all RFC paths)
Decrypting SSFS files - use pysap (the maintained OWASP reference implementation):
python3 bin/pysaphdbuserstore -c list -d SSFS_<SID>.DAT
python3 bin/pysaphdbuserstore -c get -d SSFS_<SID>.DAT -k SSFS_<SID>.KEY '/DBCON/DEFAULT'
For the encrypted-format .KEY (187 bytes), use the Python API with SAPSSFSKeyE, which auto-decrypts the wrapped key:
from pysap.SAPSSFS import SAPSSFSKeyE, SAPSSFSData
key = SAPSSFSKeyE(open("SSFS_<SID>.KEY", "rb").read())
data = SAPSSFSData(open("SSFS_<SID>.DAT", "rb").read())
print(data.get_value(b"/DBCON/DEFAULT", key))
Decrypting RSECTAB rows - pysap does not implement this older scheme; the algorithm (two-round manual 3DES with a default key, plus an MD5(SID + instance_nr)-derived key for “VERSION 2” records) was published by Dmitry Chastuchin (ERPScan) at CONFidence 2014 (“All your SAP passwords belong to us”, slides 56–66).
NoteIf the administrator configured an individual SecStore key, it is itself stored as an SSFS record namedSECSTORE_DB/KEY/...- decrypt the SSFS store first, then use the recovered individual key forRSECTAB.
- Configure an individual SecStore key via transaction
SECSTORE(SAP Note 1902611) instead of the default key; restrict OS-level read access to the key file. - Restrict
RFC_ABAP_INSTALL_AND_RUN//SAPDS/RFC_ABAP_INSTALL_RUNandSXPG_COMMAND_EXECUTE/SXPG_STEP_XPG_START(S_LOG_COM) to trusted service accounts - both are arbitrary-code-execution primitives (see OS Command execution). - Restrict
S_TABU_DIS/S_TABU_NAMandRFC_READ_TABLEsoRSECTABis not readable via generic table-read RFC calls. - Restrict OS-level and DB-CLI (
hdbsql,sqlcmd,sqlplus,db2) access to<sid>admand the DB service account only. - After any suspected exposure, rotate the SecStore key and all downstream RFC/DB destination passwords it protected - rotating the key alone is insufficient.
- ABAP execution via
RFC_ABAP_INSTALL_AND_RUN- Security Audit Log (SM20/RSAU_READ_LOG), RFC/CPIC-logon and function-module-call audit classes (configure viaSM19/RSAU_CONFIG). - External-command execution (
SXPG,SM49/SM69) ofbase64,certutil,hdbsql,sqlcmd,sqlplus,db2from an SAP work-process context - anomalous; a Security Audit Log external-command event. RFC_READ_TABLEreads ofRSECTAB(no legitimate business read use case) - visible via table-access / Read Access Logging.- OS-level file access to
SSFS_<SID>.DAT/.KEYunder/usr/sap/<SID>/SYS/global/security/rsecssfs/.
- SAP Note 1902611 - Potential information disclosure relating to BC-SEC (SECSTORE default key = obfuscation only)
- pysap (OWASP CBAS) - SSFS decryption reference implementation
- Dmitry Chastuchin (ERPScan), “All your SAP passwords belong to us”, CONFidence 2014
- redrays-io - SAP Cloud Connector SSFS Decryption
