5

I was in a trouble last few days since my web host was hacked for POST on PHP files. I've been dealing with files with .png extension that have PHP code inside. I can't even try to edit one-by-one to check if it's a valid .png file or not.

Is there any way to mass check if a file with a .png is real or fake?

9
  • 2
    That is not your problem. Your problem is that your uploaded .png files can be executed. Your files should be uploaded to a protected directory that only allows read/write access to the web server and never execute.
    – closetnoc
    Feb 6, 2016 at 1:18
  • @closetnoc ok, so that's blow another question: a file (executable or not) can always set no not-executable?
    – fiskolin
    Feb 6, 2016 at 1:31
  • You can check for the 8-byte file header in the PNG file. en.wikipedia.org/wiki/Portable_Network_Graphics#File_header What kind of PHP code do these files contain?
    – MrWhite
    Feb 6, 2016 at 1:36
  • 2
    Your server also has to be compromised in some other way for these files to be executable (as PHP). Simply having a PNG file containing PHP isn't necessarily an immediate threat.
    – MrWhite
    Feb 6, 2016 at 1:48
  • 1
    @w3dk the first 8 bytes can easily be faked, so that's not a good solution. it is quite difficult to determine the actual file type. @ Evgeniy Most mime type checks can easily be bypassed by manipulated png files (eg by storing the payload in metadata or idat chunks)
    – tim
    Mar 3, 2016 at 10:29

3 Answers 3

2

I was in a trouble last few days since my web host was hacked for POST on PHP files. I've been dealing with files with .png extension that have PHP code inside.

This is why error checking should be implemented in your upload script, that way, you can test the uploaded file to ensure the data is valid and if the data is not valid, then discard the file and show an error web page.

I can't even try to edit one-by-one to check if it's a valid .png file or not. Is there any way to mass check if a file with a .png is real or fake?

You can make a script that opens each uploaded file and check the first few bytes to ensure the file is valid, but this is an unnecessary step in the future if you decide to add file validation to your upload script like what I described above.

Also, as someone stated in the comments, for at least some protection from script execution, make the upload directory a directory in which the execute bit is not set. Also, make the folder not accessible to the general public so that you can have a chance to validate the files and only make them acceptable to the public when you have validated them.

1
  • checking the first few bytes is definitely not a proper solution to determine if an image contains PHP code, as an attacker can just place the code after the first few bytes. The image could also still be a valid image, even if it does contain PHP code, so file validation isn't as simple as it may sound. But I definitely agree that the check should take place on upload, not afterwards (of course, if there was no check in the past, already uploaded files need to be checked as well). Moving files to a non-executable directory outside the web root is however a good approach, if it can be enforced
    – tim
    Mar 3, 2016 at 19:43
2

Nowadays in most of the hosting for security reasons, they have disabled the short tags "<?".

So, you can grep / strstr for "<?php" in the uploaded file, If there is a match found simply delete the file.

We have been following this for a long time and It seems working very good.

3
  • note that <?= also works, regardless of short tag settings. Additionally, <script language="php"> - and obfuscated versions of it such as <scRipt lanGuAge = "pHp" > - work as well, but will be removed in PHP 7. I also would not rely on php.ini settings, so I would definitely filter for <?. <% and <%= may also work, depending on asp_tags setting.
    – tim
    Mar 3, 2016 at 18:41
  • @tim, thanks. We have disabled short_tags in our server settings. So, thats why we block any script which is having <?php
    – Mani
    Mar 4, 2016 at 5:36
  • Right, but like I said, even if short_tags are disabled,<script language="php"> and <?= will still work. So if you are only checking for <?php, an attacker can easily bypass that check, no matter what your php.ini settings are.
    – tim
    Mar 5, 2016 at 14:50
2

Is there any way to mass check if a file with a .png is real or fake?

No, not really.

Because it has been suggested in an answer and in the comments: Checking the first X bytes of a file is not a proper way to determine if it contains PHP code or not (what about the content after the first X bytes?).

Additionally, PHP code can be hidden in metadata or IDAT chunks, meaning that you can have a completely valid image file, which also contains PHP code.

It is extremely difficult to check if an image contains further harmful data or not.

So what you want to do is:

  • check the extension. If it is png, it will not be executed (except if you also allow upload of htaccess files or have a LFI vulnerability)
  • store the file outside of the web root (again, it cannot be executed, except via LFI)
  • forbid execution in that directory (again, can be bypassed via LFI)
  • strip all metadata from the image (which will remove PHP code in the metadata)
  • transform the image to a different format (which will destroy PHP code in IDAT chunks or similar methods)
  • as @mani said, you can search the uploaded file for opening PHP tags. You definitely want to search for <?php, <?=, and <script (case insensitive). Additionally, you might want to search for <? (if short tags are allowed) and <% (in case asp tags are allowed). This should take care of PHP code, but not of other possibly harmful content.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.