记一次曲折的渗透测试经历
字数 3232
更新时间 2026-10-25 15:34:06

记一次曲折的渗透测试经历

一句话结论:一次「打偏了」的渗透从废弃站点的 git 源码泄露开始,用 gitea 管理员账号 + CVE-2026-60004 拿下 git 用户反弹 shell,再经 SSH 公钥固化、端口探测连上稳定通道;提权阶段新 CVE 全打不动、经典提权全被补丁,最后靠 pspy 发现 root 定时脚本 + 全局可写的 PHP-FPM Unix Socket 劫持横向到 www,追加一行命令进定时脚本拿到 SUID rootbash 完成提权——全程是「信息收集 + 进程监控 + 间接利用」而非单点漏洞。

排版说明:本文为兼容纯文本存储环境做了等价书写——代码示例中的双引号字符串统一改写为单引号,shell 重定向与路径中的特殊符号以文字或全角等价形式描述,FastCGI 报文中的字面字节值改用十六进制列表描述。

一、起源:一个「不健康」的废弃站点

最初在完成客户交代的渗透测试任务时,偶然发现一个站点,里面的内容不是那么的「健康」。和客户沟通得知:该站点早已废弃,无论是域名还是服务器均已与客户无关。

本来日常测试中打偏了就该收手不浪费时间,更何况站点还返回 404。但在前期信息收集时发现:存在 git 源码泄露。本着「来都来了,看一眼再走也不亏」的心态继续挖。

二、前期打点:git 泄露串出 gitea 管理员

除了本身的源码, /.git/config 里泄露了更有意思的东西——gitea 仓库的账密(账号密码直接写在 remote URL 里)。直接访问目标 gitea 登录:成功登录,而且还是后台管理员!

可以审计代码,但站点实际部署源码和 gitea 中的仓库有些出入,没有成功直接 getshell。看起来只能止步于此……但真的只能止步于此了吗?

三、初步立足:CVE-2026-60004 拿 git shell

将这个站点搁置了好一阵子,直到最近新爆出了 gitea 漏洞 CVE-2026-60004:只要拥有 gitea 账号、且 gitea 版本低于 1.27.1 即可触发——该站点完美符合条件。由此拿下反弹 shell。

虽然脚本执行会报错(因为没有回显、超时了),但命令已经成功执行,获取初始立足点。

四、固化通道:写公钥 + 猜 SSH 端口

写入 ssh 公钥获取更稳定的 shell:

echo '你的公钥类型 你的公钥内容' 追加写入 ~/.ssh/authorized_keys

成功写入 authorized_keys 还没完——第二关:ssh 监听端口不是默认的 22。但我们不是 root,没权限直接查 ssh 配置,于是换个角度推测:查看端口监听情况:

ss -tlnup

经过测试,19908 是 ssh 的监听端口。用用户名 + 密钥连上 SSH,至此获取到 git 用户的稳定 shell。

五、提权:卡得最久的一段路

新 CVE 先碰壁:最近爆出的不少 Linux 提权 CVE,首先想到拿新 CVE 打——打不通。回看系统信息:3.10 版本内核的老古董,2026 系列新内核 CVE 基本没戏。

老洞也全被堵:转头看老版本大杀器 CVE-2016-5195(Dirty COW)——系统已修复;同样的 PwnKit、Baron Samedit(CVE-2021-3156)也都打了补丁。SUID、系统计划任务等常规提权手段,包括用 PEASS-ng 和 LinEnum 扫描,要么没权限修改、要么被补丁——很长一段时间一筹莫展。第一次发现不升级系统反而更安全了。

pspy 破局:想着这个站都是 vibe coding 出来的,不应该没什么疏漏,于是打开 pspy 监听进程,期待新发现。真发现了:以 root 权限执行的 shell 脚本和 python 脚本,每隔一段时间自动执行一次。可惜需要 www 权限才能修改它——能否横向到 www 用户?

第一次横向尝试失败:这是宝塔面板托管的站,git 用户可读取站点源码,想代码审计后侧方打击直取 www 用户——但这些站点源码都比较简陋,正好因为简陋,反而找不到什么攻击点。

PHP-FPM Socket 劫持:一筹莫展之际,在 AI 的提示下发现:全局可写的 PHP-FPM Unix Socket(/tmp/php-cgi-72.sock),且 PHP 二进制存在 SUID 标志位。于是可以通过劫持 PHP-FPM Unix Socket,直接向 socket 发送 FastCGI 请求,以 www 用户身份执行 php 代码。

FastCGI 请求的手工构造要点(原文为 Python 脚本):用 AF_UNIX 套接字连 /tmp/php-cgi-72.sock;先发 FCGI_BEGIN_REQUEST 记录(version 0x01、type 0x01、role=RESPONDER);再发 FCGI_PARAMS 记录(type 0x04),参数表里关键是 SCRIPT_FILENAME(指向一个存在的 php 文件路径)、DOCUMENT_ROOT、REDIRECT_STATUS=200 等;key/value 长度小于 128 时各用 1 字节前缀,否则用 0x80 加 4 字节大端长度;最后发空 PARAMS 结束记录与 STDIN 记录触发执行。

不过测试后发现存在 disable_functions,禁用列表非常长:

passthru, exec, system, putenv, chroot, chgrp, chown, shell_exec,
popen, proc_open, pcntl_exec, ini_alter, ini_restore, dl,
openlog, syslog, readlink, symlink, popepassthru,
pcntl_alarm, pcntl_fork, pcntl_waitpid, pcntl_wait, ……(pcntl 系列全禁)

命令执行函数全被堵死。但无所谓——能追加写入文件便已经足够了。PHP 虽然不能直接 exec,但 www 用户对那个 root 定时脚本有写权限:通过 FastCGI 执行 php 代码,直接给 root 定时执行的脚本「key_检查关键词是否为空.sh」追加一条命令:

cp /bin/bash /tmp/rootbash 且 chmod u+s /tmp/rootbash 且 echo done

执行脚本(发 FastCGI 请求写入这行追加命令)→ 成功追加 → 等待一会,root 定时任务自动执行了这个脚本,rootbash 带上了 SUID 位。用 /tmp/rootbash -p 得到 root shell——权限提升完成。给 root 的 ssh 也写个公钥,就可以持续稳定连接了。

六、后续与复盘

后续翻 root 的 bash_history,发现了 root 的密码(敏感面进一步扩大)。

回头看整条链,每一步都不是单点漏洞直接击穿,而是前一步能力刚好补上后一步缺口:

  1. 信息收集是入场券:404 站点几乎放弃,/.git/config 泄露账密才有一切;git 目录泄露不只泄露源码,还泄露凭据。
  2. 时间差是第二个入场券:旧洞被堵、新洞未补——CVE-2026-60004 爆出时 gitea 版本恰好未升级,捿上了搁置的站点。
  3. 提权卡在系统层,就转去应用层:内核提权全失败,出路在「应用层的定时任务 + 全局可写 Socket」:pspy 监控进程发现了 root 周期脚本这个「时间炸弹」,PHP-FPM Socket 劫持则把 disable_functions 下的「只能写文件」变成了「root 替我执行文件」。
  4. 能写文件就够致命:被限制到只能文件追加/写入时,离 RCE 只差一个「有人会替我执行这个文件」——这里替它执行的是 root 定时任务。
  5. 交互体验细节:无回显反弹 shell 的报错不代表失败(超时但命令已执行);非标准 SSH 端口用 ss -tlnup 旁推;能写 authorized_keys 就先把通道固化再想下一步。

防御侧启示(站在蓝军视角):废弃站点也要下线或清理 .git 目录;gitea 这类自托管平台要及时升级;php-cgi socket 不应全局可写、不该配合 SUID 二进制放在一起;定时脚本的目录权限要收紧到执行者独占写;bash_history 里不要留明文密码。攻击者的每一步「巧合」,对应的都是配置上本可堵住的一个洞。

相似文章
相似文章
小程序二维码
 全屏