From 5cc2da6d301a91007403b5f9ee5e9e46ac5bb099 Mon Sep 17 00:00:00 2001 From: Vincent Berg Date: Sun, 22 Oct 2023 20:08:39 +0200 Subject: [PATCH] rsecssfs key decrypt fix (see #70) --- pysap/SAPSSFS.py | 22 +++++++++++++++++++++- pysap/utils/crypto/__init__.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/pysap/SAPSSFS.py b/pysap/SAPSSFS.py index f131266..d91be5c 100644 --- a/pysap/SAPSSFS.py +++ b/pysap/SAPSSFS.py @@ -26,7 +26,7 @@ from cryptography.hazmat.primitives.hashes import Hash, SHA1 from cryptography.hazmat.backends import default_backend # Custom imports -from pysap.utils.crypto import rsec_decrypt +from pysap.utils.crypto import rsec_decrypt, rsec_decrypt_key from pysap.utils.fields import PacketNoPadded, StrFixedLenPaddedField, TimestampField @@ -78,6 +78,26 @@ class SAPSSFSKey(Packet): StrFixedLenPaddedField("host", None, 24, padd=" "), ] +class SAPSSFSKeyE(Packet): + """SAP SSFS Key (encrypted) file format packet. + + Key file length is 0xbb + """ + name = "SAP SSFS Encrypted Key" + fields_desc = [ + StrFixedLenField("preamble", "RSecSSFsKey", 11), + ByteField("type", None), + TimestampField("timestamp", None), + StrFixedLenPaddedField("user", None, 24, padd=" "), + StrFixedLenPaddedField("host", None, 24, padd=" "), + # probably kind of check sum or just noise + StrFixedLenField("unknown", None, 62), + StrFixedLenField("key_enc", None, 57), + ] + + @property + def key(self): + return rsec_decrypt_key(self.key_enc) class SAPSSFSDecryptedPayload(PacketNoPadded): """SAP SSFS Decrypted Payload. diff --git a/pysap/utils/crypto/__init__.py b/pysap/utils/crypto/__init__.py index fbd1dff..4bd951f 100644 --- a/pysap/utils/crypto/__init__.py +++ b/pysap/utils/crypto/__init__.py @@ -367,3 +367,32 @@ def rsec_decrypt(blob, key): round_3 = cipher.crypt(RSECCipher.MODE_DECODE, round_2, key1, len(round_2)) return ''.join([chr(i) for i in round_3]) + +def rsec_decrypt_key(key_enc): + kek = "\x9F\x60\xA6\xDD\x7E\x15\x7D\x07\x0C\xC3\x57\x90\x9A\xA2\x90\xE9\x36\x0E\xEE\x47\x2F\xDA\x47\x72" + kek = [ord(i) for i in kek] + kek1 = kek[0:8] + kek2 = kek[8:16] + kek3 = kek[16:24] + """ Default Key Encryption Key embedded in rsecssfx/kernel binaries """ + + blob = [ord(i) for i in key_enc[:56]] + last_key_byte = bytearray(key_enc[56:]) + """ Last key byte is computed outside DES decryption """ + + cipher = RSECCipher() + round_1 = cipher.crypt(RSECCipher.MODE_DECODE, blob, kek3, len(blob)) + round_2 = cipher.crypt(RSECCipher.MODE_ENCODE, round_1, kek2, len(round_1)) + round_3 = cipher.crypt(RSECCipher.MODE_DECODE, round_2, kek1, len(round_2)) + + t1 = [ord(i) for i in key_enc[48:56]] + tmp = cipher.crypt(RSECCipher.MODE_ENCODE, t1, kek3, 8) + last_key_byte = last_key_byte[0] ^ tmp[0] + + tmp = cipher.crypt(RSECCipher.MODE_ENCODE, round_2[48:56], kek2, 8) + last_key_byte = last_key_byte ^ tmp[0] + + tmp = cipher.crypt(RSECCipher.MODE_ENCODE, round_2[48:56], kek1, 8) + last_key_byte = last_key_byte ^ tmp[0] + + return [chr(c) for c in round_3[33:] + [last_key_byte]]