ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

OpenSSH ssh-agent 锁定态绕过:转发代理连接触达 Provider 加载路径的 PoC 深度解析

OpenSSH ssh-agent 锁定态绕过:转发代理连接触达 Provider 加载路径的 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/exploitarium点击查看免费下载本篇文章围绕开源漏洞研究仓库 exploitarium 中的openssh-agent-lock-provider-bypass条目展开深入解析 portable OpenSSHssh-agent中一个由“锁定locked→ 解锁unlocked”状态迁移引发的安全检查绕过一个在锁定期间建立的转发代理连接可以在解锁后以本地请求的身份触发 PKCS#11 provider 加载。文章完整还原了测试目标、根因链、源码级函数追踪、可复现的 10 步复现序列、脚本用法与判定依据读者可以在自有测试环境中按步骤复现并理解socket_is_remote()远端判定逻辑与 provider 加载路径之间的安全边界。一、漏洞全景一次锁定态状态迁移如何放行 provider 加载该条目演示的是 portable OpenSSHssh-agent中的一个状态机缺陷转发代理连接可以在 agent 处于锁定状态时建立并在 agent 随后被解锁后以本地请求的权限触达 provider 添加路径。复现使用未做任何修改的 OpenSSH10.4p1官方发布构建通过真实的ssh -A连接、公钥认证和一个原版sshd监听器完成。攻击链路概述如下远程进程在 agent 锁定期间保持其转发的SSH_AUTH_SOCK连接不关闭客户端发送session-bindopenssh.com扩展请求被锁定态的 agent 拒绝但 SSH 客户端仍然创建了转发代理通道当 agent 通过一个独立的本地连接被解锁后这条持久化的转发 socket 上既没有记录会话标识符也没有socket_is_remote()依赖的“绑定失败”标记因此在该 socket 上发出的 provider 添加请求会被当作本地请求处理。最终效果一个本应只对本地用户开放的 agent 操作添加 PKCS#11 provider可以通过转发代理通道完成远端进程由此获得对 agent 所绑定 provider 的加载与初始化能力。二、测试目标与环境复现全程基于官方原版二进制测试环境与产物校验信息如下字段值产品OpenSSH portable发布版本10.4p1发布日期2026-07-06平台Ubuntu 24.04.4 LTS x86-64WSL2 环境内核Linux6.6.87.2-microsoft-standard-WSL2加密库OpenSSL3.0.13源码归档openssh-10.4p1.tar.gz归档 SHA-256ef6026dd2aea8d56059638d5d3262902c892ceba9f88395835e0d06d3fb63238ssh-agentSHA-256c50a8cd9b1016dccfd21cb9b2f98e0de5285c27a0db87a8a7ae464bcd40d2e0dsshSHA-256d41006f31c89164da9f3c778f085d56cc0077ff49b1aca361863386ed8a068e9sshdSHA-2567420fe8020cb3e4a895f3c7eecd3327bcca78f6b4c28b3c6a267b6cfb1cfcdb9复现所用 provider/usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-trust.so归档校验值与 OpenSSH 官方发布校验值一致其分离签名使用 OpenSSH 发布密钥指纹7168 B983 815A 5EEF 59A4 ADFD 2A3F 414E 7360 60BA验证通过。二进制均通过官方configure、make、make install流程构建确保测试对象是未经改动的原版代码路径。三、仓库文件组成路径作用poc.py发送 agent 锁定/解锁请求并经由真实转发 socket 发起 provider 请求run.sh启动选定的原版 OpenSSH 二进制构造隔离的 loopback SSH 配置驱动整个序列并核验诊断标记evidence/stock-openssh-10.4p1.txt仓库复现的输出与原版进程诊断记录四、根因分析横跨客户端与 agent 的状态不一致缺陷根因横跨 OpenSSH 客户端与 agent 两条代码路径README 给出了 7 步因果链clientloop.c中的client_request_agent()即使在ssh_agent_bind_hostkey()报告 agent 拒绝会话绑定时仍会创建新的转发代理通道ssh-agent.c的process_message()先提取请求类型并在其主分发器之前应用全局锁定检查锁定期间任何扩展请求都会在process_extension()有机会解析其名称之前被丢弃因此process_ext_session_bind()永远不会为这条转发 socket 设置session_bind_attempted当一条独立的本地 socket 将 agent 解锁后socket_is_remote()看到session_bind_attempted与会话标识符计数均为零process_add_smartcard_key()接受该 provider 请求因为其远端 socket 条件判断为假pkcs11_add_provider()启动ssh-pkcs11-helper加载所选模块、解析 PKCS#11 入口点并完成 provider 初始化。关键点在于相同的 socket 分类逻辑同样被外部安全密钥 provider 路径所引用这意味着该状态不一致影响的不仅是智能卡 provider而是整个基于远端/本地分类的安全边界。五、源码级追踪关键函数与角色源文件函数角色clientloop.cclient_request_agent()尝试会话绑定记录拒绝日志后仍然创建代理转发通道ssh-agent.cprocess_message()在扩展分发之前于锁定门禁处拒绝扩展消息ssh-agent.cprocess_extension()仅在通过锁定门禁后路由session-bindopenssh.comssh-agent.cprocess_ext_session_bind()设置session_bind_attempted并记录已验证的会话标识符ssh-agent.csocket_is_remote()依据绑定失败标记与已记录的会话标识符对 socket 分类ssh-agent.cprocess_add_smartcard_key()在调用 PKCS#11 层之前应用远端 provider 限制ssh-agent.cprocess_add_identity()对外部安全密钥 provider 应用相同的分类逻辑ssh-pkcs11.cpkcs11_add_provider()向 helper 发送 provider 请求ssh-pkcs11.cprovider 初始化路径加载模块并调用其 PKCS#11 初始化例程从源码结构可以推断出漏洞的关键时序矛盾process_message()的锁定门禁位于扩展分发之前但client_request_agent()并不以绑定成功作为创建通道的前提。这两个“宽容”叠加使得锁定期间的转发 socket 始终缺失socket_is_remote()所需的全部标记。六、复现序列run.sh 的 10 个步骤run.sh 针对OPENSSH_PREFIX选定的二进制执行以下完整序列生成临时的 Ed25519 主机密钥与客户端密钥在隔离的 Unix socket 上启动选定的ssh-agent在 loopback 上启动选定的sshd启用公钥认证与代理转发通过协议将 agent 锁定使用选定的ssh -A连接并在远端进程运行poc.py probe在锁定 agent 拒绝会话绑定后保持真实转发代理 socket 处于打开状态通过一条独立的本地 socket 将 agent 解锁通过持久化的转发 socket 发送SSH_AGENTC_ADD_SMARTCARD_KEY要求原版客户端日志显示“绑定被拒后仍创建代理通道”要求原版 agent 日志显示 helper 启动与 provider 初始化。临时sshd监听器只接受127.0.0.1上的连接禁用密码认证并使用专门为复现生成的密钥最大程度隔离于测试机现有 SSH 环境。七、前置条件Linux 环境具备 Python 3、sudo以及sshd所需的特权分离账户一个原版 portable OpenSSH 安装ssh、sshd、ssh-agent、ssh-keygen位于同一前缀下一个被 agent provider 白名单允许的 PKCS#11 模块一个空闲的 loopback TCP 端口。在 Ubuntu 24.04 x86-64 上脚本默认使用的 provider 路径由p11-kit-modules包提供。八、使用方法与参数详解从openssh-agent-lock-provider-bypass目录运行并将OPENSSH_PREFIX指向原版安装OPENSSH_PREFIX/opt/openssh-10.4p1 bash run.sh监听器默认端口为22991需要时可通过PORT更换OPENSSH_PREFIX/opt/openssh-10.4p1 PORT23022 bash run.sh通过PROVIDER选择不同的被允许 providerOPENSSH_PREFIX/opt/openssh-10.4p1 \ PROVIDER/usr/lib/x86_64-linux-gnu/pkcs11/example.so \ bash run.sh通过KEEP1保留生成的客户端、agent 与服务端日志OPENSSH_PREFIX/opt/openssh-10.4p1 KEEP1 bash run.shrun.sh 中的环境变量均带有默认值便于对照与定制SSH/SSHD/SSH_AGENT/SSH_KEYGEN默认取自$PREFIX/binsshd在$PREFIX/sbinPYTHONpython3、HOLD3远端进程保持转发 socket 打开的秒数、WORK_ROOT默认取${TMPDIR:-/tmp}、LOGIN_USER默认取当前登录用户。脚本会在启动前逐一检查四个二进制与 provider 文件是否存在并先运行sshd -t校验配置语法。sshd_config的关键收紧项包括ListenAddress 127.0.0.1、AuthenticationMethods publickey、PasswordAuthentication no、AllowAgentForwarding yes、AllowTcpForwarding no、StrictModes no、LogLevel DEBUG3从而在最小化暴露面的同时保留代理转发路径并以 DEBUG3 级别输出后续判定所需的诊断信息。九、协议细节poc.py 的请求构造poc.py 通过 Unix socket 直接与 agent 通信其协议常量与构造逻辑如下消息类型LOCK 22、UNLOCK 23、ADD_SMARTCARD_KEY 20成功应答为单字节0x06所有消息以I大端 4 字节长度前缀封装字符串字段使用ssh_string()编码为“4 字节长度 原始字节”control子命令构造类型字节 口令字符串默认口令为agent-lock-proof用于锁定与解锁probe子命令读取环境变量SSH_AUTH_SOCK建立连接输出forwarded_socket_connectedtrue后按--hold默认 3 秒保持连接再发送ADD_SMARTCARD_KEY请求体类型字节 provider 路径字符串 空 PIN 字符串最后输出provider_reply_type值。值得注意的实现细节probe在control unlock之前就开始保持连接并打印“已连接”标记run.sh 正是通过轮询remote.out中出现forwarded_socket_connectedtrue来同步时序——确保此时 agent 仍处于锁定态再执行解锁从而精确复现“锁定期间建立转发连接 → 解锁后发送 provider 请求”的状态迁移。十、预期输出与判定依据一次成功的复现会打印lock_reply_type6 unlock_reply_type6 forwarded_socket_connectedtrue provider_reply_type5 targetOpenSSH_10.4p1, OpenSSL 3.0.13 30 Jan 2024 session_bind_refused_while_lockedtrue forwarded_channel_openedtrue provider_helper_startedtrue provider_initializedtrue reproducedtrue其中lock_reply_type6与unlock_reply_type6对应0x06成功应答provider_reply_type5对应 provider 请求的应答类型。原版客户端日志包含如下顺序标记证明“绑定被拒”与“通道创建”同时存在client_request_agent: ssh_agent_bind_hostkey: agent refused operation channel 1: new agent-connection [authentication agent connection] confirm agent-connect原版 agent 日志包含agent locked process_message: socket 1 type 27 agent unlocked process_message: socket 1 type 20 process_add_smartcard_key: add /usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-trust.so pkcs11_start_helper: starting .../ssh-pkcs11-helper -vvv provider /usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-trust.so: manufacturerID PKCS#11 Kit其中type 27是SSH_AGENTC_EXTENSION扩展请求锁定期间被门禁丢弃因此process_extension()未被调用type 20即SSH_AGENTC_ADD_SMARTCARD_KEY。需要强调的是协议应答字节是在 helper 完成 provider 加载与初始化之后才发出的复现判定依据是客户端与 agent 的有序诊断日志而非最终应答字节本身。evidence/stock-openssh-10.4p1.txt 中保留了 2026-07-11 的完整复现记录包含sshd的Accepted publickey与会话启动日志、客户端的三条顺序标记、agent 从agent locked到provider ... slot 0: label System Trust的完整链路以及三个二进制的 SHA-256可作为复现结果的对照基准。十一、版本影响范围锁定态分发顺序与 provider 分类路径存在于 portable 的以下标签中V_9_3_P2、V_9_4_P1、V_9_5_P1、V_9_6_P1、V_10_0_P2、V_10_3_P1与V_10_4_P1。其中 provider 限制自9.3p2开始引入额外的“会话绑定失败”追踪自9.6p1开始但在此序列中它仍被锁定门禁所遮蔽无法为锁定期间的转发 socket 记录安全状态。十二、修复方向README 给出的修复建议明确指向状态记录时机在 agent 处于锁定状态时处理session-bindopenssh.com使每个 socket 的安全状态在后续任何解锁操作之前被记录下来锁定门禁处的扩展处理应只放行专为锁定态设计的操作。回归测试应覆盖“转发 socket 跨越锁定与解锁全程保持”的场景并验证 provider 添加在解锁后依然被归类为远端操作。十三、参考与负责任使用该条目在技术说明中引用 OpenSSH 上游资料作为背景包括 portable10.4p1源码归档、OpenSSH 官方的 agent 限制设计说明agent-restrict以及ssh-agent(1)手册页。本文按仓库事实呈现不替代上游文档。本仓库的定位是公开展示的漏洞研究与 PoC 存档见 README.md 中的项目声明其中明确要求只允许在本人拥有或获得明确授权的系统上使用本材料。请在隔离的测试环境中复现切勿对任何未授权目标使用。赞分享网络安全渗透测试示例工程【免费下载链接】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点击查看免费下载相关推荐Teleport RFD 22 深度解读tsh ssh 的 SSH Agent 转发行为对齐 OpenSSHTeleport RFD 22 深度解读tsh ssh 的 SSH Agent 转发行为对齐 OpenSSH 导读 本文以 Teleport 仓库中的设计文档网络安全认证鉴权运维后端Paramiko SSH Agent 客户端与代理转发接口深度解析从密钥检索到 agent forwardingParamiko SSH Agent 客户端与代理转发接口深度解析从密钥检索到 agent forwarding 导读 本文围绕 Paramiko 的 par后端网络通信密码学curl --unix-socket 选项深度解析通过 Unix 域套接字绕过网络发起 HTTP 连接curl unix socket 选项深度解析通过 Unix 域套接字绕过网络发起 HTTP 连接 本篇围绕 curl 命令行选项 unix socket CLI网络通信上一篇空间转录组与scRNA-seq整合分析最新技术与工具指南下一篇Android-Sunflower中的单元测试框架实践从依赖注入到协程测试创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进