PHP fopen() function to local file inclusion
Hi there, This writeup is about a recent LFI vulnerability I found on a private program I've been working on for a while, and I found some interesting bugs on it, but I decided to share only this one, at least for now :)
So first of all, while I was google dorking for some interesting parameters I came through a page that looked like a video provider webpage and I found multiple endpoints for the same page that reflects with different videos which is just a parameter. i.e (https://videos.redacted.com/video/FAD4E99)
I checked that page looking for anything interesting I can find, and luckily I found a download video button, what was interesting is that the video was downloaded from an external CDN host and the download request had this video URL on it so it looked something similar to
The name parameter was just for the name of the file after being downloaded so it wasn't that important.
Anyway, after some while, I found how the filter for this
URL parameter was, and to simplify it was like checking this regex pattern.
So it was basically something like
[*]/[*]/cdn.redacted/[*], and anything not in that pattern will be filtered and a 403 response will come out...
Luckily there was an error popping up every time and it was
Warning: fopen([URL]): failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found in readfile_chunked() (line 1718 of [PATH]). as you can see clearly that my input is going through a PHP fopen() function, here I opened the php.net site and started looking for some docs about this function to know what are the limitations I'm at and how can I read something with it.
$localRead = fopen("/home/rasmus/file.txt", "r");$httpBased = fopen("http://www.example.com/", "r");$ftpBased = fopen("ftp://user:[email protected]/somefile.txt", "r");
So if I started the payload with http(s)? then I cannot ever access the local files, I'll only be limited to access websites, but luckily in my case they allowed the parameter to enter the URL without specifying any protocol to be like
//xhzeem.me, and this type of URL is handled as a local files request by the fopen() function, it doesn't recognize it as an HTTP request, so the payload I made finally was like this
/etc/cdn.redacted/../passwd and the final exploit will be
The report was fixed on the same day and they told me that I bypassed an existing fix that was supposed to prevent the bug but turns out wasn't enough.