Decrypting Dead by Daylight CDN Content
November 23, 2024
Disclaimer
The information included in this post is for educational purposes only. Any material on this webpage may not be reproduced, retransmitted, or redisplayed other than for personal or educational use.
Introduction
A content delivery network (CDN) is a network of distributed servers strategically positioned across various geographic locations to deliver web content to users more efficiently and reliably. By reducing the distance between users and the server, CDNs minimize latency, accelerate website load times, and enhance the overall user experience. Dead by Daylight serves client data from its private API through its CDN. While it is possible to recover the client data by capturing Dead by Daylight's network traffic and passing the title screen (where Dead by Daylight prompts you to "PRESS SPACE TO CONTINUE"), any attempt to retrieve the client data results in a response encoded as a modified Base64-encoded string, adding layers of obfuscation to its contents.
Dead by Daylight CDN Content Structure
The Dead by Daylight client communicates with the game server via a REST API, with different endpoints employing various encoding methods. For example, content served from the CDN is prefixed with "DbdDAwAC", whereas save profiles (when they were still in use) used the "DbdDAgAC" prefix. Additionally, a "DbdDAQEB" prefix indicates that the modified Base64-encoded string is zlib-compressed. Based on my observations, only the POST
request sent to this URL incorporates the "DbdDAgAC" prefix. Therefore, it is most relevant to focus on the content served from the CDN.
Decryption Process
Content served from the CDN uses Base64 encoding, ASCII encoding, AES encryption, bit manipulation, and potentially zlib compression. The decryption process is carried out as follows:
1. Check if the content begins with a specific encryption prefix. Decryption cannot proceed if it does not.
2. Remove the prefix from the content to isolate the encrypted payload. Base64-decode the remaining payload to get the raw binary data.
3. Determine the length of the key ID buffer slice based on the length of the branch (in the case of Dead by Daylight, this is either "qa", "stage", "cert", "ptb", or "live"), extract that slice from the beginning of the raw payload, and transform the slice by incrementing each byte's value modulo 256.
4. Decode the key ID buffer into an ASCII string, replacing any "\u0001"
(Start of Heading) characters with ""
(empty strings). Then, use the resulting string to look up the required AES access key. You can use FModel to obtain the required AES access key, provided that you have both a mapping file and the AES key associated with the Dead by Daylight client. Supply FModel with the relevant mapping file and AES key, navigate to DeadbyDaylight > Config > DefaultGame.ini, and search "[/Script/S3Command.AccessKeys]". You will see the list of AES access keys below that section header. If you do not see "DefaultGame.ini" in the "Config" folder while using FModel, then you will need to export the "Config" folder's packages raw data to the output directory of your choice and open it from there.
5. Base64-decode the AES access key to retrieve the actual decryption key.
6. Extract the remaining part of the raw payload after the key ID buffer (hereafter referred to as the decoded buffer).
7. To process the decoded buffer, first create a new AES cipher object using the decrypted key from before and specifying the electronic codebook (ECB) mode. The cipher is then used to decrypt the decoded buffer.
8. Convert the decrypted buffer into a mutable byte array to allow for in-place modifications to the bytes.
9. Loop through the byte array such that bytes with non-zero values are adjusted by adding 1 (modulo 256) and then stored back into the byte array. For each non-zero byte, increment a "valid non-padding bytes" counter; this is used to determine how much of the data is valid and how much is padding. When a byte with value 0 is encountered, terminate the loop; this is where the padding ends.
10. After the loop, slice the byte array such that only the valid non-padding bytes are kept. Convert this slice back to a byte string and decode it into an ASCII string.
11. If the content is zlib-compressed, then remove the prefix from it to isolate the compressed payload. Base64-decode the remaining payload to get the raw binary data.
12. The first 4 bytes of the raw payload are interpreted as a little-endian integer, which specifies the expected size of the decompressed data. Decompress the remaining part of the raw payload (after the first 4 bytes).
13. Once the data is decompressed, decode it from UTF-16 to a string.
14. Return the content.
15. If the content was not zlib-compressed, then return the content after following step 10.
Instructions
The following is a list of instructions required to decrypt content transmitted through the Dead by Daylight CDN:
1. Visit https://www.python.org/downloads/ and left-click on the appropriate download link.
2. Head to the location of the completed download and run the Python Setup for whichever version of Python you downloaded. Ensure that you have "Add python.exe to PATH" checked. Left-click on "Install Now".
3. Once you have installed Python, open Windows PowerShell. Type the following into the terminal:
pip install pycryptodome
This will install the PyCryptodome Python package to your machine. You can verify that you have successfully installed it by typing the following into the terminal:
pip list
If you successfully followed the instructions, then you will see the "pycryptodome" package and the version of it that you installed in the list.
4. Visit this URL and left-click on the "Download raw file" icon. Save the Python script into the directory of your choice.
5. Head to the location of the completed download, right-click inside the directory, and left-click on "Open in Terminal".
6. After Windows PowerShell launches, type the following into the terminal:
python dbd_cdn_decryptor.py
7. You should now be prompted to enter encrypted data. After doing this, you will be prompted to select a branch. After typing the key corresponding to the branch that you are selecting, press the "Enter" key.
8. For example, to decrypt "DynamicContent.json" from this URL, you would do the following in the terminal, pressing the "Enter" key after each step:
python dbd_cdn_decryptor.py
Enter the decrypted data: DbdDAwACNy0yLTFea2h1ZACpWD2xJgZ+OEu8LQwOzu9o+lubuGea7J2LocNGFk16/eb8Td94DmFX+BQK/3q492zpaSjCo1Ofsznj86OhLblonPSJrASea8MPdyIhmkShtw==
Select a branch (q: QA, s: Stage, c: Cert, p: PTB, l: live): l
9. After you do this, the Python script will return the decrypted data to your terminal.