zoukankan      html  css  js  c++  java
  • java代码审计中的一些常见漏洞及其特征函数

    文章来源:https://xz.aliyun.com/t/1633

    最近在先知上看到之前有篇关于java代码审计的文章总结的蛮好,记录以下特征函数,方便查阅,同时自己也会将在平时代码审计过程中积累的函数补充在这篇文章中。(虽然作者已经很贴心的提供了脚本)。

    1.xxe

    常见解析xml的类有如下:

    javax.xml.parsers.DocumentBuilder
    javax.xml.stream.XMLStreamReader
    org.jdom.input.SAXBuilder
    org.jdom2.input.SAXBuilder
    javax.xml.parsers.SAXParser
    org.dom4j.io.SAXReader
    org.xml.sax.XMLReader
    javax.xml.transform.sax.SAXSource
    javax.xml.transform.TransformerFactory
    javax.xml.transform.sax.SAXTransformerFactory
    javax.xml.validation.SchemaFactory
    javax.xml.bind.Unmarshaller
    javax.xml.xpath.XPathExpression

    1)javax.xml.parsers.DocumentBuilder   (原生dom解析xml)

    例子:

    DocumentBuilderFactory doc=DocumentBuilderFactory.newInstance();
    DocumentBuilder db=doc.newDocumentBuilder();
    InputStream is= new  FileInputStream("test.xml");    
    Document doc=dombuilder.parse(is);   //sink点
    Element rootElement = document.getDocumentElement();

    2)javax.xml.stream.XMLStreamReader    (StAX解析器,可读可写)

    例子:

    XMLInputFactory factory = XMLInputFactory.newFactory();
    InputStream stream = XmlInputFactory.class.getClassLoader().getResourceAsStream("webService/xml/users.xml");
    XMLStreamReader reader = factory.createXMLStreamReader(stream);   //sink点
    while (reader.hasNext()) {...}

    3)javax.xml.parsers.SAXParser  /  org.xml.sax.XMLReader  (原生SAX解析xml)

    例子:

    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser = factory.newSAXParser();
    XMLReader reader = parser.getXMLReader();   //reader.setContentHandler(new MyContentHandler());
    reader.parse(xmlPath);    //sink点

    4)org.jdom.input.SAXBuilder  /  org.jdom2.input.SAXBuilder   (jdom解析xml)

    例子:

    SAXBuilder sax = new SAXBuilder();
    Document doc = sax.build("src/config.xml");    //sink点

    5)org.dom4j.io.SAXReader    (dom4j解析xml)

    例子:

    InputStream fis=new FileInputStream("G:\eclipsewk\SDK201702\Test-Pack\package\work\before\AndroidManifest.xml");
    Document document = new SAXReader().read(fis);   //sink点

    6)javax.xml.validation.SchemaFactory    (校验xml)

    例子:

    File xsdfile=new File("xml/orders.xsd");
    File xmlfile=new File("xml/orders.xml");
    Handler errorHandler=new Handler();
    SchemaFactory schemafactory=SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); //
    Schema schema=schemafactory.newSchema(xsdfile);
    Validator vaildator=schema.newValidator();
    vaildator.setErrorHandler((ErrorHandler) errorHandler);
    vaildator.validate(new StreamSource(xmlfile));   //sink点

    7)javax.xml.bind.Unmarshaller    (JAXB解析xml,也是实现java和xml的转换)

    例子:

    JAXBContext jc = JAXBContext.newInstance(clazz);
    Unmarshaller u = jc.createUnmarshaller();
    u.unmarshal(new File(xmlstr));    //sink点

    修复方法:

    • xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
    • xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);

    8)javax.xml.xpath.XPathExpression   (XPath查询)

    DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();    
    DocumentBuilder builder = df.newDocumentBuilder();
    String result = new XPathExpression().evaluate(builder.parse(new ByteArrayInputStream(xml.getBytes())));

    值得注意的是:javax.xml.xpath.XPathExpression类似于Unmarshaller,它无法自行安全地配置,因此必须首先通过另一个安全的XML解析器解析不受信任的数据

    9)javax.xml.transform.sax.SAXSource   /   javax.xml.transform.TransformerFactory   /   javax.xml.transform.sax.SAXTransformerFactory    (生成和转换xml)

    10)Apache Commons Configuration读取xml配置

    XMLConfiguration.load

    代码审计的时候感觉一个个搜索也很麻烦,在使用脚本前可以先全局搜索下DocumentBuilder、sax、Unmarshaller 、XPath、XMLInputFactory等字眼。

    2.反序列化漏洞

    反序列化操作一般在导入模版文件、网络通信、数据传输、日志格式化存储、对象数据落磁盘或DB存储等业务场景,在代码审计时可重点关注一些反序列化操作函数并判断输入是否可控,如下:

    1)ObjectInputStream.readObject  //最常见的反序列化sink点,将流转化为object对象

    2)ObjectInputStream.readUnshared  //使用较少,和readobject有些区别

    readUnshared()方法来读取对象,readUnshared()不允许后续的readObject和readUnshared调用引用这次调用反序列化得到的对象,而readObject读取的对象可以。

    3)XMLDecoder.readObject  //读取xml转化为object,尝试了一下不能进行xxe,不过这个xml反序列化漏洞不用像其他反序列化那样构造很麻烦,可以直接使用下面的poc执行命令。

      <java>
            <object class="java.lang.ProcessBuilder">
                <array class="java.lang.String" length="1" >
                    <void index="0">
                        <string>c:\windows\system32\calc.exe</string>  
                    </void>
                </array>
                <void method="start"/>
            </object>
        </java>

    4)XStream.fromXML   //XStream用于java object与xml的相互转换,XStream.toXML(将java转换为xml)

    String payload = "<map><entry><jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data"> <dataHandler> <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource"> <is class="javax.crypto.CipherInputStream"> <cipher class="javax.crypto.NullCipher"> <initialized>false</initialized> <opmode>0</opmode> <serviceIterator class="javax.imageio.spi.FilterIterator"> <iter class="javax.imageio.spi.FilterIterator"> <iter class="java.util.Collections$EmptyIterator"/> <next class="java.lang.ProcessBuilder"> <command><string>calc</string> </command> <redirectErrorStream>false</redirectErrorStream> </next> </iter> <filter class="javax.imageio.ImageIO$ContainsFilter"> <method> <class>java.lang.ProcessBuilder</class> <name>start</name> <parameter-types/> </method> <name>foo</name> </filter> <next class="string">foo</next> </serviceIterator> <lock/> </cipher> <input class="java.lang.ProcessBuilder$NullInputStream"/> <ibuffer></ibuffer> <done>false</done> <ostart>0</ostart> <ofinish>0</ofinish> <closed>false</closed> </is> <consumed>false</consumed> </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/> </entry> <entry> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/></entry></map>";

    5)一些第三方jar包中的,这些第三方jar包历史版本中存在序列化漏洞

    ObjectMapper.readValue    jackson中的api
    JSON.parseObject    fastjson中的api

    6)Yaml.load

    审计的时候搜索readobject、readUnshared、fromXML这些关键api

    3.SSRF(服务器端请求伪造)

    HttpClient.execute
    HttpClient.executeMethod


    HttpURLConnection/URLConnection

    new  HttpGet(url)

    OkHttpClient()


    URL:URL   url = new URL();

        1) url.openStream       2)ImageIO.read(url)

     

    其他

    审计的时候搜索new URL、HttpClient、HttpURLConnection

    4.文件上传

    审计的时候搜索MultipartFile

    5.Autobinding    //参数自动绑定漏洞,在php中叫object注入漏洞,json注入也属于其中一种

    审计的时候搜索@SessionAttributes和@ModelAttribute,属于SpringMVC框架

    6.URL跳转漏洞

    1.response.sendRedirect  //重定向

    2.response.setHeader("Location", "http://www.baidu.com");      // 也是重定向

    3.request.getRequestDispatcher("/success.html").forward(request, response);     //请求转发

    7.命令执行

    1).Runtime.exec             //Runtime.getRuntime().exec(command)
    2).ProcessBuilder.start    //new ProcessBuilder(cmdArray).start(),取代了Process
    3).GroovyShell.evaluate    //主要用于在java中运行Groovy脚本

    shell.evaluate("

      static void main(String[]args){

        Runtime.getRuntime().exec(command);

      }

    ");

    类似的还有GroovyClassLoader 、ScriptEngine

    8.和文件操作相关的漏洞,例如任意文件读取、删除等等

    1)最常见的就是JDK原始的java.io.FileInputStream类

    2)JDK1.7新增的基于NIO读取文件的java.nio.file.Files类。常用方法如:Files.readAllBytes、Files.readAllLines

    3)JDK原始的java.io.RandomAccessFile类

    4)Apache Commons IO提供的org.apache.commons.io.FileUtils类

    5)JDK1.7新增的基于NIO非阻塞异步读取文件的java.nio.channels.AsynchronousFileChannel类

    9.json注入(有点类似参数自动绑定)

    1)json-lib框架中的JSONObject ,JSONArray
    2)Jackson框架中的JsonGenerator、Object(Mapper|Reader|Codec|Writer)|TreeCodec、JsonParser
    JsonGenerator.writeObject等    write(NumberField|Raw|RawUTF8String|RawValue|String|UTF8String)等


    ObjectMapper.writeValue()、ObjectMapper.writeTree()等

     

     3)Gson

     Gson.toJson()   Gson.fromJson()    JsonWriter.name|value()     JsonReader    JsonStreamParser  JsonParser.parse

    4)javax.json

     JsonWriter.write(Array|Object)     JsonParserFactory.createParser()    JsonGenerator

    5)fastjson

     10.ldap注入

    审计过程中可以直接搜索ldap字符初略的进行定位

    常见sink点:

    javax.naming.directory
        DirContext.search
    org.springframework.ldap
        LdapTemplate.search
        LdapOperations.search
    netscape.ldap
        LDAPAsynchronousConnection|LDAPv2.search
        LDAPGetEntries.getEntries
        LDAPGetProperty.getProperty

    最后是大佬的自动化脚本:https://github.com/Cryin/JavaID

    脚本还没用过。。。有机会看看效果。

  • 相关阅读:
    Parquet文件结构笔记
    parquet 简介
    Kubernetes 路由问题&网络问题
    postgresql:terminate hung query
    Python 动态加载并下载"梨视频"短视频
    Python 豆瓣mv爬取
    Ubuntu 硬盘分区只读,重新挂载为读写分区之后,文件依然创建出错
    Ubuntu 装机软件
    iTOP4412开发板相关内容
    linux driver ------ GPIO的驱动编写和调用
  • 原文地址:https://www.cnblogs.com/jinqi520/p/10083441.html
Copyright © 2011-2022 走看看