ARTICLE DETAIL

资讯详情

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

飞桨(PaddlePaddle)命令注入漏洞 PDSA-2023-020 深度解析:`_wget_download` 任意命令执行(CVE-2023-52311)

飞桨(PaddlePaddle)命令注入漏洞 PDSA-2023-020 深度解析:`_wget_download` 任意命令执行(CVE-2023-52311) 飞桨PaddlePaddle命令注入漏洞 PDSA-2023-020 深度解析_wget_download任意命令执行CVE-2023-52311【免费下载链接】PaddlePArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice 『飞桨』核心框架深度学习机器学习高性能单机、分布式训练和跨平台部署项目地址: https://gitcode.com/GitHub_Trending/pa/Paddle本文围绕飞桨PaddlePaddle安全公告 PDSA-2023-020 展开剖析paddle.utils.download._wget_download中因直接拼接 URL 调用系统命令导致的命令注入漏洞CVE-2023-52311并结合当前仓库源码 python/paddle/utils/download.py 说明其修复方向、防御手法与安全加固实践帮助读者理解该漏洞成因并掌握排查、复现与防护方法。漏洞概述项目内容安全公告编号PDSA-2023-020CVE 编号CVE-2023-52311漏洞类型命令注入Command Injection受影响函数paddle.utils.download._wget_download影响版本飞桨 2.6.0 之前版本 2.6.0修复版本飞桨 2.6.0 及之后版本报告来源huntr.com该公告完整收录于 security/advisory/pdsa-2023-020_cn.md同时在 security/README_cn.md 的公告清单中以Command injection in _wget_download受影响版本 2.6.0列出是飞桨 2.6.0 之前版本中已披露的多项安全问题之一。漏洞根因分析命令注入的本质命令注入漏洞的根源在于程序将外部可控输入此处为 URL 字符串直接拼接进系统命令中执行且未对输入做任何过滤或转义。攻击者只要在 URL 中注入 shell 元字符如;、、|、$()、反引号等就能让拼接后的命令在原有意图之外执行任意命令。历史实现中的缺陷点在旧版本中_wget_download(url, fullname)的实现方式类似def _wget_download(url, fullname): # 旧版本实现存在漏洞 os.system(wget -O %s %s % (fullname, url))攻击者传入的url参数未经任何校验直接拼入os.system命令字符串。官方公告给出的 PoC 如下from paddle import utils utils.download._wget_download(aa; touch codexecution, bb)当执行_wget_download(aa; touch codexecution, bb)时实际拼接出的 shell 命令为wget -O bb aa; touch codexecution由于;是 shell 的命令分隔符touch codexecution会被当作独立命令执行攻击者在服务器上成功创建了codexecution文件即实现了任意命令执行。若攻击者将注入负载替换为curl ... | sh、反弹 shell 等则可直接接管运行飞桨的目标机器。攻击面与可利用性从源码结构看download.py模块负责下载预训练模型权重、数据集等资源其主要入口包括get_weights_path_from_url(url, md5sum)下载预训练权重默认存放于~/.cache/paddle/hapi/weightsget_path_from_url(url, root_dir, md5sum, ...)通用下载入口支持wget与get两种方法。在漏洞版本中get_path_from_url的method参数支持wget该路径即调用存在缺陷的_wget_download。因此凡是能向下载 URL 传入外部输入的场景例如加载来自第三方 URL 的模型权重、数据集下载、定制化模型库均可能成为攻击入口攻击者无需认证即可尝试注入。修复与当前仓库的防御实现官方在 commitd5550d3f2f5bab48c783b4986ba1cd8e061ce542PR #59957中修复了该问题修复随飞桨 2.6.0 发布。移除危险的 wget 调用链在当前仓库中_download_methods仅保留get一种实现彻底移除了 wget 调用_download_methods {get: _get_download}对应地_download通过assert method in _download_methods对方法名做白名单校验同时限制重试次数DOWNLOAD_RETRY_LIMIT 3杜绝了将 URL 拼入 shell 命令的可能。其源码路径为 python/paddle/utils/download.py。以 Python 原生 HTTP 客户端替代系统命令修复后的_get_download使用httpx.stream以流式方式下载文件def _get_download(url, fullname): fname osp.basename(fullname) try: with httpx.stream(GET, url, timeoutNone, follow_redirectsTrue) as req: if req.status_code ! 200: raise RuntimeError(fDownloading from {url} failed with code {req.status_code}!) tmp_fullname fullname _tmp total_size req.headers.get(content-length) with open(tmp_fullname, wb) as f: if total_size: with tqdm(total(int(total_size) 1023) // 1024) as pbar: for chunk in req.iter_bytes(chunk_size1024): f.write(chunk) pbar.update(1) else: for chunk in req.iter_bytes(chunk_size1024): if chunk: f.write(chunk) shutil.move(tmp_fullname, fullname) return fullname except Exception as e: logger.info(fDownloading {fname} from {url} failed with exception {e}) return False关键安全设计如下不经过 shellURL 仅作为httpx请求参数使用不存在任何系统命令拼接从根上消除了命令注入面临时文件 原子替换先写入fullname _tmp下载完成后shutil.move原子移动到目标路径避免半成品文件被误用状态码校验非 200 响应直接抛出RuntimeError下载失败安全返回任何异常被捕获并记录日志后返回False由上层_download决定重试。下载完整性校验md5 检查_download循环中持续执行_md5check(fullname, md5sum)仅当文件存在且 md5 一致时才认为下载成功while not (osp.exists(fullname) and _md5check(fullname, md5sum)): if retry_cnt DOWNLOAD_RETRY_LIMIT: retry_cnt 1 else: raise RuntimeError(fDownload from {url} failed. Retry limit reached) if not _download_methodsmethod: time.sleep(1) continue_md5check分块4KB计算文件哈希并与期望值比对这不仅能发现下载损坏也能在一定程度上抵御恶意/被篡改的下载源。解压环节的路径穿越防护与命令注入同源的安全加固还体现在解压环节_safe_extract_tar、_safe_extract_zip与_safe_extract_member拒绝绝对路径与../路径穿越target_path.startswith(os.path.abspath(target_dir) os.sep)校验并对符号链接、硬链接等特殊文件采取跳过或抛错策略防止解压炸弹与 symlink 攻击。相关实现见 python/paddle/utils/download.py 中_safe_extract_*系列函数。影响范围与版本修复受影响版本飞桨 2.6.0 之前所有版本修复版本飞桨 2.6.0 及以上当前仓库version.txt显示为 3.5.0已包含修复。建议所有飞桨用户立即升级至 2.6.0 或更高版本。升级后可通过检查_download_methods中是否仅存在get实现快速确认已移除_wget_download调用链。安全自查与防护建议代码自查清单针对类似URL/文件名拼入系统命令的代码模式建议按以下清单排查是否存在os.system、subprocess.call/run/Popen且参数由外部输入直接拼接是否对 URL 做过http:///https://协议白名单校验当前仓库通过 python/paddle/utils/download.py 的is_url做基础检查是否使用参数数组形式传参subprocess.run([wget, -O, fname, url])避免 shell 解释是否对下载内容做完整性校验md5/sha256解压路径是否防止路径穿越与符号链接攻击。运行非信任模型的安全准则飞桨官方在 SECURITY_cn.md 中明确要求永远在沙箱中加载和运行非信任模型并了解其可能造成的影响。这是因为paddle.load底层使用 pickle 反序列化恶意模型可借此执行任意命令。同理凡涉及外部 URL 资源加载的功能都应视为可攻击面建议在隔离环境容器、虚拟机、专用沙箱中运行并遵循最小权限原则。漏洞上报与致谢飞桨鼓励负责任地披露Responsible Disclosure安全问题安全研究人员可通过 BSRC 平台提交漏洞提交时建议包含漏洞细节、复现步骤与 PoC攻击场景与攻击者能达到的效果问题是否已公开及公开情况姓名与从属关系可选公开。飞桨会将修复情况注明在版本发布说明中并在致谢公告中公布漏洞详情与提报人信息。完整安全模型与上报流程见 SECURITY_cn.md 与 security/README_cn.md。本次漏洞由 huntr.com 提交。延伸阅读PDSA-2023-019get_online_pass_interval 命令注入同类命令注入问题的另一案例可对照学习同类漏洞模式PDSA-2023-005fs.py 命令注入受影响版本 2.5.0 的同类问题安全公告总表查看全部已披露公告及受影响版本安全使用飞桨指南了解飞桨安全模型、沙箱运行建议与漏洞上报流程。【免费下载链接】PaddlePArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice 『飞桨』核心框架深度学习机器学习高性能单机、分布式训练和跨平台部署项目地址: https://gitcode.com/GitHub_Trending/pa/Paddle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表