慢慢更新,现在还看不得!!!!
准备
工具
漏洞挖掘第一步当然是把环境搭起来,然后安装一些必要的工具:
1.Idea:不会还有人用eclipse吧?!!
2.jclasslib/fernflower/bytecodeviewer/jd-gui:各种反编译工具
4.javaassist/asm:字节码修改工具
由于jar和class不便于搜索,所以可以将其先反编译为java文件,此处使用fernflower,可下载最新版编译,idea也自带此jar包:
git clone https://github.com/fesh0r/fernflower.git # 下载软件
gradlew.bat # 安装gradle
gradlew.bat build # 编译项目,最新版默认使用jdk11,可修改build.gradle里的配置
cd workdir # 切换到项目目录
mkdir src # 创建新文件夹存放源码
java -jar fernflower.jar ./class ./src #反编译
知识
1.Java基础语法
2.Java EE语法,就JSP/Servlet/MVC这些
3.其他高级语法:反射,动态代理(proxy/cglibc),动态代码生成,注解,类加载
注解:类似于注释但在多个阶段可使用,如可创建运行时有效的注解,运行时使用反射获取其值并进行相应动作。

语言特性漏洞
java代码审计手书:http://wiki.ioin.in/post/group/74mW
技术分享|浅谈Java Web漏洞分析:https://mp.weixin.qq.com/s/S4UEHy-JTVJ23VcPjooqcQ
sun.net.www.protocol.包下面可以看到所支持的协议:gopher file ftp http https jar mailto netdoc
将库和类文件添加到项目里,如一般项目会把classes
与lib
放入WEB-INF
目录下,另外可能需要调试J2EE相关的库,可以将其添加到项目结构里:

XXE
XXE 漏洞代码及修复代码整理:https://zhuanlan.zhihu.com/p/265402618
Java XXE Vulnerability:https://docs.ioin.in/writeup/joychou.org/_web_java_xxe_vulnerability_html/index.html
一篇文章读懂Java代码审计之XXE:https://blog.csdn.net/sun1318578251/article/details/104426472
SMTP over XXE − how to send emails using Java's XML parser:https://shiftordie.de/blog/2017/02/18/smtp-over-xxe/
SAXBuilder
SAXParserFactory
SAXReader
SAXTransformerFactory
TransformerFactory
ValidatorSample
XMLReader
Unmarshaller
SchemaFactory
.....
SSRF
SSRF in JAVA:https://docs.ioin.in/writeup/joychou.org/_index_php_web_javassrf_html/index.html
JAVA代码审计之XXE与SSRF:https://xz.aliyun.com/t/2761
模板注入
搜Freemarker和Velocity
[模板注入一例(]http://gv7.me/articles/2019/apache-solr-velocity-rce-20191031/)
LDAP注入
浅谈LDAP注入攻击:https://www.anquanke.com/post/id/212186
表达式注入
EL/OGNL/SPEL
浅析 OGNL 的攻防史:https://paper.seebug.org/794/
由浅入深SpEL表达式注入漏洞:http://rui0.cn/archives/1043
Bean Stalking: Growing Java beans into RCE:https://securitylab.github.com/research/bean-validation-RCE/
文件包含
动态包含:<jsp:include page="<%=file%>"></jsp:include>
、<c:import url="<%= url%>"></c:import>
命令注入
常见的会使用new ProcessBuilder.command
和Runtime.getRuntime.exec
文件上传
找multipart
,fileUpload
或getParts
获取文件上传点[1],看文件名能不能穿越或传恶意文件,再看文件内容能不能造成危害。
对于spring可搜索multipartResolver
看是否修改了默认解析器,它的StandardMultipartFile
(默认)不过滤目录穿越而CommonsMultipartFile
会过滤[0]。
参考
[0] Spring MultipartFile 文件上传的潜在威胁 -- JOHNSON (2021)
[1] 任意文件上传漏洞 -- 园长
框架
spring
现在遇到的基本都是spring,包括spring,spring mvc, spring boot, spring cloud等,它们有各自的应用场景,关系如下:
理解spring需要懂它的面向切面编程(AOP)/控制反转(IOC)/依赖注入(DI)等概念
现在遇到的一般都是基于Spring框架的,Spring家族里有很多东西,但只需理解它的核心概念:
IOC:控制反转,将对象的生成交由Spring实现,这样方便实现DI和AOP
AOP:面向切面编程,可用于避免面向对象编程时必须的层级关系,作为补充它通过功能来复用代码
DI:依赖注入,可自动根据属性类型,名称等注入所需的实例

spring mvc一般了解它的处理流程即可,可见“Spring MVC的介绍与执行流程”:

spring在查找handler时,可能会做一些奇怪的操作(如可匹配//
),或者开发自行添加了路径匹配规则,从而绕过一些限制。
历史漏洞
- CVE-2022-22965:利用参数绑定修改Tomcat的日志配置实现写马
- CVE-202X-XXXXX: 和Shiro一起造成的各种问题
- ...
参考
Java框架级SSM代码审计思路:https://paper.seebug.org/1075/
struts
struts和struts2有些区别,但都很少见了,在我开始挖Java应用后只见过一次,关于它的基础可看W3school,现在一般也就是学它的那一系列漏洞,主要是ognl表达式的问题,可见如下链接:
webservice
这一类没有特别的,就是要六节web service协议,常见的框架有WebService,xfire(cxf),axis。
组件
持久化
mybatis
mybatis是半自动化的,需要开发编写SQL语句,此时参数可用#{}和${}方式放置,后者直接替换如SQL语句再预编译因此存在SQLi,有三种情况无法用#{},因此易出问题[1]:
1.like后无法直接用,可like concat('%', #{}, '%')
的方式
2.in后的参数
3.oder by后的参数,可用白名单限制
hibernate
H2
它可以执行Java命令,堆叠注入(猜测未验证),注意每次修改后函数名也需要修改:
// http://www.h2database.com/html/commands.html?highlight=alias&search=alias#create_alias
CREATE ALIAS DDrrArr AS $$void replace() throws java.io.IOException{new java.io.File("webapps/ROOT/weixin.jsp").renameTo(new java.io.File("webapps/ROOT/weixin.jsp.bak"));java.io.FileWriter writer = new java.io.FileWriter("webapps/ROOT/weixin.jsp");writer.write("<%=123;%>");writer.close();}$$;
CALL DDrrArr();
JavaWeb中的信息泄漏——H2 database:https://www.sec-in.com/article/827
Ehcache
。。。
MYSQL-JDBC反序列化入口
使用MySQL JDBC连接器在连接可控时可能存在反序列化入口点(版本小于8.0.23
),若再存在利用链则可RCE,原因是它的结果集封装了反序列化操作getObject
,如下:
public Object getObject(int columnIndex) throws SQLException {
int columnIndexMinusOne = columnIndex - 1;
Field field = this.fields[columnIndexMinusOne];
switch (field.getSQLType()) {
/* 当SQL类型与域类型如下时,将会调用getObjectDeserializingIfNeeded*/
case Types.BIT:
if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT && !field.isSingleBit()) {
return getObjectDeserializingIfNeeded(columnIndex);
}
return Boolean.valueOf(getBoolean(columnIndex));
...
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_GEOMETRY) {
return getBytes(columnIndex);
}
return getObjectDeserializingIfNeeded(columnIndex);
...
}
}
private Object getObjectDeserializingIfNeeded(int columnIndex) throws SQLException {
final Field field = this.fields[columnIndex - 1];
if (field.isBinary() || field.isBlob()) {
byte[] data = getBytes(columnIndex);
if (this.connection.getAutoDeserialize()) { // 设置了自动反序列化
Object obj = data;
if ((data != null) && (data.length >= 2)) {
if ((data[0] == -84) && (data[1] == -19)) { // 数据以ACED开始
try {
ByteArrayInputStream bytesIn = new ByteArrayInputStream(data);
ObjectInputStream objIn = new ObjectInputStream(bytesIn);
obj = objIn.readObject();
...
}
如果我们能(1)控制MySQL查询的返回数据且(2)设置了自动反序列化,而且(3)会对结果集调用getObject,就能在此处进行反序列化。这个连接器支持的一个拦截器满足条件(3):
public class ServerStatusDiffInterceptor implements StatementInterceptor {
public ResultSetInternalMethods postProcess(String sql, Statement interceptedStatement, ResultSetInternalMethods originalResultSet, Connection connection)
throws SQLException {
if (connection.versionMeetsMinimum(5, 0, 2)) {
populateMapWithSessionStatusValues(connection, this.postExecuteValues);
...
}
private void populateMapWithSessionStatusValues(Connection connection, Map<String, String> toPopulate) throws SQLException {
try {
stmt = connection.createStatement();
rs = stmt.executeQuery("SHOW SESSION STATUS");
Util.resultSetToMap(toPopulate, rs);
...
}
public static void resultSetToMap(Map mappedValues, java.sql.ResultSet rs) throws SQLException {
while (rs.next()) {
mappedValues.put(rs.getObject(1), rs.getObject(2));
}
}
漏洞点能指定连接器,连接器能指定拦截器,拦截器会在查询前后自动执行于是满足了条件(3),这个漏洞点又满足条件(1)(2),串起来就是个反序列化点了,接下来就是找利用链,至于如何构造数据包可参考[1][2][3]。
安全
Shiro
密钥不正确或者反序列化后类不正确会返回rememberMe=deleteMe
CVE-2020-11989,CVE-2020-13933权限绕过漏洞
shiro < 1.6.0的认证绕过漏洞分析(CVE-2020-13933):https://www.anquanke.com/post/id/214964
Spring Security
漏洞利用
回显
Java 反序列化回显的多种姿势:https://xz.aliyun.com/t/7740
木马
- https://www.anquanke.com/post/id/214435
- https://www.anquanke.com/post/id/214483#h2-6
自动化
漏洞挖掘
类型 | 说明 | 参考 |
---|---|---|
tabby | 白猪写的,用图数据库存储调用关系,通过写查询语句就可以自动化完成利用链查找工作 | |
CodeQL | [0]代码分析引擎 CodeQL 初体验,[1]使用 CodeQL 分析闭源 Java 程序 | |
RASP | 运行时应用自保护,一般通过Agent侵入待保护进程,根据规则对危险操作进行检测与拦截 | [0]Java RASP浅析——以百度OpenRASP为例,[1]浅谈 RASP |
IAST | 聊聊对目前Passive IAST的思考 | |
探索先进自动化漏洞挖掘技术中的不足:https://paper.seebug.org/1404/
插桩技术在Java安全中的应用简述:http://rui0.cn/archives/1063
Java 反序列化工具 gadgetinspector 初窥:https://paper.seebug.org/1034/
Java动态追踪技术探究:https://juejin.cn/post/6844903785219751943
[译]使用ASM对Java字节码插桩:https://c0d3p1ut0s.github.io/%E8%AF%91-%E4%BD%BF%E7%94%A8ASM%E5%AF%B9Java%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9/