怎么可能得到用md5加密的密码

时间:2014-02-20 01:59:36

标签: php mysql sql encryption

我有一个大问题。

我拥有一个拥有会员区的网站。 我有一个竞争对手,一直黑客攻击会员的帐户。

我聘请了一位安全专家。他修复了一些sql查询,但没有发现登录代码有任何问题。

真正的问题 - 如果有人自动将其密码错误地插入到数据库中,那么我就能知道他提交了什么字符串。

使用MD5对DB上的密码进行加密。但是同一个竞争对手,我自己破解了帐户,当我更改密码时,他试图提交我的最后一个密码。所以现在我知道他确切知道我的密码是什么。

我的密码真的很长很棘手,没有机会在任何MD5在线预订。

你知道可能是什么问题吗?他是怎么砍掉这个的?他怎么知道我的密码字符串呢?

谢谢!

这是包含的login.php文件:

if(isset($_POST['login'])){
  //Input filteren
  $name = htmlspecialchars(addslashes($_POST['username'])); 
  $ww = htmlspecialchars(addslashes($_POST['password']));
  //Wachtwoord omzetten naar md5 
  $wwmd5 = md5($_POST['password']);

  //Gegevens laden voor het foute inloggen.
  $inlog_fout_sql = mysql_query("SELECT `datum`, `ip`, `spelernaam` FROM `inlog_fout` WHERE `ip`='".$_SERVER['REMOTE_ADDR']."' ORDER BY `id` DESC");
  $inlog_fout = mysql_fetch_array($inlog_fout_sql); 
  $aftellen = 1200-(time()-strtotime($inlog_fout['datum']));

  //Geen inlognaam ingevuld
  if($_POST['username'] == '')
    $inlog_error = $txt['alert_no_username'];
  //Geen wachtwoord ingevoerd
  elseif($ww == '')
    $inlog_error = $txt['alert_no_password'];
  //Is het wel drie keer mis gegaan
  elseif((mysql_num_rows($inlog_fout_sql) >= 300) AND ($inlog_fout['ip'] === $_SERVER['REMOTE_ADDR']) AND ($aftellen > 0)) {
    $inlog_error = $txt['alert_time_sentence'].' <span><script type="text/javascript">writetimer("'.$aftellen.'")</script></span>';
  }
  else{
    if($aftellen < 0)
      mysql_query("DELETE FROM `inlog_fout` WHERE `ip`='".$_SERVER['REMOTE_ADDR']."'");

    // Gegevens laden om te kijken voor de gebruiker
    $naam = $_POST['username'];
    $gegevens_sql = mysql_query("SELECT `id`, `username`, `wachtwoord`, `premiumaccount`, `account_code` FROM `members` WHERE `username`='".$naam."'"); 
    // Gegevens laden om te kijken voor de gebruiker
    $gegeven_sql  = mysql_query("SELECT `username`, `wachtwoord`, `account_code` FROM `members` WHERE `wachtwoord`='".$wwmd5."' AND `username`='".$naam."'");
    $gegeven = mysql_fetch_array($gegevens_sql);

    if(mysql_num_rows($gegevens_sql) == 0)
      $inlog_error = $txt['alert_unknown_username'];
    elseif($gegeven['username'] != $naam)
      $inlog_error = $txt['alert_unknown_username'];
    //Kijken of account niet is verbannen
    elseif(mysql_num_rows(mysql_query("SELECT id FROM ban WHERE id = '".$gegeven['id']."'")) > 0)
      $inlog_error = $txt['alert_account_banned'];
    elseif(mysql_num_rows($gegeven_sql) == 0){
      $datum = date("Y-m-d H:i:s");
      mysql_query("INSERT INTO `inlog_fout` (`datum`, `ip`, `spelernaam`, `wachtwoord`) 
        VALUES ('".$datum."', '".$_SERVER['REMOTE_ADDR']."', '".$naam."', '".$ww."')");

      if((mysql_num_rows($inlog_fout_sql) < 300) AND ($gegeven['wachtwoord'] != $wwmd5))
        $inlog_error = 'סיסמא שגויה';
    }
    elseif($gegeven['account_code'] != 1)
      $inlog_error = $txt['alert_account_not_activated'];
    else{
      //If Onthoud Check box is checked save cookie
        setcookie("pa_1", $gegeven['username'], time()+(60*60*24*365));
        setcookie("pa_2", $_POST['password'], time()+(60*60*24*365));

      //Zorgen dat gebruiker weer 3 pogingen heeft.
      mysql_query("DELETE FROM `inlog_fout` WHERE `ip`='".$_SERVER['REMOTE_ADDR']."'");

      //tijd opslaan dat het lid inlogt, zodat de site weet dat hij online is.
      $tijd = time();
      mysql_query("UPDATE `members` SET `ip_ingelogd`='".$_SERVER['REMOTE_ADDR']."', `online`='".$tijd."' WHERE `username`='".$gegeven['username']."'");

      //Datum opvragen
      $date = date("Y-m-d H:i:s");
      //Opslaan in de inlog_logs tabel
      $queryloginlogs = mysql_query("SELECT `id` FROM `inlog_logs` WHERE `ip`='".$_SERVER['REMOTE_ADDR']."' AND `speler`='".$gegeven['username']."'");
      if(mysql_num_rows($queryloginlogs) == "0"){
        mysql_query("INSERT INTO `inlog_logs` (`ip`, `datum`, `speler`) 
          VALUES ('".$_SERVER['REMOTE_ADDR']."', '".$date."', '".$naam."')");
      }
      else
        mysql_query("UPDATE `inlog_logs` SET `datum`='".$date."' WHERE `speler`='".$gegeven['username']."' AND `ip`='".$_SERVER['REMOTE_ADDR']."'");

      //zet naam in variabele, zodat het later nog gebruikt kan worden
      $_SESSION['id'] = $gegeven['id'];
      $_SESSION['naam'] = $gegeven['username'];
      //Hash opslaan
      $_SESSION['hash'] = md5($_SERVER['REMOTE_ADDR'].",".$gegeven['username']);
      //Ben je wel premium
      if($gegeven['premiumaccount'] > 0)
        $_SESSION['userid'] = $gegeven['id'];
      //naar de ingame pagina sturen
      header('location: ?page=home');
    }
  }
}

1 个答案:

答案 0 :(得分:2)

我至少可以看到一种攻击者可以使用您的代码读取密码的方式,没有打破MD5哈希。

$naam = $_POST['username'];
. . .
$gegevens_sql = mysql_query("SELECT `id`, `username`, `wachtwoord`, `premiumaccount`, `account_code` FROM `members`
    WHERE `username`='".$naam."'"); 

您正在将$_POST['username']插入到SQL查询中,而根本不保护它。


不 - 等等,我错了。他们可以在您显示的代码中的至少两个位置执行SQL注入攻击,但由于以下代码,我看不出他们如何读取密码:

elseif($gegeven['username'] != $naam)
  $inlog_error = $txt['alert_unknown_username'];

他们不能同时将明文密码提取到$gegeven['username'] 传递此if-test。


但是,您的代码容易受到SQL注入的影响是一个巨大的危险信号。如果您习惯将$ _POST变量直接复制到查询中,可能还有另一种方法可以在应用程序的其他部分利用它,我们在这里看不到。

建议:

  1. 重置数据库@EPB建议的所有密码。

  2. 了解how to prevent SQL injection

  3. 询问您的安全分析师,为什么他们没有发现这一点。

  4. 绝不存储明文密码。