Huntress CTF 2025 - ARIKA
A web challenge exploiting a regex misconfiguration in a terminal-style web application to bypass command whitelisting and extract the flag through newline injection.
Introduction
This write up covers the ARIKA challenge from the 2025 Huntress CTF. Huntress CTF is a yearly CTF hosted by Huntress every October to celebrate cybersecurity awareness month, containing dozens of different challenges ranging from OSINT, to forensics, to full on web application penetration testing, and many more. To see my other write ups for this years CTF Click here.
Background
In this web challenge we were required to exploit a web application running a limited terminal to extract the flag. Normally the user should only be able to a certain list of commands that were whitelisted in the web applications code, so we needed to find a fault in the web applications code that would allow us to inject non-whitelisted commands.
Finding the vulnerability
For this challenge we were given the applications code, allowing us to look through it’s files to find any possible logic errors or vulnerabilities we could exploit. Looking at the file app.py I found exactly that in line 30, the section of the application that handles checking if the user’s input matched the list of approved commands.
In theory, the line if not any([ re.match(r"^%s$" % allowed, command, len(ALLOWLIST)) for allowed in ALLOWLIST]): takes the users input and checks it against ALLOWLIST, the list of approved commands. If the input matches one of the items in that list the command should be able to run, and if it doesn’t match it should return a message prompting the user to use the help command to see a list of the available commands. The issue comes in the third argument of the re.match() function, which the developer has set to len(ALLOWLIST), which evaluates to the integer 8 since ALLOWLIST has 8 items inside of it. This is problematic because the third argument of the re.match() function is reserved for regex flags, and the value 8 corresponds to the regex the re.MULTILINE flag.
Without getting too much into how regex works it can be understood that the developer intended for the function work as “if the input matches an item in the allowed list , run the command”, however because the multiline flag is set the function actually runs as “if the input matches an item in the allowed list, OR IF IT IS IN A NEW LINE, run the command”.
Exploiting the vulnerability
Having found the vulnerability it was now just a matter of using it to our advantage so that we could input any command we wanted. Using burp suite I realized that the application handles commands by sending a POST request to the server, which would then run the command and return the output. Intercepting one of the POST requests I added a newline character /n) as well as the ls command.
As we can see in the screenshot above the server returned the expected output of the help command, but also appended the output for the ls command to the response, proving that the command injection worked. From this output I could see that the flag was stored in the same directory the web application was running on, so now it was only a matter of repeating the process but this time appending cat flag.txt after the newline character.
Success! The server correctly returned the output for the help command while also printing out the flag found in flag.txt.




