OrangeSite - "1 CAT COMPANY CTF" spring xxe challenge

On November 27 Cyhub Armenia organized a very fun local CTF event - 1 CAT COMPANY CTF and Hayk Andriasyan created an XXE challenge for it.

As a task description, we get only the website location:

task description

Visiting which we see nothing helpful, so we run our web fuzzer with a generic wordlist and get some interesting endpoints - /health, a health service actuator endpoint, /test some spring endpoint which throws java error containing script’s full path, /api, which returns 403 forbidden response.

path disclosure

Combing what we got - task’s name clearly referring to Orange Tsai, NginX server, we can clearly understand we must have NginX off by slash directory traversal vulnerability, so we try traversing to /api endpoint discovered before and succeed

api endpoint

Fuzzing for the obvious {path}, we find /api/data endpoint which expects XML body

api/data endpoint

So we try to exploit the XXE accessing external services via http/https and getting blocked by the parser, accessing external ftp server via file protocol and failing. But we see quickly the difference between existent and non existent file paths. When the server responds Your XML is valid the file exists and /somepath (No such file or directory) when it doesn’t.

successfull file read

failed file read

Then we realize that the only way to exfiltrate the data is through exploiting xxe with local dtd files. After trying some known gadgets we fail, so we should find a gadget ourselves. To do so we run a FreeBSD VM, as we know Antranig Vartanian, who is hosting the challenges, is a huuge FreeBSD fan and contributor, installing most probable maven dependencies like spring boot and jetty. And to find local dtd files we run the dtd finder tool made by GoSecure in our home directory with the following command.

java -jar dtd-finder-1.1-all.jar /home/tmp-user/.m2/ > out

Which yields the following results:


To find which jetty version the server is using, we pull the repo, extract version tags, feed it to Burp’s Intruder and find that it is using 9.3.3.v20150827

intruder window

We choose configure_6_0.dtd file to create our gadget as we have a perfect candidate CONFIG, which gets reflected few lines after.


To create the gadget we should escape CONFIG reflection on line 41

<!ENTITY % CONFIG 'Set|Get|Put|Call|New|Ref|Array|Map|Property)*>
<!ENTITY &#x25; file SYSTEM "file:///usr/home/app/">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
<!ELEMENT asd ('>

Sending the payload we get directory listing for the /usr/home/app/ folder

initial payload

Finally, in .extraverysupErSEcr3Tfolder folder, we find flag.txt


Thanks Cyhub for such a great event !.