Tags: xxe waf-bypass
# Challenge Name: Unagi
Vulnerability: External XML Entity (XXE)
Solution: Bypass character encoding
**Part 0x01 - Information Gathering**
There are three interesting pages on the website: [user](http://web.chal.csaw.io:1003/user.php), [upload](http://web.chal.csaw.io:1003/upload.php), and [about](http://web.chal.csaw.io:1003/about.php). This site is written using PHP based on the file extensions of the pages.
Displayed information of users on `user.php` page are `name`, `email`, `group`, and `intro`. In `upload.php` page, there's a format sample in XML. (http://web.chal.csaw.io:1003/sample.xml)
About.php page gives us a hint that the flag is located at `/flag.txt`.
**Part 0x02 - Vulnerability Exploitation**
We can perform an External XML Entity (XXE) attack on this challenge.
Adding the following payload `]>` throws a WAF error message.
So to solve this, we have to look for WAF bypass to exploit the vulnerability.
Searching on Google gives us this article: https://www.phdays.com/en/press/news/phdays-vi-waf-bypass-contest/. Check out #3 for XXE WAF Bypass.
The author found out that if we converted the character encoding of UTF-8 to UTF-16 Big Endian, we could easily bypass the WAF.
> encoded the body in UTF-16 Big Endian via the command cat x.xml | iconv -f UTF-8 -t UTF-16BE > x16.xml
Using the sample.xml given by the challenge author, we will convert the character encoding of the file to UTF-16BE.
After uploading the XML file, we managed to retrieve the `passwd` file from the internal server. However, it only prints 20 characters.
I tried adding the variable to Name and Email but the same result. Fortunately, I remembered that there's another field named `intro` in the user page. I then added it to the XML file and converted the character encoding again.
Uploading it to the challenge website will give us the content of the `passwd` file.
But that doesn't mean we can quickly get the `flag` located at `/flag.txt`. To get the flag, I have to use the `php://filter` wrapper.
Final Payload would be
Uploading it will print a BASE64 cipher.
Decoding it to text will give us the flag.
Thanks for reading.