我注意到,PHP Imagick在處理PNG時改變了IDAT塊。 這到底如何?是否有可能創建保持不變的IDAT塊?是否有可能預測Imagick的結果?PHP Imagick對PNG IDAT塊的重新解釋
背景資料這個問題: 我不知道下面的代碼(PHP文件上傳的一部分)是否能防止PNG圖像隱藏PHP代碼(例如webshells):
$image = new Imagick('uploaded_file.png');
$image->stripImage();
$image->writeImage('secure_file.png');
評論被剝離出來,所以繞過此過濾器的唯一方法是將PHP有效內容隱藏在IDAT塊中。如here所述,理論上可行,但Imagick以某種方式重新解釋此圖像數據,即使我將Compression
和CompressionQuality
設置爲我用於創建PNG的值。我還設法創建了一個PNG,它的ZLIB頭由Imagick保持不變,但原始壓縮圖像數據沒有。我得到相同輸入和輸出的唯一PNG是之前通過Imagick的PNG。我也試圖在source code中找到原因,但找不到它。
我知道其他檢查是必要的,以確保上傳的文件實際上是一個PNG等,如果服務器配置正確,但PNG中的PHP代碼沒有問題,但現在我只是感興趣在這個問題上。
感謝您的回答。 1)strip操作本身不會改變IDAT塊,它只是刪除tEXt塊等等。它是Imagick的構造函數,正確地放置輸入文件(因爲實際的像素數據保持不變),但使用其他參數再次放氣(編寫輸出文件)。我想知道在這裏使用哪些參數(例如哪個壓縮級別,哪個歷史緩衝區(或窗口大小)以及哪個壓縮策略)生成PNG,其將具有完全相同的二進制數據(至少在IDAT塊中)由Imagick處理。 – user7390973
如果使用ImageMagick來創建原始文件,那麼您可能有機會。如果使用其他工具,則可能無法生成相同的PNG文件。如果你只是剝離元數據,那麼解壓縮和重新壓縮圖像是CPU時間的可怕浪費。更糟糕的是,ImageMagick通常是一組非常慢的函數。沒有辦法訪問所有這些參數。 IM使用zlib和單個參數(壓縮級別)來生成flate數據。 – BitBank
2)我不打算找到(或寫)一個可以做到這一點的工具,實際上我正在尋找相反的東西。我設法對GD做了完全相同的事情,所以我知道在這一點上它不是「安全的」(儘管在漏洞利用中必須有其他漏洞使用這樣的PNG)。但只有我不能用Imagick做同樣的事情並不能證明這是不可能的。所以我問了這個問題來澄清它是否在理論上可行。 – user7390973