Blind XXE Leads to Internal Port Scanning Through SSRF

2 minute read

General Description Of XXE

XML External Entity injection better known as XXE is an attack where the attacker can to interfere with a web application XML data and make it parse in the server side for unintended purposes. This vulnerability has different ways to bring impact towards its exploitation, commonly, it allows to view files in the application server file system, or interact with external systems that only the application can access. In this case, it was possible to prove internal port scanning by leveraging the XXE vulnerability to perform SSRF attack.

For more information regarding labs and a description regarding XXE flaws, I strongly recommend Portswigger.

Background Behind The Flaw

After testing my favorite program in Synack Red Team, there were certain endpoints where XXE have been reported before, so I decided to take a look to see if it was doable to replicate the flaw, fortunatelly after a few hours of constant testing, it was possible to prove the existence of the flaw and its capability to perform internal port scanning. This was my first ever XXE, so it felt great to see it working in one way or another.


Note: Information regarding the client’s name and paths will not be fully disclosed in this write-up due to the vulnerability disclosure policy.

When mapping the web application, there was a form to submit a different kind of ideas with several fields to fill information. The landing page looked like the following:


Therefore, after filling all the forms in the landing page, a POST request was sent with content type application/x-www-form-urlencoded, but there was an interesting parameter that caught my attention due to its name which was WebDocXML, and as its name says it, it was taking XML data from the form and parsing it in the server side. The POST request looked as the following:


Flaw Exploitation

So, after recognizing that the parameter WebDocXML was receiving XML data, there was the need to look for a payload that will prove the existence of the vulnerability as blind XXE, as the response was not giving any other information than 200 status code with a small script to proceed with a redirect. Therefore, a common blind XXE payload was used with the purpose to receive an HTTP request in my VPS where, fortunately, the vulnerability proved to exist as I was able to receive an HTTP request from the target’s IP. The following blind XXE payload was used.

< ! DOCTYPE foo [<!ENTITY % xxe SYSTEM ""> %xxe; ] >


As the flaw has been confirmed successfully, it’s time to escalate it to see its capabilities which unfortunately were limited in this case. Internal port scanning was possible by using the XXE payload mentioned before and sending a different kind of HTTP requests to possible web services running over HTTP within the server. Just to confirm the flaw, this was a time-based port scanning meaning that:

  • If the port is open, the response time will take less than 1000 mills.
  • If the port is filtered or closed, the response will take more than 2000 mills

Therefore, the following payload was slightly modified to prove port 80 as closed when the response takes more than 2000 mills as the following, please take a close look at the response time:

< ! DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://localhost:80" > %xxe; ] >


This is another proof of concept of port 443 being open as as the response time takes less than 1000 mills.

< ! DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://localhost:443"> %xxe; ] >


After proving that port scanning was possible via time based method, Synack accepted and rewarded the vulnerability with 10% of the value as the endpoint was reported before, with a 5.8 CVSS score.


If you’re a Synack Red teamer, take a constant look at analytics to see what endpoints and technologies some of the web applications might be running, also, take a close look at HTTP parameters that may disclose different type of data like in this case XML data.

Any feedback and future recommendations are always welcome :)

Thanks for making it to the end!

If you want to chat or just connect, feel free to shoot a direct message on Twitter.


Leave a comment