【高危漏洞预警】llama.cpp无认证远程代码执行漏洞CVE-2026-34159

admin 2026-04-30 06:15:11 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: CVE-2026-34159是llama.cpp开源LLM推理框架中的高危内存越界读写漏洞,攻击者无需认证即可通过RPC后端构造恶意GRAPH_COMPUTE消息实现远程代码执行,CVSS评分9.8。漏洞影响b8492之前版本,公网超23万实例面临风险。文档详细分析漏洞成因、利用链及检测方案,并提供升级至b8492版本的修复指南。 综合评分: 85 文章分类: 漏洞分析,漏洞预警,解决方案,WEB安全,安全建设


cover_image

【高危漏洞预警】llama.cpp无认证远程代码执行漏洞CVE-2026-34159

飓风网络安全

2026年4月29日 08:56 云南

在小说阅读器读本章

去阅读

漏洞类型: 内存越界读写(CWE-119)→ 预认证远程代码执行(RCE) 风险等级:严重(Critical) CVSS评分 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H(9.8分) 影响组件: llama.cpp 开源LLM推理框架 影响范围:llama.cpp 版本 < b8492(开启RPC后端的场景) 安全补丁: llama.cpp b8492 及以上版本(修复commit:39bf0d3) 在野利用状态: 漏洞原理简单、利用门槛极低,公开后已出现定向探测与PoC,公网暴露面超23万个实例面临直接攻击风险 llama.cpp是全球最主流的开源大模型本地推理框架,以轻量、高效、跨平台的特性广泛应用于个人开发者、企业级AI推理服务、分布式集群部署场景。其内置的RPC后端用于实现多机分布式张量计算,解决单卡显存不足的大模型推理需求,默认监听TCP 50052端口。 漏洞描述: 本次披露的CVE-2026-34159是一处无需任何认证、仅需TCP端口访问即可触发的高危RCE漏洞,攻击者通过精心构造的GRAPH_COMPUTE消息,可绕过张量反序列化环节的边界校验,实现进程内存的任意读写,结合指针泄露完成ASLR绕过,最终在目标服务器执行任意代码,完全接管主机权限。该漏洞利用复杂度极低,单条TCP连接即可完成完整攻击链,公网暴露的未修复实例面临极高的失陷风险。 一、漏洞技术深度分析 1.1 漏洞根本成因 漏洞核心源于llama.cpp RPC后端的deserialize_tensor()函数存在严重的安全校验缺陷:当RPC请求中张量的buffer字段为0时,程序会完全跳过所有内存边界校验,直接将攻击者可控的data字段赋值为张量的内存指针,导致任意内存地址的读写操作。 该漏洞的本质是设计层面的安全假设失效:框架原本假设buffer=0的”视图张量”仅用于内部可信场景,却未对网络传输的RPC请求做任何输入校验与合法性验证,导致攻击者可通过网络传入恶意构造的张量数据,完全控制张量的内存地址、维度、步长等核心参数,最终形成内存越界读写原语。 1.2 漏洞代码级还原 漏洞核心代码(b8492之前版本) 漏洞位于rpc.cpp文件中的deserialize_tensor()函数,该函数负责处理RPC请求中张量数据的反序列化,是分布式推理的核心环节: // 漏洞代码:反序列化环节的边界校验绕过 static bool deserialize_tensor(const rpc_tensor* src, ggml_tensor* dst) { // 直接复制攻击者可控的张量类型、维度、步长,无任何合法性校验 dst->type = (ggml_type)src->type; for (int i = 0; i < GGML_MAX_DIMS; i++) { dst->ne[i] = src->ne[i]; dst->nb[i] = src->nb[i]; // 步长参数完全可控,无范围校验 }

// 核心缺陷:buffer=0时,跳过所有内存边界校验,直接设置任意data指针 if (src->buffer == 0) { dst->data = reinterpret_cast(src->data); return true; // 直接返回,无后续任何安全校验 }

// 仅buffer非0时,才会执行正常的缓冲区合法性校验 auto* buf = reinterpret_cast(src->buffer); // 缓冲区地址范围校验、权限校验等安全逻辑 // … } 攻击者可完全控制的核心字段:

• src->buffer:设置为0,触发校验绕过逻辑,是漏洞利用的核心开关;

• src->data:可设置为任意内存地址,实现对目标进程内存的精准定位;

• src->ne[]:控制张量维度元素数量,决定读写操作的字节长度;

• src->nb[]:控制张量维度字节步长,决定内存访问的范围与偏移。

官方修复代码(b8492版本) 官方在commit 39bf0d3中彻底修复该漏洞,核心修复逻辑为:

  1. 禁止网络传入的buffer=0张量携带非空data指针,彻底阻断任意地址设置;

  2. 新增张量步长、维度的合法性校验,避免异常参数导致内存越界;

  3. 新增合法缓冲区白名单校验,仅允许使用服务端已分配的缓冲区地址。 // 修复后的核心逻辑 static bool deserialize_tensor(const rpc_tensor* src, ggml_tensor* dst, const std::unordered_set& valid_buffers) { dst->type = (ggml_type)src->type; // 新增步长合法性校验,避免异常步长导致越界访问 for (int i = 0; i < GGML_MAX_DIMS; i++) { dst->ne[i] = src->ne[i]; if (i > 0 && dst->nb[i] < dst->nb[i-1] * dst->ne[i-1]) { return false; // 步长异常,直接拒绝处理 } dst->nb[i] = src->nb[i]; }

    // 核心修复:buffer=0时,禁止设置非空data指针 if (src->buffer == 0) { if (src->data != 0) { return false; // 直接拒绝恶意构造的请求 } dst->data = nullptr; return true; }

    // 新增缓冲区合法性校验,仅允许使用服务端已分配的合法缓冲区 auto* buf = reinterpret_cast(src->buffer); if (valid_buffers.find(buf) == valid_buffers.end()) { return false; // 非法缓冲区指针,直接拒绝 } // 后续正常的地址范围校验逻辑 // … }

1.3 完整利用链技术分析 攻击者仅需一条TCP连接,即可通过3个步骤完成完整的RCE攻击,全程无需任何认证,平均攻击耗时低于3秒。 第一步:ASLR绕过(内存指针泄露) 现代操作系统的ASLR(地址空间布局随机化)会导致内存地址动态变化,攻击者通过RPC协议自带的ALLOC_BUFFER和BUFFER_GET_BASE合法指令,无需触发漏洞即可获取服务端进程的真实内存地址,完成ASLR绕过:

  1. 向目标RPC服务发送ALLOC_BUFFER指令,申请一块内存缓冲区;
  2. 服务端响应中会返回该缓冲区在进程中的真实堆内存指针;
  3. 攻击者通过指针地址对齐计算,推算出进程基址、libc库基址等关键地址,为后续内存读写和RCE提供精准的地址定位。 第二步:任意内存读写原语构造 攻击者构造恶意的GRAPH_COMPUTE消息,触发漏洞实现对目标进程内存的任意读写:
  4. 构造恶意rpc_tensor结构体,设置buffer=0触发校验绕过;
  5. 将data字段设置为想要读取/写入的目标内存地址;
  6. 通过ne[]和nb[]字段控制读写的长度和范围,精准读取目标内存数据,或向指定地址写入恶意数据;
  7. 发送GRAPH_COMPUTE指令,服务端执行张量计算时,会完成对目标地址的读写操作。 第三步:远程代码执行 基于任意内存读写原语,攻击者通过常规的内存篡改手法完成RCE,主流利用路径如下:
  8. 通过任意内存读,读取进程GOT表中的函数地址,计算出libc库的真实基址,定位system、__free_hook等关键函数地址;
  9. 通过任意内存写,将__free_hook钩子函数的地址替换为system函数地址;
  10. 构造恶意命令字符串写入内存,触发一次正常的内存释放操作,__free_hook被调用时执行system(恶意命令),最终完成远程代码执行,完全接管目标服务器。 二、自查与检测方案 2.1 版本与启用状态自查(必做) 步骤1:检查RPC服务是否启用

检查是否存在llama-rpc-server相关运行进程

ps aux | grep -E ‘llama.*rpc|rpc.*server’

检查默认50052端口是否处于监听状态

ss -tlnp | grep 50052 若存在相关进程或端口处于监听状态,说明已启用RPC后端,需进一步检查版本。 步骤2:检查llama.cpp版本是否受影响

方式1:查看编译后的服务版本

./llama-server –version 2>&1 | grep -E ‘build|version’

方式2:通过git commit检查(源码部署场景)

git -C /path/to/llama.cpp log –oneline -1

若commit哈希早于39bf0d3,或版本号低于b8492,即为受影响版本

步骤3:公网暴露面自查

  1. 通过防火墙、云服务器安全组,检查是否对互联网开放50052端口;
  2. 对内网网段进行批量扫描,排查内网暴露的脆弱实例:

nmap内网扫描示例(替换为企业内网网段)

nmap -p 50052 –open 192.168.0.0/16 2.2 攻击行为检测 1. 网络流量检测: 监控50052端口的异常TCP连接,尤其是境外IP、匿名代理、恶意IP池的访问请求; 检测单IP短时间内的高频连接与异常数据包,特征为固定长度的二进制payload,对应漏洞利用的构造请求。 2. 进程行为检测: 监控llama-rpc-server进程的异常子进程,正常情况下该进程不会派生shell、python、bash等子进程,若出现则大概率已被入侵; 检测进程的异常系统调用,如execve、open、write等敏感操作,对应RCE攻击的命令执行行为。 3. 日志与文件检测: 排查llama.cpp服务日志,是否存在异常的张量反序列化报错、RPC指令执行失败记录; 检查/tmp、/dev/shm、/var/tmp等临时目录,是否存在漏洞攻击后写入的恶意可执行文件、后门程序。 永久修复方案(必做) 官方已在llama.cpp b8492版本中彻底修复该漏洞,所有受影响用户必须立即升级至安全版本,升级操作如下: # 1. 拉取最新代码 cd /path/to/llama.cpp git pull

2. 切换到安全修复版本

git checkout b8492

3. 重新编译(CPU版本,启用RPC后端)

cmake -B build -DLLAMA_RPC=ON cmake –build build –config Release -j $(nproc)

4. CUDA版本编译(GPU场景)

cmake -B build -DGGML_CUDA=ON -DLLAMA_RPC=ON cmake –build build –config Release -j $(nproc) # 5. 重启RPC服务,验证版本升级成功 ./llama-rpc-server –version 升级完成后,需验证业务分布式推理功能正常,同时构造漏洞探测请求,确认漏洞已无法触发。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:飓风网络安全 《【高危漏洞预警】llama.cpp无认证远程代码执行漏洞CVE-2026-34159》

评论:0   参与:  0