php中的md5()的安全問題


  匯總下php中md5()的安全問題

  安全問題1:

  1.x=任意字符串  md5('x')=0e***  

  2.y=任意字符串  md5('y')=0e***

  如果x==y,php會返回true,在有些時候可以繞過邏輯判斷

  x==0 /y==0都為true,有些時候可以用來繞過邏輯判斷

  原理:php使用==會把兩邊的數值進行類型轉換,0e***都轉換成了0

  例子var_dump(md5('240610708') == md5('QNKCDZO'));  返回true

  修復方案,進行類型匹配使用強等於(===)進行判斷

  安全問題2:

    md5 ( string $str [, bool $raw_output = FALSE ] ) : string

  如果設置第二個參數為true,那么 MD5 報文摘要將以16字節長度的原始二進制格式返回。

  就是說返回16個字節

  漏洞測試demo:

  md5_login.html

  

<html>  

<head>用戶登錄</head>  

<form name="LoginForm" method="post" action="md5_loop.php" onSubmit="return InputCheck(this)">  

<p>  

<label for="username" class="label">用戶名:</label>  

<input id="username" name="username" type="text" class="input" />  

<p/>  

<p>  

<label for="password" class="label">密 碼:</label>  

<input id="password" name="password" type="password" class="input" />  

<p/>  

<p>  

<input type="submit" name="submit" value="  確 定  " class="left" />  

</p>  

</form>  

</html>

 

md5_loop.php

  

<?php
$username=$_POST['username'];
$password=$_POST['password'];
error_reporting(0);
$link = mysql_connect('localhost', 'root', 'root');
if (!$link) { 
  die('Could not connect to MySQL: ' . mysql_error()); 
} 
// 選擇數據庫
$db = mysql_select_db("test", $link);
if(!$db)
{
  echo 'select db error';
  exit();
}
// 執行sql
//$password = "admin";
$sql = "SELECT * FROM login WHERE username='$username' and password = '".md5($password,true)."'";
var_dump($sql);
$check_query=mysql_query($sql) or die('<pre>' . mysql_error() . '</pre>' );
if($result = mysql_fetch_array($check_query)){  

  echo "login true";

} else {  

    exit('登錄失敗!點擊此處 <a href="javascript:history.back(-1);">返回</a> 重試');  

}  
//$row1 = mysql_fetch_row($result);
//var_dump($row1);
mysql_close($link);
?>

  當用戶輸入任意賬號和密碼ffifdyop

  就可以登錄系統:

  

 

任意登錄原理講解:

  首先是sql語句:

  SELECT * FROM login WHERE username='hello' and password=''

  如果password萬能密碼是SELECT * FROM login WHERE username='hello' and password='' or '1'--+

  他會提示登錄成功,如果是' or '1aaa會進行類型轉換,轉換成int類型的1,or '1aaa相當於1,那么' or 'a1就相當於0

  0相當於false

  

 

 

 

 

  因為設置md5設置第二個參數是true,那么會自動截取前16個字節的數據

  就是:md5('ffifdyop')= 276f722736c95d99e921722cf9ed621c

  獲取十六個字節=276f722736c95d99

  十六個字節轉換成字符串就是%27%6f%72%27%36%c9%5d%99

  解碼

  

 

再次帶入數據庫查詢就是:   

   SELECT * FROM login WHERE username='hello' and password = ''or'6蒥欓!r,b'

   mysql中,只要不是0和空等,那就為true。

  

   修復方案:md5+鹽(salt)+別設置true

  黑盒測試的時候可以嘗試:任意賬號+密碼ffifdyop

 

 

 

 

  

   

 


免責聲明!

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



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