Uploadlabs wp
師傅們好!這是我最近打uploadlabs時寫的wp,肯定有錯誤和疏忽的地方,如果師傅們看到了錯誤或者概念不清的地方,請師傅們不要吝嗇自己的批評和建議,我會認(rèn)真去改去弄懂那些錯誤的地方!再次感謝各位師傅們!
該靶場純用來學(xué)習(xí)文件上傳,跳過了很多解題步驟,比如測試它是那種繞過方式等等,一般直接研究該繞過產(chǎn)生的原因和使用方法
網(wǎng)上的答案很少有對源碼進(jìn)行細(xì)致分析,特別是越到后面越?jīng)]有分析,讓人很容易摸不著頭腦,所以本wp最重要的異地就是關(guān)于源碼防御代碼的分析(當(dāng)然CTF不會給你源碼,必須一個一個試)
通關(guān)經(jīng)驗總結(jié)(直接使用版):
用來總結(jié)文件上傳漏洞的一些基本方法和思想,便于自己以后使用
1.看是前端繞過還是后端繞過,如果是前端直接抓包改完發(fā)進(jìn)去就行
2.抓包修改我們實體請求部分的content-type部分,有些題目會檢測
黑名單繞過:
1.php3 php4 php5等后綴的繞過
2.htaccess文件間接繞過
3.PhP等大小寫繞過(沒有全部轉(zhuǎn)小寫的繞過)
4.后綴沒有去空格,導(dǎo)致他的對后綴名的提取多提取了一個空字符,黑名單找不到,繞過了
5.首尾不去點,哥們直接1.php. 加個·的繞過 或者 ?. ? . (點空格點)的繞過,適用于刪點和刪空格順序弄反的情況
6.::$DATAwindows系統(tǒng)漏洞
7.pphphp 刪除php等敏感后綴 我們直接這么構(gòu)造去繞過
白名單繞過:
1.GET方法直接1.php%00.jpg在我們的儲存路徑中注釋掉后面的部分
POST方法直接二進(jìn)制改找到我們自己給的一個中間變量 a.phpa.jpg php后面的a用二進(jìn)制改成00就行或者我們直接選定中間變量然后右鍵URL變一下碼就行
2.文件頭的檢測,我們要用到雜項里面用的多的010editor 來修改我們的文件頭 比如GIF89a 建議是用gif格式來傳shell ,gif問題小一點
3.用文件包含來解析我們的php代碼 但要注意繞過
4.二重繞過建議前10行的二進(jìn)制繞過 但可以用010editor找一下修改過后的圖片有哪些部分不同,再在那個里面插入我們的php代碼就行,然后用我們的文件包含來
條件競爭
真遇到了看題目具體是怎么操作的,然后再用burpsuite爆破就行
有些關(guān)卡的因為phpstudy版本過高的原因,導(dǎo)致我們的題目最終一步,例如將配置.htaccess將我們的.jpg文件
轉(zhuǎn)換為php文件解析,又或者是配置apache使它能夠解析php3 php4 php5文件,這些操作網(wǎng)上經(jīng)過調(diào)整后仍有bug(頁面直接下載圖片,甚至不會加載頁面等等),大部分網(wǎng)上的辦法都試過了,甚至學(xué)到一些新的東西,但最后結(jié)果還是不行,索性最后一步結(jié)果如果驗證phpinfo();得不到結(jié)果,但是前面該學(xué)的知識和思路都領(lǐng)悟了,后面的驗證無法進(jìn)行也是沒辦法。但不影響做題,這類題目的解題步驟最后一步的得到phpinfo();的測試回顯做不到,但解題思路依然會不漏 ,突出一個過程比結(jié)果重要
(這個時候還不會用docker)
Pass-1

首先看題,直接讓我們傳個webshell 再看看源碼,是前端的一個防御模式。

這里我有兩種方法,首先看第一種
1.抓包改的方法


先用文本文件寫一下腳本,這里用的eval函數(shù)是將里面的字符串內(nèi)容當(dāng)作php代碼去執(zhí)行的函數(shù)
出來之后把文件名后綴改為jpg,用來繞過前端的檢測

找到文件,先別急著上傳,還要等著抓包的

我們找到火狐的設(shè)置,在常規(guī)那一欄的最下方網(wǎng)絡(luò)配置,改成這樣的代理配置,當(dāng)然burpsuite的配置也和這個一樣,不然抓不到

把抓包的開關(guān)打開

點擊上傳后我們可以看到請求報文,這個時候其實已經(jīng)繞過前端了,之后發(fā)過去的包就是直接給后端了,然后又是傳的文件,要想我們的shell能夠?qū)崿F(xiàn),必須要還要將文件后綴改為php 這樣才能使webshell里面的代碼執(zhí)行

修改完之后再點擊上面的intercept is on,把他變?yōu)閛ff狀態(tài)來發(fā)包

這個時候算是成功一半了,我們點擊圖片,看我們的shell被放在哪了

新建標(biāo)簽打開圖像

應(yīng)該算是成功了,傳個phpinfo();看看

成功了
2.直接禁用或者修改javascript的方法

在火狐游覽器中F12,然后點擊調(diào)試器,到右邊設(shè)置中,點擊禁用javascript
這種方法其實不是很推薦,有些靶場或者實戰(zhàn)中如果禁用了javascript的話我們的頁面將無法正常顯示了
然后步驟與1相同,就不過多贅述了,重點是下面的總計
4.注意事項以及防御思路和代碼解析提取繞過經(jīng)驗
可能我們點擊新鏈接進(jìn)入圖片時會直接在pass1這個路徑下打開,有些題目是找不到的,把前面的pass1去掉試試就行,這個題就是要去掉前面的pass1那個路徑
看看防御手段,仔細(xì)學(xué)習(xí)以下
function checkFile() {
//這一步的var是為了看客戶端有沒有上傳文件
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 + "類型的文件,當(dāng)前文件類型為:" + ext_name;alert(errMsg);
? ?return false;
? ?}
}
這里要補充幾個腳本語言方法和php里面的函數(shù)
1.document.getElementsByName
其實看名字就能看出來,就是統(tǒng)計表單中選擇了某一個name選項的數(shù)量,比如有兩個name=upload_file 選擇了,這里我們的document.getElementsByName返回的對象中就肯定有2
1.返回值有統(tǒng)計的元素個數(shù) 用下列方法查找:num = document.getElementsByName("animal").length;
2.返回值有所有name為animal的元素(也就是返回整個input標(biāo)簽中的所有屬性,可以直接調(diào)用出來看的) 用下列方法查找:elements = document.getElementsByName("fname");
接下來就可以這么查找了 elements[0].type elements[0].checked 這樣去查找了,相當(dāng)于返回了所有name=滿足要求的input 標(biāo)簽,包括里面的屬性,將它們一個一個都化為了nodelist,相當(dāng)于一個列表,或者說是結(jié)構(gòu)(c語言中的結(jié)構(gòu)類似)然后可以一個一個查找屬性值
2.file.substring與file.lastIndexOf結(jié)合使用提取文件末標(biāo)判斷是否為圖片文件
這是兩個javascript的方法
file.substring就是提取它傳值的兩個數(shù)之間的字符串,如果只有一個數(shù),則從那一位數(shù)下標(biāo)開始一直提取到最后
然后是file.lastIndexOf('')就是找到最后方法傳值內(nèi)的那個字符的下標(biāo)
結(jié)合使用就是file.substring(file.lastIndexOf(".")); 查找最后一次出現(xiàn)'.'的地方,然后從那個地方開始提取字符串一直提到最后 ? ?這不就是提取文件上傳類型嘛 很容易理解
3.整體的攻擊邏輯
因為它只是在前端寫的腳本語言,完全沒有防御我們的抓包操作,我們只需要提前將webshell寫入文本文檔,然后修改后綴上傳,就可以繞過這個前端的檢測,后端就隨便入侵了。
Pass-2
1.解題與Pass-1一樣步驟也能繞過
跟第一題是一樣的,我們這邊還是寫一句木馬<?php @eval($_GET['a']); ?>
上幾個步驟與Pass-1中是一樣的,我們還是抓個包
由于我們傳的還是jpg文件,直接繞過了,但是有幾個函數(shù)我們還是要學(xué)習(xí)以下,并且分析一下他的防御代碼
2.Pass-2的獨特用法
我們直接傳一個php的文件,這里傳php4是為了驗證下面Pass-3的問題,很煩
抓一下包
我們發(fā)現(xiàn)請求包下面限定文件傳輸?shù)母袷街惺莂pplication/octet-steam 這個字段會有什么作用呢,說人話就是會把我們的實體文件請求直接攔下來,因為它也不知道是什么 無法解析
這里我們改成image/jpeg、image/png、image/gif
這里三種組合的任意一種都能是我們的請求能夠過去
過去之后直接傳值 a=phpinfo();就行
或者蟻劍連一下也是可以的
注意事項,防御思路,補充知識
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == '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 = '文件類型不正確,請重新上傳!';}
? ? ? ? ? ?} else {$msg = UPLOAD_PATH.'文件夾不存在,請手工創(chuàng)建!';}
? ? ? ? ? ?}
1.防御與攻擊思路
現(xiàn)在看來只有當(dāng)我們的傳入文件的類型是jpeg png gif的時候才能算是進(jìn)入 那跟我們第一題是一樣的,它主要是為了檢測我們的傳入的文件的后綴是否符合他的要求,我懷疑它這個檢驗代碼還是存在于前端,不然我們的后面抓包修改后的php后綴是過不了的
1.FILE[][]方法
$_FILES["file"]["name"] - 上傳文件的名稱
$_FILES["file"]["type"] - 上傳文件的類型
$_FILES["file"]["size"] - 上傳文件的大小,以字節(jié)計
$_FILES["file"]["tmp_name"] - 存儲在服務(wù)器的文件的臨時副本的名稱
$_FILES["file"]["error"] - 由文件上傳導(dǎo)致的錯誤代碼
這些都是php中的文件函數(shù),能夠?qū)ξ覀兛蛻舳藗魅氲奈募M(jìn)行操作
2.move_uploaded_file(file,newloc) 函數(shù)
該函數(shù)用一句話概括就是將指定文件移動到新地方
有兩個變量 1.file即是我們需要移動的文件 2.newloc就是我們移動到的新位置
當(dāng)然如果移動成功,那么就會返回值true 如果出現(xiàn)任何差錯,比如說文件找不到,文件路徑出錯等等,都會返回flase
Pass-3(本人出bug關(guān),設(shè)置了之后雖然可以解析,但是解析到直接下載圖片,頁面直接顯示為blank)
1.解題步驟
F12查看后發(fā)現(xiàn)這不是前端的檢測,是后端檢測,抓包直接改后綴是沒辦法的
在我們直接傳了個12.phpshell后被告知我們不允許傳這些后綴的文件,一般這類都是shell的后綴格式,被納入了黑名單,那其實除了這些我們還有很多漏網(wǎng)之魚的shell后綴可以使用 php3 php4 php5 都是可以使用的
那這里我們選擇php5后綴的文件進(jìn)行繞過
這是我們的文本內(nèi)容,改一下后綴格式
上傳成功了,我們直接右鍵新建頁面打開這個圖片,找到圖片的所在位置
由于配置apache后,添加了php5后綴的解析后雖然能夠正常解析,但是還是存在跳轉(zhuǎn)到這個頁面直接下載這個文件,其他什么都做不了的情況,無法做出最后一步的驗證
2.防御與攻擊思路以及補充函數(shù)和方法
這是防御的代碼
1.函數(shù)與方法的補充
trim()方法
傳入的變量是一個字符串,用于刪除字符串頭尾部的空字符,然后返回這個經(jīng)過處理的字符串
dedot()方法
刪除給定字符串的末尾的點,從末尾開始,如果遇到的第一個字符不是'.' 就直接完成,如果遇到'.' 就會一直刪除'.' ,只要碰到非'.'的字符串就不會刪除了
Strrchr()函數(shù)
這居然是一個C函數(shù),有兩個參數(shù)值 (string,char)第一個是字符串,第二個是字符,作用是從這個字符串中尋找最后一次出現(xiàn)char的地方,返回值是一個字符串,即我們這個char出現(xiàn)后的所有字符串部分,包括char
str_ireplace()函數(shù)
有三個參數(shù)值(str1,str2,str3) ?該函數(shù)的意思是將str3中的所有str2字符子串全部替換為str1
1.防御與攻擊思路
我們一行代碼一行代碼的來解析,前面的is_upload msg變量申明,用于后續(xù)判斷
接下來的最開始的第一個if判斷我們是否點擊了提交,點擊了進(jìn)入下一個if判斷
第二個if判斷里面是file函數(shù),即判斷我們的文件是否上傳成功了,如果成功了就進(jìn)入if語句內(nèi)進(jìn)行一些賦值操作
下面才是重頭戲,它首先是對我們的文件名進(jìn)行清除空字符,然后刪除我們文件名后的,假如還有的點全部刪除,然后再開始找清除完多余'.'的最后一個'.',然后讀取它后面的字符串,即找我們的后綴名
最后再是根據(jù)它指定的黑名單進(jìn)行篩查
看上去邏輯是很容易的,而且確實繞過也很簡單
如果設(shè)置的黑名單不夠多的話我們是很容易可以繞過的
Pass-4
如果是自己線下做題,一個一個后綴去試試,如果大部分都不可以,就要考慮考慮.htaccess直接配置一下了
1.知識補充
.htaccess是什么呢,我們每次用小皮選定文件夾,是不是發(fā)現(xiàn)都會多出這樣兩個文件
這個就是apache的配置文件 作用如下:URL重寫、自定義錯誤頁面、MIME類型配置以及訪問權(quán)限控制等。主要體現(xiàn)在偽靜態(tài)的應(yīng)用、圖片防盜鏈、自定義404錯誤頁面、阻止/允許特定IP/IP段、目錄瀏覽與主頁、禁止訪問指定文件類型、文件密碼保護(hù)等
我們也可以直接構(gòu)造這個文件,讓它幫我們把所有我們傳的文件后綴全部識別為php
這里要做一個筆記,就是一般的話如果涉及.htaccess 文件的繞過,要寫哪些木馬
<FilesMatch "xxx"> ? ? ? ? ?SetHandler application/x-httpd-php ? </FilesMatch>
這是比較常用的一個,就是將我們指定的文件名的文件全部解析為php文件來看待 ?"xxx"里面的內(nèi)容就是我們指定的文件名了,也就是我們在植入完.htaccess文件后下一個想要傳入的webshell的名字
解題步驟
1.首先寫個.htaccess文件名的腳本,用來為我們后續(xù)的上傳繞過做準(zhǔn)備
內(nèi)容如下
然后再看我們指定的4.jpg的內(nèi)容
直接打印phpinfo();用來驗證
結(jié)果就不演示了,因為最后結(jié)果不能顯示
Pass-5
1.信息收集與分析
按照基本的文件上傳題來做,肯定是要各種方法都要試一遍,前端后端的防御。這一題也是給我們拓展了一個思路就是大小寫繞過
點開提示(這樣其實不好,但是第一次寫uploadlabs的目的就是為了去學(xué)習(xí)文件上傳漏洞,能夠盡量多的去吸收,節(jié)約時間,可以去做題網(wǎng)站上再去按部就班,這里還是一個重學(xué)習(xí)的目的)
發(fā)現(xiàn)我們的.htaccess都被禁用了,php3 php4 什么的更是不行,但是我們卻看到了大小寫的區(qū)別,突然想起Pass-3里的防御代碼,給你全部無論大小寫都強制轉(zhuǎn)換為小寫,做到這才明白為什么要這么去做。
2.解題步驟
上面的分析中已經(jīng)指明了,我們這里可以看看黑名單了缺了啥,PHP這種純大寫沒有被禁用,那我們試試純大寫,用burpsuite改一下文件名后綴就行
還是直接傳我們的phpinfo();進(jìn)去,就不設(shè)置密碼了啥的
改一下文件名,再看看其他信息,允許的內(nèi)容是image/jpeg的格式,傳jpg沒問題的,這里抓包改一下后綴為PHP
右鍵鏈接到新頁面查看我們的文件被儲存在哪了就行
這邊防御代碼也稍微分析一下
跟第3題的差不多一樣的,少個全部轉(zhuǎn)化為小寫的過程而已
Pass-6
本題也是相當(dāng)于給我們提供一種思路吧,是一種優(yōu)先級很高的思路,感覺也是一種優(yōu)先級很高的思路,就是文件后綴加空格的繞過
1.解題步驟
直接看源碼,或者直接看提示都比較快能夠看到解題思路,如果是平時去做題網(wǎng)站做題的話還是要將前面的思路全都試一遍的,然后才能確定它的繞過類型是什么
1.還是上傳直接寫phpinfo();

2.
burp抓一下包


改成php ' 空字符'繞過,放包,點擊新頁面打開看看

成功了
2.防御思路與攻擊思路

其實前面幾個題的思路都大差不差,最終的方面是防御代碼對我們文件名的處理,前面幾道題也無非就是在

這個區(qū)域內(nèi)增增刪刪,而我們現(xiàn)階段的繞過,也算是可以依據(jù)這個處理思路來
與我們Pass-4 Pass-3的防御思路差不多,最多就是窮舉所有可能會拿來繞過的文件后綴,然后前后刪空字符,強制改大小寫的之類,這就是沒有前后刪空字符的繞過
Pass-7

1.解題步驟和防御思路
第7關(guān)看上去有點哈人,所有的解析都被禁用了

源碼其實和前面差不多,然后就是找它有哪些操作是漏了的,第7關(guān)缺了個去除文件末尾'.'的操作,我們也是按照這個思路來

還是傳我們的phpyinfo();的源碼
用burp抓一下包改一下后綴

加一個'.'的繞過

也是成功繞過,防御思路和攻擊思路其實與上面幾個差不多,就是看有哪些檢測手段是缺了的
其實點的繞過也是根據(jù)windows特性來的,自動過濾了文件末尾的點,也就是我們服務(wù)器創(chuàng)建新文件的,我們的4.php.直接變成了4.php 這樣就能成功給我們的shell提供環(huán)境
Pass-8

我們這里發(fā)現(xiàn)缺了::$DATA的檢測,大小寫 收尾去空的操作都是有的
??1.知識補充
??那么我們這里要補充一點知識 就是::$DATA是什么?
??當(dāng)我們傳入文件名末尾有::$DATA的文件時,windows會自動將它檢測為數(shù)據(jù)流,并不是說直接不進(jìn)入這個if判斷里面進(jìn)行檢測了,只是我們繞過了這個判斷之后,服務(wù)器創(chuàng)建文件夾的時候,會自動省略::$DATA 然后我們傳入的.php::$DATA文件名的文件就直接變成了.php,shell環(huán)境還是創(chuàng)建成功了的
??所以要明確::$DATA是在哪一步起作用,并不是連這個if判斷都繞過了,它只是我們在繞過之后,服務(wù)器系統(tǒng)創(chuàng)建文件的時候起的作用,以及還能幫助我們繞過黑名單的窮舉
2.解題步驟
1.

直接傳我們的shell,用burp抓一下抓包
進(jìn)去后就應(yīng)該顯示phpinfo(); 我這里環(huán)境沒配好,顯示403了,就不演示了
Pass-9
1.解題思路和防御思路
我們看源碼和提示,應(yīng)該是把前面的后綴都給禁止了,但是的防御代碼的對字符串后綴的處理有少許變化,就是它先取出我們后綴中的所有點,然后再開始刪空格,而且只有一次檢測,就一次if的處理,那我們可以這樣設(shè)置文件
4.php改成 4.php. .(注意兩點之間是有一次空格的)
這樣處理過后我們的可以自己推一下,它首先將最后一個.去除了,然后遇到不是·了,開始轉(zhuǎn)大小寫,取出::$DATA字符串,最后開始取出空字符,使其變成了4.php.在文件也是可以正常做shell的
Pass-10
1.知識復(fù)習(xí)以及分析
我們首先來分析一下這道題,看看源碼和提示 它會將這些字符串從你的文件名中全部刪除,這個功能是怎么實現(xiàn)的呢?我們看這個函數(shù)
之前講過這個函數(shù)的具體作用,估計這個函數(shù)就是這道題的考點了,我們回憶一下這個函數(shù)實現(xiàn),首先從字符串的開頭開始找我們指定刪除的字符串,比如說我們要刪除'php'這個字符串,我們傳上去的字符串是'pphphp',它會先一個一個對應(yīng),如果出現(xiàn)了php這三個字符連在一起出現(xiàn)的情況,就直接刪除,我們的p’php‘hp中間的php被刪除了,首尾的php就又連起來了,又能夠組成了解析的php文件了
2.解題步驟
用4.php先預(yù)備傳入,再抓一下包
修改文件名后放包
點擊新鏈接打開圖片后驗證,成功繞過
上面10個題目都是黑名單的繞過,但是平時基本上不會給你設(shè)置黑名單窮舉,很難用的到,做做簽到題學(xué)學(xué)思路還是挺不錯的
Pass-11
1.知識點補充以及漏洞產(chǎn)生的原理
首先我們要補充一個知識點 關(guān)于%00截斷的一些補充
這其實一個系統(tǒng)函數(shù),系統(tǒng)是由匯編或者C寫成的,所以當(dāng)里面的字符串遇到\0就會把它讀成一個字符串的結(jié)束符號,后面的內(nèi)容就不會去解析了,這一步的應(yīng)用在最后我們傳入jpg文件繞過白名單檢測后創(chuàng)建文件時,文件名會變成我們想要的.php形式
我們先來分析一下源碼,看到這行代碼和我們抓包的內(nèi)容
$sava_path這個變量應(yīng)該就是我們傳入文件的存放地址了,再看看burpsuite里面抓到的包的內(nèi)容,應(yīng)該是要存到一個upload的文件夾里面,當(dāng)然還要經(jīng)過我們下面這個變量的處理方式,將他加密之后和我們處理過后的文件名連起來,才能最終成為我們文件存放地址
如果我們不做修改,文件存放的文件地址直接就是upload/???.jpg了,就沒用,還是沒有shell環(huán)境,這個時候我們可以在burp里面修改一下,做一個00截斷
2.解題步驟
修改前
修改后
這樣我們傳入的文件名就變成了4.php,即使我們傳輸?shù)臅r候?qū)λ旧淼?jpg格式?jīng)]做任何的處理,但是我們創(chuàng)立的文件卻是我們想要的名字。
本題需要php5.30以下的版本,還要把魔術(shù)標(biāo)點的功能去掉,才能在最后出現(xiàn)phpinfo();的結(jié)果,就不演示了
Pass-12
12題的防御代碼是跟11的防御代碼是一樣的,只是11的提交方式是GET方法,而12題的方法是POST方法,而我們的POST方法提交的東西是不會經(jīng)過URL的編碼的,直接看作是字符串,所以我們的%00是不會被認(rèn)為是/0的,這時候可以有如下方法進(jìn)行操作
還是傳我們的4.jpg,抓包來改一些東西
找到我們的POST方法提交的地方,還是跟我們的GET方法一樣的方式,給個文件名
這個4.php后面隨便加個什么字符都是可以的,主要是作為一個媒介給我們二進(jìn)制修改
再來到我們的HEX界面
找到對應(yīng)的+,在16進(jìn)制中表現(xiàn)為2b,我們把它改成00 之后就變成了\0,就到達(dá)了同樣的效果
還有另一種方法
選定我們在4.php后面加的%00后,右鍵打開這幾個選項就可以進(jìn)行URL的編碼了,效果也是一樣的
Pass-13
這題涉及到文件包含的漏洞利用,要結(jié)合使用,由于本人只有文件上傳的知識,所以對于文件包含的問題可能講的不是很好。
1.解題步驟
1
我們首先來看一下題目要求和提示,
它說只檢測圖標(biāo)內(nèi)容的開頭兩個字節(jié),這里我們拿GIF舉例子,我隨便在網(wǎng)上找一個GIF圖片然后用010editor打開看看gif文件的結(jié)構(gòu)
可以看到,前兩個字節(jié)是GIF8a,加半個字節(jié),不過無傷大雅,我們依然可以根據(jù)這個原理來構(gòu)造我們的木馬
2.
這里建議用記事本打開,用notepad打開好像有問題,不知道是編碼形式還是什么,notepad去編輯總是解析不出來
寫完之后上傳,但是現(xiàn)在躺在upload文件夾里面的還是我們的.gif格式的圖片,那我們怎么去拿它當(dāng)shell呢?
這里要用文件包含的漏洞,本靶場已經(jīng)幫我們上傳了一個文件包含的解析頁面,能夠幫助我們?nèi)ソ馕鑫覀兊膚ebshell,就是讀取它的php內(nèi)容,該文件如下
如何使用呢? 我們在這個頁面中通過get方式來傳值,傳入我們的剛剛寫進(jìn)的木馬的文件名
3.
復(fù)制一下,在我們的include.php界面里通過get方式傳值

成功繞過,主要是涉及到文件包含的內(nèi)容,以及一些常用文件的文件頭的內(nèi)容,涉及的知識比較多。
2.防御思路和攻擊思路
function getReailFileType($filename){
$file = fopen($filename, "rb");
$bin = fread($file, 2); //只讀2字節(jié)fclose($file);$strInfo = @unpack("C2chars", $bin); ? ?
? ?$typeCode = intval($strInfo['chars1'].$strInfo['chars2']); ? ?
? ?$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'])){
? ? ? ?$temp_file = $_FILES['upload_file']['tmp_name'];
? ? ? ?$file_type = getReailFileType($temp_file);
? ? ? ?if($file_type == 'unknown'){
? ? ? ?$msg = "文件未知,上傳失?。?#34;;
? ? ? ?}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 = "上傳出錯!";
? ? ? ? ? ? ?}
? ? ? ?}
? ? ? ?}
這里的防御代碼用的是白名單,而且要進(jìn)入我們的文件內(nèi)容去檢查我們的文件頭部分,所以想要直接傳php文件進(jìn)去還是很難的。這個時候就要想到文件包含的操作,把我們的shell環(huán)境提取出來,文件包含的意思不是我們的shell被我們的啟動頁面包含著,而是通過我們的啟動頁面去啟動我們的shell環(huán)境

真正的包含關(guān)系是在我們的URL中體現(xiàn)出來的,那么如何傳入我們的這個include.php文件呢?
,這里有一個很雞賊的方法,我們可以通過上幾個靶場來上傳這個include文件,當(dāng)然具體的方法等到文件包含漏洞時再詳細(xì)學(xué)習(xí)
Pass-14-getimagesize()
1.知識補充
本題的主要繞過點是getimagesize()函數(shù),那我懷疑就是檢測一下圖片文件的文件頭來判斷它是否是圖片文件,這個本人在雜項的學(xué)習(xí)中遇到過,可以到本人的雜項筆記中詳細(xì)了解
getimagesize()函數(shù)和我想的一樣,就是檢測文件的文件頭來判斷它是不是該文件
那么我們的繞過方法還是一樣的,在shell文件前面加繞過判斷的字符段
2.解題步驟
我們拿010edior打開看一下

之前做雜項留的png圖片,前面文件頭的前兩個字符用來判斷文件類型,我們把其他內(nèi)容全部刪除,然后直接在后面接上我們的webshell的內(nèi)容就行
上傳這個文件,再按照我們Pass13的思路用文件包含漏洞來訪問我們的這個文件,將它的php代碼解析出來。

Pass-15—exif_imagetype()
1.知識補充
exif_imagetype()函數(shù) 作用是用來檢測我們的指定文件的前面第一個字節(jié)來判斷它的文件類型
那其實呢和我們 13 14的繞過方法其實是差不多的,而且這個只檢測你文件頭的第一個字節(jié),繞過更加容易。步驟也是一樣的,用010editor打開我們的webshell

前面的png判斷的文件頭不要改,后面的webshell部分可以寫自己想寫的內(nèi)容,這里只是來驗證一下phpinfo()看繞過是否成功
當(dāng)然也要用到文件包含的漏洞
這里我們就不做演示了,步驟與13 14相同
Pass16-二重渲染
本題個人感覺難度挺高的,如果事先不知道這種渲染的規(guī)則和規(guī)律,很難做的出來
但本靶場的講解是用來學(xué)習(xí)新東西的,如果實在不知道繞過點的利用,可以先學(xué)知識再來解題
1.知識補充
二次渲染是什么?
在我們上傳文件后,網(wǎng)站會對圖片進(jìn)行二次處理(格式、尺寸要求等),服務(wù)器會把里面的內(nèi)容進(jìn)行替換更新,處理完成后,根據(jù)我們原有的圖片生成一個新的圖片并放到網(wǎng)站對應(yīng)的標(biāo)簽進(jìn)行顯示。
而我們?nèi)绾稳ダ枚武秩镜穆┒茨?
二次渲染過后我們的渲染過后的圖片和原來的圖片是有一些地方是沒有變化的,渲染過程那一部分是不會變得,那我們的利用這個漏洞的關(guān)鍵就是找到那個沒有變的地方在哪,這個時候也要去看我們的圖片的二進(jìn)制的形式才能看出哪里不同,010editor太好用了,下面是010editor比較的結(jié)果,它能比較兩個文件的二進(jìn)制形式的差異,而且能直接標(biāo)出哪些相同,哪些不同,那么我們就在這幾個相同的區(qū)域內(nèi)寫自己的木馬就行

那我們試試在這個區(qū)域內(nèi)寫webshell,還是寫phpinfo()直接來驗證
保存后將我們的這個文件上傳一下,按照上面的文件包含的順序進(jìn)行操作得到驗證,繞過成功

Pass-17(條件競爭)

直接要我們代碼審計了,那我們就看看源碼吧

整體結(jié)構(gòu)就是if語句的嵌套
1.
那我們看第一個if語句的判斷,判斷我們是否點了提交按鈕,點了就直接進(jìn)我們的if語句的內(nèi)容
2.
1號if的內(nèi)容是首先定義了一個ext_arr的列表,然后用file_name儲存我們的文件名,又用temp_file來儲存我們的臨時文件名
最后再聯(lián)合使用substr和strrpos來尋找我們的文件名的最后一個'.'的位置到我們文件結(jié)尾,就是我們的文件后綴名,file_ext這個變量存起來
upload_file用來儲存我們的文件的地址,也就是存入我們的文件的路徑
3.
進(jìn)入二號if查看,開始移動我們的文件,移動到upload_file指定的文件路徑下
然后再進(jìn)入三號if,看看我們的后綴是不是這幾個白名單的內(nèi)容,如果是的話就讓我們進(jìn)入三號if的內(nèi)容,將文件名隨機化儲存起來
4.分析漏洞
對于我們文件后綴名的繞過,是file_ext這個變量,它的處理方式是找到我們最后一個.的位置然后將后面的所有字符串作為我們的文件名后綴
好吧,我的分析思路完全錯了,這一題要利用的漏洞是條件競爭。條件競爭的一個比較明顯的標(biāo)志就是后端php對上傳的文件的處理順序不當(dāng),它是先將文件存入文件夾,然后再對其進(jìn)行判斷,看它是否符合允許上傳的條件,如果符合就還是不動它,不符合才把它刪除。在我們上傳入文件到后端進(jìn)行文件檢測這一段時間內(nèi),是可以進(jìn)行重復(fù)發(fā)包然后截獲的,這個瞬間的時間就導(dǎo)致我們的webshell被寫入后臺文件了,但是還沒有進(jìn)行判定它是否符合我們允許傳輸?shù)臈l件,如果我們在這個時候,訪問了這個尚未被處理的文件,那我們就可以執(zhí)行我們上傳的webshell從而達(dá)到目的
那么具體操作是什么呢?
首先我們先抓一個上傳我們shell的請求,下面是我上傳的5.phpshell的內(nèi)容


右鍵點擊將他送入我們的intruder頁面
payload的位置清除

然后這樣設(shè)置
然后再截斷一個我們訪問upload/shell.php(我上傳shell的php執(zhí)行代碼的一個結(jié)果,就是寫一個shell.php的shell)
設(shè)置還是一樣設(shè)置,先開我們的shell請求的攻擊
然后再開我們的上傳shell的攻擊,如果在我們的本地文件夾下看見了我們的shell.php文件就說明成功
Pass-18
源碼很長
<?php
include '../config.php';
include '../head.php';
include '../menu.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ù)制到目標(biāo)目錄。';
? ? ? ? ? ?break; ? ? ?
? ? ? ?default:
? ? ? ? ? ?$msg = '未知錯誤!';
? ? ? ? ? ?break;
? ?}
}
?>
<div id="upload_panel">
? ?<ol>
? ? ? ?<li>
? ? ? ? ? ?<h3>任務(wù)</h3>
? ? ? ? ? ?<p>上傳一個<code>webshell</code>到服務(wù)器。</p>
? ? ? ?</li>
? ? ? ?<li>
? ? ? ? ? ?<h3>上傳區(qū)</h3>
? ? ? ? ? ?<form enctype="multipart/form-data" method="post">
? ? ? ? ? ? ? ?<p>請選擇要上傳的圖片:<p>
? ? ? ? ? ? ? ?<input class="input_file" type="file" name="upload_file"/>
? ? ? ? ? ? ? ?<input class="button" type="submit" name="submit" value="上傳"/>
? ? ? ? ? ?</form>
? ? ? ? ? ?<div id="msg">
? ? ? ? ? ? ? ?<?php
? ? ? ? ? ? ? ? ? ?if($msg != null){
? ? ? ? ? ? ? ? ? ? ? ?echo "提示:".$msg;
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ??>
? ? ? ? ? ?</div>
? ? ? ? ? ?<div id="img">
? ? ? ? ? ? ? ?<?php
? ? ? ? ? ? ? ? ? ?if($is_upload){
? ? ? ? ? ? ? ? ? ? ? ?echo '<img src="'.$img_path.'" width="250px" />';
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ??>
? ? ? ? ? ?</div>
? ? ? ?</li>
? ? ? ?<?php
? ? ? ? ? ?if($_GET['action'] == "show_code"){
? ? ? ? ? ? ? ?include 'show_code.php';
? ? ? ? ? ?}
? ? ? ??>
? ?</ol>
</div>
<?php
include '../footer.php';
?>
Pass-19
$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)建!';}
? ? ?}
1.知識補充
pathinfo()函數(shù)
pathinfo()函數(shù)的返回值是一個數(shù)組,這個數(shù)組包含的信息是這個文件的路徑的一些基本信息
他有兩個參數(shù) pathinfo(path(檢查的路徑),process_sections(想要返回的信息))
1.path就是我們傳入的文件這個路徑
2.process_sections就是我們的文件的路徑信息的一個細(xì)分,用來控制我們想要返回的路徑信息
PATHINFO_DIRNAME - 只返回 dirname(我們文件的目錄)
PATHINFO_DIRNAME - 只返回 basename(文件名稱)
PATHINFO_EXTENSION - 只返回 extension(文件的后綴名)
2.解題思路
1.找到繞過點
那我們這個題目的防御代碼中的使用是這樣的pathinfo($file_name,PATHINFO_EXTENSION)
就表示他返回我們文件路徑的最后一個,文件的后綴名,也就是檢測我們的后綴名
拿到我們的后綴名之后就開始黑名單檢測
經(jīng)過檢測之后就會寫入我們的upload文件夾中
那我們的繞過就是要繞過這個文件后綴名的條件
再想想我們的文件名的寫入是我們直接上傳的文件的文件后綴,還是我們本題savename里面的文件后綴名?
看題之后發(fā)現(xiàn)是我們savename自己提交的一個文件后綴名
2.繞過具體操作
我們可以直接傳入.php文件了,因為他檢測是我們的savename,也就是我們自己定義的那個文件名
可以按照如下操作來
上傳的文件的后綴名其實無所謂
我們看保存名稱
a.phpa.jpg jpg是為了繞過檢測,而php后面的a是為了我們能夠再burpsuite里面方便我們二進(jìn)制形式改為%00從而繞過(post提交,所以要二進(jìn)制改)
這樣去修改,再發(fā)包出去,進(jìn)入我們的webshell的頁面就能看到了繞過成功了
Pass-20
本題感覺網(wǎng)上的講解都過于形式化,沒有理解其本質(zhì),就是來一句數(shù)組繞過就完事了,很沒意思
(在給了你代碼的前提下)看懂代碼,才能知道哪里有漏洞 本題的漏洞就是三個if語句里面的判斷條件造成的
1.源碼分析 找繞過點
分為兩個部分,A部分:用來判斷我們的文件MIME的類型,抓包改一下type就行
然后A部分的else用來判斷我們的自己上傳的save_name是否為空,如果為空就直接那我們的文件的名字作為filename,如果不為空還是按我們自己上傳的savename來命名
然后再把我們的這個file改為數(shù)組的形式,好檢驗
B部分:首先將我們的后綴名提取出來儲存到我們的ext變量中
再將我們的ext與我們的白名單進(jìn)行比較,如果通過就讓我們進(jìn)行儲存操作
后面的就不用看了,就沒有進(jìn)行判斷操作了
2.根據(jù)繞過點一個一個繞過
下面我們將根據(jù)我們的請求包來一個一個繞過
1.首先是我們的第一個繞過點,我們的第一個if語句的繞過
這個很簡單,我們直接在抓包操作中關(guān)于我們的upload_file那一欄的content-type實體字段修改為題目源碼允許的類型就行
2.第二if語句的繞過
它首先做了個判斷,判斷我們的save_name有沒有值提交,如果有,那么我們的$file變量就賦值為save_name
沒有就用我們的提交的文件的文件名
很明顯,自己提交一個顯然更容易控制來繞過,但是這里要注意一個細(xì)節(jié)

它會判斷我們的file是否為數(shù)組,這里的轉(zhuǎn)file為數(shù)組極為重要,而且直接關(guān)系到本題的解答,如果能理解這一步就很好做了。為此我們先不急,來看下面的判斷操作
這是我們源碼里面唯二判斷我們能不能正常上傳的操作了,也是最后一個,繞過它就很好做了
它的判斷條件是判斷我們的ext變量是不是這個allowsuffix列組里面的值,而ext是由我們的file來決定的,而我們的file是一個數(shù)組,而且它是我們flie數(shù)組的最后一個元素
那我們直接先來解決這個
直接復(fù)制一個關(guān)于save_name的實體部分,然后將我們的save_name數(shù)組(為什么是save_name?在我們賦值file變量的時候進(jìn)行了一個操作,可以往回看看)的最后一個元素隨便指定一個符合條件的元素就行,這一步我們也成功繞過
那么,第三個繞過,也很容易了
第三個繞過是關(guān)系到我們shell文件存到文件夾里面命名的問題了
他將我們file數(shù)組變量的第一個變量作為了我們的文件名
那我們直接將第一個變量設(shè)置為我們想要的文件名即可,但是要注意注釋掉后面的內(nèi)容
就是這一部分要注釋掉,所以
這樣子命名即可
至此,三層繞過已全部完畢,直接發(fā)包等待結(jié)果,順便附上請求包的所有內(nèi)容便于查看
然后就報錯了,好吧。。。。php版本必須低于5.3才能用那個注釋,我這個環(huán)境是7開頭的,所以不行,答案出不來