Disguise PHP Logic in Images Files

Let’s say you want to share an image file on your Apache server. It is as simple as uploading the image file to your server and sharing the URL which points to the image file.

It is also possible to configure your server to keep track of the access logs even do some advance protection techniques such as hot-link protection and password protection.

However, if you have more complicated business requirements, these basic protocols may not be enough for you.

PHP Scripting in an Image File

Normally servers are configured to parse/compile .php files as PHP script files and serve the other files untouched. We can change that with 2 possible ways; First, by informing the Apache server to run image files as php files. Second, by forcing the Apache server to pass images through a .php file before serving. To achieve the second option, we will create a configuration file and manage server’s serving style for some specific file types.

This file, .htaccess, is a configuration file to be used on web servers running Apache Web Server software. You can create or edit the .htaccess file via FTP or File Manager in cPanel.

RewriteRule ^(.*)\.jpg$ image.php [NC]
RewriteRule ^(.*)\.jpeg$ image.php [NC]
RewriteRule ^(.*)\.png$ image.php [NC]
RewriteRule ^(.*)\.gif$ image.php [NC]
RewriteRule ^(.*)\.bmp$ image.php [NC]

Placing these lines in a .htaccess file will automatically redirect all listed extensions to image.php file. The .htaccess file must be located in the same folder with the images and image.php file.

Now, image.php file can contain our business logic in the form of PHP Script. We can extend the possibilities and protection in the way we want. PHP can detect user information such as IP address and browser type, can trigger any other related functions and can alter or block the image file before serving.

<?php
  /*
  	image.php
    You can put any php here. Script at the end serve the image as expected.
  */
  	$filepath = '.'. $_SERVER['REQUEST_URI'];
	if (file_exists($filepath)) {
      $path_parts = pathinfo($filepath);
      header("Content-type: image/" . strtolower($path_parts['extension']));
      header("Expires: Mon, 1 Jan 2099 05:00:00 GMT");
      header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
      header("Cache-Control: no-store, no-cache, must-revalidate");
      header("Cache-Control: post-check=0, pre-check=0", false);
      header("Pragma: no-cache");
      header("Accept-Ranges: bytes");
      header('Content-Length: ' . filesize($filepath));
      readfile($filepath);
    } else {
	   header( "HTTP/1.0 404 Not Found");
  	}
?>

This PHP file serves the image as expected with the correct file, file size and file type. Client won’t suspect anything because the url looks like an image file and they also receive an image file.