文章总结: 文档分析了CVE-2026-29058AVideo命令注入漏洞,漏洞位于getImage.php,因URL参数未过滤Shell元字符直接拼接执行,导致未授权攻击者通过GET请求实现RCE。文章从四个层次剖析成因,指出格式校验无法替代安全过滤,并提供了升级至7.0版本、配置访问控制及WAF检测等修复建议,强调开发中应使用escapeshellarg或参数数组调用外部程序。 综合评分: 95 文章分类: 漏洞分析,代码审计,漏洞预警,WEB安全
一个 GET 请求拿下服务器:CVE-2026-29058 AVideo 命令注入漏洞分析
原创
CVE-SEC CVE-SEC
CVE-SEC
2026年3月8日 11:00 四川
一个 GET 请求拿下服务器:CVE-2026-29058 AVideo 命令注入漏洞分析
发布日期:2026-03-07 CVE 编号:CVE-2026-29058 CVSS v3.1 评分:9.8(Critical)
背景
AVideo,前身是 YouPHPTube,是一套由 WWBN 开源社区维护、基于 PHP 开发的自托管音视频平台。许多教育机构、企业和独立站点用它搭建私有视频系统,支持视频上传、转码、直播、频道管理等功能。
它的转码组件 AVideo-Encoder 负责调用 ffmpeg 处理视频文件,部署在独立服务器上,对外暴露 HTTP 端点。这个组件在 GitHub 上有 157 个 Star、192 个 Fork,许可证为 AGPL-3.0。
这次出问题的,就是 AVideo-Encoder。
漏洞在哪里
问题出在 objects/getImage.php。
这个文件的功能是根据传入的视频 URL,调用 ffmpeg 提取缩略图。它接收一个叫做 base64Url 的 GET 参数,对其进行 Base64 解码,得到一个 URL 字符串,然后把这个 URL 拼进 ffmpeg 的命令里执行。
修复前的核心代码大致如下:
$url = base64_decode($_GET['base64Url']);
// ...
$exec = get_ffmpeg()." -i \"{$url}\" -f image2 -vframes 1 -y {$destination}";
execAsync($exec);
$url 直接被双引号包裹,拼进了 Shell 命令字符串,然后通过 execAsync() 执行。
execAsync() 内部是这样的:
$newCmd = "nohup " . $command . " > /dev/null 2>&1 & echo $!;";
$pid = shell_exec($newCmd);
也就是说,命令最终由 shell_exec() 在后台异步执行。
问题的关键
代码里确实有一道校验,在 objects/security.php 中:
if (!filter_var(base64_decode($scanThis['base64Url']), FILTER_VALIDATE_URL)) {
error_log('base64Url attack ' . json_encode($_SERVER));
exit;
}
看起来做了验证。但问题在于:FILTER_VALIDATE_URL 只判断字符串格式上像不像一个 URL,也就是检查它有没有合法的 scheme、host、path 结构。它从来不承担过滤 Shell 特殊字符的职责。
这两个字符串都能通过 FILTER_VALIDATE_URL 的检查,因为它们在语法上都是合法的 URL:
http://x.x.x.x/$(id)
http://x.x.x.x/$(cat /etc/passwd)
通过校验之后,$url 被拼进了双引号包裹的 Shell 命令字符串。Shell 在解析双引号字符串时,会将 $(...) 和反引号识别为命令替换语法,原地执行括号里的内容。于是攻击者注入的命令就在服务器上跑起来了。
这个漏洞特别在哪里
大多数命令注入漏洞,攻击者至少要登录账号,或者诱导受害者点击某个链接。这个漏洞不需要。
CVSS 向量 AV:N/AC:L/PR:N/UI:N 四个字母说明了一切:网络可达、低复杂度、无需权限、无需用户交互。一次 GET 请求,不需要账号,服务器就会执行你指定的命令。
还有一个细节让防御更难:攻击 Payload 本身经过了 Base64 编码。WAF 如果只对参数的原始值做关键字检测,看到的是一段 Base64 字符串,恶意内容隐藏在编码里,常见的明文检测规则会失效。必须在 WAF 层解码后再检测,才能识别注入内容。
命令通过 nohup ... & echo $! 异步在后台执行,HTTP 响应里不包含命令的输出,攻击行为在日志里更难被即时发现。
成因的四个层次
这不是一个偶然的低级错误,是四个决策叠加的结果。
第一层:信任边界模糊。base64Url 是外部用户完全可控的参数,但代码在简单校验后直接使用了它,没有把它当作不可信数据处理。
第二层:校验语义误解。 开发者用 URL 格式校验代替了安全校验。格式合法只说明字符串结构符合规范,与内容是否安全是两件完全不同的事。这是一种很常见的认知偏差。
第三层:Shell 插值未转义。 外部数据以双引号插值方式拼进了 Shell 命令,没有调用 escapeshellarg() 或 escapeshellcmd()。双引号内 Shell 的命令替换语法是无条件生效的基础特性,不是漏洞,是规范。
第四层:执行函数选择不当。shell_exec() 把整个命令字符串交给 Shell 解释器处理。如果改用 proc_open() 配合参数数组的形式,就不经过 Shell,命令替换语法根本不会被解析,注入面彻底消失。
攻击者能做什么
命令执行成功后,攻击者获得的是 Web 服务进程的权限,通常是 www-data 或 apache。在此基础上可以:
读取服务器上的配置文件、数据库凭据、API 密钥;向 Web 可访问目录写入 Webshell,建立长期后门;发起反弹 Shell,获得完整的交互式控制能力;以当前服务器为跳板,向内网其他系统横向移动。
时间线
| 日期 | 事件 | | — | — | | 2026-03-02 17:57 UTC | 修复 commit 提交(SHA: 78178d1),版本更新到 7.0 | | 2026-03-02 18:56 UTC | AVideo-Encoder 7.0 正式发布 | | 2026-03-02 19:03 UTC | GitHub Security Advisory(GHSA-9j26-99jh-v26q)发布 | | 2026-03-03 | CVE-2026-29058 由 MITRE 收录,编号由 GitHub_M 分配 | | 2026-03-06 | NVD 正式发布漏洞详情,评分 9.8 Critical |
漏洞由安全研究员 arkmarta 发现,项目维护者 DanielnetoDotCom(Daniel Neto)接收报告后完成修复,并通过 GitHub Security Advisory 机制进行了负责任披露。修复完成后约四天,漏洞信息才对外公开。
官方如何修复
修复方式写在提交信息里:”enhance security by validating and sanitizing URLs across multiple files”。
核心改动是在 objects/getImage.php 中,Base64 解码之后、拼进命令之前,增加了两步处理:
第一步,先过滤 shell 元字符:
$url = str_replace(
array('"', "'", '`', '$', '\\', ';', '|', '&', '(', ')', '{', '}', '<', '>', "\n", "\r", "\0"),
'',
$url
);
第二步,用 escapeshellarg() 转义:
$urlEscaped = escapeshellarg($url);
然后把所有命令里的 "{$url}" 替换为 {$urlEscaped}。
escapeshellarg() 的作用是用单引号包裹字符串,并对内部的单引号进行转义,使 Shell 将其视为一个完整的字面量参数,而不是可解析的命令语法。
同一批次修复还覆盖了 objects/getSpiritsFromVideo.php、objects/FTPDownloader.php、view/watermark.php 等文件中类似的 shell 注入点,并修复了 objects/security.php 中 str_replace 被误用作正则过滤的独立 bug。
立即升级至 AVideo-Encoder 7.0 是消除该漏洞的根本措施。
如果暂时无法升级,可在 Web 服务器层对 getImage.php 端点做访问控制:
Nginx:
location ~ /objects/getImage\.php {
allow 192.168.1.0/24;
deny all;
}
Apache:
<Files "objects/getImage.php">
Require ip 192.168.1.0/24
</Files>
WAF 规则需要对 base64Url 参数值进行 Base64 解码后再做内容检测,仅对原始值做明文关键字匹配是无效的。
如何判断是否已受到攻击
在访问日志中检索:
grep "getImage.php" access.log | grep "base64Url"
对命中记录提取 base64Url 的值并做 Base64 解码,检查结果中是否出现 $(、反引号、wget、curl、bash、nc 等 Shell 元字符或命令关键词。
在主机层,关注 Web 服务进程是否存在异常的子进程创建行为,特别是由 PHP 进程派生的系统命令调用。auditd 或 eBPF 工具可以提供进程级别的监控。
给开发者的提醒
这个漏洞揭示了一个很普遍的问题:格式校验和安全校验是两件独立的事,不能相互替代。FILTER_VALIDATE_URL 的文档从未声称自己能防止命令注入,但开发者在潜意识里把”URL 格式合法”等同于”可以安全使用”。
凡是需要把外部输入传给系统命令的场景,三条原则:
优先使用参数数组形式调用外部程序,完全绕过 Shell 解析层;如果必须用 shell_exec(),所有外部输入都必须经过 escapeshellarg() 处理;格式校验通过不代表内容安全,两件事要分开做。
参考资料
NVD 漏洞详情:https://nvd.nist.gov/vuln/detail/CVE-2026-29058
GitHub 官方安全公告:https://github.com/WWBN/AVideo-Encoder/security/advisories/GHSA-9j26-99jh-v26q
CVE 官方记录:https://www.cve.org/CVERecord?id=CVE-2026-29058
修复 commit:https://github.com/WWBN/AVideo-Encoder/commit/78178d11541d44b238c4dfd9241cacb031db3765
AVideo-Encoder 7.0 Release:https://github.com/WWBN/AVideo-Encoder/releases/tag/7.0
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:CVE-SEC CVE-SEC CVE-SEC《一个 GET 请求拿下服务器:CVE-2026-29058 AVideo 命令注入漏洞分析》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论