繼續上一篇securityoverridehacking challenge 解題思路彙總的工作,這次把Advanced給弄完了。這當中主要涉及到了關於php的一些攻擊方法,可以以此爲基礎做一個深入的瞭解。
3 Advanced
3.1 PHP Sucks
利用PHP中==的跨類型比較而產生的漏洞。最終目的是要$input=="0000". 這個好辦,php中,任何數字型字符串最終都會轉化爲數字去做比較,所以input可以是任意個0。不過Filter最後加了個正則判斷preg_match
(
"/^[\d]{1,}$/D"
,
$input
)
。意思就是不能爲純數字。也比較簡單,利用0的特性嘛(小學知識:0等於0的負數),於是輸入-0就好了。
PS: 關於php的弱類判斷法則 http://php.net/manual/en/types.comparisons.php
3.2 Obfuscated PHP:
考察能否在混淆的前提下整理出代碼邏輯。這題沒有什麼快捷方法,手動清理。清除註釋和分號後代碼量其實不多,然後把一些該解碼的解碼,函數該返回的直接替換,就能把代碼邏輯理清楚了。整理完畢後代碼邏輯如下:
<?php
session_start();
$_u=array();
$_u[0]='SERVER_ADDQUERY_STRINGREQUEST_METHODHTTP_ACCEPT'; //一個字符串
$_u[1]='substr'; // substr函數
$_u[2]='base64_decode'; // decode方法
$_§§§§§§§ =preg_split('/(?!\\##\$\$\$uu)=/',_SERVER['QUERY_STRING']); // 可以簡單理解爲按=分割
${"_g_1"} = urldecode($_§§§§§§§[0]); // key
${"_g_2"} = _GET[${"_g_1"}]; // value
if(LEVENSHTEIN(${"_g_1"},${"_g_2"})==0){// 參數的key和value必須一樣
validate_result(${"_g_2"});
};
function validate_result($result){ // value = phpinfo(); 則成功(必須要分號)
if($result === 'phpinfo();'){
$_SESSION["solved_advanced_2"] = true;
header("Location:./");
}
}
echo "Good luck. <a href='./'>Back to thechallenges main page.</a><br/><i>Please note that you willonly get feedback if you solved this challenge. Wrong attempts do not generateany output at all.</i><hr/>";
highlight_file('code.php');
?>
之後就很簡單了,構造一個符合要求的url即可。
3.3 Upload bypass
要求你bypass過濾程序,上傳一個php腳本。常規思路:1 直接上傳.php文件(失敗)。2 上傳.php文件,但是修改post內容中的contentType爲image/jpg(失敗)。3 上傳正常jpg文件,隱藏php腳本(Linux:cat test.php>>image.jpg, Windows:copy /b image.jpg + test.php image.jpg, 或者使用工具來添加註釋),儘量保證圖片簡單或純色,以免某些圖片字符干擾php解析)。通過第三步,這個問題就解決了。
接下來還研究了一下怎麼執行jpg中的php腳本這個問題,在查閱資料以及自己試驗後,基本只有這兩種方法比較可行:
- 在另一個php文件中includeu或者require這個jpg文件
<?php
include('images/' . $_GET['test.jpg']);
require('images/' . $_GET['test.jpg']);
include('images/' . $_POST['test.jpg']);
include('images/' . $_POST['test.jpg']);
include('test.jpg');
require('test.jpg');
?>
- 在/etc/apache2/mods-available/php5.conf中設置jpg格式的解釋器爲php
<FilesMatch ".jpeg">
SetHandler application/x-httpd-php
</FilesMatch>
修改.htaccess原理一樣(簡單嘗試了一下,沒有成功)
既然題目中已經提到了存在local file inclusiong這個漏洞的存在,那麼想利用第一種方法執行php腳本就很簡單了,大致是利用注入的方法去控制include或者require中的變量,使得腳本執行。
3.4 Local File Inclusion/WAF Bypass
好吧,3.3的研究起到作用了,3.4就是要求執行已上傳的文件(文件路徑在3.3上傳成功的時候已給出,我的是/challenges/advanced/uploads/Ac3sk9j.jpg,不知道是不是大家都一樣)。3.3中已經提到了,php中如果有include或者require等函數,就可以被用來執行jpg中的php代碼。進入3.4,觀察後發現url帶有參數page,嘗試隨意修改,果然給出了錯誤提示:test.phpcannot be found。那麼目標就很明確了,修改page參數,將路徑指定到jpg文件。利用路徑中,..代表上一級文件夾,很容易寫出相對路徑來../uploads/Ac3sk9j.jpg。嘗試請求,結果爲:uploads/Ac3sk9j.jpg.phpcannot be found。有兩點不如人意:1)../給過濾掉了;2)文件名爲Ac3sk9j.jpg.php而不是Ac3sk9j.jpg。於是分別尋找解決方法:
- 對於某種特定字符串被過濾的情況,最簡單的就是string replace了。對應的破解方法很簡單,拼湊類似aabb的字符串就好了。中間的ab在被過濾後,就會生成新的ab了。這裏寫成….//就可以了。所以stringreplace的過濾方法和沒有是一樣的。
- php後綴問題。顯然網站對任何請求路徑都加了.php後綴。Google了一下繞過策略,主要有兩種:1)利用文件路徑最大長度4096bytes,然後通過添加任意個/.來構造超長的文件路徑。但是這麼長的url,直接會被服務器攔截返回414;2)利用C中字符串終止符,在.php之前加入終止符,表示截斷。比較普遍都是拿%00舉例,不過嘗試了一下沒成功。後來在某個示例中查到了\0,就成功了。
這道題到這裏也就成功了。在查找資料的過程中,對LocalFile Inclusion的漏洞又學到了一點新東西。在如何寫入某個帶腳本的文件上,除了直接的上傳文件外,也可以利用服務器將用戶信息輸入到文件的過程,寫入某個腳本。例如,服務器可能會記錄訪問請求的UserAgent(/proc/self/environ),url(access.log),或者登錄的用戶名密碼等到一個log文件中,而這些信息都是可以被攻擊者控制的(UserAgent和url似乎默認都是會被Apache服務器記錄的,路徑已經寫出,當然,根據配置不同,路徑可能變化)。所以這種情況下,只需要修改對應的值,向服務器發起請求,php腳本就已經被寫入到服務器某個文件中了,接下來就只需要執行就好了。