How I Hacked my Car Part 5: How I Hacked my Car Again

If you haven’t read the earlier parts, please do so.
如果您还没有阅读前面的部分,请阅读。

The Same Car as Before
和以前一样的车⌗

Two summers ago I bought a 2021 Hyundai Ioniq SEL. It is a nice fuel-efficient hybrid with a decent amount of features like wireless Android Auto/Apple CarPlay, wireless phone charging, heated seats, & a sunroof.
两个夏天前,我买了一辆 2021 款现代 Ioniq SEL。这是一款不错的省油混合动力车,具有相当多的功能,如无线Android Auto / Apple CarPlay,无线手机充电,加热座椅和天窗。

One thing I particularly liked about this vehicle was the In-Vehicle Infotainment (IVI) system. As I mentioned before it had wireless Android Auto which seemed to be uncommon in this price range, and it had pretty nice, smooth animations in its menus which told me the CPU/GPU in it wasn’t completely underpowered, or at least the software it was running wasn’t super bloated.
我特别喜欢这辆车的一件事是车载信息娱乐 (IVI) 系统。正如我之前提到的,它有无线 Android Auto,这在这个价格范围内似乎并不常见,而且它的菜单中有相当漂亮、流畅的动画,告诉我它的 CPU/GPU 并没有完全不足,或者至少它运行的软件不是超级臃肿。

As with many new gadgets I get, I wanted to play around with it and ultimately see what I could do with it.
就像我得到的许多新小工具一样,我想玩一玩,最终看看我能用它做什么。

And I did, which lead to the adventure that is the original How I Hacked my Car Series.
我做到了,这导致了最初的冒险,即最初的我如何入侵我的汽车系列。

But why does this post exist if I already hacked it?
但是,如果我已经破解了它,为什么这个帖子还存在呢?

Because Hyundai 因为现代⌗

Sometime in late July 2022, Hyundai removed the links to all of their DAudio2 firmware downloads. Leaving only a message that said the updates would return on Sepember 1st. If I had to guess, someone at Hyundai/Mobis read my blog and they wanted to fix their issues. In anticipation of that I started to gear up to hack the latest firmware.
在 2022 年 7 月下旬的某个时候,现代汽车删除了所有 DAudio2 固件下载的链接。只留下一条消息,说更新将在 9 月 1 日返回。如果我不得不猜测,现代/摩比斯的某个人阅读了我的博客,他们想解决他们的问题。在预料到这一点的情况下,我开始准备破解最新的固件。
How I Hacked my Car Part 5: How I Hacked my Car Again

September 1st came and went with no changes to the page, no new firmware updates available. After almost a week a new update was posted, but only to push back the date to September 26th.
9 月 1 日来了又去,页面没有变化,没有新的固件更新可用。将近一周后,发布了新的更新,但只是将日期推迟到 9 月 26 日。
How I Hacked my Car Part 5: How I Hacked my Car Again

Then for good measure they did it once more. This time they pushed the date back to “~October 2022”.
然后,为了更好地衡量,他们再次做到了。这一次,他们将日期推迟到“~2022 年 10 月”。
How I Hacked my Car Part 5: How I Hacked my Car Again

But finally on October 24th, 2022 they released a new set of firmware updates.
但最终在 2022 年 10 月 24 日,他们发布了一组新的固件更新。

Looking Inside 向内看 ⌗

I quickly downloaded the new firmware zip and extracted the files.
我快速下载了新固件 zip 并解压缩了文件。

Wait file(s)? 等待文件?

Instead of the normal, singular enc_system_package_{version}.zip file where were two files:
而不是普通的单数 enc_system_package_{version}.zip 文件,其中有两个文件:
How I Hacked my Car Part 5: How I Hacked my Car Again

One with the expected name of “enc_system_package_134.100.220927.zip” and another one with the name “enc_d2vsystem_package_134.100.220927.zip”.
一个预期名称为“enc_system_package_134.100.220927.zip”,另一个名称为“enc_d2vsystem_package_134.100.220927.zip”。

Using the previously found zip password and encryption keys I was able to unzip and decrypt the enc_system_package_134.100.220927.zip file, but they didn’t work on the other file.
使用以前找到的 zip 密码和加密密钥,我能够解压缩和解密 enc_system_package_134.100.220927.zip 文件,但它们对另一个文件不起作用。

Hyundai changed the keys.
现代换了钥匙。

Same Game, New Round
相同的游戏,新一轮 ⌗

Ok, if I wanted the latest and greatest firmware, I would have to rehack it. But how could I do that?
好吧,如果我想要最新最好的固件,我将不得不重新破解它。但是我该怎么做呢?

My first instinct was to gather some information. Both of the provided zips appeared to be full system updates, so I decided to figure out the difference between the two.
我的第一反应是收集一些信息。提供的两个拉链似乎都是完整的系统更新,所以我决定弄清楚两者之间的区别。

But since Hyundai changed the zip password I had to crack it. Using bkcrack (The tool I learned in Part 1) I was able to successfully decrypt the “d2v” zip using the files from the normal zip.
但是由于现代更改了zip密码,我不得不破解它。使用 bkcrack(我在第 1 部分中学到的工具),我能够使用普通 zip 中的文件成功解密“d2v”zip。

Like usual, most files in the update were encrypted, but the system.img file wasn’t. So, I ran a comparison between the two system.img files. They turned out to be identical.
像往常一样,更新中的大多数文件都已加密,但 system.img 文件未加密。因此,我对两个 system.img 文件进行了比较。结果证明它们是相同的。

The system.img file contains the whole normal system image which the IVI usually boots from. This means the system updates were basically identical except for the keys used.
system.img 文件包含 IVI 通常从中启动的整个正常系统映像。这意味着除了使用的密钥外,系统更新基本相同。

I guess they need to be able to update any vehicle’s head unit with the latest update. Since there are many head units that are still running the old firmware, they need to include an update package that uses the old encryption keys, and they include the second file to update head units that have already been updated previously to use the new keys.
我想他们需要能够使用最新更新更新任何车辆的主机。由于有许多主机仍在运行旧固件,因此它们需要包含使用旧加密密钥的更新包,并且它们包括第二个文件,用于更新之前已更新为使用新密钥的主机。

If this was true, the new zip password and encryption keys would still be in the “old” zip update that I could read. If I could figure those out I could see if I can decrypt the new d2v update and potentially modify it like I did last time.
如果这是真的,新的 zip 密码和加密密钥仍将在我可以读取的“旧”zip 更新中。如果我能弄清楚这些,我可以看看我是否可以解密新的 d2v 更新并可能像上次一样修改它。

Like a key in a haystack but I least I knew which haystack it was this time
就像大海捞针中的钥匙,但我至少知道这次是哪个干草堆⌗

From my previous adventures I knew the update logic was in the /usr/bin/updateagent executable in the recovery image (updateboot.img). After extracting updateagent I got to work decompiling it.
从我之前的冒险中,我知道更新逻辑位于恢复映像 (updateboot.img) 的 /usr/bin/updateagent 可执行文件中。提取updateagent后,我开始对其进行反编译。

Using my previous knowledge of updateagent I quickly figured out the new zip password.
利用我以前对 updateagent 的了解,我很快就弄清楚了新的 zip 密码。
How I Hacked my Car Part 5: How I Hacked my Car Again

I wasn’t able to extract the d2v update zip using the “$09#$모비스98@!OTA$$” password on Windows, but using the unzip command in linux worked flawlessly.
我无法使用“$09#$모비스98@!OTA$$“密码,但在 linux 中使用 unzip 命令可以完美运行。

Now to find the encryption key/iv, as well as the RSA public key used to verify the firmware update’s signature.
现在查找加密密钥/iv,以及用于验证固件更新签名的 RSA 公钥。

Quick Maths 快速数学 ⌗

The update agent binary looked a bit different compared to before. Hyundai must have made some changes.
与以前相比,更新代理二进制文件看起来有点不同。现代一定做了一些改变。

At least one of the changes was how they “stored” the encryption Key and IV in the calcAES128() function.
至少有一个变化是他们如何在 calcAES128() 函数中“存储”加密密钥和 IV。
How I Hacked my Car Part 5: How I Hacked my Car Again

The values I was looking for were “iv” and “key” on lines 114/115. So I started reverse engineering the code to find them.
我正在寻找的值是第 114/115 行的“iv”和“key”。因此,我开始对代码进行逆向工程以找到它们。

The code started by creating what I called “userIV”. This value is a combination of some passed in value and the data found in unk_86510.
代码从创建我称之为“userIV”的东西开始。此值是一些传入值和unk_86510中找到的数据的组合。
How I Hacked my Car Part 5: How I Hacked my Car Again

Then the code combines the data from unk_8651C and the same passed in value to make what I called “userKey”.
然后,代码将来自unk_8651C的数据和相同的传入值组合在一起,形成我所说的“userKey”。
How I Hacked my Car Part 5: How I Hacked my Car Again

After that, the AESDecryptWithKey() function is called twice. The first call decrypts the value in “byte_86528” using the previously made “userIV” as the Key and IV and then stores it into “iv”.
之后,AESDecryptWithKey() 函数被调用两次。第一次调用使用先前创建的“userIV”作为密钥和 IV 解密“byte_86528”中的值,然后将其存储到“iv”中。

The second call decrypts the value in “byte_86538” using “userKey” as the Key and IV and stores it into “key”.
第二次调用使用“userKey”作为密钥和 IV 解密“byte_86538”中的值,并将其存储到“key”中。
How I Hacked my Car Part 5: How I Hacked my Car Again

This is a bit confusing for sure, and I could’ve used better variable names, but at least I now had the chain of logic used to figure out the real encryption Key and IV. The only unknown left was what value was passed in that helps make “userIV” and “userKey”?
这肯定有点令人困惑,我本可以使用更好的变量名称,但至少我现在有了用于计算真实加密密钥和 IV 的逻辑链。唯一未知的是传递了什么值来帮助制作“userIV”和“userKey”?

I looked at the references to the calcAES128() function to see what value was passed in. It appears that it was the first 6 bytes of the value of “variantDataStruct”.
我查看了对 calcAES128() 函数的引用,以查看传入的值。它似乎是“variantDataStruct”值的前 6 个字节。
How I Hacked my Car Part 5: How I Hacked my Car AgainHow I Hacked my Car Part 5: How I Hacked my Car Again

Based on my previous research I knew the variant struct was a data structure used to store various information about the vehicle like: the model, what type of rear-view camera it has, or if it supports HD Radio.
根据我之前的研究,我知道变体结构是一种数据结构,用于存储有关车辆的各种信息,例如:型号、它拥有什么类型的后视摄像头,或者它是否支持高清收音机。

To figure out exactly was was setting variantDataStruct I looked for references to it. There was only 1 other function which used it, receive_variant_data().
为了弄清楚究竟是设置 variantDataStruct,我寻找了它的引用。只有 1 个其他函数使用它,receive_variant_data()。
How I Hacked my Car Part 5: How I Hacked my Car Again

Now this function wasn’t decompiled the nicest but from what I could gather it took in some type of buffer value (named buf) and moved 30 bytes of it to variantDataStruct.
现在这个函数没有最好的反编译,但从我能收集到的信息来看,它采用了某种类型的缓冲区值(名为 buf)并将其中的 30 个字节移动到 variantDataStruct。

So I chased the value of buf, which lead me to the function receive_pd(). In it I saw a log that referred to reading data from the micom.
因此,我追逐了buf的值,这导致了函数receive_pd()。在其中,我看到了一个日志,其中提到了从micom读取数据。
How I Hacked my Car Part 5: How I Hacked my Car Again

Micom? More like MiHaveSeenThisBefore.
米康?更像是 MiHaveSeenThisBefore。⌗

Based on my previous research into the vehicle interactions with the CAN bus I knew the micom was the bridge between the IVI and the vehicle’s CAN bus. Any time the IVI wants to interact with the rest of the vehicle, it has to go through it.
根据我之前对车辆与CAN总线交互的研究,我知道micom是IVI和车辆CAN总线之间的桥梁。每当IVI想要与车辆的其余部分进行交互时,它都必须通过它。

I also knew that it worked by reading and writing packets in this format:
我还知道它通过以下格式读取和写入数据包来工作:

  • Always FF (Byte) 始终 FF(字节)
  • SID (Byte) – Sender ID
    SID (Byte) – 发件人 ID
  • RID (Byte) – Receiver ID
    RID (Byte) – 接收方 ID
  • Type: (Byte) 类型:(Byte)
  • Function (Int16, Big Endian)
    函数 (Int16, Big Endian)
  • Payload Length (Int16, Big Endian)
    有效负载长度(Int16,大端序)
  • Payload (Array of {Payload Length} Bytes)
    Payload ({Payload length} 字节数组)

So updateagent must send a packet to the micom requesting the variant data and the micom responds with the data that eventually ends up in variantDataStruct.
因此,updateagent 必须向 micom 发送一个数据包来请求变体数据,而 micom 会使用最终出现在 variantDataStruct 中的数据进行响应。

By moving up the call chain I came to the request_variant_info() function. In it, it saves some data to the v4 variable which appears to be a packet. (Lines 11-12)
通过向上移动调用链,我来到了 request_variant_info() 函数。在其中,它将一些数据保存到 v4 变量中,该变量似乎是一个数据包。(第 11-12 行)
How I Hacked my Car Part 5: How I Hacked my Car Again

Due to endian weirdness, the two sections of the packet are reversed. So the packet is: FF8A010101170001
由于字节序的怪异性,数据包的两个部分被颠倒了。所以数据包是:FF8A010101170001

Splitting it out reveals the following structure:
拆分它可显示以下结构:

  • Packet Start: FF 数据包开始:FF
  • Sender ID (SID): 8A
    发件人 ID (SID):8A
  • Receiver ID (RID): 01
    接收机 ID (RID):01
  • Type: 01 类型: 01
  • Function: 0117 功能:0117
  • Payload Length: 0001 有效载荷长度:0001
  • Payload: 98 (Checksum byte)
    有效负载:98(校验和字节)

So if I could send this packet to the micom and receive the response, I could take the first 6 bytes of it and use it to decrypt the encryption key/IV!
因此,如果我可以将此数据包发送到 micom 并接收响应,我可以获取它的前 6 个字节并使用它来解密加密密钥/IV!

Since in Part 4 I made an app which I could use to interface with the micom, I used to to send the above packet. Since I was sending it through the micom_mux socket and not directly to /dev/tcc_ipc like how update agent does it, I did not add the checksum byte since the micomd process would do that for me.
由于在第 4 部分中,我制作了一个可用于与 micom 交互的应用程序,因此我曾经发送上述数据包。由于我是通过 micom_mux 套接字发送它,而不是像更新代理那样直接发送到 /dev/tcc_ipc因此我没有添加校验和字节,因为 micomd 进程会为我这样做。

I sent “FF8A010101170001” through and received the following: “FF018A0181171642??????????????????????????????????????????…” (censored payload) a successful response packet which is decoded to:
我发送了“FF8A010101170001”,并收到了以下内容:“FF018A0181171642??????????????????????????????????????????…”(删失有效负载)一个成功的响应数据包,它被解码为:

  • Packet Start: FF 数据包开始:FF
  • Sender ID (SID): 01
    发件人 ID (SID):01
  • Receiver ID (RID): 8A
    接收器 ID (RID):8A
  • Type: 01 类型: 01
  • Function: 8117 功能:8117
  • Payload Length: 1642 有效载荷长度:1642
  • Payload: {0x1642 bytes} 有效负载:{0x1642 字节}

I now had my value of variantDataStruct.
我现在有了我的 variantDataStruct 值。

I went back to the calcAES128() to figure out the values of userIV and userKey.
我回到calcAES128()来计算userIV和userKey的值。
How I Hacked my Car Part 5: How I Hacked my Car Again

It looked simple enough but I did not trust myself, so I just copied the pseudo C and converted it to C#. I filled in variantData with the payload of the get variant data packet and ran it:
它看起来很简单,但我不相信自己,所以我只是复制了伪 C 并将其转换为 C#。我用获取变体数据包的有效负载填充了 variantData 并运行了它:
How I Hacked my Car Part 5: How I Hacked my Car Again

It gave me a key and IV which I prompty used to decrypt the files from the d2v zip.
它给了我一个密钥和 IV,我提示使用它来解密 d2v zip 中的文件。
How I Hacked my Car Part 5: How I Hacked my Car Again

“bad decrypt”? 🙁 “坏解密”?:(

I had something wrong. I thought back on it and realized that the variant data for each vehicle model should be relatively unique, since each vehicle model has different capabilities. And if the variant data was different between cars, they would have different calculated keys/ivs and therefor different encrypted files.
我做错了什么。我回想了一下,意识到每个车型的变体数据应该是相对唯一的,因为每个车型都有不同的功能。如果汽车之间的变体数据不同,它们将具有不同的计算密钥/iv,因此具有不同的加密文件。

To check if this was true I downloaded the same update version for the Elantra and compared some of the encrypted files in the update to the one for the Ioniq.
为了检查这是否属实,我下载了与伊兰特相同的更新版本,并将更新中的一些加密文件与 Ioniq 的文件进行了比较。

To my suprise, all of the files I compared were identical. This meant that the first 6 bytes from the variantData Struct must be identical between models.
令我惊讶的是,我比较的所有文件都是相同的。这意味着 variantData Struct 中的前 6 个字节在模型之间必须相同。

After this I attempted many things like double checking my code, re-getting the variant data packet, even trying to brute force the missing 6 bytes. All with no success. Eventually, I realized that the variantDataStruct contained not only the payload of the packet but the header of the packet as well.
在此之后,我尝试了很多事情,例如仔细检查我的代码,重新获取变体数据包,甚至尝试暴力破解丢失的 6 个字节。一切都没有成功。最终,我意识到 variantDataStruct 不仅包含数据包的有效负载,还包含数据包的标头。

The key to solving this was right in my face. The start of the header of the response packet was the 6 bytes I was looking for.
解决这个问题的关键就在我的面前。响应数据包标头的开头是我正在寻找的 6 个字节。

By setting the variant data to “FF018A0181171642” and running the code, it gave me the following Key and IV:
通过将变体数据设置为“FF018A0181171642”并运行代码,它给了我以下 Key 和 IV:

Key: F4DA05A5E848309EE8377464CF4254A3
键:F4DA05A5E848309EE8377464CF4254A3

IV: 763AC2AFAC9E8EE379788B6CC08612B0
四:763AC2AFAC9E8EE379788B6CC08612B0

And it worked!  它奏效了!How I Hacked my Car Part 5: How I Hacked my Car Again

This was all very necessary for the security of the IVI and not at all convoluted.
这对于IVI的安全都是非常必要的,而且一点也不复杂。

66.6% Completed 66.6% 完成 ⌗

I now could decrypt the entire system update. With that, I finally verified that the two update files (the normal one and the d2v one) were in fact identical.
我现在可以解密整个系统更新。有了这个,我终于验证了两个更新文件(普通文件和 d2v 文件)实际上是相同的。

I also spent time looking for the RSA Public Key which is used to verify the firmware signature.
我还花时间寻找用于验证固件签名的 RSA 公钥。

I eventually found a function which I called decryptPublicKey(). This function called calcAES128() just like the encryption keys, but it instead goes through a different branch of the function. This second branch creates the bytes which are used as the key and IV to decrypt the “/usr/share/pub_key/updatePublic.info” file into the actual public key.
我最终找到了一个我称之为 decryptPublicKey() 的函数。此函数调用 calcAES128() 就像加密密钥一样,但它通过函数的不同分支。第二个分支创建用作密钥的字节,IV 将“/usr/share/pub_key/updatePublic.info”文件解密为实际的公钥。
How I Hacked my Car Part 5: How I Hacked my Car AgainHow I Hacked my Car Part 5: How I Hacked my Car Again

I once again copied the decompiled code, turned it into C#, ran it and it gave me the key/iv: FF018A018117D0AD830AD5A7DABEDA72
我再次复制了反编译的代码,将其转换为 C#,运行它,它给了我 key/iv:FF018A018117D0AD830AD5A7DABEDA72

Nice, although I am not sure why they even bothered to try to encrypt the public key in the first place (It is a Public Key after all, it is fine if it is publicly known.).
很好,虽然我不确定为什么他们一开始就费心尝试加密公钥(毕竟它是公钥,如果它是公开的就好了。

I then used the found key/iv to decrypt the public key:
然后我使用找到的密钥/iv 来解密公钥:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApTCnVgqDkrE4VrnuEI5G
slnmP6GmO03Pg0RuW1wzWsP9BybsNX4GuULSCqr3MsZWOquSO3ftEM9c59LSuTli
9LE57zsfohoieeeFaE1mFW5fLio+AQhwpeEVIeOLzt/gX/bcq0c+JKcwEawpOxM0
GhMenNdA+jaODjlhK1cqjrTdBQUPcQNBguAbNU6VVufjmAsNTwT7hUVEvdZIllIo
RE8c3lQqRy7eV1nQxxQXiGSK/YkcAfjgmaSuLamdgBUcbc8s8wMs6xoXbJqxFXW1
2zDMXPD98g/mysGZgzfQPfr2w1r4b5q7wvC0kbhrcZFuJ9mmf1cufzB2NgMvzZJ6
qQIDAQAB
-----END PUBLIC KEY-----

I also googled the key but it appears it was uniquely generated, unlike last time.
我也用谷歌搜索了密钥,但与上次不同,它似乎是唯一生成的。

0% Completed? 0% 完成?⌗

The RSA public key was actually unique. This meant I had no idea what the private key is and I wouldn’t be able to sign custom firmware updates.
RSA 公钥实际上是唯一的。这意味着我不知道私钥是什么,也无法签署自定义固件更新。

Rant for Hyundai/Mobis
现代/摩比斯的咆哮 ⌗

This all goes to show that the security by obscurity that Hyundai/Mobis is practicing here is completely unnecessary. Hiding the keys doesn’t matter if you have a proper security setup. Even if the zip password, encryption key/iv, and the RSA Public Key are publically published, their firmware updates would still be secure since they used a uniquely generated RSA Public/Private key pair. All this does is make the original code harder to read and maintain. It may even make it easier to miss something security wise because it is harder to read. Think of the programmers!
这一切都表明,现代/摩比斯在这里实行的隐蔽性是完全没有必要的。如果您有适当的安全设置,隐藏密钥并不重要。即使 zip 密码、加密密钥/iv 和 RSA 公钥公开发布,它们的固件更新仍然是安全的,因为它们使用了唯一生成的 RSA 公钥/私钥对。所有这些都使原始代码更难阅读和维护。它甚至可能使人们更容易错过一些安全方面的东西,因为它更难阅读。想想程序员!

Rant over but seriously lets hack it
咆哮,但认真地让我们破解它⌗

So nice job Hyundai/Mobis on security, anyways… Through my decompiling of updateAgent I found something very interesting.
无论如何,现代/摩比斯在安全方面做得很好……通过对updateAgent的反编译,我发现了一些非常有趣的东西。

Firmware updates do not have to be encrypted.
固件更新不必加密。

In the function that I called “unzipUpdate” there are two logical branches:
在我称为“unzipUpdate”的函数中,有两个逻辑分支:
How I Hacked my Car Part 5: How I Hacked my Car Again

One branch unzips the zip on the USB drive with the password I found, and the other unzips it without one. Here is the general logic of how updateAgent handles firmware updates:
一个分支使用我找到的密码解压缩 USB 驱动器上的 zip,另一个分支在没有密码的情况下解压缩它。以下是 updateAgent 处理固件更新的一般逻辑:
How I Hacked my Car Part 5: How I Hacked my Car Again

To the untrained eye this might seem fine, but to my expertly trained Security Eye™️ I could see a potential vulnerability.
对于未经训练的人来说,这似乎很好,但对于我受过专业训练的安全眼睛™️来说,我可以看到一个潜在的漏洞。

One of those branches just doesn’t have any security checks.
其中一个分支机构没有任何安全检查。

If I could make the system take an unencrypted update file (system_update.zip) I could modify it however I wanted.
如果我可以让系统采用未加密的更新文件(system_update.zip),我可以随心所欲地修改它。

95%? 95%?⌗

The first step to flashing an unencrypted firmware update is of course to make an unencrypted firmware update.
刷新未加密固件更新的第一步当然是进行未加密的固件更新。

From the get-go I decided to make a C# utility to help with automating the process of creating an unencrypted firmware update.
从一开始,我就决定制作一个 C# 实用程序来帮助自动创建未加密的固件更新。

I creatively called it “HyundaiFirmwareDecrypter”. Source Download
我创造性地称它为“HyundaiFirmwareDecrypter”。源代码下载

I engineered it to have discrete “steps”. Each step is one, well step in the process to make the decrypted update zip.
我设计它具有离散的“步骤”。每个步骤都是使解密的更新zip过程中的一个步骤。

The available steps are:
可用的步骤包括:

  1. Extract – Extracts a d2v formatted zip to a temporary directory.
    Extract – 将 d2v 格式的 zip 解压缩到临时目录。
  2. Decrypt – Decrypts all of the extracted files if necessary. (Also renames the folders that start with “enc_” to not have that)
    解密 – 如有必要,解密所有提取的文件。(还要重命名以“enc_”开头的文件夹,使其没有)
  3. Install ADB Backdoor – Enables the Android Debug Bridge TCP server which can be used to access a root shell. (Needs to be run as root/sudo)
    安装 ADB 后门 – 启用可用于访问 root shell 的 Android 调试桥 TCP 服务器。(需要以 root/sudo 身份运行)
  4. Calculate Hashes – Calculates the SHA512 hashes for every file in the update and compiles them into the update.list file
    计算哈希值 – 计算更新中每个文件的 SHA512 哈希值,并将它们编译到 update.list 文件中
  5. Create Zip – Zips up all of the files, creating the system_update.zip update file.
    创建 Zip – 压缩所有文件,创建system_update.zip更新文件。

The utility was made to run only the steps specified. This makes it easy to do custom modifications as you can run the first two steps; Extract and Decrypt. Then make the changes you want to the system files, followed by running the Calculate Hashes and Create Zip steps which will compile your changes into the firmware update file.
该实用程序仅运行指定的步骤。这使得进行自定义修改变得容易,因为您可以运行前两个步骤;提取和解密。然后对系统文件进行所需的更改,然后运行“计算哈希值”和“创建 Zip”步骤,这些步骤会将更改编译到固件更新文件中。

Or if you want a more “one-click-solution”, you run the “Install ADB Backdoor” (-i) step, which will enable the ADB TCP server in the firmware update. This means you can simply connect to the head unit’s Wi-Fi or use an ethernet connection and the adb tool to get a root shell. For more information see How I Hacked my Car Guides: Creating Custom Firmware
或者,如果您想要更“一键式解决方案”,请运行“安装 ADB 后门”(-i) 步骤,这将在固件更新中启用 ADB TCP 服务器。这意味着您只需连接到主机的 Wi-Fi 或使用以太网连接和 adb 工具来获取 root shell。有关更多信息,请参阅我如何入侵我的汽车指南:创建自定义固件

There is also an easy to use “-a” argument which runs through every step to make an unencrypted firmware file with the ADB backdoor.
还有一个易于使用的“-a”参数,它贯穿于使用 ADB 后门制作未加密固件文件的每个步骤。

I took the compiled x64 linux binary and threw it in a new folder on my Kali VM. I then transfered over the latest firmware update zip for my IVI (enc_d2vsystem_package_134.100.220927.zip) into the same folder.
我获取了编译后的 x64 linux 二进制文件并将其放入 Kali VM 上的一个新文件夹中。然后,我将IVI(enc_d2vsystem_package_134.100.220927.zip)的最新固件更新zip传输到同一文件夹中。

How I Hacked my Car Part 5: How I Hacked my Car Again

I then ran the following command which create a backdoored firmware update:
然后,我运行了以下命令,该命令创建了后门固件更新:

sudo ./HyundaiFirmwareDecrypter enc_d2vsystem_package_134.100.220927.zip -a

After a minute of waiting I had a backdoored, unencrypted firmware update in hand. All I had to do was figure out how to flash it.
经过一分钟的等待,我手头有一个后门、未加密的固件更新。我所要做的就是弄清楚如何刷新它。

I should really stop using the term “all I had to do”
我真的应该停止使用“我必须做的所有事情”这个词⌗

Ok, ok I am being a little dramatic with the subtitle here. Flashing the update on my car was actually pretty easy.
好吧,好吧,我在这里的副标题有点戏剧化。在我的车上刷新更新实际上很容易。

My head unit was running version 098.152.211130, the last update before Hyundai fixed the issues I previously found.
我的主机运行的是版本 098.152.211130,这是现代修复我之前发现的问题之前的最后一次更新。

Because it was before their security audit, it was more lax with the features that could be used to flash unauthorized updates.
因为它是在他们的安全审计之前,所以它对可用于刷新未经授权的更新的功能更加宽松。

In the Engineering Mode there was an option called “USB Image”
在工程模式下,有一个名为“USB 映像”的选项
How I Hacked my Car Part 5: How I Hacked my Car Again

The “Update ALL” button would make the IVI reboot into recovery mode and flash the system_update.zip file from the flash drive, following the beautiful flowchart I made above.
“全部更新”按钮将使IVI重新启动到恢复模式,并按照我上面制作的精美流程图从闪存驱动器刷新system_update.zip文件。

After one button press and a little bit of waiting I had my IVI flashed with the latest and greatest update all while keeping my root access. (I definitely did not mess up the hashing or zip format multiple times leading to countless debugging sessions and trips back and forward between the car and my workstation haha of course not.)
按下一键并稍作等待后,我的 IVI 闪烁着最新和最伟大的更新,同时保持我的 root 访问权限。(我绝对没有多次搞砸哈希或 zip 格式,导致无数次调试会话和在汽车和我的工作站之间来回跳动,哈哈,当然不是。

Yay? 耶?⌗

This is great for me, I still have my head unit backdoored and it is running the latest and greatest firmware. But what about everyone else?
这对我来说很棒,我的主机仍然在后门,它正在运行最新和最好的固件。但是其他人呢?

I decided to look into the latest firmware and see if it could be hacked, and don’t worry, I found another way in.
我决定研究最新的固件,看看它是否可以被黑客入侵,别担心,我找到了另一种方法。

Through my endevors into researching how the head unit works I have decompiled countless functions in countless (~47) applications.
通过对主机工作原理的研究,我已经在无数(~47)个应用程序中反编译了无数函数。

One of the most decompiled is the Engineering Mode app. For good reason too, it has some of the most interesting functionality in the whole system.
最反编译的应用程序之一是工程模式应用程序。这也是有充分理由的,它在整个系统中具有一些最有趣的功能。

And throughout the code I saw many mentions of a “Force Update” popup in the app’s Variant Coding section. Based on the code I decompiled it was clear what it did. It would try to find any system update-looking zip file in the usb drive and reboot into recovery mode with that as the selected update file.
在整个代码中,我看到在应用程序的变体编码部分多次提到“强制更新”弹出窗口。根据我反编译的代码,它的作用很清楚。它将尝试在 USB 驱动器中找到任何具有系统更新外观的 zip 文件,并将其作为选定的更新文件重新启动到恢复模式。

I even saw that it had some kind of password screen to access it. (And the password was 3600 based on the MD5 hash)
我什至看到它有某种密码屏幕来访问它。(根据 MD3600 哈希值,密码为 5)
How I Hacked my Car Part 5: How I Hacked my Car Again

After a small adventure/tangent in trying to figure out all of the SetupApp’s secrets I came back to the Engineering Mode app and decided to figure out how to get to this screen.
在试图弄清楚 SetupApp 的所有秘密之后,我回到了工程模式应用程序,并决定弄清楚如何进入这个屏幕。

Based on many strings I found in the binary, the Forced Update screen was somehow linked to the Variant Coding screen.
根据我在二进制文件中发现的许多字符串,“强制更新”屏幕以某种方式链接到“变体编码”屏幕。
How I Hacked my Car Part 5: How I Hacked my Car Again

Because no entries related to system updates were visible on the Variant Coding screens I knew there were to possibilities: One was that the feature was disabled on production IVIs, or there was some secret way to get into the screen, like how Engineering Mode or Dealer Mode are entered.
因为在变体编码屏幕上看不到与系统更新相关的条目,所以我知道有各种可能性:一种是该功能在生产 IVI 上被禁用,或者有一些秘密方式进入屏幕,例如如何进入工程模式或经销商模式。

I looked deeper. I did not find the screen mentioned where the Variant Coding UI was built, so it wasn’t just a menu option for development-only units. I also did not have much luck in finding hidden buttons like the ones used to get into Engineering Mode. So, I started looking for functions that used key presses like Dealer Mode.
我看得更深了。我没有找到提到的构建变体编码 UI 的屏幕,因此它不仅仅是仅开发单元的菜单选项。我也没有太多运气找到隐藏的按钮,比如那些用于进入工程模式的按钮。因此,我开始寻找使用按键的功能,例如荷官模式。

To get into Dealer Mode you have to:
要进入荷官模式,您必须:

  • Set the volume to 7, the press in the tune knob,
    将音量设置为 7,按下调谐旋钮,
  • Set the volume to 3, the press in the tune knob,
    将音量设置为 3,按下调谐旋钮,
  • Set the volume to 1, the press in the tune knob
    将音量设置为 1,按下调谐旋钮

One the tune knob is pressed for the final time, a password screen is displayed. Once the password (2400) is entered the Dealer Mode app is started.
最后一次按下调谐旋钮后,将显示密码屏幕。输入密码 (2400) 后,将启动经销商模式应用程序。

Funnily enough, while looking through the functions related to VariantCodingDisplay, I found one that fired when the tune knob was pressed.
有趣的是,在查看与 VariantCodingDisplay 相关的函数时,我发现了一个在按下调谐旋钮时触发的函数。
How I Hacked my Car Part 5: How I Hacked my Car Again

This function happened to be fairly easy to read. It seemed to follow the same pattern that Dealer Mode used.
这个函数恰好相当容易阅读。它似乎遵循与经销商模式相同的模式。

This time the combination was 7, 5, 3 instead of 7, 3, 1.
这次的组合是 7、5、3 而不是 7、3、1。

Because this event was on VariantCodingDisplay directly I guessed that if I were to enter in that code using the volume and tuner knobs while on the Variant Coding screen, the Forced Update password input would show.
因为这个事件直接在 VariantCodingDisplay 上,我猜如果我在 Variant Coding 屏幕上使用音量和调谐器旋钮输入该代码,就会显示强制更新密码输入。

To my car I went. I entered Engineering mode only to find they updated the password (And made it twice as long!). Luckily the password list is easily found in the Engineering Mode app and is also listed in many places online.
我去了我的车。我进入工程模式,却发现他们更新了密码(并使其长度增加了一倍!幸运的是,密码列表可以在工程模式应用程序中轻松找到,并且还在线许多地方列出。

The Engineering Mode password that worked for me was 26031236.
对我有用的工程模式密码是26031236。

Variant Coding has its own password entry and that also got a shiny, new, longer password. Using the same list I linked above I figured out the code was 23060663.
Variant Coding 有自己的密码条目,并且还获得了一个闪亮的、新的、更长的密码。使用我上面链接的相同列表,我发现代码是23060663的。

Once I was in the Variant Coding menu, I dialed in the secret volume code.
进入“变体编码”菜单后,我拨入了秘密音量代码。

7, *tune knob*, 5, *tune knob*, 3, *tune knob*…
7、*调谐旋钮*、5、*调旋钮*、3、*调旋钮*…

And voilà:  瞧:How I Hacked my Car Part 5: How I Hacked my Car Again

After entering the previously found password “3600” it quickly scanned my flash drive and suggested to flash my unencrypted update.
输入之前找到的密码“3600”后,它快速扫描了我的闪存驱动器,并建议刷新我未加密的更新。
How I Hacked my Car Part 5: How I Hacked my Car Again

After selecting “Yes” the head unit rebooted and successfully reinstalled my update file. This also means it did not do any version checks as the versions were the same. This means this “Force Update” feature could be used to downgrade the head unit if need be.
选择“是”后,主机重新启动并成功重新安装了我的更新文件。这也意味着它没有进行任何版本检查,因为版本是相同的。这意味着如果需要,此“强制更新”功能可用于降级主机。

The Result 结果 ⌗

D-Audio 2V based head units are now once again open for tinkering and modifications.
基于 D-Audio 2V 的音响主机现在再次开放进行修补和修改。

But wait, has this all happened just for it to be Doomed in the end?
但是等等,这一切的发生只是为了最终注定要失败吗?

A Little Message to Hyundai/Mobis
给现代/摩比斯的一点信息 ⌗

I know I have very little sway in your company’s business decisions, and I know you already have big plans for ccOS, but I would appreciate it if you would listen nonetheless.
我知道我对贵公司的业务决策几乎没有影响,而且我知道您已经对 ccOS 制定了宏伟的计划,但如果您愿意倾听,我将不胜感激。

I think this platform you developed is really cool and has a lot of potential. But I believe having this platform locked down is a mistake.
我认为您开发的这个平台真的很酷,并且具有很大的潜力。但我认为锁定这个平台是一个错误。

Sometime in the future, maybe not today but not too far from now, you will stop supporting these head units. Whether it be just not adding new features (I think we are already past this), not fixing bugs, or just not supporting the platform in general, there will be a time where these neat gadgets will no longer be supported.
在未来的某个时候,也许不是今天,但离现在不远,您将停止支持这些主机。无论是不添加新功能(我认为我们已经过去了),不修复错误,还是只是不支持平台,总有一天将不再支持这些整洁的小工具。

The head unit is where remote start, remote climate controls, and remote monitoring are done. Not to mention where navigation, and music playback occurs.
主机是完成远程启动、远程气候控制和远程监控的地方。更不用说导航和音乐播放发生的位置了。

If BlueLink just stops working one day, if Android Auto, Apple CarPlay, or simple music playback just starts getting glitchy, or if a bug like the Year 2038 problem occurs. The value, longevity, and usefulness of our vehicles will be severely degraded.
如果 BlueLink 有一天停止工作,如果 Android Auto、Apple CarPlay 或简单的音乐播放开始出现故障,或者出现像 2038 年这样的错误问题。我们车辆的价值、寿命和实用性将严重下降。

But unlike most other parts of the vehicle that we can just replace when they break, we won’t be able to do this for the head unit. Don’t get me wrong, I am aware aftermarket head units exists, but due to the proprietary nature of them nothing will actually be able to replace the original head unit in terms of its functionality, especially the tight vehicle integration.
但与车辆的大多数其他部件不同,我们可以在它们损坏时更换它们,我们将无法为主机做到这一点。不要误会我的意思,我知道售后市场主机的存在,但由于它们的专有性质,就其功能而言,实际上没有什么能够取代原来的主机,尤其是紧密的车辆集成。

This leads to my suggestion. If you were to open up the platform, vehicle owners, or even other businesses could pick up where you left off and support it for much longer.
这导致了我的建议。如果你要开放这个平台,车主,甚至其他企业都可以从你离开的地方继续,并支持它更长的时间。

By “opening up the platform” I mean make the system support externally developed applications and/or externally developed system updates. You would not need to open source all of your code. Although that would be nice, I understand the want or need to protect the company’s (Or other company’s) intellectual property.
通过“开放平台”,我的意思是使系统支持外部开发的应用程序和/或外部开发的系统更新。您不需要开源所有代码。虽然这很好,但我理解保护公司(或其他公司)知识产权的愿望或需要。

I also understand everything is not black and white, I know there are also considerations like reducing legal liability. But then again, any idiot can duct tape a tablet to their car, plug in a OBD2 dongle and be just as dangerous (If not more so). If the platform is opened, ccOS and other available APIs can in fact be a safe guard against anything that would negatively impact the vehicle. Making developing apps for the head units the safer choice compared to trying to play around with the CAN bus directly. Because of all of this and more, I recommend opening up the platform.
我也明白一切都不是非黑即白的,我知道还有一些考虑因素,比如减少法律责任。但话又说回来,任何白痴都可以在他们的车上贴上平板电脑,插入 OBD2 加密狗并且同样危险(如果不是更危险的话)。如果平台是开放的,ccOS和其他可用的API实际上可以成为防止任何会对车辆产生负面影响的东西的安全保障。与直接尝试使用CAN总线相比,为主机开发应用程序是更安全的选择。由于所有这些以及更多,我建议开放平台。

Here is a little layout of what I think would need to be done to make the platform “open”:
以下是我认为要使平台“开放”需要做的事情的一个小布局:

  • Provide the system header files so applications can be developed.
    提供系统头文件,以便开发应用程序。

    • This can be as simple as once again including header files in the system updates, like you use to do.
      这可以像以前一样在系统更新中再次包含头文件一样简单。
  • Provide a way for applications/firmware update to be installed.
    提供安装应用程序/固件更新的方法。

    • Simplest option is re-enabling the “Update ALL” button in Engineering Mode to allow for unencrypted updates. (Or keep the current Forced Update feature.)
      最简单的选项是在工程模式下重新启用“全部更新”按钮,以允许未加密的更新。(或保留当前的强制更新功能。
    • I also should say that this should not require express Hyundai/Mobis permission. Like requiring a specific key from Hyundai/Mobis to “unlock” the head unit. As this would still require you to maintain this feature and it wouldn’t help people who need to unlock it after you stopped giving out keys.
      我还应该说,这不应该需要现代/摩比斯的明确许可。就像需要现代/摩比斯的特定钥匙来“解锁”主机一样。因为这仍然需要您维护此功能,并且在您停止发放钥匙后需要解锁它的人不会提供帮助。

There is also a number of things that could be done that would be nice and help with opening up the platform, but would not be necessary by any means.
还有很多事情可以做,这些事情会很好,有助于开放平台,但无论如何都不是必需的。

  • Making the apps list dynamic and allow for new apps to be added and launched from the home screen.
    使应用程序列表动态,并允许从主屏幕添加和启动新应用程序。

    • This could be easily done by loading the available apps from a .json file.
      这可以通过从.json文件加载可用的应用程序来轻松完成。
  • Making ccOS documentation publicly available to help in the development of ccOS integrated applications.
    公开 ccOS 文档,以帮助开发 ccOS 集成应用程序。
  • Continued development of ccOS and ccOS APIs for existing vehicles.
    继续为现有车辆开发 ccOS 和 ccOS API。
  • Publicly available documentation on how to setup a development environment for D-Audio 2V applications.
    有关如何为 D-Audio 2V 应用程序设置开发环境的公开文档。
  • Making some of/parts of the built in apps open source to serve as examples.
    将内置应用程序的某些/部分开源以作为示例。
  • Making some kind of installer system to make adding or updating apps easier.
    制作某种安装程序系统,使添加或更新应用程序更容易。

    • This may be necessary to develop in the future to allow for live OTA updates anyways.
      这可能需要在未来开发,以允许实时 OTA 更新。
  • A custom, Hyundai/Mobis run marketplace for applications, including approved apps made by other developers (Like an App Store)
    现代/摩比斯为应用程序定制的市场,包括由其他开发人员制作的批准应用程序(如 App Store)
  • Have a tier in BlueLink or otherwise to pay for just SIM data (+ a small surcharge?). It would allow applications to be developed that use the internet and also give you a small but reliable continued revenue stream, even after BlueLink shuts down.
    在 BlueLink 或其他方式中有一个层,只需支付 SIM 卡数据(+ 少量附加费?它将允许开发使用互联网的应用程序,并为您提供少量但可靠的持续收入来源,即使在 BlueLink 关闭后也是如此。

In a time where companies are locking down their platforms and reducing functionality, you could be the company that breaks the mold. Hyundai has the chance to be a leader here and guide the industry to be more open as a whole, benefiting everyone involved.
在公司锁定其平台并减少功能的时代,您可能是打破常规的公司。现代汽车有机会成为这里的领导者,并引导整个行业更加开放,使所有相关人员受益。

Of course, time will always continue marching onward and some day the head units will become outdated and will no longer be serviceable by anyone but until then, please allow the community to support these devices.
当然,时间总是会继续前进,总有一天主机会过时,任何人都无法再使用,但在此之前,请允许社区支持这些设备。

Thanks for reading, 感谢您的阅读,

-greenluigi1 -格林路易吉1

原文始发于Programming With Style:How I Hacked my Car Part 5: How I Hacked my Car Again

版权声明:admin 发表于 2024年6月9日 上午9:48。
转载请注明:How I Hacked my Car Part 5: How I Hacked my Car Again | CTF导航

相关文章