XXE漏洞
XXE(XML External Entity Injection),中文称作XML外部实体注入。和SQL注入、XSS、XPath注入等类似,都是违反了“数据与代码分离原则”的产物。
XXE危害:配合各种协议和老哥们的骚思路,可以读取任意文件、执行系统命令、探测内网端口、攻击内网网站等。
XML常见接口
XMLReader
SAX2(Simple API for XML 2)
XMLReader接口是XML解析器实现SAX2驱动程序所必需的接口,当XMLReader使用默认的解析方法并且没有对XML进行过滤时,会造成XXE漏洞。
1 2 3 4 5 6
| try{ XMLReader xmlReader = XMLReaderFactory.createXMLReader(); xmlReader.parse(new InputSource(request.getInputStream())); }catch (Exception e){ e.printStackTrace(); }
|
SAXBuilder
SAXBuilder是JDOM解析器,使用第三方SAX解析器来处理解析任务,当使用默认解析方法时,会造成XXE。
1 2 3 4 5 6 7 8 9 10 11
| try{ String body = WebUtils.getRequestBody(request); logger.info(body); SAXBuilder builder = new SAXBuilder(); builder.build(new InputSource(new StringReader(body))); return "SAXBuilder xxe vuln code"; }catch(Exception e){ e.printStackTrace(); }
|
SAXReader
DOM4J是dom4j.org出品的一个开源XML解析包,有DOMReader
和SAXReader
两种方式,使用的是同一个接口
1 2 3 4 5 6 7 8 9 10
| try{ String body = WebUtils.getRequestBody(request); logger.info(body); SAXReader builder = new SAXReader(); reader.read(new InputSource(new StringReader(body))); }catch(Exception e){ e.printStackTrace(); }
|
SAXParseFactory
1 2 3 4 5 6 7 8 9 10 11
| try{ String body = WebUtils.getRequestBody(request); logger.info(body); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser parser = spf.newSAXParser(); parser.parse(new InputSource(new StringReader(body)),new DefaultHandler()); return "SAXParser xxe vuln code" }catch(Exception e){ e.printStackTrace(); }
|
Digester
它是Apache Commons
库中的一个jar包:common-digester
1 2 3 4 5 6 7 8 9
| try{ String body = WebUtils.getRequestBody(request); logger.info(body); Digester digester = new Digester(); digester.parse(new StringReader(body)); }catch(Exception e){ e.printStackTrace(); }
|
DocumentBuilderFactory
DocumentBuilderFactory是一个抽象工厂类,不能直接实例化,但是提供了newInstance()
方法,会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| try{ String body = WebUtils.getRequestBody(request); logger.info(body); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); String Reader sr = new StringReader(body); InputSource is = new InputSoure(sr); Document document = db.parse(is); StringBuffer buf = new StringBuffer(); NodeList rootNodeList = document.getChildNodes(); for(int i=0;i<rootNodeList.getLength();i++){ Node rootNode = rootNodeList.item(i); NodeList child = rootNode.getChildNodes(); for(int j=0;j<child.getLength();j++){ Node node = child.item(i); buf.append(node.getNodeName()+":"+node.getTextContent()+"\n"); } } sr.close(); return buf.toString(); }catch(Exception e){ e.printStackTrace(); }
|
XXE的payload
https://hackerqwq.github.io/2020/08/05/XXE%E6%B3%A8%E5%85%A5payload/
XXE漏洞修复
可以通过设置XML解析器的属性,禁用DTD或者禁用外部实体来达到防御XXE攻击的效果
1 2 3 4
| obj.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true); obj.setFeature("http://xml.org/sax/features/external-general-entities",false); obj.setFeature("http://xml.org/sax/features/external-parameter-entities",false);
|
需要注意的是当使用DocumentBuilder进行解析时,需要先设置属性再获取解析器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; String result = ""; try{ String FEATURE = null; FEATURE = "http://javax.xml.XMLConstants/feature/secure-processing"; dbf.setFeature(FEATURE,true); FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; dbf.setFeature(FEATURE,true); FEATURE = "http://xml.org/sax/features/external-general-entities"; dbf.setFeature(FEATURE,false); FEATURE = "http://xml.org/sax/features/external-parameter-entities"; dbf.setFeature(FEATURE,false); FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; dbf.setFeature(FEATURE,false); dbf.setXIncludeAware(false); dbf.setExpandEntityReferences(false); db = dbf.newDocumentBuilder(); Document doc = db.parse(request.getInputStream()); ... }catch(Exception e){ e.printStackTrace(); }
|
XXE漏洞代码审计关键字
1 2 3 4 5 6
| XMLReader SAXBuilder SAXReader SAXParserFactory Digester DocumentBuilderFactory
|