Schweren Bug im VMS gefunden

ABC

abgemeldet
21 April 2006
3.851
444
So liebe Leute.

Heute waren von unserem EF eineige Lose verschwunden. Dabei haben wir einen noch nicht gefixten BUG im VMS gefunden. Hier wollte ich euch hinterlegen wie ihr euch schützen könnt.

Folgendes Szenario. Ein User überlastet eure Datenbank so lange bis sie im Lockstatus hängen bleibt. Ab diesem Moment lässt er sich Lose auszahlen. Er bekommt sie ausbezahlt, aber ihm wird nichts vom VMS abgebucht.
Die Folge ist die, dass er seinen Kontostand xbelibig mal auszahlen kann, ohne, dass ihm irgend was abgebucht wird. Also so lange bis euer EF leer ist.

Umd das zu verhindern, müsst ihr den Lockstatus überprüfen.

Beispiel Auszahlung.php
Bugfix:
direkt nach folgender Zeilen:
PHP:
// Variabeln definieren
if (!isset($_POST['auszahlen']))	$_POST['auszahlen']			= "";
if (!isset($_POST['uid_passwort']))	$_POST['uid_passwort']		= "";
if (!isset($_POST['trans_menge']))	$_POST['trans_menge']		= "";
if (!isset($auszahlmeldung))		$auszahlmeldung				= "";

folgenden Code anfügen:

PHP:
//-----> Sicherheitsbeschreibung auf die Datenbank
$kontodaten	= mysql_fetch_array(db_query("SELECT `kontostand` FROM ".$db_prefix."_kontodaten WHERE uid=".$_SESSION['uid']." LIMIT 1"));
@mysql_query("UPDATE ".$db_prefix."_kontodaten SET kontostand = kontostand - '1' WHERE uid='".$_SESSION['uid']."' LIMIT 1");
$kontodaten2 = mysql_fetch_array(db_query("SELECT `kontostand` FROM ".$db_prefix."_kontodaten WHERE uid=".$_SESSION['uid']." LIMIT 1"));
if ($kontodaten['kontostand'] != ($kontodaten2['kontostand'] + 1))
{
	die('FEHLER BEI DER SICHERHEITSBESCHREIBUNG');
	exit;
}
else 
{
	@mysql_query("UPDATE ".$db_prefix."_kontodaten SET kontostand = kontostand + '1' WHERE uid=".$_SESSION['uid']." LIMIT 1");
	unset($kontodaten,$kontodaten2);
}

Den gleichen Code in der Einzahlung nachfixen. Das macht euch nicht arm, aber spart euch Ärger.

Beispiel Einzahlung.php
Bugfix:
direkt nach:
PHP:
// Variabeln definieren
if (!isset($_POST['einzahlen']))	$_POST['einzahlen']			= "";
if (!isset($_POST['uid_passwort']))	$_POST['uid_passwort']		= "";
if (!isset($_POST['trans_menge']))	$_POST['trans_menge']		= "";
if (!isset($einzahlmeldung))		$einzahlmeldung				= "";

vorherigen code einfügen!

Nun kann euer Hacker eure DB überlasten wie er mag. Aber ist ein Update nicht mehr möglich, verschwinden euch keine Lose mehr.

Übrigens dieser Bug ist auch in anderen Scripten möglich wie FWX etc. Auch dort sollte man die Sicherheitsbeschreibung prüfen.
 
Zuletzt bearbeitet:
Danke dir für das Bugfix.

Habe diese Sicherheitslücke natürlich gleich bei mir zu gemacht.
 
Übrigens dieser Bug ist auch in anderen Scripten möglich wie FWX etc. Auch dort sollte man die Sicherheitsbeschreibung prüfen.

so etwas ist in fast allen Scripten vorhanden, und nennt sich Race Condition, Race Hazard oder Wettlaufbedingung.
Das Problem liegt an der Verteilung der CPU-Zeit und dass dadurch der Ablauf eines Scriptes unterbrochen werden kann, ein anderes dran kommt und dann erst wieder das alte. Wenn es natürlich mal passiert (ist selten) und dann an einer doofen Stelle, ist es natürlich ärgerlich, dieser Bug ist in Klamm auch unter dem Namen "negativer Gewinntopf"-Bug bekannt.
es gibt aber eindeutig auch geschicktere Lösungen dafür.
 
so etwas ist in fast allen Scripten vorhanden, und nennt sich Race Condition, Race Hazard oder Wettlaufbedingung.
Das Problem liegt an der Verteilung der CPU-Zeit und dass dadurch der Ablauf eines Scriptes unterbrochen werden kann, ein anderes dran kommt und dann erst wieder das alte. Wenn es natürlich mal passiert (ist selten) und dann an einer doofen Stelle, ist es natürlich ärgerlich, dieser Bug ist in Klamm auch unter dem Namen "negativer Gewinntopf"-Bug bekannt.
es gibt aber eindeutig auch geschicktere Lösungen dafür.

Natürlich gibt es geschicktere Lösungen. Das muss ich dir recht geben. Was aber wenn Lösung auf dem Server versagt. Mir ist das schon mehrere Male passiert. Eigentlich ist ja jeder Apache dagegen gesichert. Leider aber ist es nun mal so, dass der Schreibpufferprozess sich aufhängen kann, da ein lockprozess hängen geblieben ist. Folge ist Daten kommen raus, aber kein Update möglich.

Leider habe ich das letzten Tagen gezielt per Angriff bitteren ernstes feststellen dürfen. Da bist mir einer statischen IP machtlos. Wenn ein Kidi spielen will, kannst nicht viel tun. Ein wenig IP blocken, ein wenig Firewall einstellungen umfummeln. Doch das bringt garnichts. Ein simples Script welches sich zur DB verbindet reicht vollkommen aus um das Ergebnis zu erzielen.

Ganz China und Russland kommt bei mir net auf die prots. Aber dennoch einmal AOL und das wars. Mir scheint dir Lösung im Script sicherer. Denn so kann das Problem garnichts auswirken.
 
1000 Dank für deine Mühe. Auch ich hab meine Seite mal rasch gefixt und hoffe das alles behoben ist.


Danke

Sweety2410
 
Kann man das nicht so machen, dass zuerst die Lose vonner DB abgebucht werden, wenn dieses Okay ist dann Lose auszahlen?
Oder Lose auszahlen und wenn danach Lose vonner DB einziehen nicht Okay ist Lose wieder einziehen?
 
Hallo

Leider nicht. Denn die Abbuchung sagt dir in diesem Fall Okay, obwohl nichts abgebucht wird. Es gibt also keinen Mysql Error. Man kann also nur den aktuellen Kontostand laden, und dann ein Los abziehen. Wenn man sicher gehen will, dass die DB nicht im Lock hängt, holt man sich erneut den Kontostand. Ist dieser 1 Lose weniger, so hat man die Sicherheit, dass das abbuchen geht.
 
Achso...
Is ja ne sche** Macke bei Apache+MySQL

wenn man keine Ahnung hat, einfach mal Fre*** halten.
Das ist weder ne MAcke von MySQL noch von Apache sondern einfach Programmierfehler, dass die net genug nachdenken, Race Conditions gibt es in jeder Sprache.
Und im VMS werden noch viele mehr stecken, wie in jedem anderem System (habe noch keines gesehen, dass Schutzmaßnahmen dagegen hatte)
 
  • Like
Reaktionen: ABC
wenn man keine Ahnung hat, einfach mal Fre*** halten.
Das ist weder ne MAcke von MySQL noch von Apache sondern einfach Programmierfehler, dass die net genug nachdenken, Race Conditions gibt es in jeder Sprache.
Und im VMS werden noch viele mehr stecken, wie in jedem anderem System (habe noch keines gesehen, dass Schutzmaßnahmen dagegen hatte)

Im Thema Race Conditions habe ich keine Ahnung, stimmt... Also :sick: