為一名經(jīng)驗豐富的數(shù)據(jù)分析師,我深知采集文章所需的下載工具對于提高工作效率和數(shù)據(jù)準確性的重要性。在這篇文章中,我將分享我在采集文章過程中使用的一些下載工具,并提供一些實用的技巧和注意事項。
第一,選擇合適的下載工具
在采集文章時,選擇合適的下載工具是至關(guān)重要的。根據(jù)不同的需求,可以選擇使用專業(yè)的網(wǎng)頁抓取工具,如Scrapy和Beautiful Soup,或者使用瀏覽器插件來實現(xiàn)頁面截取和保存。
第二,了解目標網(wǎng)站結(jié)構(gòu)
在采集文章之前,先了解目標網(wǎng)站的結(jié)構(gòu)是非常必要的。通過分析網(wǎng)站的HTML結(jié)構(gòu)和URL規(guī)律,可以更好地確定采集規(guī)則,并避免因網(wǎng)站結(jié)構(gòu)變化而導(dǎo)致的數(shù)據(jù)抓取失敗。
第三,設(shè)置合理的采集頻率
在進行大規(guī)模文章采集時,設(shè)置合理的采集頻率非常重要。過快或過頻繁的訪問可能會給目標網(wǎng)站帶來壓力,并可能導(dǎo)致IP被封禁。因此,在進行大規(guī)模數(shù)據(jù)采集時,建議合理設(shè)置訪問間隔和訪問頻率,以避免給目標網(wǎng)站造成困擾。
第四,處理反爬機制
許多網(wǎng)站為了防止數(shù)據(jù)被非法采集,會設(shè)置一些反爬機制。在采集文章時,我們需要了解并應(yīng)對這些反爬機制。可以通過設(shè)置合理的請求頭、使用代理IP等方式應(yīng)對反爬措施,確保數(shù)據(jù)的正常采集。
第五,數(shù)據(jù)清洗和整理
采集到的文章數(shù)據(jù)可能存在一些噪音或冗余信息,因此在采集之后,我們需要進行數(shù)據(jù)清洗和整理。可以使用正則表達式、自然語言處理等技術(shù)來去除HTML標簽、過濾無效內(nèi)容,并對文章進行格式化和結(jié)構(gòu)化處理。
第六,存儲與備份
為了保證數(shù)據(jù)的安全性和可用性,在采集文章時需要做好存儲與備份工作。可以選擇將數(shù)據(jù)存儲在數(shù)據(jù)庫中,或者將其導(dǎo)出為CSV或Excel文件以備后續(xù)分析使用。同時,定期進行數(shù)據(jù)備份是非常必要的,以防止意外情況導(dǎo)致數(shù)據(jù)丟失。
第七,合規(guī)與道德
在進行文章采集時,我們要始終遵守相關(guān)法律法規(guī),并尊重網(wǎng)站的使用規(guī)則和版權(quán)。不得采集敏感信息和未經(jīng)授權(quán)的內(nèi)容,同時要注意保護用戶隱私和個人信息。
第八,持續(xù)學(xué)習(xí)與改進
文章采集是一個不斷學(xué)習(xí)和改進的過程。隨著技術(shù)的發(fā)展和網(wǎng)站的變化,我們需要不斷更新自己的知識和技能,并關(guān)注新的數(shù)據(jù)采集工具和方法,以提高效率和準確性。
通過以上八點經(jīng)驗分享,我希望能夠幫助到正在進行文章采集工作的各位同仁。采集文章需要下載,但更需要我們對技術(shù)和道德的認知與把握。只有在合規(guī)、持續(xù)學(xué)習(xí)與改進的基礎(chǔ)上,我們才能更好地完成我們的工作。愿大家都能在文章采集中取得優(yōu)異的成果!
么是css的調(diào)用方式?
簡單來講,就是解決把css代碼寫在哪里的問題,這塊內(nèi)容之前在課堂上演示過,這里再用文字說明一下,權(quán)當復(fù)習(xí)。
大體有以下四種方式:
1,外聯(lián)式樣式表
添加在HTML的頭部信息標識符< head>里:
<head>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
其中href是目標文檔的URL, type則規(guī)定了目標URL的MIME類型,而media規(guī)定了文檔將顯示在什么設(shè)備上。
2,內(nèi)嵌樣式表
添加在HTML的頭部信息標識符< head>里:
<head>
<style type="text/css">
<!-- 樣式表的具體內(nèi)容 -->
</style>
</head>
type=”text/css”表示樣式表采用MIME類型,幫助不支持CSS的瀏覽器過濾掉CSS代碼,避免在瀏覽器面前直接以源代碼的方式顯示我們設(shè)置的樣式表。但為了保證上述情況一定不要發(fā)生,還是有必要在樣式表里加上注釋標識符“< !--注釋內(nèi)容-->”。
3,元素內(nèi)定
語法:
<Tag style="properties">網(wǎng)頁內(nèi)容</tag>
舉個例子:
<p style="color: blue; font-size: 10px">CSS實例</p>
上面例子的代碼說明:
用藍色顯示字體大小為10px的“CSS實例”。盡管使用簡單、顯示直觀,但是這種方法不怎么常用,因為這樣添加無法完全發(fā)揮樣式表的優(yōu)勢——即內(nèi)容結(jié)構(gòu)和格式控制分別保存。
4,導(dǎo)入樣式表(高級用法,暫時先放下)
語法:
<style type="text/css">
<!-- @import url("css/base.css"); -->
</style>
其中外部引用CSS主要用到兩種方式link和@import
本質(zhì)上,這兩種方式都是為了加載CSS文件,但還是存在著細微的差別。
link和@import存在如下差別:
差別1:老祖宗的差別。link屬于HTML標簽,而@import完全是CSS提供的一種方式。
link標簽除了可以加載CSS外,還可以做很多其它的事情,比如定義RSS,定義rel連接屬性等,@import就只能加載CSS了。
差別2:加載順序的差別。當一個頁面被加載的時候(就是被瀏覽者瀏覽的時候),link引用的CSS會同時被加載,而@import引用的CSS會等到頁面全部被下載完再被加載。所以有時候瀏覽@import加載CSS的頁面時開始會沒有樣式(就是閃爍),網(wǎng)速慢的時候還挺明顯。
差別3:兼容性的差別。由于@import是CSS2.1提出的所以老的瀏覽器不支持,@import只有在IE5以上的才能識別,而link標簽無此問題。
差別4:當使用javascript控制DOM去改變樣式的時候,只能使用link標簽,因為@import不是DOM可以控制的。
從上面的分析來看,還是使用link標簽比較好。
課后練習(xí):
步驟一:新建一個名為index.html的網(wǎng)頁。
步驟二:在index.html網(wǎng)頁文檔里加入兩個p標簽,分別在p標簽中加入內(nèi)容(內(nèi)容隨意)
步驟三:嘗試用上面提到的前三種方式,用css代碼改變p標簽內(nèi)容的顯示格式。
在文件上傳的功能處,若服務(wù)端腳本語言未對上傳的文件進行嚴格驗證和過濾,導(dǎo)致惡意用戶上傳惡意的腳本文件時,就有可能獲取執(zhí)行服務(wù)端命令的能力,這就是文件上傳漏洞。文件上傳漏洞對Web應(yīng)用來說是一種非常嚴重的漏洞。
一般情況下,Web應(yīng)用都會允許用戶上傳一些文件,如頭像、附件等信息,如果Web應(yīng)該沒有對用戶上傳的文件進行有效的檢查過濾,那么惡意用戶就會上傳一句話木馬等webshell,從而達到控制web網(wǎng)站的目的。
由于程序員在對用戶文件上傳部分的控制不足或者處理缺陷,而導(dǎo)致用戶可以越過其本身權(quán)限向服務(wù)器上傳可執(zhí)行的動態(tài)腳本文件,并通過此腳本文件獲得了執(zhí)行服務(wù)端命令的能力。
高危出發(fā)點:
相冊、頭像上傳視頻、照片分享附件上傳(論壇發(fā)帖、郵箱)文件管理器
1、代碼執(zhí)行
上傳文件是web腳本語言,服務(wù)器的web容器解釋并執(zhí)行了用戶上傳的腳本,導(dǎo)致代碼執(zhí)行,甚至導(dǎo)致網(wǎng)站甚至整個服務(wù)器被控制
2、域控制
上傳文件是flash的策略文件crossdomiain.xml,黑客用以控制flash在該域下的行為;
3、網(wǎng)站掛馬
上傳文件是病毒、木馬,黑客用以誘騙用戶或者管理員下載執(zhí)行;
4、釣魚
上傳文件是釣魚圖片或為包含了腳本的圖片,在某些版本的瀏覽器中會被作為腳本執(zhí)行,被用于釣魚和欺詐。
首先,上傳的文件能夠被web容器解釋執(zhí)行。所以文件上傳后所在的目錄要是web容器所覆蓋到的路徑。
其次,用戶能夠從web訪問這個文件。如果文件上傳了,但用戶無法通過web訪問,或者無法得到web容器解釋這個腳本,那么也不能稱之為漏洞。 最后,用戶上傳的文件若被安全檢查、格式化、圖片壓縮等功能改變了內(nèi)容,則也可能導(dǎo)致攻擊不成功。
將上傳文件與web服務(wù)隔離 白名單過濾、限制上傳文件類型 ? 文件上傳路徑設(shè)置為不可執(zhí)行權(quán)限 ? 檢查文件上傳路徑 ? 自帶函數(shù)檢測 ? 自定義函數(shù)檢測 ? 圖片渲染 ? 對上傳文件重命名 ? 對文件內(nèi)容壓縮,重新生成文件內(nèi)容 ? 檢查文件內(nèi)容
詳情看圖片,后面有一些場景的題目配合學(xué)習(xí)
需要上傳個webshell上去 但是限制了上傳的文件類型
F12查看javascrip內(nèi)容
代碼審計
function checkFile() {
var file=document.getElementsByName('upload_file')[0].value;
if (file==null || file=="") {
alert("請選擇要上傳的文件!");
return false;
}
//定義允許上傳的文件類型
var allow_ext=".jpg|.png|.gif"; //前端白名單,只允許這三個格式
//提取上傳文件的類型
var ext_name=file.substring(file.lastIndexOf("."));
//判斷上傳文件類型是否允許上傳
if (allow_ext.indexOf(ext_name)==-1) {
var errMsg="該文件不允許上傳,請上傳" + allow_ext + "類型的文件,當前文件類型為:" + ext_name;
alert(errMsg); //輸出errMsg
return false;
}
}
F12點擊查看器,將其中的js過濾代碼(上面那段)刪除掉,ctrl+s保存在本地桌面上,在桌面上右鍵文本方式打開,尋找action(目標),ctrl+f,沒有找到,說明沒有上傳目標,手動添加,重新刷新網(wǎng)頁正常上傳正常圖片,查看網(wǎng)絡(luò),可以看到一個post數(shù)據(jù)包,200ok,里面有一個地址
action="http://127.0.0.1/upload/Pass-01/index.php"
將這個代碼添加在<from>標簽
<div id="upload_panel">
<ol>
<li>
<h3>任務(wù)</h3>
<p>上傳一個<code>webshell</code>到服務(wù)器。</p>
</li>
<li>
<h3>上傳區(qū)</h3>
<form action="http://127.0.0.1/upload/Pass-01/index.php" enctype="multipart/form-data" method="post" onsubmit="return checkFile()">
<p>請選擇要上傳的圖片:</p><p>
<input class="input_file" type="file" name="upload_file">
<input class="button" type="submit" name="submit" value="上傳">
</p></form>
<div id="msg">
</div>
<div id="img">
</div>
</li>
</ol>
</div>
重新上傳一個a.php文件,(<?php phpinfo(); ?>)
在網(wǎng)站根目錄result可以查看到a.php文件,說明上傳成功。
或者訪問:http://127.0.0.1/upload/upload/a.php
瀏覽器172.21.172.56訪問靶場,修改php文件后綴改為png文件,上傳,bp抓包,修改數(shù)據(jù)包后綴,又改回php,發(fā)送數(shù)據(jù)包,再次訪問http://172.21.172.56/upload/upload/b.php出現(xiàn)phpinfo信息說明成功
接著再地址欄輸入about:config,點擊回車鍵。
接著看到如下畫面。去掉下次任顯示此警告前面的方框里的鉤,再點擊我 保證會小心按鈕
點擊后看到如下畫面,在搜索地址欄中輸入javascript.enabled
改為flase
直接上傳c.php就可以了
訪問:http://172.21.172.56/upload/upload/c.php
出現(xiàn)信息,成功
js代碼很明顯是白名單,只允許三種通過,那么我們可以手動添加一個規(guī)則
直接上傳php文件
右鍵網(wǎng)頁源碼,沒有發(fā)現(xiàn)js過濾
網(wǎng)站根目錄查看index.php源碼
<?php
include '../config.php';
include '../head.php';
include '../menu.php';
$is_upload=false;
$msg=null;
if (isset($_POST['submit'])) { //isset — 檢測變量是否已設(shè)置并且非 null
if (file_exists(UPLOAD_PATH)) { // file_exists 檢查文件或目錄是否存在 ,UPLOAD_PATH如果存在
if (($_FILES['upload_file']['type']=='image/jpeg') || ($_FILES['upload_file']['type']=='image/png') || ($_FILES['upload_file']['type']=='image/gif')) { //如果文件類型是image/jpeg image/png image/gif(白名單)
$temp_file=$_FILES['upload_file']['tmp_name'];
$img_path=UPLOAD_PATH . '/' . $_FILES['upload_file']['name'];
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload=true;
} else {
$msg='上傳出錯!';
}
} else {
$msg='文件類型不正確,請重新上傳!'; //非image/jpeg image/png image/gif,重新上傳
}
} else {
$msg=UPLOAD_PATH.'文件夾不存在,請手工創(chuàng)建!';
}
}
?>
不是在js中,而是在服務(wù)器端進行了限制
MIME (Multipurpose Internet Mail Extensions) 是描述消息內(nèi)容類型的因特網(wǎng)標準 MIME 消息能包含文本、圖像、音頻、視頻以及其他應(yīng)用程序?qū)S玫臄?shù)據(jù) 在HTTP 協(xié)議中,使用Content-Type 字段表示文件的MIME 類型。
所以抓包修改Content-Type
200ok
僅僅判斷content-type類型,因此上傳a.php抓包修改content-type為圖片類型:image/jpeg、image/png、image/gif 就可了
$is_upload=false;
$msg=null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) { //檢查文件或目錄是否存在
$deny_ext=array('.asp','.aspx','.php','.jsp'); //數(shù)組deny_exit相當于黑名單
$file_name=trim($_FILES['upload_file']['name']); //trim()去除字符串首尾處的空白字符(或者其他字符)
$file_name=deldot($file_name);//刪除文件名末尾的點
$file_ext=strrchr($file_name, '.'); // 查找指定字符在字符串中的最后一次出現(xiàn)
$file_ext=strtolower($file_ext); //轉(zhuǎn)換為小寫
$file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext=trim($file_ext); //收尾去空
if(!in_array($file_ext, $deny_ext)) { //檢查數(shù)組中是否存在某個值,如果不存在 執(zhí)行下一步
$temp_file=$_FILES['upload_file']['tmp_name'];
$img_path=UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext; //date()重置時間,時間戳 //rand產(chǎn)生一個隨機整數(shù)
if (move_uploaded_file($temp_file,$img_path)) { //將上傳的文件移動到新位置
$is_upload=true;
} else {
$msg='上傳出錯!';
}
} else {
$msg='不允許上傳.asp,.aspx,.php,.jsp后綴文件!';
}
} else {
$msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!';
}
}
/*
move_uploaded_file(string `$filename`, string `$destination`)
filename
上傳的文件的文件名。
destination
移動文件到這個位置。
*/
是個黑名單,不允許上傳.asp,.aspx,.php,.jsp后綴的文件
那最簡單的繞過辦法,用特殊后綴名
.phtml
.phps
.php5
.pht
類似的 前提是apache的配置文件httpd.conf中有如下配置
AddType application/x-httpd-php .php .phtml .phps .php5 .pht
實質(zhì)就是添加可以執(zhí)行php的文件類型
回復(fù)告訴我們路徑以及文件名了。圖片上傳后右鍵也能得到圖片地址
$is_upload=false;
$msg=null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext=array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");
$file_name=trim($_FILES['upload_file']['name']);//trim()去除字符串首尾處的空白字符(或者其他字符)
$file_name=deldot($file_name);//刪除文件名末尾的點
$file_ext=strrchr($file_name, '.');
$file_ext=strtolower($file_ext); //轉(zhuǎn)換為小寫
$file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext=trim($file_ext); //收尾去空
?
if (!in_array($file_ext, $deny_ext)) {
$temp_file=$_FILES['upload_file']['tmp_name'];
$img_path=UPLOAD_PATH.'/'.$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload=true;
} else {
$msg='上傳出錯!';
}
} else {
$msg='此文件不允許上傳!';
}
} else {
$msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!';
}
}
黑名單拒絕了幾乎所有有問題的后綴名,除了.htaccess 前提條件(1.mod_rewrite模塊開啟。2.AllowOverride All)
因此先上傳一個.htaccess文件,內(nèi)容如下:SetHandler application/x-httpd-php
這樣所有文件都會當成php來解析
在上傳一個 1.jpg,(內(nèi)容寫成 <?php phpinfo();?>)之后訪問就會以php來執(zhí)行
$is_upload=false;
$msg=null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext=array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
$file_name=trim($_FILES['upload_file']['name']);
$file_name=deldot($file_name);//刪除文件名末尾的點
$file_ext=strrchr($file_name, '.');// 查找指定字符在字符串中的最后一次出現(xiàn)
$file_ext=strtolower($file_ext); //轉(zhuǎn)換為小寫
$file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext=trim($file_ext); //首尾去空
if (!in_array($file_ext, $deny_ext)) {
$temp_file=$_FILES['upload_file']['tmp_name'];
$img_path=UPLOAD_PATH.'/'.$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload=true;
} else {
$msg='上傳出錯!';
}
} else {
$msg='此文件類型不允許上傳!';
}
} else {
$msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!';
}
}
更完善的黑名單.htaccess文件也被禁了
但是.ini沒禁 所以可以上傳.user.ini文件 內(nèi)容是 auto_prepend_file=1.jpg
讓所有php文件都“自動”包含1.jpg文件
試了半天根本不行,介紹另一個方法
$is_upload=false;
$msg=null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext=array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
$file_name=trim($_FILES['upload_file']['name']);
$file_name=deldot($file_name);//刪除文件名末尾的點
$file_ext=strrchr($file_name, '.');
$file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext=trim($file_ext); //首尾去空
?
if (!in_array($file_ext, $deny_ext)) {
$temp_file=$_FILES['upload_file']['tmp_name'];
$img_path=UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload=true;
} else {
$msg='上傳出錯!';
}
} else {
$msg='此文件類型不允許上傳!';
}
} else {
$msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!';
}
}
更完善的黑名單
但是大小寫的函數(shù)去掉了
所以可以后綴名大寫繞過
$file_ext=strtolower($file_ext); //轉(zhuǎn)換為小寫
這里沒得
抓包看看,文件改成啥名字了
$is_upload=false;
$msg=null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext=array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
$file_name=$_FILES['upload_file']['name'];
$file_name=deldot($file_name);//刪除文件名末尾的點
$file_ext=strrchr($file_name, '.');
$file_ext=strtolower($file_ext); //轉(zhuǎn)換為小寫
$file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
if (!in_array($file_ext, $deny_ext)) {
$temp_file=$_FILES['upload_file']['tmp_name'];
$img_path=UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload=true;
} else {
$msg='上傳出錯!';
}
} else {
$msg='此文件不允許上傳';
}
} else {
$msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!';
}
}
對比前面的題 這題沒有對后綴名進行去空 所以在后綴名里加個空格就能繞過
$file_ext=trim($file_ext); //收尾去空 $file_name=trim($_FILES['upload_file']['name']); //trim()去除字符串首尾處的空白字符(或者其他字符)
這里沒有
$is_upload=false;$msg=null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext=array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini"); $file_name=trim($_FILES['upload_file']['name']); $file_ext=strrchr($file_name, '.'); $file_ext=strtolower($file_ext); //轉(zhuǎn)換為小寫 $file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext=trim($file_ext); //首尾去空 if (!in_array($file_ext, $deny_ext)) { $temp_file=$_FILES['upload_file']['tmp_name']; $img_path=UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload=true; } else { $msg='上傳出錯!'; } } else { $msg='此文件類型不允許上傳!'; } } else { $msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!'; }}
對比前面 沒有對后綴名末尾的點進行處理
$file_name=deldot($file_name);//刪除文件名末尾的點
沒有這個
$is_upload=false;$msg=null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext=array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini"); $file_name=trim($_FILES['upload_file']['name']); $file_name=deldot($file_name);//刪除文件名末尾的點 $file_ext=strrchr($file_name, '.'); $file_ext=strtolower($file_ext); //轉(zhuǎn)換為小寫 $file_ext=trim($file_ext); //首尾去空 if (!in_array($file_ext, $deny_ext)) { $temp_file=$_FILES['upload_file']['tmp_name']; $img_path=UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext; if (move_uploaded_file($temp_file, $img_path)) { $is_upload=true; } else { $msg='上傳出錯!'; } } else { $msg='此文件類型不允許上傳!'; } } else { $msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!'; }}
沒有對后綴名中的’::$DATA’進行過濾 在php+windows的情況下文件名+"::$DATA"會把::$DATA之后的數(shù)據(jù)當成文件流處理,不會檢測后綴名 且保持"::$DATA"之前的文件名
少了 $file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$is_upload=false;$msg=null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext=array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini"); $file_name=trim($_FILES['upload_file']['name']); $file_name=deldot($file_name);//刪除文件名末尾的點 $file_ext=strrchr($file_name, '.'); $file_ext=strtolower($file_ext); //轉(zhuǎn)換為小寫 $file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext=trim($file_ext); //首尾去空 if (!in_array($file_ext, $deny_ext)) { $temp_file=$_FILES['upload_file']['tmp_name']; $img_path=UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload=true; } else { $msg='上傳出錯!'; } } else { $msg='此文件類型不允許上傳!'; } } else { $msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!'; }}
區(qū)別是路徑里不是file_ext,而是file_name即保存文件的時候沒有重命名而使用的原始的文件名 可以利用1.php. .(點+空格+點)來繞過
$is_upload=false;$msg=null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext=array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini"); $file_name=trim($_FILES['upload_file']['name']); $file_name=str_ireplace($deny_ext,"", $file_name); $temp_file=$_FILES['upload_file']['tmp_name']; $img_path=UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload=true; } else { $msg='上傳出錯!'; } } else { $msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!'; }}
用str_ireplace把黑名單里的后綴全替換為空 但是這個函數(shù)只進行一次替換 所以可以雙寫繞過
$is_upload=false;$msg=null;if(isset($_POST['submit'])){ $ext_arr=array('jpg','png','gif'); //數(shù)組 $file_ext=substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1); /*返回字符串的子串substr(string $string, int $start, int $length=?): string返回字符串 string 由 start 和 length 參數(shù)指定的子字符串。strrpos(string,find,start)函數(shù)查找字符串中最后一次出現(xiàn)的位置*/ if(in_array($file_ext,$ext_arr)){ //檢查數(shù)組中是否存在某個值 $temp_file=$_FILES['upload_file']['tmp_name']; $img_path=$_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext; if(move_uploaded_file($temp_file,$img_path)){ $is_upload=true; } else { $msg='上傳出錯!'; } } else{ $msg="只允許上傳.jpg|.png|.gif類型文件!"; }}
定義一個白名單,只允許三種文件類型
substr()函數(shù)返回字符的一部分,strrpos(string,find,start)函數(shù)查找字符串中最后一次出現(xiàn)的位置,這里是將后綴名提取出來賦值給file_ext img_path是直接拼接
我們可以抓包修改get的參數(shù),然后通過file_ext無效,這樣就可以上傳PHP文件
%00截斷的概念和原理:
在URL中%00表示ASCII碼中的0,而0作為特殊字符保留,表示字符結(jié)束,當url中出現(xiàn)%00時就會認為讀取已結(jié)束,而忽略后面上傳的文件或圖片,只上傳截斷前的文件或圖片
要求:php版本小于5.3.4,php的magic_quotes_gpc為OFF狀態(tài) 將路徑改為path=“upload/1.php%00”,那么拼接之后,文件上傳時就變成了“upload/1.php%1.jpg”,這時上傳便將1.php上傳進去,而1.jpg則被截斷
切換php版本
$is_upload=false;$msg=null;if(isset($_POST['submit'])){ $ext_arr=array('jpg','png','gif'); $file_ext=substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1); //拿出文件名后綴 if(in_array($file_ext,$ext_arr)){ $temp_file=$_FILES['upload_file']['tmp_name']; $img_path=$_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext; if(move_uploaded_file($temp_file,$img_path)){ $is_upload=true; } else { $msg="上傳失敗"; } } else { $msg="只允許上傳.jpg|.png|.gif類型文件!"; }}
與上一題相比,區(qū)別是上傳方式變成了POST。還是利用00截斷
但是POST不會像GET對%00進行自動解碼,需要在二進制中進行修改,將70 68 70后面的2b改為00
function getReailFileType($filename){ //得到真實的文件類型 $file=fopen($filename, "rb"); //打開文件 讀 二進制 $bin=fread($file, 2); //只讀2字節(jié) 也就是說只對文件頭進行了檢測 fclose($file);//關(guān)閉文件 $strInfo=@unpack("C2chars", $bin); //根據(jù)給定的格式將二進制字符串解壓縮到數(shù)組中。 $typeCode=intval($strInfo['chars1'].$strInfo['chars2']); //獲取變量的整數(shù)值 $fileType=''; switch($typeCode){ case 255216: $fileType='jpg'; break; case 13780: $fileType='png'; break; case 7173: $fileType='gif'; break; default: $fileType='unknown'; } return $fileType; //得到文件類型,返回的只有這四種}$is_upload=false;$msg=null;if(isset($_POST['submit'])){ //檢測變量是否已設(shè)置并且非 null $temp_file=$_FILES['upload_file']['tmp_name']; $file_type=getReailFileType($temp_file); //跳轉(zhuǎn)到上面的函數(shù) if($file_type=='unknown'){ $msg="文件未知,上傳失敗!"; }else{ $img_path=UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type; if(move_uploaded_file($temp_file,$img_path)){ $is_upload=true; } else { $msg="上傳出錯!"; } }}- unpack(format,data)函數(shù)是規(guī)定在解包數(shù)據(jù)時所使用的格式,這里是文件頭按照c格式解包- intval() 函數(shù)用于獲取變量的整數(shù)值
rb是讀取二進制文件
后面的fread函數(shù)只讀兩字節(jié),也就是說只對文件頭進行了檢測
也就是說,文件頭檢測,如果你沒有偽造文件頭,即便你是jpg圖片它也識別不出來,所以這里我們要抓包,偽造一個文件頭
我們隨便拿一張圖片,文件內(nèi)容最前面添加GIF89a 和
<?php $filename=$_GET['test']; include($filename); ?>
直接上傳test.php文件,抓包拿到文件目錄以及文件名
制作圖片馬 將一句話木馬1.php和普通圖片1.jpg合并 得到shell.jpg
這里Windows會報毒."無法成功完成操作,因為文件包含病毒或潛在的垃圾軟件。"
要關(guān)掉防火墻里面的實時防護
dos命令: copy 1.jpg /b + 1.php /a shell.jpg
shell.jpg上傳上去之后,拿到圖片地址以及文件名
但直接訪問圖片并不能把圖片當做PHP解析,還需要利用文件包含漏洞
在www/upload-labs/upload目錄下建立一個php文件
<?php/*本頁面存在文件包含漏洞,用于測試圖片馬是否能正常運行!*/header("Content-Type:text/html;charset=utf-8");$file=$_GET['file'];if(isset($file)){ include $file;}else{ show_source(__file__);}
function isImage($filename){ $types='.jpeg|.png|.gif'; //三種類型的后綴 if(file_exists($filename)){ //文件存在文件名 $info=getimagesize($filename); //getimagesize()取得圖像大小 $ext=image_type_to_extension($info[2]); //image_type_to_extension — 取得圖像類型的文件后綴 if(stripos($types,$ext)>=0){ //stripos — 查找字符串首次出現(xiàn)的位置(不區(qū)分大小寫)在變量types找,返回變量ext return $ext; }else{ return false; } }else{ return false; }}$is_upload=false;$msg=null;if(isset($_POST['submit'])){ $temp_file=$_FILES['upload_file']['tmp_name']; $res=isImage($temp_file); if(!$res){ $msg="文件未知,上傳失敗!"; }else{ $img_path=UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res; if(move_uploaded_file($temp_file,$img_path)){ //move_uploaded_file — 將上傳的文件移動到新位置 $is_upload=true; } else { $msg="上傳出錯!"; } }}
用getimagesize函數(shù)獲取圖像大小及相關(guān)信息,成功返回一個數(shù)組,失敗則返回 FALSE 并產(chǎn)生一條 E_WARNING 級的錯誤信息
仍然可以圖片馬繞過
function isImage($filename){ // //需要開啟php_exif模塊 $image_type=exif_imagetype($filename); //exif_imagetype — 判斷一個圖像的類型 switch ($image_type) { //語句類似于具有同一個表達式的一系列 if 語句。很多場合下需要把同一個變量(或表達式)與很多不同的值比較,并根據(jù)它等于哪個值來執(zhí)行不同的代碼。 case IMAGETYPE_GIF: return "gif"; break; case IMAGETYPE_JPEG: return "jpg"; break; case IMAGETYPE_PNG: return "png"; break; default: return false; break; }}$is_upload=false;$msg=null;if(isset($_POST['submit'])){ //檢測變量是否已設(shè)置并且非 null $temp_file=$_FILES['upload_file']['tmp_name']; $res=isImage($temp_file); //在這里跑上去查看這個文件類型,返回一個后綴名或者錯誤 if(!$res){ //如果res==flase $msg="文件未知,上傳失敗!"; }else{ $img_path=UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res; if(move_uploaded_file($temp_file,$img_path)){ $is_upload=true; } else { $msg="上傳出錯!"; } }}
用到php_exif模塊來判斷文件類型
仍然可以圖片馬繞過
$is_upload=false;$msg=null;if (isset($_POST['submit'])){ ////檢測變量是否已設(shè)置并且非 null // 獲得上傳文件的基本信息,文件名,類型,大小,臨時文件路徑
$filename=$_FILES['upload_file']['name']; $filetype=$_FILES['upload_file']['type']; $tmpname=$_FILES['upload_file']['tmp_name']; $target_path=UPLOAD_PATH.'/'.basename($filename); //路徑 // 獲得上傳文件的擴展名
$fileext=substr(strrchr($filename,"."),1); //strrchr — 查找指定字符在字符串中的最后一次出現(xiàn) 。substr — 返回字符串的子串。 //判斷文件后綴與類型,合法才進行上傳操作
if(($fileext=="jpg") && ($filetype=="image/jpeg")){ //如果文件類型是jpg 后綴也是jpg
if(move_uploaded_file($tmpname,$target_path)){ // 將上傳的文件移動到新位置$target_path //使用上傳的圖片生成新的圖片
$im=imagecreatefromjpeg($target_path); //imagecreatefromjpeg — 由文件或 URL 創(chuàng)建一個新圖象
if($im==false){
$msg="該文件不是jpg格式的圖片!";
@unlink($target_path); //unlink — 刪除文件
}
else{ //給新圖片指定文件名
srand(time()); //srand播下隨機數(shù)發(fā)生器種子 time — 返回當前的 Unix 時間戳
$newfilename=strval(rand()).".jpg"; //strval — 獲取變量的字符串值 //顯示二次渲染后的圖片(使用用戶上傳圖片生成的新圖片)
$img_path=UPLOAD_PATH.'/'.$newfilename;//路徑
imagejpeg($im,$img_path); //imagejpeg — 輸出圖象到瀏覽器或文件。 @unlink($target_path);//刪除 $is_upload=true; } } else { $msg="上傳出錯!"; }//這里只只展示了jpg的情況
if(($fileext=="jpg") && ($filetype=="image/jpeg"))
檢測$fileext和$filetype是否為jpg格式.
if(move_uploaded_file($tmpname,$target_path)){
然后使用move_uploaded_file函數(shù)來做判斷條件,如果成功將文件移動到$target_path,就會進入二次渲染的代碼,反之上傳失敗.
在這里有一個問題,如果作者是想考察繞過二次渲染的話,在move_uploaded_file($tmpname,$target_path)返回true的時候,就已經(jīng)成功將圖片馬上傳到服務(wù)器了,所以下面的二次渲染并不會影響到圖片馬的上傳.如果是想考察文件后綴和content-type的話,那么二次渲染的代碼就很多余
由于在二次渲染時重新生成了文件名,所以可以根據(jù)上傳后的文件名,來判斷上傳的圖片是二次渲染后生成的圖片還是直接由move_uploaded_file函數(shù)移動的圖片.
在這里很明顯,代碼先將圖片進行了上傳,之后在進行判斷格式是否正確,否則刪除文件,所以這里存在一個邏輯漏洞。
我們可以用bp不斷的發(fā)送.php格式的包,一直發(fā),然后我們在網(wǎng)頁上瀏覽打開這個php文件,只要我們速度在代碼執(zhí)行刪除之前打開了php文件,那么代碼就不能對php文件進行任何操作了。
https://xz.aliyun.com/t/2657
二次渲染了上傳的圖片
繞過方法:找到渲染前后沒有變化的位置,然后將php代碼寫進去,就可以成功上傳帶有php代碼的圖片。
$is_upload=false;$msg=null;if(isset($_POST['submit'])){ $ext_arr=array('jpg','png','gif'); $file_name=$_FILES['upload_file']['name']; $temp_file=$_FILES['upload_file']['tmp_name']; $file_ext=substr($file_name,strrpos($file_name,".")+1); $upload_file=UPLOAD_PATH . '/' . $file_name; if(move_uploaded_file($temp_file, $upload_file)){ if(in_array($file_ext,$ext_arr)){ $img_path=UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext; rename($upload_file, $img_path); $is_upload=true; }else{ $msg="只允許上傳.jpg|.png|.gif類型文件!"; unlink($upload_file); } }else{ $msg='上傳出錯!'; }}
先將文件上傳到服務(wù)器,然后判斷文件后綴是否在白名單里,如果在則重命名,否則刪除。
這就在文件的處理順序上出現(xiàn)了問題,不管文件類型是否合格就上傳至服務(wù)器,之后再對其類型進行判斷,這樣的處理順序?qū)е铝嗽诙嗑€程的情況下,有可能對于不合格的文件還沒來得及刪除就已經(jīng)被訪問,導(dǎo)致不合格的文件繞過了限制。
因此我們可以打個時間差:上傳1.php,只需要在它刪除之前訪問即可。
可以利用burp的intruder模塊不斷上傳,然后我們不斷的訪問刷新該地址。
//index.php$is_upload=false;$msg=null;if (isset($_POST['submit'])){ require_once("./myupload.php"); $imgFileName=time(); $u=new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName); $status_code=$u->upload(UPLOAD_PATH); switch ($status_code) { case 1: $is_upload=true; $img_path=$u->cls_upload_dir . $u->cls_file_rename_to; break; case 2: $msg='文件已經(jīng)被上傳,但沒有重命名。'; break; case -1: $msg='這個文件不能上傳到服務(wù)器的臨時文件存儲目錄。'; break; case -2: $msg='上傳失敗,上傳目錄不可寫。'; break; case -3: $msg='上傳失敗,無法上傳該類型文件。'; break; case -4: $msg='上傳失敗,上傳的文件過大。'; break; case -5: $msg='上傳失敗,服務(wù)器已經(jīng)存在相同名稱文件。'; break; case -6: $msg='文件無法上傳,文件不能復(fù)制到目標目錄。'; break; default: $msg='未知錯誤!'; break; }}//myupload.phpclass MyUpload{.................. var $cls_arr_ext_accepted=array( ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt", ".html", ".xml", ".tiff", ".jpeg", ".png" );.................. /** upload() ** ** Method to upload the file. ** This is the only method to call outside the class. ** @para String name of directory we upload to ** @returns void **/ function upload( $dir ){ $ret=$this->isUploadedFile(); if( $ret !=1 ){ return $this->resultUpload( $ret ); } $ret=$this->setDir( $dir ); if( $ret !=1 ){ return $this->resultUpload( $ret ); } $ret=$this->checkExtension(); if( $ret !=1 ){ return $this->resultUpload( $ret ); } $ret=$this->checkSize(); if( $ret !=1 ){ return $this->resultUpload( $ret ); } // if flag to check if the file exists is set to 1 if( $this->cls_file_exists==1 ){ $ret=$this->checkFileExists(); if( $ret !=1 ){ return $this->resultUpload( $ret ); } } // if we are here, we are ready to move the file to destination $ret=$this->move(); if( $ret !=1 ){ return $this->resultUpload( $ret ); } // check if we need to rename the file if( $this->cls_rename_file==1 ){ $ret=$this->renameFile(); if( $ret !=1 ){ return $this->resultUpload( $ret ); } } // if we are here, everything worked as planned :) return $this->resultUpload( "SUCCESS" ); }.................. };
白名單,一步一步檢查文件大小、文件是否存在等等。
move在rename之前,move操作進行了一次文件保存,rename進行了一次更改文件名。
因此可以通過不斷上傳圖片馬,由于條件競爭可能來不及重命名。
$is_upload=false;$msg=null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext=array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess"); $file_name=$_POST['save_name']; $file_ext=pathinfo($file_name,PATHINFO_EXTENSION); if(!in_array($file_ext,$deny_ext)) { $temp_file=$_FILES['upload_file']['tmp_name']; $img_path=UPLOAD_PATH . '/' .$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload=true; }else{ $msg='上傳出錯!'; } }else{ $msg='禁止保存為該類型文件!'; } } else { $msg=UPLOAD_PATH . '文件夾不存在,請手工創(chuàng)建!'; }}
這關(guān)感覺像是個測試,對比前面可以發(fā)現(xiàn)有很多方法
點繞過或空格繞過:直接在后綴名后面加上/.
利用 apache 的解析漏洞,如給文件命名為test.php.aba
Post的00截斷
$is_upload=false;$msg=null;if(!empty($_FILES['upload_file'])){ //檢查MIME $allow_type=array('image/jpeg','image/png','image/gif'); if(!in_array($_FILES['upload_file']['type'],$allow_type)){ $msg="禁止上傳該類型文件!"; }else{ //檢查文件名 $file=empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name']; if (!is_array($file)) { $file=explode('.', strtolower($file)); } $ext=end($file); $allow_suffix=array('jpg','png','gif'); if (!in_array($ext, $allow_suffix)) { $msg="禁止上傳該后綴文件!"; }else{ $file_name=reset($file) . '.' . $file[count($file) - 1]; $temp_file=$_FILES['upload_file']['tmp_name']; $img_path=UPLOAD_PATH . '/' .$file_name; if (move_uploaded_file($temp_file, $img_path)) { $msg="文件上傳成功!"; $is_upload=true; } else { $msg="文件上傳失敗!"; } } }}else{ $msg="請選擇要上傳的文件!";}
in_array(value,array,type) 在數(shù)組中搜索給定的值
參數(shù) | 描述 |
value | 必需。規(guī)定要在數(shù)組搜索的值 |
array | 必需。規(guī)定要搜索的數(shù)組。 |
type | 可選。如果設(shè)置該參數(shù)為true,則檢查搜索的數(shù)據(jù)與數(shù)組的值的型昰否相同 |
explode(separator,string,limit) 把字符串打散為數(shù)組
參數(shù) | 描述 |
separator | 必需。規(guī)定在哪里分割字符串。 |
string | 必需。要分割的字符串。 |
limit | 可選。規(guī)走所返回的數(shù)組元素的數(shù)目。 |
白名單限制
對文件上傳的文件類型做了判斷 將用戶輸入的文件名賦值給 $file is_array($file) 判斷文件名是不是數(shù)組,如果不是,使用 explode() 以 . 為標記分割為數(shù)組 如果是數(shù)組,則定義后綴名白名單 $allow_suffix 對數(shù)組最后一個元素 $ext(正常情況是指后綴名)進行過濾 如果符合則取數(shù)組的第一個元素reset($file)作為文件名,倒數(shù)第二個元素$file[count($file)-1]作為后綴名。
繞過方法
$file[0]為smi1e.php/,也就是reset($file) $file[2]為白名單中的jpg,此時end($file)等于jpg,$file[count($file) - 1]為空 而$file_name=reset($file) . '.' . $file[count($file) - 1];,也就是smi1e.php/. 于是move_uploaded_file會忽略掉/.,最終上傳smi1e.php
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。