1. 程式人生 > >【CTF】PHP漏洞(學習積累中)

【CTF】PHP漏洞(學習積累中)

1. strcmp字串比較

strcmp() 函式比較兩個字串,且對大小寫敏感

語法:strcmp(string1,string2);

strcmp函式比較字串的本質是將兩個變數轉換為ascii,然後進行減法運算,然後根據運算結果來決定返回值。

  • 0 - 如果兩個字串相等

  • <0 - 如果 string1 小於 string2

  • >0 - 如果 string1 大於 string2

define('FLAG', 'flag{1}');
if (isset($_GET['flag'])) {
    if (strcmp($_GET['flag'], FLAG) == 0) {
        echo
"success, flag:" . FLAG; } }

如果一個數值和字串進行比較的時候,會將字串轉換成數值,strcmp就會比較出錯,返回NULL,NULL==0成立,得到flag

GET傳入flag[]=1就能繞過了

2. md5碰撞

define('FLAG', 'flag{2}');
if (isset($_GET['a']) and isset($_GET['b'])) {
    if ($_GET['a'] != $_GET['b']
    && md5($_GET['a']) == md5($_GET['b'])) {
    echo
"success, flag:" . FLAG; } }

如果a的值不等於b的值,並且a的md5值要等於b的md5值,PHP在處理雜湊字串時,它把每一個以“0E”開頭的雜湊值都解釋為0,所以如果兩個不同的密碼經過雜湊以後,其雜湊值都是以“0E”開頭的,那麼PHP將會認為他們相同,都是0。

md5('QNKCDZO') ==
'0e830400451993494058024219903391'
md5('240610708') ==
'0e462097431906509019562988736854'

以下值在md5加密後以0E開頭

  • QNKCDZO

  • 240610708

  • s878926199a

  • s155964671a

  • s214587387a

  • s214587387a

以下值在sha1加密後以0E開頭,sha1(str)

  • sha1(‘aaroZmOk’)

  • sha1(‘aaK1STfY’)

  • sha1(‘aaO8zKZF’)

  • sha1(‘aa3OFF9m’)

GET傳入a=QNKCDZO&b=240610708就能繞過了

3. md5函式特性

define('FLAG', 'flag{2}');
if (isset($_GET['a']) and isset($_GET['b'])) {
    if ($_GET['a'] !== $_GET['b']
    && md5($_GET['a']) === md5($_GET['b'])) {
    echo "success, flag:" . FLAG;
    }
}

在php中===為完全等於運算,不僅比較值,而且還比較值的型別,只有兩者一致才為真。再次使用a=QNKCDZO&b=240610708就不行了,因為a和b型別不同。

PHP中md5的函式特性

md5([1,2,3]) == md5([4,5,6]) == NULL

[1] !== [2] && md5([1]) === md5([2])

所以GET傳入a[]=1&b[]=2就能夠繞過了

4. json繞過

define('key', 'flag{4}');
if (isset($_POST['a'])) {
    $a = json_decode($_POST['a']);
    if ($a->key == $key) {
        echo "flag" . key;
    } else {
        echo "不相等";
    }
 } else{
     echo "a不存在";
 }

輸入一個json型別的字串,json_decode函式解密成一個數組,判斷陣列中key的值是否等於keykey的值我們不知道,但是可以利用0==”string”這種形式繞過。

所以POST傳入a={“key”:0}就能夠繞過了。

如果以後再學習到了就寫上來