ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

如何读懂Redis HNSW向量索引:Exploitarium VSET重复ID PoC原理完整指南

如何读懂Redis HNSW向量索引:Exploitarium VSET重复ID PoC原理完整指南 如何读懂Redis HNSW向量索引Exploitarium VSET重复ID PoC原理完整指南【免费下载链接】exploitariumA single archive of public exploit PoCs and vulnerability research writeups. At the time I post these, none have been reported. Feel free to report them yourself and take credit for the CVE if handed out lulz. Please do not abuse these. I do this so to allure people into the field, and Ive always found this is the most efficient way.项目地址: https://gitcode.com/GitHub_Trending/ex/exploitariumExploitarium 是一个公开的漏洞 PoC概念验证研究档案库收录了多个尚未报告厂商的漏洞验证代码。本文聚焦其中 redis-vset-duplicate-hnsw-id-rce-poc 目录一个针对Redis 向量集Vector SetHNSW 索引的重复节点 ID 远程代码执行 PoC。我们先用通俗的方式讲清 Redis HNSW 向量索引的数据结构基础再带你看懂这个 PoC 是如何从两个节点共用一个 ID走到在 Redis 进程内执行任意命令的。先认识主角Redis 向量集与 HNSW 索引向量集Vector Set是 Redis 中用来存储向量数据的集合类型常用于相似度搜索——比如找出和这 128 维 embedding 最接近的 10 条记录。为了快它不会暴力比较所有向量而是依赖HNSW分层可导航小世界图索引。你可以把 HNSW 想成一栋分层的跳表式大楼底层所有向量节点都在每个节点连接若干最近的邻居越往上层节点数量按指数衰减连接越稀疏负责大跨度过路查找过程从顶层出发贪心地逼近目标逐层下降直到底层精确锁定最近邻。这套结构让近似最近邻搜索的复杂度接近 O(log N)。对普通用户来说你只需要记住三个关键点结构要素作用在漏洞中的角色节点 IDnode ID序列化/反序列化时的身份证号攻击者伪造的重复 ID 就藏在这里元素字典按元素名存节点对象ID 表与元素字典不一致的根源链接数组links每层邻居 ID 的列表删除节点后残留的陈旧链接漏洞根因两个节点同一个身份证问题出在 Vector Set 模块的RDB 反序列化阶段也就是通过RESTORE命令恢复一个预先序列化的数据集时。根据 redis-vset-duplicate-hnsw-id-rce-poc/README.md 的根因分析反序列化允许多个 HNSW 节点携带相同的节点 ID。此时节点 ID 查找表里每个 ID 只能存一份只保留了一个节点元素字典却按元素名把另一个节点对象也存了下来链接校验时只按 ID 比较从不强制一个 ID 对应一个节点对象。结果就是同一个 ID 别名指向了两个不同的节点对象。当攻击者用VREM删掉字典中可见的那个重复节点后内存里的对象被释放但其他节点的链接数组里还留着一排指向它的指针——这就是经典的 use-after-free释放后使用漏洞只是它潜伏在图数据结构里而不是普通的链表或指针。源码级的追踪路径记录在 PoC 目录的 README 中涉及 Redis 源码的modules/vector-sets/vset.chnsw_insert_serialized()与modules/vector-sets/hnsw.chnsw_deserialize_index()、hnsw_reconnect_nodes()以及src/object.c的freeModuleObject()可以作为进阶阅读的索引。PoC 的利用链从陈旧链接到 system() 调用redis-vset-duplicate-hnsw-id-rce-poc/poc.py 是一个自包含脚本它启动一个未改动的redis-server全程只用RESTORE、VREM、VLINKS、SET、SETRANGE、DEL等正常 Redis 协议命令驱动整个攻击。完整链条分 11 步这里挑四个最巧妙的环节讲1️⃣ 用距离分数读出任意内存65 个掩码节点Vector Set 默认启用量化存储向量被压成有限比特VLINKS ... WITHSCORES返回的邻居距离分数因此只能取少数几个档位。PoC 构造了65 个掩码节点1、2、4、…、2^63把被释放节点所在内存块回收成一条伪造的 HNSW 节点字符串然后逐位比较距离分数就能逐位恢复出任意地址处的 64 位值——一个纯协议层面的读取预言机。2️⃣ 泄漏 libc 基址算出 system() 地址用上面的读取预言机读出freeGOT槽位再结合二进制本地符号信息readelf/nm解析反推出 libc 基址与system的绝对地址全程不需要任何内核态或调试器权限。3️⃣ 二次利用让陈旧链接写进 module value恢复第二个畸形向量集制造两条陈旧邻居链接删除节点时 Redis 的hnsw_reconnect_nodes()会遍历这些链接并重连——攻击者把被释放的内存块回收成两个伪造 HNSW 节点字符串重连逻辑就会把受控指针写进目标向量集的 module value 中的type与value字段。4️⃣ DEL 收尾freeModuleObject() 变成 system() 调用删除被污染的键时Redis 调用freeModuleObject()→mv-type-free(mv-value)。而type指针已经被改写为systemvalue指向攻击者写入的命令缓冲区;idR;#于是 Redis 进程自己执行了这条 shell 命令。本地验证输出一次成功的完整回放仓库中 redis-vset-duplicate-hnsw-id-rce-poc/evidence/local-verification.txt 保存了针对全新原版 Redis 构建的复现记录关键片段如下[] pie0x579791926000 freeGOT0x579791cafeb8-0x78cd934add50 [] libc0x78cd93400000 system0x78cd93458750 [] fake HNSW nodes patched [] VREM w C b:1\r\n [] DEL w b:1\r\n [] RCE proof created: .../redis-vset-duplicate-hnsw-id-rce-poc/work/R uid1000(owner) gid1000(owner) groups1000(owner),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),46(users)最后一行id命令输出由Redis 进程内部执行的 payload 写入标记文件R是整个链条成功的铁证。环境要求Linux x86-64、libc malloc 构建的 Redis测试 commit5b22a099PoC 配置刻意保持sanitize-dump-payload yes、不开调试命令说明利用不依赖任何后门开关。运行方式仅限自有或已获授权测试的环境python3 poc.py \ --redis-server /path/to/redis/src/redis-server \ --work-dir /tmp/redis-vset-rce \ --port 6631新手学习路线从这个 PoC 延伸出去入门层通读 redis-vset-duplicate-hnsw-id-rce-poc/README.md对照利用流程 11 步逐条理解结构层复习 HNSW 论文思想——多层图、贪心下降、邻居重连理解为什么按 ID 校验链接是合理的日常假设、却成了攻击面实战层阅读 poc.py 中restore_payload_65_masks()65 掩码读取载荷与payload_two_stale_for_write()双陈旧链接写载荷两个函数看 RDB 模块序列化字节是如何手工拼出来的。写在最后 ⚠️仓库作者在 README.md 中强调这些 PoC 发布时均未向厂商报告欢迎自行提交漏洞报告、认领可能颁发的 CVE同时明确要求不要滥用——只在你拥有或获得明确授权的系统上运行验证代码。这正是 Exploitarium 的初衷把门槛降到最低吸引更多人进入漏洞研究这个领域。【免费下载链接】exploitariumA single archive of public exploit PoCs and vulnerability research writeups. At the time I post these, none have been reported. Feel free to report them yourself and take credit for the CVE if handed out lulz. Please do not abuse these. I do this so to allure people into the field, and Ive always found this is the most efficient way.项目地址: https://gitcode.com/GitHub_Trending/ex/exploitarium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表