Hi All,
I am sure some of you had followed along with my thread jack before at :
http://nefariousmotorsports.com/forum/index.php?topic=18870.msg143053#msg143053 .
I have been researching Simos18 SBOOT's Service Mode functionality.
The quick summary is:
Simos SBOOT is similar to Bosch GPT/Service only in that it uses two PWM pins as the "break in" signal. Otherwise, the principles and methodology seem quite different. From what I am told about Bosch Service it usually works over something CCP/UDS like, and has direct access to Flash.
The Simos Service Mode works differently. It uses a custom protocol over ISO-TP (at least, I am not aware of any other protocol using the same command values), which allows the tester to upload a signed code block into RAM, just like the signed code blocks which are used for CBOOT/ASW.
Unlike low-level Tricore BSL where Flash is locked, this signed code block is then executed with Flash unlocked for write, so the factory could use this to upload a flasher. But, the Simos18 sigchecking seems pretty sound so far (the application-level exploit for port flashing is to bypass the sigchecking entirely, not an exploit in the actual signature mechanism). So, we can't use Service Mode to run code on Simos18 as far as I can tell.
The Service Mode is also protected by a Seed/Key mechanism. The Seed/Key mechanism seems quite sound on its surface - an RSA public key stored in OTP is used to encrypt 256 bytes of random data and that is sent as the Seed, and the tester is expected to send the data back decrypted as the Key, which should require the corresponding RSA factors (private key).
However, this Seed/Key mechanism it has a fatal flaw: there is no real entropy used in the seed generation.
The PRNG (Mersenne Twister) is seeded using only 31 bits of data taken from the system timer. This is vulnerable in two ways:
* A timer isn't an entropy source, so the attacker can simply control the timing of _when_ they ask for the Seed in order to predict the value of the system timer. It seems Continental may have known about this idea as they added a "minimum wait" time before the Seed can be generated using a timer task, but, a simple fixed minimum wait time doesn't make the timing any less controllable.
* Worse, there are only 31 bits (2^31) of possible key space to begin with. Modern hardware can easily calculate hundreds of thousands or even millions of Mersenne Twister -> RSA exponentiation operations per second, so even if the seed were generated off of a true entropy source, the entire key space can easily be enumerated in a matter of minutes on a fast workstation.
The combination of these two weaknesses makes prediction trivial - even using a Raspberry Pi (no real-time OS, high level code in Python) as the tester, the timer values I have observed when the Seed is generated are always within a few hundred thousand timer iterations. And, with a single core of a modern laptop able to calculate 100,000 signatures/second, it takes only 1-2 seconds to brute-force a Seed/Key match starting from an observed timing offset.
Of course, if the calculation were slower, it would also be possible to generate a table mapping Seed values back to Keys, which I spent a bit of time on before deeming it unnecessary as I can simply spend 2-3 seconds brute-forcing a match to the Seed/Key each time.
Now, once we are past the Seed/Key mechanism, we can't upload a valid code block, at least as far as I can tell. Again, the actual sigchecking in S18 seems pretty sound, and for those thinking about a block reuse attack, the signed SHA256 used in the RSA signature has addresses mixed in to prevent this very thing.
But, just like all other Simos18 software blocks, the code block also has a CRC header, and this header has very weak bounds checking. By manipulating the CRC header, we can ask the Service Mode command shell to checksum the Tricore boot passwords, then quickly RST into a normal Tricore BSL which has access to RAM.
Next, we can dump the CRC values from the temporary area where they are being stored in RAM. Since CRC is a reversible (non-cryptographic) hash, by sliding the CRC start value along by the values, we can infer boot passwords from Flash.
Here is a more detailed write-up, including some other odd bits of SBOOT :
https://github.com/bri3d/Simos18_SBOOT .
Here is a Seed/Key brute force tool. It takes two command-line parameters as hex strings: the "initial" timer value to start from (to speed up the process, once you've run the exploit once with a given tool, you know the general range of where the timer values will land), and the first 32 bits of the Seed data sent from the ECU (I haven't found a collision yet... maybe I should expand the matcher to a few more bits though!). Once a match is recovered, will return the full Seed/Key data as well as the timer value used to create them.
https://github.com/bri3d/Simos18_SBOOT/blob/main/twister.cAnd here is an implementation of the CAN comms stack and the overall break-in process, including the necessary PWM signals (sorry, it is mixed with normal Tricore BSL since the exploit requires doing an RST into the Tricore BSL to dump RAM):
https://github.com/bri3d/TC1791_CAN_BSL/blob/main/bootloader.pyCheers and enjoy!