Moin!
Zur Zeit beschäftige ich mich wieder intensiv mit einigen Teilbereichen von (My)SQL, um mein Wissen bezüglich Sicherheit zu verbessern. Ich habe mir nämlich vorgenommen, mir die kleinen oder eventuell auch großen Sicherheitslücken meines (noch nicht online gestellten Projektes), die durch SQL-Injection entstehen können einmal genauer unter die Lupe zu nehmen. Man muss seine Feinde ja kennen, um ihnen vorbereitet gegenübertreten zu können.
Alo hab ich mir ein kleines Script geschrieben, um die billigste aller SQL-Injections zu testen und auch einzelne andere Fälle mal zu beleuchten und durchzugehen.
Wer mir helfen möchte, aber selbst testen will kann sich ganz schnell die benötigte Datenbank mit diesem SQL anlegen:
Mit diesem absichtlich primitiven Script habe ich mir das Testen vorgenommen:
Um die magic_quotes_gpc kümmert sich die erste Abfrage, somit habe ich keine "störenden" Slashes in den $_POST-Variablen.
Das Wichtigste ist ja nun der Query und wie die $_POST-Variablen behandelt oder eben nicht behandelt werden.
Query:
Die billigste Methode ist jetzt wahrscheinlich, die Abfrage durch ein OR so zu zu relativieren, dass die "count" immer mindestens 1, also TRUE ist.
Wenn ich jetzt in das Formular "bla" als Namen und "irgendwas' OR '1'='1" (ohne doppelte Anführungszeichen) eingebe, so sollte der Query doch zu:
werden und folglich zumindest eine Zahl liefern, die höher ist als 0, womit wiederum die Abfrage im Script vernalassen müsste, dass: "Welcome bla, you are logged in." ausgegeben wird.
Stutzig macht mich, dass ich, obschon ich versuche, mein eigenes Script zu "hacken", keinen Erfolg habe, wobei es andere auf anderen Seiten leider immer wieder ohne Probleme hinbekommen.
Ohne ein Beispiel, wie man es denn wirklich nicht machen wollte, kann ich mir allerdings auch keine Gedanken zu einer Gegenmaßahem machen.
Was mache ich also falsch, bzw richtig? ;-)
Zur Zeit beschäftige ich mich wieder intensiv mit einigen Teilbereichen von (My)SQL, um mein Wissen bezüglich Sicherheit zu verbessern. Ich habe mir nämlich vorgenommen, mir die kleinen oder eventuell auch großen Sicherheitslücken meines (noch nicht online gestellten Projektes), die durch SQL-Injection entstehen können einmal genauer unter die Lupe zu nehmen. Man muss seine Feinde ja kennen, um ihnen vorbereitet gegenübertreten zu können.
Alo hab ich mir ein kleines Script geschrieben, um die billigste aller SQL-Injections zu testen und auch einzelne andere Fälle mal zu beleuchten und durchzugehen.
Wer mir helfen möchte, aber selbst testen will kann sich ganz schnell die benötigte Datenbank mit diesem SQL anlegen:
Code:
CREATE DATABASE IF NOT EXISTS sql_injection_check; USE sql_injection_check; CREATE TABLE IF NOT EXISTS users ( id INT(6) unsigned auto_increment, username VARCHAR(24) NOT NULL DEFAULT '', password VARCHAR(40) NOT NULL DEFAULT '', privatedata VARCHAR(100) NOT NULL DEFAULT '', PRIMARY KEY(id)); INSERT INTO users (username, password, privatedata) VALUES ('Someone', SHA1('abc'), 'Gestern ne Flasche Schnaps geklaut'), ('Someoneelse', SHA1('123'), 'Heute ordentlich die Putze vernascht');
PHP-Code:
<?php
if (get_magic_quotes_gpc()) {
$_POST = array_map("stripslashes", $_POST);
$_GET = array_map("stripslashes", $_GET);
$_COOKIE = array_map("stripslashes", $_COOKIE);
}
if(!isset($_POST['submit'])) {
?>
<form action="hacking_test.php" method="post">
<p>
<label for="username">Username: </label>
<input type="text" name="username" id="username" />
</p>
<p>
<label for="password">Password: </label>
<input type="password" name="password" id="password" />
</p>
<p>
<input type="submit" name="submit" value="Submit" />
</p>
</form>
<?php
} else {
if(isset($_POST['username'], $_POST['password'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$link = mysql_connect("localhost", "root", "")
OR die("<p>Database connection could not be established.</p>\n");
mysql_select_db("sql_injection_check", $link)
OR die(mysql_error("<p>Database could not be selected.</p>\n"));
$sql = "SELECT
COUNT(*) AS count
FROM
users
WHERE
username = '" . $username . "'
AND
password = SHA1('" . $password . "')";
$result = mysql_query($sql, $link) OR die("<p>Bad query.</p>\n");
while($row = mysql_fetch_assoc($result)) {
if($row['count'] !== '0') {
echo "<p>Welcome " . $username . ", you are logged in.</p>\n";
} else {
echo "<p>Wrong password and/or username</p>\n";
}
}
}
}
?>
Das Wichtigste ist ja nun der Query und wie die $_POST-Variablen behandelt oder eben nicht behandelt werden.
Query:
Code:
SELECT COUNT(*) AS count FROM users WHERE username = '" . $username . "' AND password = SHA1('" . $password . "');
Wenn ich jetzt in das Formular "bla" als Namen und "irgendwas' OR '1'='1" (ohne doppelte Anführungszeichen) eingebe, so sollte der Query doch zu:
Code:
SELECT COUNT(*) AS count FROM users WHERE username = 'bla' AND password = SHA1('irgendwas') OR '1'='1';
Stutzig macht mich, dass ich, obschon ich versuche, mein eigenes Script zu "hacken", keinen Erfolg habe, wobei es andere auf anderen Seiten leider immer wieder ohne Probleme hinbekommen.
Ohne ein Beispiel, wie man es denn wirklich nicht machen wollte, kann ich mir allerdings auch keine Gedanken zu einer Gegenmaßahem machen.
Was mache ich also falsch, bzw richtig? ;-)
Kommentar