PHP中MD5常見繞過

函數:

md5($string,bool): 得到一個字符串散列值。

其中第二個參數默認爲false,表示該函數返回值是32個字符的十六進制數。

若指定爲true,則表示函數返回的是16字節的二進制格式(這樣通過瀏覽器解析會出現亂碼)。

md5($password,true)的SQL注入問題

這裏需要注意一下MYSQL中的一些數值比較的特徵。

1.當數字和字符串比較時,若字符串的數字部分(需要從頭開始)和數字是相同的,那麼則返回的是true。

select if(1="1a","相等","不相等") as test

if(exp1,stat1,stat2):類似於高級語言中三元運算符。當exp1爲true的是否返回stat1,爲false返回stat2
在這裏插入圖片描述

2.以數字開頭的字符串,若開頭的字符不是0,那麼在做邏輯運算的時候返回的是1,也就是true。

比如以下語句就是一個萬能密碼的例子:

select * from user where password =''or'1234a';

解釋一下:'1234a’會被當做true對待。而任何數和true做邏輯或運算返回的值都是true.
在這裏插入圖片描述

看這個md5($password,true)的漏洞

select * from usera where username = 'admin' and password = md5($pass,true)

若我們可找到字符串,在對該字符串進行md5後能夠得到 'or’加上一個非0的字符就可以繞過。這裏我們可以用到的字符串爲:ffifdyop。它的md5結果是:276f722736c95d99e921722cf9ed621c 。通過這個結果我們可以發現得到16字節的二進制被解析爲字符的結果是:'or’6後面接亂碼 (27是單引號的16進制編碼,67是字母o的16進制…)這樣後構造的sql語句就位

select * from user where password=' 'or'6xxx'

和上面分析的萬能密碼是一致的。

兩變量值不相等,md5計算散列值後相等的繞過

  • ==的繞過

PHP中==是判斷值是否相等,若兩個變量的類型不相等,則會轉化爲相同類型後再進行比較。PHP在處理哈希字符串的時候,它把每一個以0e開頭的哈希值都解析爲0。常見的如下:

在md5加密後以0E開頭

  • QNKCDZO
  • 240610708
  • s878926199a
  • s155964671a

一下值在sha1加密後以0E開頭

  • aaroZmOk
  • aaK1STfY

payload: /?a=QNKCDZO&b=240610708

<?php
    if($_GET['a'] !== $_GET['b']){
        if(md5($_GET['a']) == md5($_GET['b'])){
            echo "flag";
        }
    }
?>
  • ===的繞過

===會比較類型,這個時候可以用到PHP中md5()函數無法處理數組(會返回NULL)來實現繞過。

payload: /?a[]=1&b[]=2 (上面==的例子也可以用數組繞過)

<?php
    if($_GET['a'] !== $_GET['b']){
        if(md5($_GET['a']) === md5($_GET['b'])){
            echo "flag";
        }
    }
?>

MD5碰撞

可以谷歌查找一下MD5值相同的不同字符串。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章