
Malware Hidden Inside JPG EXIF Headers - cubictwo
http://blog.sucuri.net/2013/07/malware-hidden-inside-jpg-exif-headers.html
======
vog
Although this obfuscation is very clever, I think the article overstates a
bit. The author claims that the following two commands "harmless by
themselves":

    
    
      $exif = exif_read_data('/homepages/clientsitepath/images/stories/food/bun.jpg');
      preg_replace($exif['Make'],$exif['Model'],'');
    

I don't agree with that. While the first command is indeed harmless, the
second one is executing a REGEX machine with a dynamic regex param. This is
almost like having a user-defined format string to printf(), and thus very
suspicious and should be found by any decent security analysis tool.

Even without the "/e" feature of preg_replace, this could result at least in a
denial of service attack via some specially crafted regex parameters.

So I agree that this is clever, but I don't agree that this call to
preg_replace() should normally be considered harmless by itself. So the
question remains why the authors overstate the cleverness of this attack, and
I think they give the answer in the last sentence of the article:

 _" Note: Any of Sucuri clients using Server Side Scanning are protected
against this type of injection (detected by us)."_

~~~
randomdrake
I completely agree with your assessment.

I would like to add that there's probably no reason regex would even be needed
for this task. str_replace() would be the more appropriate call. In ##php on
Freenode we often have to tell people that you don't need to use preg_*
functions if you are not using the power of regular expressions. If you don't
need the power of regular expressions, you should be using str_replace() for
your operation. In this case, str_replace() would be not only be more
appropriate, it would have helped remove the risk of exploit.

That aside, there have been reports of people exploiting metadata in images
for years with PHP and other languages. This is not new in any way.

I'm disappointed that the article seems to stress that JPEGs are somehow
inherently insecure when, in fact, it should be stressing that one should
always be extremely careful dealing with user-submitted input.

In this example, one could simply replace the image uploading aspect with any
sort of submitted data. If you're going to be dynamically passing user input
into functions of your application, you should always be certain to
appropriately clean and escape those situations. Whether that data is hidden
in the EXIF data on an image, is going to be put into a database, or is
dynamic regex, a healthy level of distrust for all user submitted data is
necessary.

~~~
ceol
_> In this case, str_replace() would be not only be more appropriate, it would
have helped remove the risk of exploit._

Actually, the exploit was a backdoor planted by the hacker, so the system was
already compromised. The recommendation to use str_replace in this instance
would be useless, as it appears the victim didn't even put the code there in
the first place.

~~~
randomdrake
I see. I didn't read it as a back door attack but an injection attack against
bad code.

------
savories
Important to note the jpg is just one part of the malware. It is harmless by
itself. It still requires some other file to actually execute it. The jpg just
contains further instructions for the backdoor. The jpg is really just an
obfuscator.

~~~
pjungwir
Exactly. The attacker-added PHP code to run preg_replace is still there. But
it does look quite innocuous! This really points to why when compromised you
need to wipe the box and start over from scratch, not assume you can find all
the backdoors by auditing the filesystem.

------
amitparikh
From PHP documentation ([http://php.net/manual/en/function.preg-
replace.php](http://php.net/manual/en/function.preg-replace.php))

    
    
        5.5.0  The /e modifier is deprecated.  Use preg_replace_callback() instead.

~~~
infinity
From the perspective of an attacker it doesn't really matter if the malicious
code contains deprecated things or lacks elegance or is generally ugly.

~~~
Arnor
You can configure your server to log usage of deprecated features in PHP so
that the attack would ultimately appear in the log. Admittedly, it would still
take a pretty vigilant Sys Admin to catch it.

------
morpher
If I'm reading this correctly, someone compromised a site (by other means) and
then added the exif_read_data() and preg_replace() lines to the code somewhere
as a back door?

If a site was compromised, wouldn't any modified files be replaced with
canonical source? Or do people manually scan through files looking for code
that looks suspicious?

Or am I misunderstanding and this site for some reason legitimately called
preg_replace() with exif make/model parameters (which seems pretty unlikely to
do anything useful)?

~~~
devrelm
The code in question seems to be removing any occurrences of the Make from the
Model. This might be useful if you have a camera that sets the Model to
contain the Make name, like setting Make="Nikon" and Model="Nikon D5000". If
we want to know the actual model number, then we have to remove the Make from
the Model, giving us " D5000". Using preg_replace() might just as good as
anything to do this.

~~~
devicenull
No, the signature for preg_replace is ( $pattern , $replacement , $subject) .
So, given the call as preg_replace($exif['Make'],$exif['Model'],'') it would
replace any occurances of Make with Model within the empty string ''. This is
essentially a noop unless your exif data contains exploit code.

~~~
devrelm
In that case I agree that it would never be used as it was written, and
suggest that the author must have jumbled the parameters. Calling the method
as preg_replace($exif['Make'], '', $exif['Model']) would correct the behavior
to something useful, while keeping the vulnerability in place.

------
lcedp
Eval in replace funtion.. But why?!

~~~
Afforess
Because PHP.

~~~
devgutt
[http://docs.python.org/2/library/functions.html#eval](http://docs.python.org/2/library/functions.html#eval)

~~~
Dylan16807
Just curious, how many points does your comment have right now even though
it's completely wrong? I'm not insulting you for making a tiny mistake, I'm
wondering why a 7 hour old post with multiple 6 hour old corrections attached
to it still has a positive score.

~~~
devgutt
because eval is the real source of the problem

~~~
Dylan16807
Would you remove the ability to load libraries, too? Because that's as
dangerous as eval when it comes to purposely writing code to run external
commands. The ability of a programming language to run code is not the cause
of the problem, it's having domain-breaking misleading functions like a string
replacer that can compile and execute.

~~~
devgutt
yeah because libraries, which is available for scrutiny of a community (and
you), is the same as a function that can run any arbitrary code in your
program at runtime.

~~~
Dylan16807
If you can load libraries at runtime, you can load a secret malicious library,
or replace a standard library with arbitrary code before triggering the
loading.

So would you remove that ability to avoid its exploitation potential by
malware?

------
martin_
This isn't new, and it certainly isn't specific to JPGs. It's quite frequent
for people to embed malicious code into files masquerading as images. There
has also been instances where hacked WordPress instances[1] hide code inside
images so they aren't so obviously found ready for execution at a later date

The most common way to exploit this however is by uploading an image with a
valid magic number (e.g. GIF89a) which will any mime type checks and then
finding a way to rename that file to one with an executable extension, or
finding a way to include it through an LFI vuln.

A simple solution is to simply load the image up in ImageMagick (or
GraphicsMagick, GD) and re-write the image to disk.

Disclaimer: Former lead developer of an image hosting service

[1] [https://media.blackhat.com/bh-eu-12/Be'ery/bh-
eu-12-Be'ery-F...](https://media.blackhat.com/bh-eu-12/Be'ery/bh-eu-12-Be'ery-
FYI_you_got_LFI-WP.pdf)

------
ibudiallo
This is not a bug in php that is being exploited. The server has already been
compromised. The code look harmless enough for most people to ignore it, this
is the point here.

It's a clever obfuscation

------
jeltz
Seems like itt was possible to hide it so well due to an oversight in the API
for preg_replace. In-band signaling in general makes it easy for people to
accidentally add security holes. What they should have done is pass the regex
options as a separate parameter, then it would have been obvious that
something fishy was going on here.

------
equiknox
If I understand this correctly, there is PHP code (preg_replace) in the jpg
exif header filled into the preg_replace function in the executable. The
executable looks clean that way. The executable finds the jpg via hard-coded
file path.

Seems possible that the malicious code could appear in an image itself and be
flagged with a simple but distinct header. The executable could just scan
display memory for the simple header and execute subsequent code when header
is found. Then when a user browses the image on a website, the code is
executed without hard-coding the location.

Pure speculation. Such an executable may be too visible. In any case it seems
the essential problem of the preg_replace or some kind of PHP executable
command would still be the red flag to find such malware.

------
chrisweekly
Interesting... but clueful site owners already strip all EXIF headers anyway,
for performance reasons. Options for doing this abound (e.g. mod_pagespeed,
grunt imagemin, [http://smush.it](http://smush.it), etc).

~~~
philrt
How about tricking the server into generating the payload like this?

[https://www.idontplaydarts.com/2012/06/encoding-web-
shells-i...](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-
png-idat-chunks/)

------
trebor
Wow, this would bypass the execution constraints we put on the upload
directories. Usually I make an uploads folder rw-rw-rw (0666); it would take
another attack in conjunction with it, but that's really something.

~~~
morpher
Only if someone modifies an executable file to call preg_replace with exif
headers.

------
kghose
So the real hole is in `preg_replace` which can execute arbitrary strings on
the server if the /e flag is found? Why does this exist?

Any how, this seems to be a genius exploit! If a site lets users upload photos
and they use this function, a user could do this.

Basically a good frame work should have 'safe' functions that are designed to
accept 'user input' i.e arbitrary strings and never set up a situation where
these strings are executed

~~~
A1kmm
It isn't an exploit, but rather a code obfuscation technique.

The attacker compromised the site first (the exploit used isn't disclosed in
the article), and then tried to conceal the malware they installed on the
compromised system by putting most of the malware in an EXIF header.

The malware code used a hardcoded image path, so for someone else to replace
the code to be executed, they would need to have access replace the particular
image file that contains the malware.

One interesting aspect is that the malware images are public, and probably
already referenced to from the site (since the attacker used an existing
image), so it might be possible to write a spider (or something based on
Common Crawl perhaps) that finds many compromised sites.

------
smegel
Surely any file format with metadata can contain malware if there is a bug in
the program reading it...

------
jheriko
i don't see how this is anything more than yet another lesson in why you
should escape strings from external data soures unless you have a very good
reason not to... interesting example though.

------
nice2kn0w
saw this already?
[http://ninjafirewall.com/malware/index.php?threat=2013-05-28...](http://ninjafirewall.com/malware/index.php?threat=2013-05-28.01)

------
ebarock
nice post!

------
bbsec
Great discovery!

------
3327
As malicious as this may be it is pure genius. It should include a message as
such:

Elk Cloner: The program with a personality It will get on all your disks It
will infiltrate your chips Yes, it's Cloner! It will stick to you like glue It
will modify RAM too Send in the Cloner!

