From 697eeeb99eda579c78eedf125d68837e7cd3d100 Mon Sep 17 00:00:00 2001 From: Bottersnike Date: Fri, 17 Feb 2023 09:37:51 +0000 Subject: [PATCH] Restructure security pages --- docs.py | 5 +- templates/pages/sega/software/security.html | 526 ------------------ .../software/{ => security}/alphadvd.html | 0 .../pages/sega/software/security/index.html | 526 +++++++++++++++++- 4 files changed, 526 insertions(+), 531 deletions(-) delete mode 100644 templates/pages/sega/software/security.html rename templates/pages/sega/software/{ => security}/alphadvd.html (100%) diff --git a/docs.py b/docs.py index f1b9ad2..284517f 100644 --- a/docs.py +++ b/docs.py @@ -49,8 +49,9 @@ SEGA_CONTENTS = { "software": ("Software", { "pcp": ("PCP", {"libpcp.html": "libpcp"}), "drivers": ("Device drivers", None), - "security.html": "Security", - "alphadvd.html": "AlphaDVD", + "security": ("Security", { + "alphadvd.html": "AlphaDVD", + }), "groovemaster.html": "GrooveMaster.ini", }), "manual": ("Manual", { diff --git a/templates/pages/sega/software/security.html b/templates/pages/sega/software/security.html deleted file mode 100644 index 4c27b22..0000000 --- a/templates/pages/sega/software/security.html +++ /dev/null @@ -1,526 +0,0 @@ -{% extends "sega.html" %} -{% block title %}{% endblock %} -{% block body %} -

System Security

-

The Ring* series have a number of security measures in place, some easy to bypass, others requiring more work. They - are listed here in, roughly, the order in which each layer is applied.

- -

Drive ATA Password

-

The SSD contained within the system has an ATA password set. The system BIOS contains a password derivation function - that derives the specific password for that drive based on its serial number.

-

This can be bypassed either by extracting the password used, or by first powering on the Ring* system with the drive - connected, then hotplugging the SATA data cable on the drive while keeping the drive powered.

- -
- Why does this work? -

The following is the sequence of possible security modes for an ATA drive:

- - - - - - - - - - - - - - - - - - - - - - SEC0 - - - - - Power: off - - - Security: No - - - - - - Power on - - - - - Freeze - - - - - HW Reset - - - - - - - - - - SEC1 - - - - - Security: No - - - Frozen: No - - - - - - - - SEC2 - - - - - Security: No - - - Frozen: Yes - - - - - - - - SEC5 - - - - - Security: Yes - - - Unlocked: Yes - - - Frozen: No - - - - - - - - SEC4 - - - - - Security: Yes - - - Unlocked: No - - - Frozen: No - - - - - - - - SEC6 - - - - - Security: Yes - - - Unlocked: Yes - - - Frozen: Yes - - - - - - Power on - - - - - HW reset - - - - - - - Unlock - - - - - - Freeze - - - - - - - - SEC3 - - - - - Power: off - - - Security: Yes - - - -

When the drive has a password set, it initially starts in SEC3. The RingEdge then transitions the drive to SEC5 - then SEC6. Importantly, however, as long as power is never lost, the drive will remain in SEC6 mode, even if we - connect it to a different system.

-

This allows us full read-write access to the drive without ever knowing the password!

-
- -

Windows Password

-

It seems silly to mention, but it's worth noting. AppUser will automatically log in, but if you need to - log back in, or wish to login as SystemUser, you'll need the passwords.

-

AppUser's password is segahard.

-

SystemUser's password is <6/=U=#tpe!$*3!5. NOTE: if a debugger is attached to - mxprestartup, Miflac=Ifme9Jfp0 will be attempted as the password for - SystemUser instead. This is not the correct password for a production unit. -

- -
- Finding SystemUser's password - -

When AppUser logs in, mxprestartup is executed. This binary constructs SystemUser's password then elevates - permissions. When no debugger is present, the following steps are performed:

- - - -

If a debugger is present, a similar process is performed:

- - - -

Why is the process for a debugged process more elaborate? I'm not sure.

-
- -

System binaries encryption

-

The system binaries, normally located on S:, are a TrueCrypt partition. The partition file can be found - at C:\System\Execute\System. It has password segahardpassword, and used the alternate data - stream loated at - C:\System\Execute\DLL:SystemKeyFile as a keyfile. -

-

C:\System\Execute\DLL:UpdateKeyFile is also present here, which is used for encryption of update - data (but is not utilised in the process of mounting S:).

- -
- What's an Alternate Data Stream? -

An alternate data stream, or ADS for short, is a feature of the NTFS filesystem where additional data can be - stored alongside a file or directory. On modern Windows systems, they can be shown using dir /R. If - you are performing analysis on the system using digital forensics software, which you probably should be, all - major packages will show these streams clearly.

- -
- -
The alternate data streams, in FTK Imager
-
- -

The SANS Institude - website is a great resource for more information and links.

-
-
- Finding this information - -

The decryption of the system partition is the responsibility of mxstartup. This file contains pairs - of hex strings which sum to produce the paths to the alternate data streams, and the volume password.

-
- -

Keyfile downloads

- - -

Keychip

-

This is the first point during the boot process where a physical keychip is required in order to continue the system - boot process.

-

With the exception of mxkeychip, processes do not - directly communicate with the keychip. Instead, they communicate with mxkeychip via a PCP. mxkeychip itself is then responsible for - communicating with the keychip. These communications are AES encrypted with keys agreed during the initial - handshake.

- -

The keychip is responsible for a number of functions:

- - -

This security layer can be bypassed by replacing the mxkeychip.exe binary with a custom binary, - eliminating the need to emulate the physical parallel device, and its encryption.

- -

Game data encryption

-

Once the system has verified it is allowed to continue booting, it proceeds to decrypt the game partition. This is - done by performing a keychip.decrypt request.

-

The specific key used varies by game. The easiest way to retrieve this key is to, well, ask the keychip for it. We - can first start a listener on port 40106 to retrieve the value that the boot process is passing. - Following that, we can start the real mxkeychip, and request the same decryption. It will then provide us with the - key to be used for the game encryption!

-

TODO: Some proper digging into the mx binaries to determine exactly where it pulls the encrypted string in the - request

-

The value we have now should be 16 bytes, and is the contents for a keyfile.

-

Like the S: drive, game data is a TrueCrypt partition. Check the SEGA partition description to determine which partition contains - the game data. If in doubt, just try they all until one works :).

- -

Game-keychip handshake

-

There is one final security step present, however I believe this to only be present in some games.

-

When the game boots, it makes requests to keychip.ssd.proof and keychip.ds.compute. These - are challenge-response queries, which the keychip will internally look up in a large table of possible values.

-

While we could dump the EEPROM chip located on the keychip, there is no need for this. As the game also needs a copy - of the responses to validate against, we can just grab that file, as we have already decrypted the game partition by - this point. The file will likely be named [game ID]_Table.dat.

- -

I'll flush this out later, but for now, here's the structure of that file:

-
{% highlight "c" %}
-struct {
-    struct {
-        char challenge[7];
-        char responses[4][20];
-    } ds[10000];
-    struct {
-        char challenge[16];
-        char response[16];
-    } ssd[10000];
-}
-{% endhighlight %}
- -

The responses are scrambled as described below:

-

DS Scramble:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Output index012345678910111213141516171819
Input index155131410121116741812630178199
-

SSD Scramble:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Output index0123456789101112131415
Input index6841271311023111415059
- -

NOTE: The following information may only be true for MaiMai FiNALE! I have not yet verified this on other - games! -
- In dev mode, the game will only ever request a single string as the challenge. -

-

This string is 2CFECBC71CF1E4, and its corresponding four response pages are (not scrambled):

-
    -
  1. ca6ed736401682dd4411a27d2440ac4b478bad8b
  2. -
  3. 4ac606302ce5ef51abb3df2dc46c863b3c06aa2c
  4. -
  5. 2aaf35b2aba4c6840bdb7bd40ecbce2cca934795
  6. -
  7. 2f6d713dabde3c43df818491ab9467ba8ba0fed4
  8. -
-

- NOTE: The following information is super un-verified!
- Occasionally the game will make a query to the DS table that is not present in the table. In this instance, the - keychip responds with the entry at index n, where n is a counter that increments every time a - keychip.ds.compute query is performed, modulo 100. -

-

It should be noted that if the keychip binary imemdiatly terminates the connection, rather than sending a - known-incorrect response (such as if the challenge matches none in the known tables), the game will re-attempt the - query, and this query will, with a high likelyhood, be different.

- -

It should additionally be noted that this whole process can be skipped by returning code=54 rather than - a valid response.

- -{% endblock %} \ No newline at end of file diff --git a/templates/pages/sega/software/alphadvd.html b/templates/pages/sega/software/security/alphadvd.html similarity index 100% rename from templates/pages/sega/software/alphadvd.html rename to templates/pages/sega/software/security/alphadvd.html diff --git a/templates/pages/sega/software/security/index.html b/templates/pages/sega/software/security/index.html index 0b31831..4c27b22 100644 --- a/templates/pages/sega/software/security/index.html +++ b/templates/pages/sega/software/security/index.html @@ -1,6 +1,526 @@ {% extends "sega.html" %} -{% block title %}Security{% endblock %} +{% block title %}{% endblock %} {% block body %} -

Security

-{{ generate_toc()|safe }} +

System Security

+

The Ring* series have a number of security measures in place, some easy to bypass, others requiring more work. They + are listed here in, roughly, the order in which each layer is applied.

+ +

Drive ATA Password

+

The SSD contained within the system has an ATA password set. The system BIOS contains a password derivation function + that derives the specific password for that drive based on its serial number.

+

This can be bypassed either by extracting the password used, or by first powering on the Ring* system with the drive + connected, then hotplugging the SATA data cable on the drive while keeping the drive powered.

+ +
+ Why does this work? +

The following is the sequence of possible security modes for an ATA drive:

+ + + + + + + + + + + + + + + + + + + + + + SEC0 + + + + + Power: off + + + Security: No + + + + + + Power on + + + + + Freeze + + + + + HW Reset + + + + + + + + + + SEC1 + + + + + Security: No + + + Frozen: No + + + + + + + + SEC2 + + + + + Security: No + + + Frozen: Yes + + + + + + + + SEC5 + + + + + Security: Yes + + + Unlocked: Yes + + + Frozen: No + + + + + + + + SEC4 + + + + + Security: Yes + + + Unlocked: No + + + Frozen: No + + + + + + + + SEC6 + + + + + Security: Yes + + + Unlocked: Yes + + + Frozen: Yes + + + + + + Power on + + + + + HW reset + + + + + + + Unlock + + + + + + Freeze + + + + + + + + SEC3 + + + + + Power: off + + + Security: Yes + + + +

When the drive has a password set, it initially starts in SEC3. The RingEdge then transitions the drive to SEC5 + then SEC6. Importantly, however, as long as power is never lost, the drive will remain in SEC6 mode, even if we + connect it to a different system.

+

This allows us full read-write access to the drive without ever knowing the password!

+
+ +

Windows Password

+

It seems silly to mention, but it's worth noting. AppUser will automatically log in, but if you need to + log back in, or wish to login as SystemUser, you'll need the passwords.

+

AppUser's password is segahard.

+

SystemUser's password is <6/=U=#tpe!$*3!5. NOTE: if a debugger is attached to + mxprestartup, Miflac=Ifme9Jfp0 will be attempted as the password for + SystemUser instead. This is not the correct password for a production unit. +

+ +
+ Finding SystemUser's password + +

When AppUser logs in, mxprestartup is executed. This binary constructs SystemUser's password then elevates + permissions. When no debugger is present, the following steps are performed:

+ + + +

If a debugger is present, a similar process is performed:

+ + + +

Why is the process for a debugged process more elaborate? I'm not sure.

+
+ +

System binaries encryption

+

The system binaries, normally located on S:, are a TrueCrypt partition. The partition file can be found + at C:\System\Execute\System. It has password segahardpassword, and used the alternate data + stream loated at + C:\System\Execute\DLL:SystemKeyFile as a keyfile. +

+

C:\System\Execute\DLL:UpdateKeyFile is also present here, which is used for encryption of update + data (but is not utilised in the process of mounting S:).

+ +
+ What's an Alternate Data Stream? +

An alternate data stream, or ADS for short, is a feature of the NTFS filesystem where additional data can be + stored alongside a file or directory. On modern Windows systems, they can be shown using dir /R. If + you are performing analysis on the system using digital forensics software, which you probably should be, all + major packages will show these streams clearly.

+ +
+ +
The alternate data streams, in FTK Imager
+
+ +

The SANS Institude + website is a great resource for more information and links.

+
+
+ Finding this information + +

The decryption of the system partition is the responsibility of mxstartup. This file contains pairs + of hex strings which sum to produce the paths to the alternate data streams, and the volume password.

+
+ +

Keyfile downloads

+ + +

Keychip

+

This is the first point during the boot process where a physical keychip is required in order to continue the system + boot process.

+

With the exception of mxkeychip, processes do not + directly communicate with the keychip. Instead, they communicate with mxkeychip via a PCP. mxkeychip itself is then responsible for + communicating with the keychip. These communications are AES encrypted with keys agreed during the initial + handshake.

+ +

The keychip is responsible for a number of functions:

+ + +

This security layer can be bypassed by replacing the mxkeychip.exe binary with a custom binary, + eliminating the need to emulate the physical parallel device, and its encryption.

+ +

Game data encryption

+

Once the system has verified it is allowed to continue booting, it proceeds to decrypt the game partition. This is + done by performing a keychip.decrypt request.

+

The specific key used varies by game. The easiest way to retrieve this key is to, well, ask the keychip for it. We + can first start a listener on port 40106 to retrieve the value that the boot process is passing. + Following that, we can start the real mxkeychip, and request the same decryption. It will then provide us with the + key to be used for the game encryption!

+

TODO: Some proper digging into the mx binaries to determine exactly where it pulls the encrypted string in the + request

+

The value we have now should be 16 bytes, and is the contents for a keyfile.

+

Like the S: drive, game data is a TrueCrypt partition. Check the SEGA partition description to determine which partition contains + the game data. If in doubt, just try they all until one works :).

+ +

Game-keychip handshake

+

There is one final security step present, however I believe this to only be present in some games.

+

When the game boots, it makes requests to keychip.ssd.proof and keychip.ds.compute. These + are challenge-response queries, which the keychip will internally look up in a large table of possible values.

+

While we could dump the EEPROM chip located on the keychip, there is no need for this. As the game also needs a copy + of the responses to validate against, we can just grab that file, as we have already decrypted the game partition by + this point. The file will likely be named [game ID]_Table.dat.

+ +

I'll flush this out later, but for now, here's the structure of that file:

+
{% highlight "c" %}
+struct {
+    struct {
+        char challenge[7];
+        char responses[4][20];
+    } ds[10000];
+    struct {
+        char challenge[16];
+        char response[16];
+    } ssd[10000];
+}
+{% endhighlight %}
+ +

The responses are scrambled as described below:

+

DS Scramble:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Output index012345678910111213141516171819
Input index155131410121116741812630178199
+

SSD Scramble:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Output index0123456789101112131415
Input index6841271311023111415059
+ +

NOTE: The following information may only be true for MaiMai FiNALE! I have not yet verified this on other + games! +
+ In dev mode, the game will only ever request a single string as the challenge. +

+

This string is 2CFECBC71CF1E4, and its corresponding four response pages are (not scrambled):

+
    +
  1. ca6ed736401682dd4411a27d2440ac4b478bad8b
  2. +
  3. 4ac606302ce5ef51abb3df2dc46c863b3c06aa2c
  4. +
  5. 2aaf35b2aba4c6840bdb7bd40ecbce2cca934795
  6. +
  7. 2f6d713dabde3c43df818491ab9467ba8ba0fed4
  8. +
+

+ NOTE: The following information is super un-verified!
+ Occasionally the game will make a query to the DS table that is not present in the table. In this instance, the + keychip responds with the entry at index n, where n is a counter that increments every time a + keychip.ds.compute query is performed, modulo 100. +

+

It should be noted that if the keychip binary imemdiatly terminates the connection, rather than sending a + known-incorrect response (such as if the challenge matches none in the known tables), the game will re-attempt the + query, and this query will, with a high likelyhood, be different.

+ +

It should additionally be noted that this whole process can be skipped by returning code=54 rather than + a valid response.

+ {% endblock %} \ No newline at end of file