郝子希,王志軍,劉振宇
(1.東華大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,上海 200050;2.上海計(jì)算機(jī)軟件技術(shù)開發(fā)中心 上海市計(jì)算機(jī)軟件評(píng)測(cè)重點(diǎn)實(shí)驗(yàn)室,上海 201112)
“互聯(lián)網(wǎng)+”推動(dòng)了各行各業(yè)與互聯(lián)網(wǎng)的融合,各行各業(yè)大到工業(yè)、金融、商貿(mào),小到娛樂(lè)、民生、家庭,與互聯(lián)網(wǎng)的聯(lián)系越來(lái)越緊密,形成創(chuàng)新2.0下的互聯(lián)網(wǎng)發(fā)展的新業(yè)態(tài)。但“互聯(lián)網(wǎng)+”在帶動(dòng)國(guó)內(nèi)互聯(lián)網(wǎng)經(jīng)濟(jì)的同時(shí),也為通過(guò)網(wǎng)絡(luò)傳播的有害信息提供了更大的空間,攻擊者的攻擊手段也在不斷更新。2017年6月1日,國(guó)家開始實(shí)施《中華人民共和國(guó)網(wǎng)絡(luò)安全法》并對(duì)互聯(lián)網(wǎng)和信息系統(tǒng)的安全做出了明確的要求,網(wǎng)絡(luò)安全的防御工作更加迫切。
近年來(lái),雖然國(guó)內(nèi)幾乎所有企業(yè)都開發(fā)了自己的Web應(yīng)用系統(tǒng),但是這些Web應(yīng)用是重點(diǎn)致力于方便客戶使用,給予客戶更方便、快捷的服務(wù)支持,因此現(xiàn)在的開發(fā)人員更注重的是Web應(yīng)用的功能和性能,而在非常關(guān)鍵的安全性方面,卻沒(méi)有付諸足夠的重視。滲透測(cè)試指的是一種通過(guò)模擬惡意攻擊者的技術(shù)與方法,對(duì)目標(biāo)系統(tǒng)進(jìn)行攻擊,繞過(guò)或挫敗目標(biāo)系統(tǒng)的安全控制措施,從而達(dá)到取得訪問(wèn)控制權(quán)的目的,并發(fā)現(xiàn)具備業(yè)務(wù)影響后果安全隱患的一種安全測(cè)試與評(píng)估方式[1]。文件上傳漏洞作為滲透測(cè)試過(guò)程中經(jīng)常出現(xiàn)的Web漏洞,正在嚴(yán)重威脅著網(wǎng)絡(luò)空間的安全。攻擊者可以通過(guò)文件上傳漏洞竊取服務(wù)器的信息,種植木馬,在受害服務(wù)器網(wǎng)站上傳播惡意信息,甚至獲取服務(wù)器的管理員權(quán)限。
文件上傳漏洞指的是,由于程序員對(duì)信息系統(tǒng)中用戶上傳文件的模塊的控制不足或者文件上傳模塊本身存在處理缺陷而導(dǎo)致的漏洞,攻擊者可能利用此類漏洞越過(guò)其本身權(quán)限向服務(wù)器中上傳可執(zhí)行的動(dòng)態(tài)腳本文件,并通過(guò)該文件對(duì)目標(biāo)系統(tǒng)進(jìn)行進(jìn)一步的惡意操作。例如,某信息系統(tǒng)使用的是Linux服務(wù)器,并且以php作為服務(wù)器端的動(dòng)態(tài)網(wǎng)站環(huán)境,那么在信息系統(tǒng)有上傳文件功能的地方,就不能允許用戶上傳后綴為*.php的文件,否則攻擊者可以直接上傳一個(gè)php語(yǔ)言編寫的Webshell,服務(wù)器就被攻擊者入侵了。
文件上傳后導(dǎo)致的常見(jiàn)安全問(wèn)題一般有:
(1)上傳的文件是Web腳本語(yǔ)言,服務(wù)器的Web容器解釋并執(zhí)行了用戶上傳的腳本,導(dǎo)致代碼執(zhí)行;
(2)上傳的文件是Flash的策略文件crossdomain.xml,攻擊者用以控制Flash在該域下的行為,其他通過(guò)類似方式控制策略文件的情況類似;
(3)上傳的文件是病毒、木馬文件,用于誘騙用戶或者管理員下載、執(zhí)行;
(4)上傳的文件是釣魚圖片或包含了腳本的圖片,在某些版本的瀏覽器中會(huì)被作為腳本執(zhí)行,被用于釣魚和欺詐。
在文件上傳漏洞中,攻擊者上傳了一個(gè)可執(zhí)行的腳本文件,并通過(guò)此文件進(jìn)行進(jìn)一步的惡意操作,這種攻擊方法是最直接和有效的。但是通常在信息系統(tǒng)中,“文件上傳”功能本身是沒(méi)有問(wèn)題的。但是如果攻擊者上傳的是php等腳本語(yǔ)言編寫的惡意文件,那么就需要注意惡意文件上傳后,服務(wù)器怎樣處理和解釋該文件。如果攻擊者上傳惡意文件后沒(méi)辦法執(zhí)行,那么攻擊行為是沒(méi)有意義的。所以,文件上傳漏洞一般和服務(wù)器中的解析漏洞一起存在。以下介紹幾種常見(jiàn)的Web容器中存在的文件解析漏洞。
IIS的全稱是Internet Information Services,意思是互聯(lián)網(wǎng)信息服務(wù),它是一個(gè)萬(wàn)維網(wǎng)服務(wù)器,意味著你可以通過(guò)IIS發(fā)布網(wǎng)頁(yè),并且由Asp、Java、VB腳本產(chǎn)生頁(yè)面。使用IIS5.x-6.x的服務(wù)器大多是Windows Server 2003,運(yùn)行的網(wǎng)站比較古老,開發(fā)語(yǔ)言一般為Asp。由于版本限制的原因,該漏洞只能解析asp文件,而不能解析aspx文件[2]。
該版本的解析漏洞有兩個(gè):
(1)如果存在一個(gè)以*.asp或*.asa結(jié)尾的文件夾,則該文件夾中所有的文件都會(huì)被解析成asp文件。
例如,在網(wǎng)站目錄下存在一個(gè)folder.asp的文件夾,然后上傳一個(gè)hacker.txt到該文件夾內(nèi)(假如hacker.txt文件中存在Webshell),攻擊者可以通過(guò)直接訪問(wèn)該文件在服務(wù)器上執(zhí)行命令。
(2)IIS解析文件名時(shí)從前往后解析,遇到分號(hào)自動(dòng)停止。
假如存在一個(gè)名為hacker.asp;.jpg的圖片,則它會(huì)被解析為一個(gè)asp文件,若該文件中存在Webshell,同樣可以被攻擊者利用。
(注:asp環(huán)境下除了asp還有三種后綴的文件:*.asa、*.cer、*.cdx,也是可執(zhí)行的腳本文件)
Apache解析文件時(shí),如果遇到不認(rèn)識(shí)的文件擴(kuò)展名,則會(huì)從后往前解析,直到遇到認(rèn)識(shí)的擴(kuò)展名為止。例如,上傳一個(gè)名為“hacker.php.aa.xx”的文件,由于Apache不認(rèn)識(shí).xx的擴(kuò)展名,向前解析,又不認(rèn)識(shí).aa的擴(kuò)展名,再向前解析,就會(huì)將該文件解析為.php文件。在Apache的安裝目錄下的/conf/mime.type文件中,有詳細(xì)的文件名列表,它定義了Apache可以解析哪些擴(kuò)展名的文件,如圖1所示。
在動(dòng)態(tài)環(huán)境為php的服務(wù)器中,通過(guò)從客戶端訪問(wèn)服務(wù)器端文件構(gòu)造惡意的Url,也可以實(shí)現(xiàn)執(zhí)行服務(wù)器上腳本文件的目的。假如在服務(wù)器中存在一個(gè)路徑為www.test.com/123.jpg的圖片,攻擊者訪問(wèn)時(shí)在路徑后面加上/hacker.php變?yōu)閣ww.test.com/123.jpg/hacker.php,則服務(wù)器會(huì)將圖片123.jpg當(dāng)作PHP腳本解析。實(shí)際上Url最后的hacker.php是不存在的,所以路徑中“hacker”可以是任意的。通過(guò)這個(gè)漏洞,攻擊者將Webshell寫進(jìn)一張合法的圖片制作成圖片木馬,并上傳至服務(wù)器。上傳成功后在該圖片的路徑后加上/xxx.php即可入侵成功[3]。
因?yàn)镹ginx服務(wù)器通常作為php的解析容器,而Nginx和php配合很容易導(dǎo)致該解析漏洞,所以盡管該漏洞與Nginx關(guān)系不大,也通常被認(rèn)為是Nginx的解析漏洞[4]。
圖1 Apache可以解析的文件擴(kuò)展名(mime.types文件)
客戶端驗(yàn)證,就是在前端頁(yè)面編寫JavaScript代碼來(lái)對(duì)用戶上傳文件的文件名進(jìn)行合法性檢測(cè)。這種驗(yàn)證原理是在載入上傳的文件時(shí)使用JavaScript對(duì)文件名進(jìn)行校驗(yàn),如果文件名合法[5],則允許載入,否則不允許。
但是此類驗(yàn)證非常容易被攻破。攻擊者使用抓包軟件攔截HTTP請(qǐng)求,并修改請(qǐng)求內(nèi)容即可繞過(guò)。例如,先把木馬文件改成hacker.jpg的合法文件,成功載入到等待上傳區(qū),然后點(diǎn)擊發(fā)送上傳請(qǐng)求。用Burpsuite將上傳請(qǐng)求攔截后將文件名改回hacher.php,再發(fā)送給服務(wù)器,則實(shí)際上傳的文件后綴名為.php,實(shí)現(xiàn)了對(duì)客戶端驗(yàn)證的繞過(guò),如圖2所示。
需要注意,如果HTTP請(qǐng)求修改前后的文件名長(zhǎng)度發(fā)生了變化,那么在請(qǐng)求頭中Content-Length的值也需要修改。Content-Length代表實(shí)體正文長(zhǎng)度。例如,如果修改之前文件名為123.jpg,正文長(zhǎng)度為200,修改后文件名為1.php,那么少了兩個(gè)字符,Content-Length就要改為198,否則會(huì)上傳失敗。
由此看來(lái),任何客戶端驗(yàn)證都是不安全的??蛻舳蓑?yàn)證是防止用戶輸入錯(cuò)誤而進(jìn)行的輸入有效性檢查,服務(wù)器端驗(yàn)證才可以真正防御攻擊者。
圖2 修改前后的HTTP請(qǐng)求
3.2.1 繞過(guò)黑名單與白名單驗(yàn)證
(1)黑名單過(guò)濾方式。
黑名單過(guò)濾是一種不安全的過(guò)濾方式。黑名單過(guò)濾在服務(wù)器端定義了一系列不允許上傳的文件擴(kuò)展名。在接收用戶上傳文件時(shí),判斷用戶上傳文件的擴(kuò)展名與黑名單中的是否匹配。匹配則不允許上傳,不匹配則允許上傳。黑名單驗(yàn)證PHP代碼如下:
$Blacklist = array(‘a(chǎn)sp’,‘php’,‘jsp’,‘php5’,‘a(chǎn)sa’,‘a(chǎn)spx’);//黑名單
……
foreach (Blacklist as $key=>$value) {
if($value==$extension) {//判斷是否為黑名單中的擴(kuò)展名
$boo=true;
break; //退出循環(huán)
}
}
if(!$boo)
{……//允許上傳}
else {
echo “文件不合法”;
}
……
?>
在以上代碼中,黑名單定義的危險(xiǎn)的文件擴(kuò)展名有6種,但實(shí)際上攻擊者還是可以繞過(guò)黑名單檢測(cè)[6]。
(a)攻擊者可以找到Web開發(fā)人員忽略的擴(kuò)展名,如*.cer;
(b)如果代碼中沒(méi)有對(duì)擴(kuò)展名進(jìn)行大小寫轉(zhuǎn)換操作,那就意味著可以上傳如AsP、pHp這樣擴(kuò)展名的文件,而該類擴(kuò)展名依然可以被Windows平臺(tái)中的Web容器解析;
(c)在Windows系統(tǒng),可以上傳如下文件名:“*.asp.”或“*.asp_(此處下劃線為空格)”,在上傳后,Windows會(huì)自動(dòng)去掉文件名后的點(diǎn)和空格。
(2)白名單過(guò)濾方式。
相對(duì)于黑名單,白名單擁有更好的防御機(jī)制。白名單與黑名單相反,僅允許上傳白名單中定義的擴(kuò)展名。白名單驗(yàn)證PHP代碼如下:
$Whitelist=array(‘rar’,‘jpg’,‘png’,bmp,‘gif’,‘doc’);
……
foreach(Whitelist as $key=>$value) {
if($value==$extension) {
$boo = true;
}
}
if(boo){
… //允許上傳}
else{
echo “文件不合法”;
}
?>
雖然白名單可以防御未知擴(kuò)展名的上傳,但是并不能完全防御上傳漏洞。例如前文提到的IIS5.x-6.x解析漏洞,攻擊者可以把文件改為hacker.asp;.jpg來(lái)繞過(guò)檢測(cè),并執(zhí)行木馬程序。
3.2.2 繞過(guò)MIME驗(yàn)證
在HTTP請(qǐng)求頭中存在一個(gè)Content-Type字段[7],它規(guī)定著文件的類型,即瀏覽器遇到此文件時(shí)使用相應(yīng)的應(yīng)用程序來(lái)打開。在上傳時(shí),服務(wù)器端一般會(huì)對(duì)上傳文件的MIME類型進(jìn)行驗(yàn)證,php代碼如下(以圖片格式j(luò)pg為例):
if($_FILES[‘file’][‘type’]==“image/jpeg”){ //判斷是否是jpg格式
$imageTempName=$_FILES[‘file’][‘temp_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);//指定上傳文件到uploadFile目錄
echo(“文件上傳成功”);
}else {
echo(“文件類型錯(cuò)誤,上傳失敗”);
exit;
}
但是,MIME驗(yàn)證也可以被中間人攻擊[8]。攻擊者用抓包軟件攔截到上傳文件的請(qǐng)求時(shí),可以看到上傳文件的部分的Content-Type是application/x-php類型,這樣上傳文件對(duì)于有MIME類型驗(yàn)證的服務(wù)器肯定是上傳不了的。將請(qǐng)求這里的值改為image/jpeg,即可成功繞過(guò)該驗(yàn)證上傳文件,如圖3所示。
圖3 修改前后的HTTP請(qǐng)求
3.2.3 繞過(guò)目錄驗(yàn)證
用戶上傳文件時(shí),Web程序一般是允許用戶上傳文件到一個(gè)指定的文件夾。不過(guò)有時(shí)Web開發(fā)人員為了方便,通常會(huì)做這樣一個(gè)操作:如果用戶上傳的目錄存在,則將用戶的文件存入該文件夾;如果目錄不存在,則創(chuàng)建該目錄,并寫入文件[9]。示例PHP代碼如下:
//HTML代碼
//PHP代碼
if($_FILES[‘file’][‘type’]==“image/jpeg”)
$imageTempName=$_FILES[‘file’][‘temp_name’];
$imageName=$_FILES[‘file’][‘name’];
$last=substr($imageName,strrpos($imageName,“.”));//判斷圖片類型是否符合
if($last!=”.jpg”){
Exit(“圖片類型錯(cuò)誤”);
}
$Extension=$_POST[‘Extension’];//獲取文件上傳目錄
if(!is_dir(Extension)){
mkdir($Extension);
}
$imageName=md5($imageName).$last;
move_upload_file($imageTempName,“./uploadFile/”.$imageName);
echo(“文件上傳成功”);
exit();
}
//Upload.php中有如下代碼
if(!is_dir($Extension)){
mkdir ($Extension);
}
在upload.php中的這一段代碼是引發(fā)漏洞的關(guān)鍵點(diǎn)。在html中有一個(gè)隱藏的標(biāo)簽,這個(gè)標(biāo)簽標(biāo)示的是上傳文件時(shí)默認(rèn)的文件夾,而同樣該標(biāo)簽的參數(shù)對(duì)攻擊者來(lái)說(shuō)是可控的。依然可以用burp對(duì)請(qǐng)求進(jìn)行攔截,對(duì)該標(biāo)簽的參數(shù)進(jìn)行修改。例如前文提到的Web容器IIS6.0,將新建的文件夾的名稱命名為123.asp并在其中包含木馬文件,則可直接獲得webshell[10-11]。
3.2.4 截?cái)嗌蟼鞴?/p>
截?cái)嗌蟼鞴舻暮诵氖恰?00”字符,也被稱為Url終止符,通俗的講就是如果Url中包含這個(gè)字符,那么這個(gè)字符之后的所有內(nèi)容都會(huì)被丟棄。同樣在HTTP請(qǐng)求中也適用[12]。
//test.asp
<%
Username=request(“username”)
Response.write username
%>
以上代碼的作用是接收username的值并輸出。訪問(wèn)Url:HTTP://www.test.com:8080/test.asp?username=hacker%00admin,可以發(fā)現(xiàn),輸出的內(nèi)容只有“hacker”,%00后面的字符都被截?cái)嗔?,這就是截?cái)喙舻脑蚚13]。
例如,如下網(wǎng)頁(yè)有一個(gè)文件上傳模塊,先上傳一張普通圖片,得到提示如果要得到flag,必須要上傳PHP文件才可以。然后再上傳一個(gè)1.php文件,提示*.php是不被允許的文件類型,僅支持上傳jpg,gif,png后綴的文件。
針對(duì)這種情況可以使用截?cái)喙簟O壬蟼饕粋€(gè)1.php_.jpg的文件(此處的下劃線為空格,方便修改請(qǐng)求),在上傳時(shí)將請(qǐng)求攔截,用Burpsuite的hex視圖在上傳路徑的1.php后的%20(空格)改成Url終止符%00再上傳,提示獲取flag成功,如圖4和圖5所示。
盡管上傳的是一個(gè)*.php文件,但是如果不進(jìn)行%00截?cái)啵蟼鞯奈募诜?wù)器上以<1.php.jpg>格式保存,也就是說(shuō)這是一個(gè)圖片文件,PHP無(wú)法解析這個(gè)文件。當(dāng)進(jìn)行%00截?cái)嗪?,服?wù)器就會(huì)將%00后的<.jpg>丟棄,這時(shí)文件將以<1.php>的形式保存在服務(wù)器上,惡意腳本也就成功上傳了。
圖4 修改HTTP請(qǐng)求
圖5 獲得flag
通過(guò)分析,文件上傳漏洞形成的主要原因有兩點(diǎn):
(1)上傳文件過(guò)濾不嚴(yán),攻擊者可能直接上傳惡意腳本;
(2)攻擊者可能通過(guò)上傳“合法文件”,利用Web解析漏洞使之能夠被執(zhí)行[14]。
文件上傳漏洞的防御,主要圍繞以下幾點(diǎn):文件上傳路徑;文件訪問(wèn)權(quán)限;文件執(zhí)行權(quán)限。另外,由于業(yè)務(wù)領(lǐng)域不同,根據(jù)上傳文件類型的不同也需要進(jìn)行不同的防御。以下提出了防范文件上傳漏洞的幾種常見(jiàn)方法:
(a)文件上傳的目錄設(shè)置為不可執(zhí)行。只要Web容器無(wú)法解析目錄下面的文件,即使攻擊者直接上傳了webshell,服務(wù)器本身也不會(huì)受到影響,這一點(diǎn)至關(guān)重要。
(b)判斷文件類型。即前文提到的MIME驗(yàn)證,在文件類型檢查中,強(qiáng)烈推薦白名單方式,黑名單方式已經(jīng)無(wú)數(shù)次被證明是不可靠的。此外,對(duì)于圖片的處理,可以使用壓縮函數(shù)或者resize()函數(shù),在處理圖片的同時(shí)破壞圖片中可能包含的腳本代碼。
(c)使用隨機(jī)數(shù)改寫文件名和文件路徑攻擊者如果要執(zhí)行上傳的文件,則需要能夠訪問(wèn)到這個(gè)文件。在某些環(huán)境中,攻擊者能上傳,但不能訪問(wèn)。如果應(yīng)用了隨機(jī)數(shù)改寫了文件名和路徑,將極大地增加攻擊的成本。像shell.php.rar.rar和crossdomain.xml這種文件,都將因?yàn)橹孛鵁o(wú)法攻擊[15]。
(d)單獨(dú)設(shè)置文件服務(wù)器的域名。由于瀏覽器同源策略的關(guān)系,一系列客戶端攻擊將失效:上傳crossdomain.xml、上傳包含JavaScript的XSS利用等問(wèn)題將得到解決。
在服務(wù)器工作環(huán)境中,Shell指的是“為使用者提供使用界面”的軟件,類似于Windows系統(tǒng)中的cmd.exe,網(wǎng)絡(luò)管理員可以通過(guò)Shell對(duì)服務(wù)器進(jìn)行一些管理行為的操作。而對(duì)于攻擊者來(lái)說(shuō),文件上傳漏洞一直都是獲取服務(wù)器Shell的重要途徑,對(duì)系統(tǒng)維護(hù)人員來(lái)說(shuō),文件上傳漏洞的巨大危害,可以直接導(dǎo)致操作系統(tǒng)對(duì)攻擊者暴露且被控制,并通過(guò)操作系統(tǒng)橫向滲透入網(wǎng)絡(luò)內(nèi)部的其他設(shè)備。文中給出的方法基本可以解決上傳漏洞,但不能說(shuō)完全防御,因?yàn)闆](méi)有絕對(duì)的安全,攻擊者總是可以從不同角度對(duì)服務(wù)器進(jìn)行攻擊。所以,Web開發(fā)人員不僅要在代碼層面對(duì)Web程序做好安全防護(hù)工作,更要對(duì)服務(wù)器操作系統(tǒng)、網(wǎng)絡(luò)通信層面進(jìn)行保護(hù)和嚴(yán)密的監(jiān)控。及時(shí)更新服務(wù)器操作系統(tǒng)和WAF的補(bǔ)丁[16],對(duì)網(wǎng)絡(luò)設(shè)備的日志進(jìn)行及時(shí)、全面的審計(jì),對(duì)用戶的非法行為進(jìn)行記錄并做相應(yīng)的處理[17]。不能只在某一個(gè)方面做好防護(hù),安全是一個(gè)整體。與此同時(shí),安全人員需要注意文件上傳漏洞和其他Web漏洞配合所做出的“組合攻擊”,這將成為今后Web安全研究的重點(diǎn)。