SAP Credv2¶
The following subsections show a representation of the file format portions and how to generate them.
First we need to perform some setup to import the packet classes:
[1]:
from pysap.SAPCredv2 import *
from IPython.display import display
Credv2 without LPS¶
We’ll read the files used in the test case suite and use them as example:
[2]:
with open("../../tests/data/credv2_lps_off_v0_3des", "rb") as fd:
credv2_lps_off_v0_3des_string = fd.read()
credv2_lps_off_v0_3des = SAPCredv2(credv2_lps_off_v0_3des_string)
with open("../../tests/data/credv2_lps_off_v1_3des", "rb") as fd:
credv2_lps_off_v1_3des_string = fd.read()
credv2_lps_off_v1_3des = SAPCredv2(credv2_lps_off_v1_3des_string)
with open("../../tests/data/credv2_lps_off_v1_aes256", "rb") as fd:
credv2_lps_off_v1_aes256_string = fd.read()
credv2_lps_off_v1_aes256 = SAPCredv2(credv2_lps_off_v1_aes256_string)
with open("../../tests/data/credv2_lps_off_v0_dp_3des", "rb") as fd:
credv2_lps_off_v0_dp_3des_string = fd.read()
credv2_lps_off_v0_dp_3des = SAPCredv2(credv2_lps_off_v0_dp_3des_string)
The Cred files are comprised of the following main structures:
Credv2 without LPS and version 0 cipher format 3DES encryption¶
[3]:
credv2_lps_off_v0_3des.show()
###[ SAPCredv2 ]###
\creds \
|###[ SAPCredv2Cred ]###
| \cred \
| |###[ SAPCredv2_Cred ]###
| | cert_name = <ASN1_IA5_STRING['CN=PSEOwner']>
| | unknown1 = <ASN1_IA5_STRING['']>
| | pse_path = <ASN1_IA5_STRING['/secudir/pse-v2-noreq-DSA-1024-SHA1.pse']>
| | unknown2 = <ASN1_IA5_STRING['']>
| | cipher = <ASN1_BIT_STRING[1011100011...0100100001]=�ץ�M����^4�y! (0 unused bit)>
Credv2 without LPS and version 1 cipher format 3DES encryption¶
[4]:
credv2_lps_off_v1_3des.show()
###[ SAPCredv2 ]###
\creds \
|###[ SAPCredv2Cred ]###
| \cred \
| |###[ SAPCredv2_Cred ]###
| | cert_name = <ASN1_IA5_STRING['CN=PSEOwner']>
| | unknown1 = <ASN1_IA5_STRING['']>
| | pse_path = <ASN1_IA5_STRING['/secudir/pse-v2-noreq-DSA-1024-SHA1.pse']>
| | unknown2 = <ASN1_IA5_STRING['']>
| | cipher = <ASN1_BIT_STRING[0000000100...1011010101]=n�`\@�...�Z6�� (0 unused bit)>
Credv2 without LPS and version 1 cipher format AES256 encryption¶
[5]:
credv2_lps_off_v1_aes256.show()
###[ SAPCredv2 ]###
\creds \
|###[ SAPCredv2Cred ]###
| \cred \
| |###[ SAPCredv2_Cred ]###
| | cert_name = <ASN1_IA5_STRING['CN=PSEOwner']>
| | unknown1 = <ASN1_IA5_STRING['']>
| | pse_path = <ASN1_IA5_STRING['/secudir/pse-v2-noreq-DSA-1024-SHA1.pse']>
| | unknown2 = <ASN1_IA5_STRING['']>
| | cipher = <ASN1_BIT_STRING[0000000100...0011010100]=c˶8<�...@ �s��� (0 unused bit)>
Credv2 without LPS Cipher Header version 1 cipher format¶
[6]:
cipher_header = SAPCredv2_Cred_Cipher(str(credv2_lps_off_v1_aes256.creds[0].cred.cipher))
cipher_header.canvas_dump()
[6]:

Credv2 Plain Credential¶
After decrypting the credential using the username provided, the plaintext contains the following structure:
[7]:
cred_v2_lps_off_aes256_plain = credv2_lps_off_v1_aes256.creds[0].cred.decrypt("username")
cred_v2_lps_off_aes256_plain.show()
###[ SAPCredv2_Cred_Plain ]###
pin = <ASN1_IA5_STRING['1234567890']>
option1 = None
option2 = None
option3 = None
###[ Raw ]###
load = '\xeb<'
Credv2 Plain Credential with DP API¶
When using SSO Credentials in Windows, the CommonCryptoLib encrypts the PIN using DP API.
[8]:
cred_v2_lps_off_dp_3des_plain = credv2_lps_off_v0_dp_3des.creds[0].cred.decrypt("username")
cred_v2_lps_off_dp_3des_plain.show()
###[ SAPCredv2_Cred_Plain ]###
pin = <ASN1_IA5_STRING['01000000D08C9DDF0115D1118C7A00C04FC297EB010000006B3FF795A63D2D44B7604E350C2A4ED6040000002A000000430072006500640065006E007400690061006C0045006E006300720079007000740069006F006E000000106600000001000020000000BA59F09CE09554B0728C0B3137DBAA19F2DDF1891E55B8BCBC0944E25111BFF1000000000E800000000200002000000035FCC9DF90BD839D4C346B2A141380496D03CD31CBA9723A286651FAE88323EE10000000E080324A3237B73118103135CB3D305A40000000DC036DA55EDB9ED7670A602C5EDD4B8DE8CDC890D70094117DAA8EF1B3AFBA46D817044F3FDA6EF53694D6CF13CA5AB330025855AEAB657C47F6B2B8972581F2']>
option1 = <ASN1_IA5_STRING['MSCryptProtect']>
option2 = None
option3 = None
###[ Raw ]###
load = '\x04\x04\x04\x04'
Credv2 with LPS¶
We’ll read the files used in the test case suite and use them as example:
[9]:
with open("../../tests/data/credv2_lps_on_v2_dp_aes256", "rb") as fd:
credv2_lps_on_v2_dp_aes256_string = fd.read()
credv2_lps_on_v2_dp_aes256 = SAPCredv2(credv2_lps_on_v2_dp_aes256_string)
with open("../../tests/data/credv2_lps_on_v2_int_aes256", "rb") as fd:
credv2_lps_on_v2_int_aes256_string = fd.read()
credv2_lps_on_v2_int_aes256 = SAPCredv2(credv2_lps_on_v2_int_aes256_string)
The Cred files are comprised of the following main structures:
Credv2 with LPS in DP API Mode (Windows)¶
[10]:
credv2_lps_on_v2_dp_aes256.show()
###[ SAPCredv2 ]###
\creds \
|###[ SAPCredv2Cred ]###
| \cred \
| |###[ SAPCredv2_Cred_LPS ]###
| | version = 0x2 <ASN1_INTEGER[2]>
| | \subject \
| | |###[ X509_RDN ]###
| | | \rdn \
| | | |###[ X509_AttributeTypeAndValue ]###
| | | | type = <ASN1_OID['commonName']>
| | | | value = <ASN1_PRINTABLE_STRING['PSEOwner']>
| | pse_path = <ASN1_UTF8_STRING['C:\\secudir\\pse-v2-noreq-DSA-1024-SHA1.pse']>
| | cipher = <ASN1_BIT_STRING[0000001000...1101001111]=CredEn...�U��t�O (0 unused bit)>
Credv2 with LPS in INT/Fallback mode (Linux without TPM)¶
[11]:
credv2_lps_on_v2_int_aes256.show()
###[ SAPCredv2 ]###
\creds \
|###[ SAPCredv2Cred ]###
| \cred \
| |###[ SAPCredv2_Cred_LPS ]###
| | version = 0x2 <ASN1_INTEGER[2]>
| | \subject \
| | |###[ X509_RDN ]###
| | | \rdn \
| | | |###[ X509_AttributeTypeAndValue ]###
| | | | type = <ASN1_OID['commonName']>
| | | | value = <ASN1_PRINTABLE_STRING['PSEOwner']>
| | pse_path = <ASN1_UTF8_STRING['/secudir/pse-v2-noreq-DSA-1024-SHA1.pse']>
| | cipher = <ASN1_BIT_STRING[0000001000...0110100010]=CredEn...��Z3y��9� (0 unused bit)>
[12]:
cred_v2_lps_on_int_aes256_plain = credv2_lps_on_v2_int_aes256.creds[0].cred.decrypt("username")
cred_v2_lps_on_int_aes256_plain.show()
###[ SAPCredv2_Cred_Plain ]###
pin = <ASN1_IA5_STRING['1234567890']>
option1 = None
option2 = None
option3 = None
SAP LPS Cipher header¶
[13]:
lps_cipher_header = SAPLPSCipher(str(credv2_lps_on_v2_int_aes256.creds[0].cred.cipher))
lps_cipher_header.canvas_dump()
[13]:
