1. 程式人生 > >PHP任意檔案上傳漏洞(CVE-2015-2348)

PHP任意檔案上傳漏洞(CVE-2015-2348)

安全研究人員今天釋出了一箇中危漏洞——PHP任意檔案上傳漏洞(CVE-2015-2348)。

在上傳檔案的時候只判斷檔名是合法的檔名就斷定這個檔案不是惡意檔案,這確實會導致其他安全問題。並且在這種情況下,在你自己的檔案中檢查漏洞很不現實,因為這個漏洞可以繞過你對檔名字尾、檔案型別(Content-Type)、Mime type、檔案大小等的檢查,所以僅僅依靠這些檢查是救不了你的。

漏洞細節

這個漏洞存在於php中一個非常常用的函式中:move_uploaded_files,開發者總是用這個函式來移動上傳的檔案,這個函式會檢查被上傳的檔案是否是一個合法的檔案(是否是通過 HTTP 的 post 機制上傳的),如果是合法的檔案,則將它一定到指定目錄中。

例子:

move_uploaded_file ( string $filename , string $destination )

這裡的問題是,可以在檔名中插入空字元(之前多次修復過這個漏洞,比如CVE-2006-7243),利用插入空字元的方式,攻擊者可以上傳任意檔案,引起遠端程式碼執行漏洞等。

我這裡用DVWA來演示這個例子,DVWA級別最高的一題中因為種種原因不是很容易通過,意在告訴開發者如何去開發更安全的檔案上傳元件。讓我們來看看這個例子:

程式碼地址:https://github.com/RandomStorm/DVWA/blob/master/vulnerabilities/upload/source/high.php

程式碼片段:

  1.   $uploaded_name = $_FILES['uploaded']['name']; 
  2.   $uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1); $uploaded_size = $_FILES['uploaded']['size']; 
  3.    
  4.   if (($uploaded_ext == "jpg" || $uploaded_ext == "JPG" || $uploaded_ext == "jpeg" || $uploaded_ext == "JPEG") && ($uploaded_size  100000)){ if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) { 
  5.    
  6.   $html .= '';
  7.   $html .= 'Your image was not uploaded.'; 
  8.   $html .= ''; } 
  9.   else { 
  10.   $html .= $target_path . ' succesfully uploaded!';
  11.   .
  12.   .

這段程式碼有好多個漏洞,比如XSCH, XSS等,但是沒有RCE這種嚴重的漏洞,因為從PHP 5.3.1開始,空字元的問題已經被修復了。這裡的問題是,DVWA將使用者上傳的name引數傳遞給了move_upload_file()函式,那麼 php 執行的操作可能就是這樣子的:

move_uploaded_file($_FILES['name']['tmp_name'],"/file.php\x00.jpg");

這本應該建立一個名為file.php\x00.jpg的檔案,但實際上建立的檔案是file.php。

這樣,就繞過了程式碼中對字尾名的校驗,並且事實證明GD庫中又很多其他函式也存在這個問題(比如getimagesize(), imagecreatefromjpeg()…等),可以看這個例子

如果你機器的php版本在 5.4.39, 5.5.x – 5.5.23, 或者 5.6.x – 5.6.7,可以通過檢查檔名中是否有\x00字元來解決本文中所述的問題。

安全建議

如果你的機器上存在這個漏洞,建議使用隨機字串重新命名檔名,而不是使用使用者上傳上來的name引數的值。

*參考來源www.paulosyibelo.com,轉載請註明來自FreeBuf黑客與極客(FreeBuf.COM)

轉載地址:http://www.freebuf.com/vuls/62811.html