微信號:freebuf
安全研究人員今天發布了一個中危漏洞——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級別最高的一題中因為種種原因不是很容易通過,意在告訴開發者如何去開發更安全的文件上傳組件。讓我們來看看這個例子:
代碼片段:
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1); $uploaded_size = $_FILES['uploaded']['size'];
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)) {
$html .= '';
$html .= 'Your image was not uploaded.';
$html .= ''; }
else {
$html .= $target_path . ' succesfully uploaded!';
.
.
這段代碼有好多個漏洞,比如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)