我有一个大问题。
我拥有一个拥有会员区的网站。 我有一个竞争对手,一直黑客攻击会员的帐户。
我聘请了一位安全专家。他修复了一些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');
}
}
}
答案 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变量直接复制到查询中,可能还有另一种方法可以在应用程序的其他部分利用它,我们在这里看不到。
建议:
重置数据库@EPB建议的所有密码。
询问您的安全分析师,为什么他们没有发现这一点。
绝不存储明文密码。