vehsec
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@vehsec> Run a UDS security access on the virtual ECU and show me the seed and key."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
vehsec — Vehicle Security Toolkit
CAN · UDS · Seed-Key · V2X · ICSim · DoIP · DBC — wrapped as a CLI, a TUI, and an MCP server so you (or an AI coding agent) can drive it. No car required.
中文 README / Chinese version · Attack playbook · Launch copy
Why
Vehicle / in-vehicle-network (IVN) security is one of the hottest areas in security research — and one of the most fragmented. The classic tools (CANalyzat0r, UDSim, CANToolz, ICSim, caringcaribou) are aging, Shell-heavy, and thinly documented, so a beginner cannot get started without a real car.
vehsec folds those capabilities into one modern, documented, composable package:
one command, one TUI, or one sentence to an AI agent gets you a UDS handshake, a CAN
replay, a Seed-Key solve, a V2X signature analysis, or an instrument-cluster tamper
demo. Everything runs on a virtual CAN bus (python-can virtual, or vcan0 +
ICSim on Linux) with Docker labs — nothing to brick.
Related MCP server: panda-mcp
Architecture
One core library, three surfaces (CLI / TUI / MCP), one transport. The same implementation is exposed to humans and to AI agents — that is the main difference from the older tooling.
Quick start
Option A — one line, no clone, no venv (best for handing the MCP server to an agent):
uvx --from "vehsec[mcp] @ git+https://github.com/xuange-hu/vehsec" vehsec-mcp
uvx --from "vehsec @ git+https://github.com/xuange-hu/vehsec" vehsec --help
# no uv? pipx run --spec "vehsec[mcp] @ git+https://github.com/xuange-hu/vehsec" vehsec-mcpThe @ git+… form installs straight from this repository, so it works today.
Once the package is on PyPI it shortens to uvx --from "vehsec[mcp]" vehsec-mcp;
.github/workflows/publish.yml publishes automatically on every release, it only
needs PyPI Trusted Publishing enabled once.
Option B — clone and hack on it:
git clone https://github.com/xuange-hu/vehsec && cd vehsec
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[all]"
vehsec --help # CLI
vehsec tui # interactive TUI
vehsec mcp # MCP server (stdio) for AI agents
vehsec mcp --check # list the 31 tools an agent would get, then exit
python examples/demo.py # 5-step scripted demo, no hardwareLet an AI agent drive it
Drop this into your agent's MCP config (~/.workbuddy/mcp.json, Cursor
~/.cursor/mcp.json, Cline, or Claude Desktop's claude_desktop_config.json) and
trust the server — no clone, no venv, uv/uvx fetches it on first launch:
{
"mcpServers": {
"vehsec": {
"command": "uvx",
"args": ["--from", "vehsec[mcp] @ git+https://github.com/xuange-hu/vehsec", "vehsec-mcp"]
}
}
}Already have vehsec installed? The equivalent is
{ "command": "vehsec", "args": ["mcp"] } (examples/mcp-config.json). Then just ask:
"Run a UDS security access on the virtual ECU and show me the seed and key."
Thirty-one tools are exposed: can_send, can_fuzz, can_analyze,
uds_security_access, uds_read_did, uds_read_dtcs, uds_clear_dtcs,
uds_decode_dtc, uds_raw, seedkey_solve, seedkey_vendors,
seedkey_recover, seedkey_predict, v2x_analyze, icsim_set_speed, icsim_tamper_demo,
doip_simulate, doip_probe, doip_tls_audit, doip_tls_probe, doip_tls_simulate,
dbc_decode, dbc_info,
j1939_decode, j1939_encode, j1939_decode_name, j1939_decode_dm1,
isotp_segment, isotp_decode, isotp_reassemble, isotp_explain.
Capabilities
UDS diagnostics — session control, security access (27), DID read/write, routine control, ECU reset, DTC read/clear (19/14), communication control (28), and a raw request escape hatch, over ISO-TP (
udsoncan+can-isotp). Ships with an attached virtual ECU, so all of it runs with nothing plugged in.CAN replay & fuzz — replay
candumplogs, or mutate frames against a set of IDs.CAN ID discovery — per-ID counts, unique payloads, and which bytes change, to locate the control signal in an unknown vehicle.
Seed-Key solver — pluggable algorithm registry (xor / add / rotate / bit-reverse / nibble-swap / endian-swap / CRC16-mixed / LFSR / SHA-256 keystream) for the UDS 27 handshake, plus algorithm recovery: feed it observed
(seed, key)pairs and it brute-forces the transform family and solves for the parameters — thenseedkey_predict/seedkey.predict()applies the result to a fresh seed you never observed, which is how you unlock the next session without the OEM DLL.V2X / ECDSA — detect nonce reuse and recover the signer's private key.
ICSim control — script speed / doors / turn signals on the virtual cluster.
DoIP (ISO 13400) — in-process virtual DoIP entity: vehicle discovery, routing activation, and UDS-over-Ethernet (read the VIN) with no hardware.
DoIP over TLS — the ISO 13400-2 secure diagnostics channel (TCP 3496), plus a certificate audit engine: a from-scratch, zero-dependency X.509 reader that also verifies RSA PKCS#1 v1.5 signatures in pure Python, so "self-signed" is proven rather than guessed. Grades key size, signature hash, validity, SAN/hostname and CA chain, and probes which TLS versions a gateway still accepts.
DBC parsing — pure stdlib: Intel/Motorola endianness, signed values, factor/offset scaling, value tables, multiplexed signals.
J1939 (trucks/buses) — 29-bit id ↔ PGN/priority/source (PDU1 & PDU2), NAME decode, DM1 diagnostics (SPN/FMI/CM/OC), EEC1 engine speed.
ISO-TP (ISO 15765-2) — the UDS transport layer, from scratch: SF/FF/CF/FC framing, segmentation and reassembly with sequence validation, and an ASCII visualisation of the whole transfer.
DTC (diagnostic trouble codes) — read faults (19 sub 01/02/0A), clear them (14), and decode the 3-byte code into its SAE J2012 identifier (
C10000→U0100) with status flags and a short description.
Labs — 5 runnable Docker exercises
Lab | Topic |
UDS DID decryption: identify the cipher, recover the key | |
OTA patch-chain diff reveals a hidden payload | |
ECDSA nonce reuse → private-key recovery | |
CAN state-machine injection / missing auth guard | |
UDS 0x27 Seed-Key: reverse the algorithm from 5 sniffed pairs, then unlock with an unseen seed |
python labs/v2x-ecdsa-nonce/solve.py --gen 20 # nonce reuse is the default:
# the first run recovers the key
python labs/v2x-ecdsa-nonce/solve.py --gen 20 --no-reuse # contrast: nothing found
# Lab 5 needs no third-party package — pure stdlib + vehsec.seedkey
python labs/seedkey-recover/solve.py # 5 pairs -> one algorithm -> flag
python labs/seedkey-recover/solve.py --pairs 1 # too little evidence -> 0x7F 27 35UDS in 30 seconds — no hardware
Every UDS command talks to an attached virtual ECU on a python-can virtual
bus, so the UDS stack (ISO-TP segmentation, flow control, Seed-Key) is exercised
for real — just without metal.
$ vehsec uds read --did 0xF190
{'did': '0xF190',
'value': '5756575a5a5a314a5a5857303030303031',
'ascii': 'WVWZZZ1JZXW000001'}
$ vehsec uds security --level 1 --vendor training_rotate
{'level': 1, 'seed': '01020304', 'key': '585e5c52', 'unlocked': True}
$ vehsec uds write --did 0xF190 --data 0102030405
{'did': '0xF190', 'written': 5}Diagnostic trouble codes in 30 seconds
$ vehsec uds dtc # read faults (service 0x19 sub-function 02)
Diagnostic Trouble Codes (3)
┌───────┬────────┬─────────┬──────────────────────────┬──────────────────────┐
│ code │ raw │ status │ flags │ description │
├───────┼────────┼─────────┼──────────────────────────┼──────────────────────┤
│ P0100 │ 010000 │ 0x2C │ pendingDTC,confirmedDTC… │ Mass or Volume Air … │
│ P0420 │ 042000 │ 0x0C │ pendingDTC,confirmedDTC │ Catalyst System Eff… │
│ U0100 │ C10000 │ 0x08 │ confirmedDTC │ Lost Communication … │
└───────┴────────┴─────────┴──────────────────────────┴──────────────────────┘
$ vehsec uds dtc --status 0x08 # confirmed faults only
$ vehsec uds dtc --count # just the number stored
$ vehsec uds dtc --clear # service 0x14
$ vehsec uds raw --data 1901FF # any request, response returned verbatim
590109000003Three records are 15 bytes, so this response is carried by a first frame plus consecutive frames — the ISO-TP path is the real one, not a stub.
ISO-TP in 30 seconds
The VIN response is 20 bytes, so it is carried by a first frame plus two
consecutive frames. vehsec isotp explain draws exactly how:
$ vehsec isotp explain --data 62F1904142434445464748494A4B4C4D4E4F5051
ISO-TP (ISO 15765-2) — 20-byte payload carried by 3 classic CAN frame(s)
# frame bytes PCI kind detail
0 10 14 62 F1 90 41 42 43 0x10 FF total=20 B, carries bytes 0..5
1 21 44 45 46 47 48 49 4A 0x21 CF seq=1, carries bytes 6..12
2 22 4B 4C 4D 4E 4F 50 51 0x22 CF seq=2, carries bytes 13..19
reassembled payload:
62 F1 90 41 42 43 44 45 46 47 48 49
4A 4B 4C 4D 4E 4F 50 51
= 20 bytesPoint it at metal or UDSim instead with
VEHSEC_CAN_IFACE=socketcan VEHSEC_CAN_CHANNEL=vcan0 plus auto_ecu=False.
Seed-Key algorithm recovery in 30 seconds
Real ECUs hide their seed→key algorithm in an OEM DLL. Capture a few
(seed, key) pairs (replay 27 01, log what the official tool answers with)
and let vehsec work out the transform:
$ vehsec seedkey recover --pairs 11223344:4B78691E,a5b6c7d8:FFEC9D82,deadbeeF:84F7E4B5
Recovered candidates (high confidence, 3 pair(s), 4-byte seed)
┌─────────────────────────┬────────────────────┐
│ algorithm │ key for first seed │
├─────────────────────────┼────────────────────┤
│ key[i] = seed[i] ^ 0x5A │ 4B78691E │
└─────────────────────────┴────────────────────┘The catalogue covers xor c, add c, sub c, xor i ^ c, add i + c,
rotl 1/3 ^ c, bitrev ^ c, nibble-swap ^ c, endian-swap, and the affine
family a*seed[i]+b. Every result is checked against all supplied pairs, so
three or more pairs usually collapse to a single answer. Same thing over MCP:
seedkey_recover(pairs="11223344:4B78691E,...").
Recovery is only interesting if it generalises — a candidate that happens to
fit one observation will fail on the next session. seedkey predict (CLI, MCP
seedkey_predict, or vehsec.seedkey.predict()) applies the recovered algorithm
to a seed you never captured:
$ vehsec seedkey predict --pairs 11223344:4B78691E,a5b6c7d8:FFEC9D82,deadbeeF:84F7E4B5 \
--seed 00112233
algorithm key[i] = seed[i] ^ 0x5A
key 5A4B7869 (high confidence, 3 pair(s))Lab 5 turns this into a full exercise: five sniffed pairs,
held-out seed, real 0x27 01/02 handshake, and a protected DID behind it —
including the failure mode where too little evidence survives the fit but not the
unlock (--pairs 1).
DoIP & DBC in 30 seconds
vehsec doip simulate # spin up a fake DoIP ECU, read its VIN
vehsec dbc info --file examples/sample.dbc
vehsec dbc decode --file examples/sample.dbc --id 0x100 --data 9F01393000010000
# Speed 41.5 km/h · Odometer 1234.5 km · SpeedValid 1
vehsec dbc encode --file examples/sample.dbc --id 0x100 --set Speed=41.5
vehsec dbc watch --file examples/sample.dbc --log capture.log # decode a whole captureDoIP TLS / gateway certificates in 30 seconds
# 1. a TLS DoIP gateway in-process: handshake, routing activation, UDS, then audit
vehsec doip tls-simulate
# negotiated TLSv1.3 / TLS_AES_256_GCM_SHA384
# UDS 22 F190 -> 62f1905756575a5a5a314a5a5857303030303031
# STRONG score 100/100
# 2. audit a certificate you captured (PEM or DER)
vehsec doip tls-audit --file gateway.pem --ca oem-ca.pem --hostname gateway.local
# REJECT score 10/100 grade F
# [CRITICAL] RSA key is only 1024 bits
# [HIGH ] signed with SHA1 (sha1WithRSAEncryption)
# [MEDIUM ] no subjectAltName extension; the CN is the only identity
# 3. audit a live gateway: TLS versions + cert + is plaintext 13400 still open?
vehsec doip tls-probe --host 192.0.2.10The interesting finding is usually the last one: a gateway whose plaintext port 13400 still accepts a routing activation makes its own TLS listener decorative. The audit also tries each TLS version on its own, which is how you find a gateway that still answers TLS 1.0.
Docs
Doc | What |
Recon → UDS → Seed-Key → replay → V2X, with an ISO/SAE 21434 TARA map | |
Install, CLI, TUI, MCP setup | |
What's next | |
Dev setup, tests, how to add a lab | |
Reporting vulnerabilities in vehsec itself | |
Curated resource list |
Tests
pip install -e ".[all]" && pip install pytest
pytest -q # 261 passed: core, CLI, MCP registration, all 5 labs, demo scriptCI runs ruff + pytest on Python 3.11 / 3.12 / 3.13.
Legal & ethics
For authorized security research, teaching, and testing on equipment you own only. Do not point this at vehicles or networks you are not authorized to test; comply with your jurisdiction's laws. The authors accept no responsibility for misuse.
License
MIT © xuange-hu
This server cannot be deployed
Maintenance
Related MCP Connectors
Protocol-native energy infrastructure orchestration for AI data centers. Provides 46 MCP tools across 8 grid protocols (IEC-61850, DNP3, Modbus, OCPP, OpenADR, IEEE 2030.5, IEC 60870-5-104, ICCP) with 5 core API primitives: connect, dispatch, settle, comply, and intel. Enables AI agents to programmatically interact with substations, grid interfaces, and energy assets for real-time workload-grid coordination.
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
30 security tools for AI agents: phishing links, exposure maps, DNS, SSL, PQC, history, pivots.
Real-time chat hub for AI agents — Claude Code, Cursor, Cline, Codex over MCP or REST.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables LLMs to interact with vehicle CAN bus and OBD-II data through a simulated ECU environment. Provides tools for reading frames, decoding messages via DBC files, monitoring signals, and querying automotive diagnostics without requiring physical hardware.25MIT
- AlicenseNot gradedqualityDmaintenanceTurns a comma.ai Panda into a conversational CAN reverse-engineering rig, allowing users to record, diff, find signals, and send frames through natural language with Claude.2MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI-powered automotive diagnostics by connecting LLMs to vehicle ECUs over UDS/CAN, indexing workshop manuals locally, and augmenting with web search, while enforcing a human-in-the-loop approval gate for any write operations.MIT
- AlicenseNot gradedqualityAmaintenanceLet an AI agent sniff and reverse-engineer a car's LIN bus with an open-source USB LIN dongle: per-id capture with changing bits, change log, auto-detect speed/checksum, LDF decode/encode; read-only by default, master/slave simulation behind --allow-transmit, --mock simulated bus.92GPL 3.0