文件上傳之繞過
一般防止上傳漏洞手法:
1、客戶端檢測:客戶端使用JavaScript檢測,在文件未上傳時,就對文件進行驗證 //任何客戶端的驗證都是不安全的,客戶端驗證目的是防止用戶輸入錯誤、減少 //服務器開銷,而服務端驗證才可以真正防御攻擊者。
2、服務器端檢測:服務端腳本一般會檢測文件的MIME類型,檢測文件擴展名是否合法
客戶端檢測
客戶端驗證代碼形如下:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>圖片上傳</title>
<script type="text/javascript"> function checkFile() { var flag = false; var str = document.getElementById("file").value; str = str.substring(str.lastIndexOf('.') + 1); var arr = new Array('png','bmp','gif','jpg'); for(var i=0;i<arr.length;i++) { if(str==arr[i]) { flag = true; } } if(!flag) { alert('文件不合法!'); } return flag; } </script>
</head>
<body>
<form action="upload.php" method="post" onsubmit="checkFile()" enctype="multipart/form-data">
<input type="file" name="file" id="file" /><br/>
<input type="submit" value="提交" name="submit" />
</form>
</body>
</html>
接收文件的腳本upload.php代碼如下:
<?php if(isset($_POST["submit"])) { $name = $_FILES['file']['name']; $name = md5(date('Y-m-d h:m:s')).strrchr($name,"."); $size = $_FILES['file']['size']; $tmp = $_FILES['file']['tem_name']; move_uploaded_file($tmp,$name); echo "文件上傳成功!path:".$name; } ?>
繞過:
服務端檢測
- 黑名單與白名單驗證
- MIME驗證
- 目錄驗證
- 截斷上傳攻擊
- .htaccess文件攻擊
- 檢測文件內容
黑名單與白名單驗證
黑名單過濾方式
<?php $Blacklist = array('asp','php','jsp','php5','asa','aspx'); //黑名單
if(isset($_POST["submit"])) { $name = $FILES['file']['name']; //接收文件名
$extension = substr(strrchr($name, ".") , 1); //得到擴展名
$boo = false; foreach($Blaklist as $key => $value) { if($value==$extension) { //迭代判斷是否命中
$boo = true; break; //命中后直接退出循環
} } if(!$boo) { //若沒有被命中,則進行上傳操作
$size = $_FILES['file']['size']; //接收文件大小
$tmp = $FILES['file']['temp_name']; //臨時路徑
move_uploaded_file($tmp, $name); //移動臨時文件到當前文件目錄
} else { echo "文件不合法!!"; } } ?>
- 從黑名單中找到web開發者忽略的擴展名,如:cer
- 沒有對擴展名進行大小寫轉換,在window平台依然可以大小寫繞過
- 在window下,若文件名以"."或者空格作為結尾,系統會自動去除"."與空格,
所以可以上傳以“asp.”和“asp_”為擴展名的文件 - 0x00截斷繞過
- 解析漏洞
白名單過濾方式
<?php $WhiteList = array('rar','jpg','png','bmp','gif','jpg','doc'); if(isset($_POST["submit"])) { $name = $_FILES['file']['name']; $extension = substr(strrchr($name,"."),1); $boo = false; foreach($WhiteList as $key => $value) { if($value==$extension) { $boo = true; } } if($boo) { $size = $_FILES['file']['size']; $tmp = $_FILES['file']['tmp_name']; move_uploaded_file($tmp,$name); echo "文件上傳成功!<br/>path:".$name; } else { echo "文件不合法!"; } } ?>
- 0x00截斷繞過
- 此時若在iis6.0,則可以將木馬名改為test.asp;1.jpg來上傳,從而通過驗證
- 配合解析漏洞
MIME驗證
對文件MIME類型做驗證的PHP代碼如下:
<?php if($_FILES['file']['type']==" image/jpeg") { $imageTempName = $_FILES['file']['tmp_name']; $imageName = $_FILES['file']['name']; $last = substr($imageName,strrpos($imageName,".")); if(!is_dir("uploadFile")) { mkdir("uploadFile"); } $imageName = md5($imageName).$last; move_upload_file($imageTempName,"./uploadFile/".$imageName); echo("文件上傳成功! path = /uploadFile/$imageName"); } else { echo("文件上傳類型錯誤,請重新上傳..."); exit(); } ?>

修改MIME類型,上傳成功:

目錄驗證
<html>
<head>
<meta charset="UTF-8">
<title>up</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" /><br/>
<input type="hidden" name="Extension" value="up" />
<input type="submit" value="提交" name="submit" />
</form>
</body>
</html>
<?php if($_FILES['file']['type']=="image/jpeg") { $imageTempName=$_FILES['file']['tmp_name']; $imageName=$_FILES['file']['name']; $last=substr($imageName,strrpos($imageName,".")); if($last!=".jpg") { echo("mime error!<br/>"); } $Extension=$_POST['Extension']; if(!is_dir($Extension)) { mkdir("./$Extension"); echo "mkidr $Extension succesfully"."<br/>"; } $imageName=md5($imageName).$last; move_uploaded_file($imageTempName,"./$Extension/".$imageName); echo("upload ok! path = /$Extension/$imageName"); } else { echo("type error..."); exit(); } ?>

將文件改名:


截斷上傳攻擊
截斷上傳攻擊在ASP程序中比較常見(在PHP、JSP中也有)

更改圖片名字:



.htaccess文件攻擊
通過.htaccess文件調用php解析器去解析一個文件名中只要包含"haha"這個字符串的任意文件,論擴展名是什么(沒有也行),都以php的方式來解析,.haccess文件代碼如下
<FilesMatch "haha"> SetHandler application/x-httpd-php </FilesMatch>
<FilesMatch "evil.gif"> SetHandler application/x-httpd-php </FilesMatch>
檢測文件內容
文件幻數檢測在文件首部加上如下幻數,后面跟一句話木馬即可
JFIF FF D8 FF E0 00 10 4A 46 49 46
GIF89a 47 49 46 38 39 61
PNG 89 50 4E 47
GIF89a (...some binary data for image...) <?php phpinfo(); ?> (... skipping the rest of binary data ...)
文件加載檢測
對渲染/加載測試的攻擊方式是代碼注入繞過
對二次渲染的攻擊方式是攻擊文件加載器本身
補充
繞過技巧
1 使用大小寫繞過(針對對大小寫不敏感的系統如windows),如:PhP
2 使用黑名單外的腳本類型,如:php5
3 借助文件解析漏洞突破擴展名驗證,如:test.jpg.xxx(apache解析漏洞)
4 借助系統特性突破擴展名驗證,如:test.php_(在windows下下划線是空格,保存文件時下划線被吃掉剩下test.php)
5 雙擴展名之間使用00截斷,繞過驗證上傳惡意代碼如:test.php%00.jpg
6 借助.htaccess文件上傳惡意代碼並解析。如:上傳一個.htaccess文件,內容為AddTypeapplication/x-httpd-php .jpg,上傳的jpg文件就可以當作php來解析
7 使用00截斷,繞過后綴驗證獲取webshell(php<5.3.4+關閉GPC)
8 超長文件名截斷上傳(windows 258byte | linux 4096byte)
安全建議
1 使用白名單限制可以上傳的文件擴展
2 驗證文件內容,使用正則匹配惡意代碼限制上傳
3 對上傳后的文件統一隨機命名,不允許用戶控制擴展名
4 修復服務器可能存在的解析漏洞
5 嚴格限制可以修改服務器配置的文件上傳如:.htaccess