在一次日常的安全测试任务中,笔者遇到了一个典型的任意文件上传漏洞。然而,常规的WebShell上传并未成功执行,但通过巧妙的思路转换,最终利用目录遍历技术直接获取了服务器的SSH控制权。以下是完整的发现与利用过程。
信息收集与漏洞发现
使用自动化工具进行初步扫描时,发现目标站点存在一处未受保护的API文档接口。

访问该接口后,页面直接泄露了服务器的部分配置信息,其中甚至包含了真实的IP地址。这种信息泄露为后续的深入测试打开了突破口。

获取到真实IP后,随即对其进行了标准的端口扫描,以评估服务器开放的服务。

扫描结果显示这是一台Linux服务器,运行着Nginx Web服务。在开放的端口中,一个Web应用引起了注意。
未授权文件上传功能点
直接访问该Web应用,发现其存在一个头像上传功能,且页面提示状态码为410错误。

通过抓包分析,确认了这是一个未授权即可访问的文件上传端点。这无疑是一个绝佳的入口点。于是,立即尝试上传一个常见的JSP WebShell文件。

请求返回了成功的状态码和JSON响应,表明文件已被服务器接收。

通过返回的URL尝试访问上传的文件,但服务器并未解析执行该WebShell,访问只返回了文件下载。这意味着常规的文件上传漏洞利用路径被阻断。
思路转换:尝试目录遍历
当直接执行WebShell的希望落空时,是否意味着这个漏洞毫无价值?并非如此。渗透测试中常需要转换思路。既然文件能上传,能否控制其上传路径呢?于是,尝试在文件名中构造目录遍历(Path Traversal)Payload。
将上传的文件名修改为 ../../../../../../../../tmp/test.jsp 并重新发起请求。

响应显示上传成功。通过文件管理功能或直接构造URL访问,确认文件确实被上传到了服务器的 /tmp 目录下。

目录遍历成功!这证明上传功能对文件路径没有进行有效的过滤或校验,允许攻击者将文件写入到服务器文件系统的任意可写位置。
致命一击:覆盖SSH授权密钥
既然可以任意写文件,那么目标就不再局限于Web目录。一个更直接的思路浮现出来:能否覆盖系统关键文件,例如SSH服务的授权公钥文件 authorized_keys?
构造Payload,将文件名设置为:
../../../../../../../root/.ssh/authorized_keys
这次,上传的内容替换为自己生成的SSH公钥。

使用Burp Suite等工具发送构造好的Multipart请求。

从响应看,上传操作再次返回成功。随后,使用对应的私钥尝试SSH连接服务器。
ssh -i id_rsa root@<目标IP>
连接成功!无需WebShell,直接获得了服务器的root权限。登录后,可以在服务器上看到各类应用部署包。

总结与思考
本次测试从一个简单的未授权上传点入手,在常规WebShell利用失败后,通过尝试目录遍历发现了更大的安全隐患,最终通过覆盖SSH密钥的方式直接控制了服务器。整个过程揭示了安全防护中的常见短板:单一维度的防御(如仅过滤文件内容)往往不足,必须对文件路径、目标目录权限等进行综合控制。
前期的全面信息收集为漏洞利用提供了更多可能性,而中期的灵活思考与多次尝试则是突破防线的关键。对于防御方而言,除了修复漏洞本身,还应建立纵深防御体系,例如对上传目录进行严格的权限控制、对用户输入进行全方位的校验等。
希望这个案例能为大家在Web安全实战和防御建设上带来一些启发。更多技术讨论与资源共享,欢迎访问云栈社区。