1. 程式人生 > 其它 >【CTFshow】Web入門-php特性(89-101) wp

【CTFshow】Web入門-php特性(89-101) wp

前言

感覺瞭解php特性是基礎,所以決定先做這部分。

Web89(preg_match和intval)

兩步,繞過正則,intval不為0。採取傳入陣列的方式繞過:

preg_match()只能處理字串,如果處理陣列會返回false;intval如果傳入陣列,會返回1。payload:

?num[]=1

Web90(intval)

intval處理開頭是數字的字串時,返回值為開頭的數,這個大家都比較熟悉了。payload:

?num=4476a

Web91(正則匹配多行模式)

本題中的正則:^表示表示式開頭,$表示表示式結尾,i表示不區分大小寫,m表示多行模式,這個多行模式具體是什麼意思呢,看一下下面的結果:

上面兩幅圖中,左邊的輸出結果是no,右邊的輸出結果是success。所以多行模式的意思是每一行都進行正則匹配。右側圖中,第一行末尾為php,所以返回了true;左側沒開啟多行,雖然有\n但也只有一行。所以本題的第一個正則是要求分行後至少有一行是字串"php",第二個正則只能匹配字串"php",所以傳一個:

?cmd=php%0aphp //或aaa%0aphp,php%0abbb都可

這裡還要說一下,URL的換行符是%0a,\n不起換行作用,因為URL編碼中斜槓並不是轉義字元,\n只是普通的字串而已。

Web92(intval)

第一個判斷變成弱型別比較,所以不能用4476a繞過。重點是intval的第二個引數base,base=0時,intval會自動探測num的進位制:

如果num以0x開頭,那麼按16進位制轉換;如果num以0開頭,預設按8進位制轉換;否則使用10進位制。

所以這個題用16進位制繞過即可,payload:

?num=0x117c

第一個弱型別會把0x117c轉成0,繞過比較,第二個會進行進位制轉換,判斷通過。

Web93(intval)

和上一題相比,這道題加了個正則匹配,不能出現字母,使用8進位制繞過即可。在進行弱型別比較的時候,'010574'==10574。

Web94(intval)

時刻要注意num是個字串,只要在4476後面用字元截斷,即可繞過弱型別比較。關鍵是多了個strpos,這個函式的位置很巧妙,它要求num中必須有0,但還不能在開頭,所以傳入一個浮點數:

?num=4476.0

強型別比較通過,正則通過,含0且不在頭部,intval轉換後是4476,拿到flag。

Web95(intval)

多過濾了一個點,可以用8進位制前面加個+繞過。在反序列化繞過正則時也有相似應用。intval接收'+4476'還是會轉為4476。

關於intval的常見輸出

Web96(按路徑讀取檔案)

想辦法讀取flag.php,但還不能直接傳flag.php,這裡我們利用路徑問題來讀,傳入payload:

?u=./flag.php

利用路徑繞過比較。

Web97(md5函式漏洞)

md5函式是不能處理陣列的,處理陣列會返回null,所以傳兩個陣列進去,null===null,成功繞過。

Web98(審計,傳參,取址運算子)

什麼卵程式碼,搜一下。

php中取值運算子"&"表示引用,比如\$b=&\$a表示變數b是變數a的一個引用,相當於同一個變數兩個名字,一個變化另一個也跟著變化。通常的賦值語句\$b=\$a相當於copy了一個a的副本給b,b變化a不變化。取址就相當於把根刨了。

第一句:如果傳入get引數,則get引數變成post的引數。

第二句:如果get的flag引數等於字串"flag",那麼get的引數變成cookie的引數。

第三句:如果get的flag引數等於字串"flag",那麼get的引數變成server的引數。

第四句:如果get傳入HTTP_FLAG引數的值是字串"flag",那麼高亮顯示\$flag變數對應的檔案,否則就是當前檔案。

分析完之後發現很簡單,只要get一個HTTP_FLAG變數就好了,但是get會變成post啊,所以保證post一個HTTP_FLAG=flag。至於get就隨便get一個,不能不get,不get不能觸發第一條語句的。

Web99(審計,in_array)

先了解一下這些個函式:

  • array():建立一個數組
  • array_push():將一個或多個元素插入陣列末尾(入棧)
  • in_array():檢查陣列中是否存在指定元素,第三個引數strict不指定預設為寬鬆比較
  • file_put_contents():將資料寫入檔案中,相當於fopen()+fwrite()+fclose()

這裡就要用到in_array的漏洞了,如果我們傳遞n=1.php,那麼根據寬鬆比較'1.php'==1,是可以繞過的。get一個n=1.php,向其中寫入一句話木馬<?php @eval($_POST[1]);?>,蟻劍連線即可。

php中關於array的函式可以參考:https://www.w3school.com.cn/php/php_ref_array.asp

Web100(邏輯運算子優先順序)

又添新知識了,最開始我一直以為考點在繞過is_numeric,後來發現自己錯了,考點在這裡:

邏輯運算子的優先順序:"&&" > "||" > "=" > "and",等號的優先順序高於and,所以v0只跟v1有關係,v2和v3是干擾。

然後就是怎麼構造eval內部的語句,我們不能直接輸出字串,應該輸出$ctfshow的值,所以利用v2和v3的位置把給的這個括號註釋掉,payload:

?v1=1&v2=var_dump($ctfshow)/*&v3=*/;

Web101(反射API)

什麼東西一大片,不會。求助hint和wp,得知php有個反射類(我對面向物件不是很熟悉)。

反射,通俗來講就是可以通過一個物件來獲取所屬類的具體內容,php中內建了強大的反射API:

  • ReflectionClass:一個反射類,功能十分強大,內建了各種獲取類資訊的方法,建立方式為new ReflectionClass(str 類名),可以用echo new ReflectionClass('className')列印類的資訊。
  • ReflectionObject:另一個反射類,建立方式為new ReflectionObject(物件名)。

本題中繼續傳入v1=1,v2=echo ReflectionClass來獲取類的資訊,v3=;閉合語句。