Heyho,
hab letztens wieder an meinen ersten Milw0rm Eintrag gedacht, und dann ist mir in den Kopf gekommen “Luecken finden ist die eine Sache, Luecken schließen die andere”. Daher werd ich euch einen Weg zeigen, wie man diese Luecke schließen kann.
Es geht um dieses Exploit.
Hier nochmal die SQL Injection:
http://www.site.com/galerie.php?action=show&pic=10'/**/and/**/ascii(substring((SELECT/**/password/**/from/**/bb1_users/**/WHERE/**/userid=1),1,1))>1/*
Nun sehen wir, dass die Luecke sich in der galerie.php befindet und anscheinend der parameter “pic” nicht ueberprueft wird bzw. auch Usereingaben “ausfuehrt” und dadurch laesst sich das MySQL Query beeinflussen.
Schauen wir uns mal die betroffene Zeile in der Galerie.php an, wir stoßen auf Zeile 683 & 684 und sehen:
$result = $db->query("UPDATE bb".$n."_galeriedata SET click=click+1 WHERE id = '$_GET[pic]' LIMIT 1");
$result_show = $db->query("SELECT g.*, u.userid, u.username FROM bb".$n."_galeriedata g LEFT JOIN bb".$n."_users u ON (g.userid=u.userid) WHERE id = '$_GET[pic]'");
Aha! Hier sieht man auch schoen, dass dort WHERE id = ‘$GET[pic]’ steht, daher haben wir bei unserer SQL Injection auch ein ‘ (hochkomma) gebraucht.
Nun wie schließen wir die Luecke? Ich werd intval() benutzen, warum? Weil intval() nur eine Zahl bzw. einen Integer zurueck gibt/erlaubt. Das heißt, wenn wir nun versuchen die Eingabe wieder zu manipulieren, dann passiert ganz einfach nichts, da er nur Zahlen “annimmt”. Und da wir in diesem Falle nur eine Zahl erwarten, passt intval ganz gut.
Wir suchen nun also in unserer galerie.php nach
$_GET[pic]
Dies sollte nur bei Zeile 683 & 684 auftauchen.
Dort ersetzen wir nun unser
$_GET[pic]
durch
".intval($_GET[pic])."
Dann sollten Zeile 683 & 684 etwa so aussehen:
$result = $db->query("UPDATE bb".$n."_galeriedata SET click=click+1 WHERE id = '".intval($_GET[pic])."' LIMIT 1");
$result_show = $db->query("SELECT g.*, u.userid, u.username FROM bb".$n."_galeriedata g LEFT JOIN bb".$n."_users u ON (g.userid=u.userid) WHERE id = '".intval($_GET[pic])."'");
Danach speichern wir das ganze, rufen unsere Galerie auf und probieren nochmal
http://www.site.com/galerie.php?action=show&pic=10'/**/and/**/ascii(substring((SELECT/**/password/**/from/**/bb1_users/**/WHERE/**/userid=1),1,1))>1/*
Was passiert? Richtig, kein MySQL Error, nichts. Die Luecke wurde gefixxt 🙂