- Hacking my Tesla Model 3 - Internal API
- Hosts
- Data Values
- Fetching all Data Values
- Setting a Data Value
- CID/ICE Services
- Hermes
- Odin
- DebugService - :4035
- VehicleService - :4030
- TelemetryService - :4032
- CenterDisplay/QtCar interface - :4070
- CarServer - :7654
- /diag_vitals
- /Alerts
- /ServiceStatus
- APE/ICE Updater
- HTTP Methods
- /readsig
- /status
- /install
- /reset
- /handshake
- /service-redeploy
Hacking my Tesla Model 3 - Internal API
This is a technical description of all the internal services I’ve found and notes about how they work.
All of these services described are normally unaccessible due to seceth and firewall rules.
Hosts
192.168.90.100 cid ice
192.168.90.100 ic
192.168.90.102 gw
192.168.90.103 ap ape
192.168.90.104 lb
192.168.90.105 ap-b ape-b
192.168.90.30 tuner
192.168.90.60 modem
Tuner isn’t present on newer Model 3s as the AM/FM radio has been removed. I’m not sure what lb is.
Data Values
Much of the UI and CID/ICE services are based off of “data values”. These are shared KV pairs between most of the services running on the UI. These appear to be propagated between services and nodes via UDP multicast.
softool.cn Notes:
propagate 英 [ˈprɒpəgeɪt] 美 [ˈprɑpəgeɪt] vt.繁衍,增殖; 使遗传; 扩散; 使蔓延;vi.繁殖; 扩大; [物] 通过媒介传送;
Many of the values seem to be “read only” such as the VAPI_
values which seem to come from the Gateway. Some values are propagated back to the Gateway and the rest of the car such as the various GUI requests (ex: GUI_blinkerRequest
, GUI_pedestrianWarningMuteRequest
).
A lot of these data values are not Model 3 specific and are only present in the Model S/X and have little to no effect.
Here’s the provided when you query the car. This is only the keys and not the values themselves since there might be personal/car specific information in there. If you do have any questions on specific ones feel free to reach out to me.
You can query the DebugService at port 4035 to view and set these values.
Fetching all Data Values
$ curl http://cid:4035/Debug/get_data_values?format=csv&show_invalid=true
softool.cn Notes:
Fetch 英 [fetʃ] 美 [fɛtʃ] vt.接来(某人); 使发出; 吸引; 售得(若干价钱);vi.抵达,到达; 取来; 卖得(好价钱);n.拿取,拿来; 诡计; 风浪区;
Setting a Data Value
$ curl http://cid:4035/set_data_value?name=GUI_trackMode&value=true
CID/ICE Services
See the full list of QT based services on CID/ICE + ports at services.cfg. This config appears to be how the various services know how to talk to each other. Port is typically a HTTP service. DataPort I suspect is for propagating data values between services but I’m not 100% sure.
Hermes
Hermes is the secure tunnel that the car uses to talk to Tesla.
softool.cn Notes:
tunnel 英 [ˈtʌnl] 美 [ˈtʌnəl] n.隧道; 地道; 烟道; (动物栖息的)穴;vi.打通隧道; 挖掘隧道;vt.在…挖掘隧道; 在…打开通道;
Odin
Odin is a service running on the car for service/support/engineering can use to debug and control the car.
DebugService - :4035
This service lets you get/set data values as well as get other metadata about the car.
/Debug/vitals
/Debug/get_data_values?format=csv&show_invalid=true
/set_data_value?name=<>&value=<>
/do_not_sleep?minutes=15&reason=updater
/mothership_bandwidth
/emmc_vitals
/ServiceStatus
/Debug/get_data_values
VehicleService - :4030
Only really seeing things calling it for alerts.
/sendAlert
/requestAccPower
/sendAlertForUnexpectedExetingProcess
/alert_kernel_panic
/sendGpuHangAlert
TelemetryService - :4032
/send_network_data
/yubikey_added
/yubikey_removed
The udev rules on the car send back information about any yubikeys inserted into the car. I’m not really sure why Tesla has yubikey support. It’s possibly for development purposes or factory purposes for 2FA to provision the car?
CenterDisplay/QtCar interface - :4070
This is the graphical QT app running on the car display.
/display_message
/screenshot
/ensure_power_on
/setStorageRunningLow
/_data_set_value_request_
/update_spool_folder_created
/update_failed?early_failure=true
You can display messages on the screen via:
$ curl http://192.168.90.100:4070/display_message?message=owned
Displaying messages on the screen using the internal API. Version 2020.12.11.1
CarServer - :7654
/alerts
/ServiceStatus
/diag_vitals
/get_message_names
/upcoming_calendar_entries
/update_remote_files
/schedule_software_update
/cancel_software_update
/diag_vitals
This returns a big blob of JSON with diagnostic vital info about the car.
/Alerts
$ curl http://192.168.90.100:7654/Alerts
{ }
/ServiceStatus
$ curl http://192.168.90.100:7654/ServiceStatus
{"uptime":7598, "requests":68, "avgtime":-1.0, "maxtime":0, "info":""}
APE/ICE Updater
The updaters are used to update the car. There’s several variants of them depending on what the binary is named.
The updater can either run as a CLI or as a service. There’s a number of commands only present as CLI presumably for debugging purposes. A subset of the CLI commands are present as part of the HTTP.
Some of the more powerful commands are only enabled for HTTP when the car isn’t fused (presumably for development/factory purposes).
When running as a service they have two ports open. One for HTTP and one for Telnet. You can see more about the telnet/CLI interface at
The updaters are running servers internally at:
- CID:
http://192.168.90.100:20564
and telnet is on25956
- APE:
http://192.168.90.103:28496
- APB:
http://192.168.90.105:28496
HTTP Methods
/readsig
$ curl http://192.168.90.103:28496/readsig
installed_firmware_signature:
<base64 hash>
offline_firmware_signature:
<base64 hash>
/status
ICE
$ curl http://192.168.90.100:20564/status
Executable: /deploy/ice-updater, personality: ice-updater, hash <hex hash>, built for package version: <version>
uptime: <uptime>
/proc/uptime:
<uptime>
current bootdata Contents: <hex data>
Pattern: 0xdeadbeef
Online boot bank: KERNEL_B
Online fail count: 0
Online dot-model-s size: 1243770944
Offline boot bank: KERNEL_A
Offline fail count: 0
Offline dot-model-s size: 1209049152
MCU Board Revision:
Fused: 1
Override-version: 0
Online map bank: BANK_A
Online map package size: 5541724224
Online map signature:
<base64 hash>
Offline map bank: BANK_B
Offline map package size: 0
Offline map signature: NULL
Game: purple
Online games bank: BANK_B
Online games package size: 1134821440
Online games signature:
<base64 hash>
Offline games bank: BANK_A
Offline games package size: 1134821440
Offline games signature:
<base64 hash>
Game: teardrop
Online games bank: BANK_B
Online games package size: 1235193920
Online games signature:
<base64 hash>
Offline games bank: BANK_A
Offline games package size: 1235193920
Offline games signature:
<base64 hash>
running_in_recovery_partition = 0
installed_firmware_signature =
<base64 hash>
offline_firmware_signature =
<base64 hash>
staged_update = no
gateway_needs_update = no
updating_maps = yes
END STATUS
current bootdata Contents: <hex data>
Pattern: 0xdeadbeef
Online boot bank: KERNEL_B
Online fail count: 0
Online dot-model-s size: 1243770944
Offline boot bank: KERNEL_A
Offline fail count: 0
Offline dot-model-s size: 1209049152
MCU Board Revision:
Fused: 1
Override-version: 0
Online map bank: BANK_A
Online map package size: 5541724224
Online map signature:
<base64 hash>
Offline map bank: BANK_B
Offline map package size: 0
Offline map signature: NULL
Game: purple
Online games bank: BANK_B
Online games package size: 1134821440
Online games signature:
<base64 hash>
Offline games bank: BANK_A
Offline games package size: 1134821440
Offline games signature:
<base64 hash>
Game: teardrop
Online games bank: BANK_B
Online games package size: 1235193920
Online games signature:
<base64 hash>
Offline games bank: BANK_A
Offline games package size: 1235193920
Offline games signature:
<base64 hash>
running_in_recovery_partition = 0
installed_firmware_signature =
<base64 hash>
offline_firmware_signature =
<base64 hash>
staged_update = no
gateway_needs_update = no
updating_maps = yes
END STATUS
APE
$ curl http://192.168.90.103:28496/status
Welcome to Gadget Updater - <version> (<hex>)
Uptime: <time>
Current State: Waitjob
Session ID: <id>
Update Phase: Idle
Swapped: Online
Staged: false
Fused: true
Online Bank
Bank: KernelA
Size: <size>
Failcount: 0
Offline Bank
Bank: KernelB
Size: <size>
Failcount: 0
Installed
Signature:<base64 hash>
Offline
Signature:<base64 hash>
Job Details
Type: NoActiveJob
Install URL:
Install Path:
Package Signature:
/install
This sets a URL to download an image from and install it. These images need to have a valid signature. There’s also supposedly a mechanism to prevent downgrades which unfortunately makes it so we can’t downgrade to an known vulnerable firmware.
softool.cn Notes:
mechanism 英 [ˈmekənɪzəm] 美 [ˈmɛkəˌnɪzəm] n.[生]机制,机能,[乐]机理; (机械)结构,机械装置[作用],(故事的)结构; [艺]手法,技巧,途径; 机械作用;
Normally this is used by the cid-updater to transfer the APE firmware image from the CID to the APE to be installed. The APE does appear to have a direct internet connection so I’m not sure why this is strictly necessary. Might be to share the same update code with the S/X cars.
$ curl http://192.168.90.103:28496/install?http://bar
If you run /status again it shows:
Job Details
Type: FullDownload
Install URL: http://bar
Install Path: /dev/sda5
Package Signature:
/reset
I haven’t tried this.
I believe it returns the update status.
/handshake
Does a handshake with the Tesla mothership to check for firmware updates.
/service-redeploy
Triggers a service redeploy installation of the firmware already present on car.