This is a request based challenge where you have to craft a get request such as it passes a filter for the flag keyword

Add EXPOSE 3456 to the docker file so you can access the port on the docker.
First of all in order to build the challenge you have to use the command docker build . it will give you an id at the end which you will use in order to run docker run If you want to kill the docker you can list the docker images currently running look at the names it should be charming_sammet and get the id then using docker kill id you can kill it Also in order to make sure your docker will expose the port you should use the command sudo docker container run -p 3456:3456 –expose 3456 2b420edb6b97` to run it.

The home page looks like:

Clicking on the hyperlink shows us the page

Making a double encoding script so we can better obfuscate the flag variable:

target_string='flag.txt'
def encode(target):
    new_target=''
    for i in target:
        new_target+='%'+format(ord(i), 'x')
    return new_target
encode(target_string).replace('%','%25')

TLDR: The request that gets the flag is:

http://127.0.0.1:3456/?file[protocol]=file:&file[hostname]=&file[href]=None&file[origin]=None&file[pathname]=%2566%256c%2561%2567%252e%2574%2578%2574

How do we get here?

We need to evaluate the filtering function:

Also the function that fetches files:

The two functions we need to analyse are fs.readfilesync and JSON.stringify(item).includes.

Inputting different encodings

One encoding doesn’t work because the json stringify decodes it. The double encoding option does not work as well because the req only does one unencode. Other options like utf stuff don’t work as well.

The response on double encoding:

Looking at the function from github (https://github.com/nodejs/node/blob/main/lib/fs.js) we can see:

the function opensync opens the path we supply

Then the function openync uses getValidatedPath

The getvalidatedpath can retrieve a file or url:

And the function fileurl to path converts from our url to a path

And the function that gets a path from url also decodes again the input:

So we can bypass the filter by having double encoding if only we set the right parameters.

The query is :

http://127.0.0.1:3456/?file[protocol]=file:&file[hostname]=&file[href]=None&file[origin]=None&file[pathname]=%2566%256c%2561%2567%252e%2574%2578%2574

because we can see the following requirements:

path.protocol=='file:' fileurltopath function path.pathname=flag.txt encoded twice getpathfromurlposix function path.href not none getvalidatedpath path.origin not none getvalidatedpath path.hostname =='' getpathfromurlposix function