PHP中MD5和sha1繞過方式總結


### 1.0e繞過弱比較(MD5函數漏洞)

<?php
if ($_GET['name'] != $_GET['password'] &&
MD5($_GET['name']) == MD5($_GET['password'])){
    echo "flag";
}

PHP在處理哈希字符串時,它把每一個以“0E”開頭的哈希值都解釋為0,所以如果兩個不同的密碼經過哈希以后,其哈希值都是以“0E”開頭的,PHP會當作科學計數法來處理,也就是0的n次方,得到的值比較的時候都相同。

這種方式只有在弱比較的時候才能使用。

以下值在md5加密后以0E開頭:

  • QNKCDZO
  • 240610708
  • s878926199a
  • s155964671a
  • s214587387a
  • s214587387a

以下值在sha1加密后以0E開頭:

  • aaroZmOk
  • aaK1STfY
  • aaO8zKZF
  • aa3OFF9m
  • 0e1290633704
  • 10932435112

雙重MD5加密后0E開頭:

  • 7r4lGXCH2Ksu2JNT3BYM
  • CbDLytmyGm2xQyaLNhWn
  • 770hQgrBOjrcqftrlaZk

還有的時候會限制字符串為純數字或字母,這些特殊條件的字符串可以自行搜索。

image-20220327104619368

2.數組繞過

對於php強比較和弱比較:md5(),sha1()函數無法處理數組,如果傳入的為數組,會返回NULL,所以兩個數組經過加密后得到的都是NULL,也就是相等的。

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

GET情況下的payload(POST同理):

?a[]=1&b[]=2

image-20220327103431855

3.MD5碰撞

MD5

<?php
show_source(__FILE__);
if((string)$_POST['a']!==(string)$_POST['b'] && 
  md5($_POST['a'])===md5($_POST['b'])){
    echo "flag";
}

比較a,b時將a,b轉換為字符串比較,這邊就不能用數組了。因為數組轉換為字符串時都會變成Array。

image-20220327110714685

因為數組要求構造a和b不同,但是MD5相同,也就是說要求傳入兩個MD5相同的不同字符串。所以我們只能用MD5碰撞來實現

#1
a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2   
b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2   
#2
a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2   
b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%
#3
$a="\x4d\xc9\x68\xff\x0e\xe3\x5c\x20\x95\x72\xd4\x77\x7b\x72\x15\x87\xd3\x6f\xa7\xb2\x1b\xdc\x56\xb7\x4a\x3d\xc0\x78\x3e\x7b\x95\x18\xaf\xbf\xa2\x00\xa8\x28\x4b\xf3\x6e\x8e\x4b\x55\xb3\x5f\x42\x75\x93\xd8\x49\x67\x6d\xa0\xd1\x55\x5d\x83\x60\xfb\x5f\x07\xfe\xa2";
$b="\x4d\xc9\x68\xff\x0e\xe3\x5c\x20\x95\x72\xd4\x77\x7b\x72\x15\x87\xd3\x6f\xa7\xb2\x1b\xdc\x56\xb7\x4a\x3d\xc0\x78\x3e\x7b\x95\x18\xaf\xbf\xa2\x02\xa8\x28\x4b\xf3\x6e\x8e\x4b\x55\xb3\x5f\x42\x75\x93\xd8\x49\x67\x6d\xa0\xd1\xd5\x5d\x83\x60\xfb\x5f\x07\xfe\xa2";

注意一點,post時一定要urlencode!!!

文件:

linux使用md5collgen碰撞生成兩個md5值相同但內容不同的文件

md5collgen -o 1.bin 2.bin

windows可以下載fastcoll,碰撞生成兩個md5值相同但內容不同的文件

fastcoll.exe -p 123.txt -o 1.txt 2.txt

sha1碰撞:

url:
a=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1
b=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

兩個SHA1值相同而不一樣(SHA256的值不同)的pdf文件, shattered-1.pdfshattered-2.pdf

4.$a==md5($a)

0e215962017 的 MD5 值也是由 0e 開頭,在 PHP 弱類型比較中相等

5.NaN 和 INF

NAN和INF,分別為非數字和無窮大,但是var_dump一下它們的數據類型卻是double,那么在md5函數處理它們的時候,是將其直接轉換為字符串”NAN”和字符串”INF”使用的,但是它們擁有特殊的性質,它們與任何數據類型(除了true)做強類型或弱類型比較均為false,甚至NAN=NAN都是false,但md5('NaN')=md5('NaN')為true。

6.截斷比較

substr(md5(?),0,5)==='8ffb1'

MD5截斷爆破

給出一段md5值要求找到匹配的原碼。一般使用爆破腳本:

import hashlib
from multiprocessing.dummy import Pool as ThreadPool

# MD5截斷數值已知 求原始數據
# 例子 substr(md5(captcha), 0, 6)=60b7ef

def md5(s):  # 計算MD5字符串
    return hashlib.md5(str(s).encode('utf-8')).hexdigest()


keymd5 = '8ffb1'   #已知的md5截斷值
md5start = 0   # 設置題目已知的截斷位置
md5length = 5

def findmd5(sss):    # 輸入范圍 里面會進行md5測試
    key = sss.split(':')
    start = int(key[0])   # 開始位置
    end = int(key[1])    # 結束位置
    result = 0
    for i in range(start, end):
        # print(md5(i)[md5start:md5length])
        if md5(i)[0:5] == keymd5:            # 拿到加密字符串
            result = i
            print(result)    # 打印
            break


list=[]  # 參數列表
for i in range(10):   # 多線程的數字列表 開始與結尾
    list.append(str(10000000*i) + ':' + str(10000000*(i+1)))
pool = ThreadPool()    # 多線程任務
pool.map(findmd5, list) # 函數 與參數列表
pool.close()
pool.join()

sha256截斷爆破

腳本:

import hashlib
from multiprocessing.dummy import Pool as ThreadPool

# sha256截斷數值已知 求原始數據
# 例子 substr(sha256(captcha), 0, 6)=60b7ef

def sha256(s):  # 計算sha256字符串
    return hashlib.sha256(('TQLCTF'+str(s)).encode('utf-8')).hexdigest()


keysha256 = '5625f'   #已知的sha256截斷值
sha256start = 0   # 設置題目已知的截斷位置
sha256length = 5

def findsha256(sss):    # 輸入范圍 里面會進行sha256測試
    key = sss.split(':')
    start = int(key[0])   # 開始位置
    end = int(key[1])    # 結束位置
    result = 0
    for i in range(start, end):
        # print(sha256(i)[sha256start:sha256length])
        if sha256(i)[0:5] == keysha256:            # 拿到加密字符串
            result = i
            print(result)    # 打印
            break


list=[]  # 參數列表
for i in range(10):   # 多線程的數字列表 開始與結尾
    list.append(str(10000000*i) + ':' + str(10000000*(i+1)))
pool = ThreadPool()    # 多線程任務
pool.map(findsha256, list) # 函數 與參數列表
pool.close()
pool.join()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM