1. 程式人生 > >thinkphp 檢測上傳的圖片中是否含有木馬指令碼

thinkphp 檢測上傳的圖片中是否含有木馬指令碼

1.檢測原理

   要想檢測圖片中是否含有木馬指令碼,首先從製作原理來分析這種木馬程式。這種木馬程式是十六進位制編碼寫的,圖片的十六進位制程式碼中主要包含<% ( ) %>、<? ( ) ?> 、<script | /script>, 所以我們可以通過檢測十六進位制程式碼來檢測木馬指令碼。

2.解決方案

  2.1編寫Upload類

   要想上傳圖片檔案,我們要自己先定義一個上傳檔案的方法,然後方法中呼叫thinkphp中框架寫好的Upload類,但是tp框架中的upload類沒有檢測木馬圖片的功能,所以我們可以自己寫一個含有檢測功能的upload類。

<?php
/** +------------------------------------------------------------------------------ * Upload 檔案上傳類 +------------------------------------------------------------------------------ * @package Upload +------------------------------------------------------------------------------ */ class Upload {
private static $image = null; private static $status = 0; private static $suffix = null; private static $imageType = array('.jpg', '.bmp','.gif','.png');  //允許的圖片型別 private static $message = array(  //檔案上傳錯誤資訊 '0' => '沒有錯誤發生,檔案上傳成功。', '1' => '上傳的檔案超過了 php.ini 中 upload_max_filesize 選項限制的值。', '2' => '上傳檔案的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項指定的值。', '3' => '檔案只有部分被上傳。', '4' => '沒有檔案上傳。', '5' => '未能通過安全檢查的檔案。', '6' => '找不到臨時資料夾。', '7' => '檔案寫入失敗。', '8' => '檔案型別不支援', '9' => '上傳的臨時檔案丟失。', );
//@ 開始執行檔案上傳 public static function start($feild = 'file') { if (!empty($_FILES)) { self::$status = $_FILES[$feild]['error']; if (self::$status > 0) return array('status' => self::$status, 'msg' => self::$message[self::$status]); self::$image = $_FILES[$feild]['tmp_name']; self::$suffix = strtolower(strrchr($_FILES[$feild]['name'], '.')); return array('status' => self::_upload(), 'path' => self::$image, 'msg' => self::$message[self::$status]); } else { return array('status' => self::$status, 'msg' => self::$message[self::$status]); } } //@ 私有 上傳開始 private static function _upload($path = './upload/') { date_default_timezone_set('PRC'); $newFile = $path . date('Y/m/d/His') . rand(100, 999) . self::$suffix;  //定義上傳子目錄 self::umkdir(dirname($newFile)); if (is_uploaded_file(self::$image) && move_uploaded_file(self::$image, $newFile)) { self::$image = $newFile;                // 生成的新檔名 if (in_array(self::$suffix, self::$imageType))   // 判斷上傳型別是否符合規定 return self::checkHex();             // 返回木馬指令碼檢測的返回值 else return self::$status = 0; } else { return self::$status = 9; } } //@ 私有 16進位制檢測 private static function checkHex() { if (file_exists(self::$image)) { $resource = fopen(self::$image, 'rb'); $fileSize = filesize(self::$image); fseek($resource, 0);   //把檔案指標移到檔案的開頭 if ($fileSize > 512) { // 若檔案大於521B檔案取頭和尾 $hexCode = bin2hex(fread($resource, 512)); fseek($resource, $fileSize - 512);  //把檔案指標移到檔案尾部 $hexCode .= bin2hex(fread($resource, 512)); } else { // 取全部 $hexCode = bin2hex(fread($resource, $fileSize)); } fclose($resource); /* 匹配16進制中的 <% ( ) %> */ /* 匹配16進制中的 <? ( ) ?> */ /* 匹配16進制中的 <script | /script> 大小寫亦可*/

      /* 核心 整個類檢測木馬指令碼的核心在這裡 通過匹配十六進位制程式碼檢測是否存在木馬指令碼*/
if (preg_match("/(3c25.*?28.*?29.*?253e)|(3c3f.*?28.*?29.*?3f3e)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)/is", $hexCode)) self::$status = 5; else self::$status = 0; return self::$status; } else { return self::$status = 9; } } //@ 私有 建立目錄 private static function umkdir($dir) { if (!file_exists($dir) && !is_dir($dir)) { self::umkdir(dirname($dir)); @mkdir($dir); } } }

這個類配合自己定義的上傳圖片的方法  可以檢測上傳圖片是否存在木馬指令碼

3.製作木馬圖片 

  3.1製作過程

    1.隨便找一張圖片,名字改成1.jpg。

    2.將<%eval request("keio")%> 存為1.php。

    3.copy 1.jpg /b + 1.php /a  2.jpg 存為1.bat檔案。

    (具體操作方法:開啟-執行-cmd,進入下面這個介面,然後cd 進入放置檔案的路徑,然後輸入命令copy 1.jpg/b+1.php 2.jpg 然後回車就係統就會自動把這兩個檔案組合起來,形成一個含有木馬指令碼的圖片。)

  3.2檢視圖片

    你可以用text文件開啟2.jpg,就發現我們的一句話木馬就寫入到了圖片中。

    解釋:

    複製當前目錄下的 1.jpg 圖片和當前目錄下的 1.php 檔案並以ASCII程式碼的方式合併為2.jpg 圖片
    執行 1.bat 就會出現一個圖片 2.jpg
    而這個2.jpg就是已經做好的木馬了

4.上傳檢測

  我們將製作的木馬圖片上傳,檢測我們的十六進位制檢測木馬指令碼的方法是不是好使。

    實踐是檢驗真理的唯一途徑,大家要手動做一張圖片木馬進行驗證,本人親測可以檢測到。

  有意見和建議的兄弟們,可以留言來交流,批評指正!謝謝

  如果你使用出現問題,可以留言交流!