The lab
here is how portswigger describes it
This lab contains a path traversal vulnerability in the display of product images.
The application strips path traversal sequences from the user-supplied filename before using it.
To solve the lab, retrieve the contents of the /etc/passwd file.
the absolute path lab blocked ../ by rejecting anything that looked like traversal. this one is a little smarter, it does not reject the input, it quietly deletes the traversal sequences and uses whatever is left. that one word, strips, is the weakness we are going to lean on.
why stripping once is not enough ?#
blocking and stripping are two different reactions to a bad input. blocking throws the request away. stripping tries to clean it up and carry on, cutting the ../ out of your filename and using the remainder. that sounds safe until you ask how many times it cleans.
here the app strips the traversal sequences only once, in a single pass, and never checks the result. that is what non recursively means. it scans the input, removes every ../ it can see, and hands back what is left without looking again. the fix is to feed it a payload that still contains a valid ../ after one round of cutting, by hiding a traversal sequence inside another one.
Step 1 - Nest the sequences so one survives the strip#
we go to the same image endpoint, intercept it, and send it to repeater.
the payload looks strange at first but the logic is simple:
GET /image?filename=....//....//....//....//....//....//etc/passwd HTTP/2
here is what happens inside that ....//. the filter is looking for the exact string ../ and removing it. in ....// there is a ../ sitting in the middle, so the filter finds it and cuts it out. but look at what is left behind when you remove the ../ from ....//, the characters on either side close up into a fresh ../. in other words the strip itself rebuilds the very thing it just deleted. because the app only passes through once, it never notices the new sequence it created, and the cleaned filename ends up full of working ../ steps again.

so after the single strip, our ....//....// pile collapses into exactly the ../../ chain we wanted all along, which walks up to the root and down into the target file.

with this, the lab is solved!
