A napokban kaptam egy kódot átnézésre. Egy egyszerű beléptetést valósít meg, mysqlből user és jelszó alapján. Semmi magic, a szokásos scenario. A kódot lebutítottam, így csak azokat a elemeket tartalmazza amelyek aktív szerepet játszanak a beléptetésnél.
if (isset($_POST["login"]))
{
$u = htmlentities($_POST['user']);
$p = md5($_POST['pass']);
$q = "SELECT * FROM users WHERE (user='".$u."' AND pass='".$p."')";
$result = mysql_query($q);
if (mysql_num_rows($result) !== 0)
{
be_vagy_lepve(); // session valtozok beallitasa, stb
}
}
A szerveren magic_quotes van, úgyhogy nem bypassolsz aposztróffal, unicode sqli nem játszik. A megoldás kicsit ork, de megoldás: A jelszó mindegy, mert md5 lesz belőle, viszont a felhasználónév némi htmlentities után egy az egybe bekerül a querybe. A mysql max_allowed_packet konfig opciója default 16M, ha ezt túllépjük akkor a mysql_error() azt mondja hogy "Got a packet bigger than 'max_allowed_packet' bytes". Akkor most nézzük meg a 6. és 7. sort.
$result = mysql_query($query);
Nincs "or die()" a mysql_query() után, se semmi hibakezelés, szóval ha ez a query valamiért, bármiért elhasal, akkor futunk tovább.
A 7. sor "mysql_num_rows($result) !== 0". Mivel a query eltaknyolt, a $result egy nagy büdös false, a mysql_num_rows pedig NULL. Márpedig a NULL !== 0 határozottan true. Auth bypass successful.
A bejegyzés trackback címe:
Kommentek:
A hozzászólások a vonatkozó jogszabályok értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a Felhasználási feltételekben és az adatvédelmi tájékoztatóban.