Note that there are some explanatory texts on larger screens.

plurals
  1. POWays to stop people from uploading GIFs with injections in them?
    text
    copied!<p>I have a PHP website where people can fill out help-tickets. It allows them to upload screenshots for their ticket. I allow gif, psd, bmp, jpg, png, tif to be uploaded. Upon receiving the upload, the PHP script ignores the file extension. It identifies the filetype using only the MIME information, which for these filetypes is always stored within the first 12 bytes of the file.</p> <p>Someone uploaded several GIFs, which when viewed with a browser, the browser said it was invalid, and my virus scanner alerted me that it was a injection (or something like that). See below for a zip file containing these GIFs.</p> <p>I don't think only checking header info is adequate. I have heard that an image can be completely valid, but also contain exploit code.</p> <p>So I have two basic questions:</p> <ol> <li>Does anyone know how they did injected bad stuff into a GIF (<em>while still keeping a valid GIF MIME type</em>)? If I know this, maybe I can check for it at upload time.</li> <li>How can I prevent someone from uploading files like this? <ul> <li>I am on shared hosting so I can't install a server-side virus scanner.</li> <li>Submitting the info to a online virus scanning website might be too slow.</li> <li>Is there any way to check myself using a PHP class that checks for these things?</li> <li>Will resize the image using GD fail if it's not valid? Or would the exploit still slip through and be in the resized image? If it fails, that would be ideal because then I could use resizing as a technique to see if they are valid.</li> </ul></li> </ol> <hr> <p><strong>Update:</strong> Everyone, thanks for replying so far. I am attempting to look on the server for the GIFs that were uploaded. I will update this post if I find them.</p> <p><strong>Update 2:</strong> I located the GIFs for anyone interested. I put them in a zip file encrypted with password "123". It is located here (be careful there are multiple "Download" buttons on this hosting site -- some of them are for ads) <a href="http://www.filedropper.com/badgifs" rel="noreferrer">http://www.filedropper.com/badgifs</a>. The one called 5060.gif is flagged by my antivirus as a trojan (TR/Graftor.Q.2). I should note that these files were upload prior to me implementing the MIME check of the first 12 bytes. So now, I am safe for these particular ones. But I'd still like to know how to detect an exploit hiding behind a correct MIME type.</p> <hr> <p><strong>Important clarification:</strong> <em>I'm only concerned about the risk to the PC who downloads these files to look at them.</em> The files are not a risk to my server. They won't be executed. They are stored using a clean name (a hex hash output) with extension of ".enc" and I save them to disk in an encrypted state using an fwrite filter:</p> <pre><code>// Generate random key to encrypt this file. $AsciiKey = ''; for($i = 0; $i &lt; 20; $i++) $AsciiKey .= chr(mt_rand(1, 255)); // The proper key size for the encryption mode we're using is 256-bits (32-bytes). // That's what "mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)" says. // So we'll hash our key using SHA-256 and pass TRUE to the 2nd parameter, so we // get raw binary output. That will be the perfect length for the key. $BinKey = hash('SHA256', '~~'.TIME_NOW.'~~'.$AsciiKey.'~~', true); // Create Initialization Vector with block size of 128 bits (AES compliant) and CBC mode $InitVec = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND); $Args = array('iv' =&gt; $InitVec, 'key' =&gt; $BinKey, 'mode' =&gt; 'cbc'); // Save encoded file in uploads_tmp directory. $hDest = fopen(UPLOADS_DIR_TMP.'/'.$Hash.'.enc', 'w'); stream_filter_append($hDest, 'mcrypt.rijndael-128', STREAM_FILTER_WRITE, $Args); fwrite($hDest, $Data); fclose($hDest); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload