Auditing a Hikvision DS-K1T671M access terminal: one finding, and four leads that died
The DS-K1T671M is a door access terminal. It reads faces, cards, and PINs, talks to a door controller, and exposes a web interface, RTSP video, and a couple of Hikvision-specific discovery and management protocols. Anything that unlocks a physical door is worth a careful look, so I pulled the firmware and worked through it.
This is the whole audit, not just the part that worked. Most of what I chased turned out to be a dead end, and I think the dead ends are the useful part to write down, because ruling a lead out with evidence is most of what the job actually is. One finding survived and is with Hikvision now.
How I approached it
- Get the firmware and unpack it. Pull the vendor firmware, work through the container format down to the root filesystem, and get a clean tree of binaries to read.
- Map the attack surface. List every network-facing service and the binaries behind them: the web stack, RTSP, the discovery and management protocols (SADP and the DVR network protocol), and the on-device shell.
- Pick targets by blast radius. Prioritize anything that could get an unauthenticated attacker past authentication, recover a credential, or reach code execution, since those are the outcomes that matter on a door.
- Prove or kill each lead in the disassembly. For every hypothesis, trace it to the actual code path and decide it on evidence, not on how bad it would be if it were true.
The finding that held up: predictable RTSP session tokens
The RTSP service hands out a session identifier per stream. I traced how that identifier is generated and found the routine seeds itself from the wall clock, using gettimeofday() as its source of randomness rather than a cryptographic random source such as /dev/urandom or getrandom().
That matters because a value meant to be unguessable is only as strong as its seed. A token derived from the current time is not high entropy. An attacker who knows roughly when a session started has a small space to search, which weakens the guarantee the session token is supposed to give. This is a weak randomness issue in the class of CWE-330 / CWE-338.
I confirmed the behavior in the disassembly rather than inferring it from observed values, so the claim rests on the code path itself. I reported it to Hikvision HSRC. Their initial response disputed it; the technical point is that the generator does read from gettimeofday(), so the finding is still open on my side and under review with the vendor. No CVE has been assigned.
Lead 1: the no-auth URL table
Early on, the web layer looked like it kept a table of URL patterns that skip authentication. If those entries reached sensitive handlers such as config export or device reset, that would be an authentication bypass, which on a door lock is the worst case.
So I traced the request path instead of trusting the table at face value. Following how a request actually flows through the handler showed the entries did not do what the shape suggested: the paths I cared about still passed through the authentication check. The promising table was not a bypass.
Lead 2: a computable device reset code
Hikvision devices support a recovery flow that produces a reset code. If that code were derived from public inputs such as the serial number and the date, anyone could compute it and reset a device they should not control.
I found a routine that does derive a code from the serial and a date, which looked like the whole story. But when I searched for who calls it, the answer was no one. It had zero live callers, only self-internal references and debug prints. The path the device actually uses for reset verification is a different routine that checks a challenge against a stored answer, not the serial-and-date derivation. The computable function was dead debug code.
Lead 3: the root credential scheme
The device derives a root password from a hash over fixed inputs including the account name and a stored password field. I worked out the scheme and recovered the value, which cracked to a simple default. For a moment this looked like a static, fleet-wide root credential, which would have been serious.
Then I checked when it applies. That simple value is the legacy pre-activation default, and on activation the device rewrites the root password from the administrator password the operator sets. So on any activated unit the root shell password equals the admin web password the owner chose, not a secret baked into every device. What is left is only that un-activated units ship with a known default, which is a much smaller issue and is already public knowledge.
Lead 4: the discovery and management protocols
The SADP discovery protocol and the DVR network protocol are attractive because they answer before authentication. I walked the unauthenticated entry points looking for a path that reaches a sensitive action without a credential check. The management protocol verified in one place and failed closed, with no unauthenticated route through to the actions I was after. This was the fourth clean front-door target that did not give anything up.
What the audit was worth
One finding out of a long list of leads is a normal ratio for this kind of work, and the discipline is in the leads you close, not the ones you keep. Every dead end here was killed with a specific reason: a request that still hit auth, a function with no callers, a password that gets rewritten at activation, a protocol that fails closed. That is the difference between a report a vendor can dismiss and one they cannot.
The RTSP session-token weakness is the piece that survived, and it is with Hikvision now. If the status changes I will update this page.
Responsible disclosure note: findings were reported to the vendor before publication. This writeup describes analysis and root cause at the level needed to understand the issue, not a turnkey exploit.