• Es freut uns dass du in unser Minecraft Forum gefunden hast. Hier kannst du mit über 130.000 Minecraft Fans über Minecraft diskutieren, Fragen stellen und anderen helfen. In diesem Minecraft Forum kannst du auch nach Teammitgliedern, Administratoren, Moderatoren , Supporter oder Sponsoren suchen. Gerne kannst du im Offtopic Bereich unseres Minecraft Forums auch über nicht Minecraft spezifische Themen reden. Wir hoffen dir gefällt es in unserem Minecraft Forum!
ProfessionalBans Reloaded • Webinterface

ProfessionalBans Reloaded • Webinterface 1.8

Tutorialwork

Minecrafter
Mitglied seit
19 November 2018
Beiträge
3
Alter
18
Minecraft
ManuGun

Taminoful

Minecrafter
Mitglied seit
3 August 2012
Beiträge
20
Alter
22
Minecraft
Taminoful
Ich würdige deinen Versuch, wirklich.

Allerdings ist deine Implementierung weiterhin anfällig für alle Arten von Sicherheitslücken, der Code den du nun geschrieben hast kann ich mit genau dem selben Angriff wie das letzte Mal aushebeln, es handelt sich bei diesem Webinterface weiterhin um eine Zeitbombe.

Man sieht, dass du dir die Kritik, die ich geäußert habe angesehen hast, dir aber nicht sicher warst, wie man Sachen anständig implementiert.
Dafür ist das Beispiel für die CSRF Tokens aus dieser Version des Webinterfaces gut anzuführen.
Einen CSRF Token speichert man weder in der Datenbank noch in einem Cookie, durch die XSS Lücken die weiterhin in deinem Code bestehen, kann ich so einfach die Cookies entführen und komme an jeden Account und notfalls, auch wenn dann nicht mehr wirklich relevant, auch an den CSRF Token. Auch wird weiterhin nicht mit Prepared Statements gearbeitet, das ist wirklich schade.

Falls Unklarheiten bei der Umsetzung von sicherheitsrelevanten Themen bestehen sollten, ist es keine Schande jemanden um Rat zu fragen. Ich beantworte immer fragen, so wie die meisten anderen Entwickler auch. Dafür muss man aber auch die Fragen stellen und bereit sein sich weiterzubilden und etwas neues zu lernen.
 
Zuletzt bearbeitet:

Tutorialwork

Minecrafter
Mitglied seit
19 November 2018
Beiträge
3
Alter
18
Minecraft
ManuGun
Du meintest das meine CSRF Token nutzlos sind. Aber wieso? Wegen der XSS Lücke oder wegen dem CSRF Token an sich. Und wo meinst du ist die XSS Lücke in meinem Code? Kannst du mir da bitte ein Beispiel zeigen. Denn ich habe schon an Stellen wo ich dachte dort könnte eine XSS Lücke bestehen die Ausgabe in HTML umgewandelt so das JavaScript nutzlos wird. Du meintest ja ich sollte gegen SQL Injections Prepared Statements verwenden. Sollte man dann weiterhin mysqli_real_escape_string verwenden wenn das ja schon die Prepared Statements alleine machen? Und wieso ist mysqli_real_escape_string kein ausreichender Schutz gegen SQL Injections denn sie neutralisieren ja genauso gefährliche Eingaben. Außerdem hast du geschrieben das Passworter NULL sein können. Das ist von mir gewollt denn so kann ganz einfach über das Plugin ein Account erstellt werden und der Benutzer kann sich beim ersten Login ein Passwort festlegen. Denn man möchte ja nicht sein Passwort dem Admin sagen welches er für die Accounterstellung angeben müsste wenn das Passwort gleich gesetzt werden soll. Und dem Benutzer eine Email zu senden kam für mich auch nicht in Frage da einfach zu viele Anwender das Problem haben das die Emails nicht versendet werden weil das benötigte PHP-Modul oft als Standardeinstellung deaktiviert ist.

Ich hoffe du kannst mir helfen und bedanke mich für deine ausführliche Analyse meines Projekts.
 

Taminoful

Minecrafter
Mitglied seit
3 August 2012
Beiträge
20
Alter
22
Minecraft
Taminoful
Du meintest das meine CSRF Token nutzlos sind. Aber wieso? Wegen der XSS Lücke oder wegen dem CSRF Token an sich. Und wo meinst du ist die XSS Lücke in meinem Code? Kannst du mir da bitte ein Beispiel zeigen. Denn ich habe schon an Stellen wo ich dachte dort könnte eine XSS Lücke bestehen die Ausgabe in HTML umgewandelt so das JavaScript nutzlos wird. Du meintest ja ich sollte gegen SQL Injections Prepared Statements verwenden. Sollte man dann weiterhin mysqli_real_escape_string verwenden wenn das ja schon die Prepared Statements alleine machen? Und wieso ist mysqli_real_escape_string kein ausreichender Schutz gegen SQL Injections denn sie neutralisieren ja genauso gefährliche Eingaben. Außerdem hast du geschrieben das Passworter NULL sein können. Das ist von mir gewollt denn so kann ganz einfach über das Plugin ein Account erstellt werden und der Benutzer kann sich beim ersten Login ein Passwort festlegen. Denn man möchte ja nicht sein Passwort dem Admin sagen welches er für die Accounterstellung angeben müsste wenn das Passwort gleich gesetzt werden soll. Und dem Benutzer eine Email zu senden kam für mich auch nicht in Frage da einfach zu viele Anwender das Problem haben das die Emails nicht versendet werden weil das benötigte PHP-Modul oft als Standardeinstellung deaktiviert ist.

Ich hoffe du kannst mir helfen und bedanke mich für deine ausführliche Analyse meines Projekts.
Hallo @Tutorialwork (und die restlichen Leser),

Ich finde es sehr gut, dass du diese Rückfragen gestellt hast und die Sache nicht einfach als "Mir doch egal, was so ein Typ im Internet faselt" hinnimmst. Im nachfolgenden habe ich einmal versucht deine Fragen zu beantworten und dazu immer relevante Informationen verlinkt, die ich selbst für qualitativ hochwertig erachte. Am Ende findest du noch weitere Ressourcen, die dir das Leben leichter machen sollten und die du dir mal ansehen kannst. Gerne kann man mich auch privat kontaktieren, ich stehe über die üblichen Kanäle zur Verfügung. Aus meinem MCSEU Profil kann man meinen Discord Tag entnehmen. Man kann mir dort gerne Fragen stellen, nur bitte keine Metafragen.

How to...

... implement CSRF Tokens

Das Problem des Cross-Site-Request-Forgery Angriffs besteht darin, dass gesicherte Anfragen an den Server vorgetäuscht werden können.
Das ganze Sicherheitsproblem basiert auf der Statuslosigkeit des HTTP-Protokolls. Der Browser sendet nach einmaliger Authentifizierung jedes Mal seine kompletten Sitzungsdaten an den Server (Cookies etc).
Als Angreifer kann ich mir das ganze zu nutze machen und dem Browser einen Request unterjubeln, der bspw. dafür sorgt, dass ein neuer administrativer Benutzer für den Angreifer im System angelegt wird. Hierfür muss der Angreifer lediglich das System oder in diesem Fall die URI kennen. Klickt der Administrator der Seite also auf eine Seite (Link) welche einen solchen Angriff durchführt während er eine gültige Session besitzt, wird die Aktion auf dem System ausgeführt ohne, dass der Administrator direkt etwas davon mitbekommt.

Deswegen ist es, anders als es Wikipedia in diesem Fall rät, nicht sinnvoll einen CSRF Token als Cookie zu implementieren, dieser würde nämlich auch einfach an den Server geschickt werden.

Best Practice ist es in diesem Fall einen CSRF Token als "Hidden Field" in ein Formular einzubauen, welcher sich bei jedem Seitenabruf ändert.
Dieser wird zusammen mit den Formulardaten an den Server gesendet und dort überprüft. Das ganze ist deswegen sicher, da der Angreifer den CSRF Token nicht einfach auslesen kann um diesen so ebenfalls an den Server zu schicken.
Das ganze lässt sich zwar recht einfach selbst implementieren, es wird aber angeraten die Hausmittel von Frameworks oder externe Libraries zu verwenden.

... set an initial password
Das Problem lässt sich recht einfach lösen, wie ich gesehen habe, hast du dich damit bereits einmal auseinandergesetzt und eine BCrypt Klasse in das Java Projekt eingebaut. Beim Erstellen des Webaccounts kannst du einen zufällig generierten Wert erzeugen den du für den Nutzer vorhältst. Diesen zufälligen String steckst du in die kryptographische Einwegfunktion um den BCrypt Hash in die Datenbank zu speichern. Den zufällig generierten String kannst du dem Nutzer einfach via Privatnachricht ausgeben, dies ist das Initialpasswort des Accounts. Das Passwort sollte natürlich nach erstmaligem Login geändert werden.

... escape user output properly
Generell bietet es sich an seine Webanwendungen nach bekannten Design Patterns wie MVC oder ADR zu entwickeln. Damit spart man sich hier eine Menge arbeit. Ebenfalls nehmen einem hier Template Engines wie Twig, Blade oder Smarty eine Menge ab. Twig escaped beispielsweise jede Ausgabe einer Variable, außer wenn man Twig explizit anweist dies nicht zutun. Das ist besonders hilfreich, da es schnell passieren kann eine Ausgabe zu vergessen.
Arbeitet man ohne Template Engine ist es wichtig jede Ausgabe mehrfach zu überprüfen.

Um hier das XSS Problem anzusprechen, da du nachgefragt hast:
Code:
<h3>Willkommen <?php echo $_SESSION["username"]; ?></h3>

Prepared Statements vs mysqli_real_escape_string
Zunächst dazu, warum die Funktion mysqli_real_escape_string keinen ausreichenden Schutz vor SQL Injections darstellt.
Die Funktionsweise der Funktion ersetzt rekursiv den Inhalt eines übergebenen Strings. Hierbei werden potentiell gefährliche Symbole wie NUL (ASCII 0), \n, \r, \, ', " und Control-Z normalisiert. Intern wird, wenn diese Zeichen gefunden werden, ein Backslash vor das Zeichen gesetzt. Man kann die Funktion umgehen, allerdings nur unter sehr spezifischen Umständen auf die ich jetzt nicht näher eingehen werde. Wichtiger als das ist sowieso, dass der wahre Mehrwert beim Escaping mit dieser Funktion nicht durch das nutzen der Funktion kommt, sondern durch die verwendeten Singlequotes in den SQL Statements. Hierfür reicht ein Blick in die Dokumentation um zu verstehen wieso. Werden einfache Anführungszeichen verwendet muss man einen Backslash vor potentiell gefährliche Zeichen einfügen. Da die Funktion dies für uns macht wird also bspw. statt einem \n ein \\n im Code stehen, was dazu führt, dass wir hier zwei unabhängige Zeichen ausgegeben bekommen. Würden normale Anführungszeichen benutzt werden, würden die norminalisierten Werte als Escape-Sequenz interpretiert werden.

Prepared Statements auf der anderen Seite benutzen Platzhalter für Parameterwerte. In MySQLi werden hierfür Fragezeichen verwendet und in PDO variable Bezeichnernamen. Dadurch, dass das Datenbanksystem die Gültigkeit von Parametern prüft bevor diese verarbeitet werden, verhindert man mit Prepared Statements effektiv SQL Injections. Hierfür ein kleines Beispiel.

Code:
<?php

$selectQuery = $pdoObject->prepare('SELECT username, email, avatar FROM users WHERE username=:username'); // Wir setzen :username als Platzhalter.
$selectQuery->bindParam(':username', $username, PDO::PARAM_STR); // Wir binden den Platzhalter an den Wert aus der Username Variable und legen fest, dass es sich um einen String Datentypen handelt.
$selectQueryResult = $selectQuery->execute(); // Wir führen die SQL Query aus und speichern das Ergebnis.
In PDO ist es ebenfalls möglich mit ? zu arbeiten, hierfür würde man dann in der bindParam Funktion den Platzhalter durch den Index ersetzen. Wichtig hierbei ist, dass der Index nicht bei 0 beginnt sondern bei 1.
Allgemein sollte MySQLi nicht mehr verwendet werden, da viele wichtige Funktionen als Deprecated markiert wurden.
Die Dokumentation zu PDOs Prepared Statements erklärt nochmal besser warum Prepared Statements sicher sind.


Weiterführende Ressourcen:
Composer
Objektorientierung in PHP
PHP Data Objects (PDO)
Should I Use mysqli_real_escape_string With Prepared Statements in PHP?
 
Zuletzt bearbeitet:

Brickchef

Schafhirte
Osterei Experte
Mitglied seit
8 Oktober 2017
Beiträge
120
Alter
19
Minecraft
Brickchef
Hallo @Tutorialwork (und die restlichen Leser),

Ich finde es sehr gut, dass du diese Rückfragen gestellt hast und die Sache nicht einfach als "Mir doch egal, was so ein Typ im Internet faselt" hinnimmst. Im nachfolgenden habe ich einmal versucht deine Fragen zu beantworten und dazu immer relevante Informationen verlinkt, die ich selbst für qualitativ hochwertig erachte. Am Ende findest du noch weitere Ressourcen, die dir das Leben leichter machen sollten und die du dir mal ansehen kannst. Gerne kann man mich auch privat kontaktieren, ich stehe über die üblichen Kanäle zur Verfügung. Da man auf MCSEU keinen Discord Tag verlinken kann, setze ich diesen hier einmal. Man kann mir dort gerne Fragen stellen, nur bitte keine Metafragen.

Discord: Taminoful#0001

How to...

... implement CSRF Tokens
Das Problem des Cross-Site-Request-Forgery Angriffs besteht darin, dass gesicherte Anfragen an den Server vorgetäuscht werden können.
Das ganze Sicherheitsproblem basiert auf der Statuslosigkeit des HTTP-Protokolls. Der Browser sendet nach einmaliger Authentifizierung jedes Mal seine kompletten Sitzungsdaten an den Server (Cookies etc).
Als Angreifer kann ich mir das ganze zu nutze machen und dem Browser einen Request unterjubeln, der bspw. dafür sorgt, dass ein neuer administrativer Benutzer für den Angreifer im System angelegt wird. Hierfür muss der Angreifer lediglich das System oder in diesem Fall die URI kennen. Klickt der Administrator der Seite also auf eine Seite (Link) welche einen solchen Angriff durchführt während er eine gültige Session besitzt, wird die Aktion auf dem System ausgeführt ohne, dass er direkt etwas davon mitbekommt.

Deswegen ist es, anders als es Wikipedia in diesem Fall rät, nicht sinnvoll einen CSRF Token als Cookie zu implementieren, dieser würde nämlich auch einfach an den Server geschickt werden.

Best Practice ist es in diesem Fall einen CSRF Token als "Hidden Field" in ein Formular einzubauen, welcher sich bei jedem Seitenabruf ändert.
Dieser wird zusammen mit den Formulardaten an den Server gesendet und dort überprüft. Das ganze ist deswegen sicher, da der Angreifer den CSRF Token nicht einfach auslesen kann um diesen so ebenfalls an den Server zu schicken.
Das ganze lässt sich zwar recht einfach selbst implementieren, es wird aber angeraten eine Hausmittel von Frameworks oder externe Libraries zu verwenden.

... set an initial password
Das Problem lässt sich recht einfach lösen, wie ich gesehen habe, hast du dich damit bereits einmal auseinandergesetzt und eine BCrypt Klasse in das Java Projekt eingebaut. Beim Erstellen des Webaccounts kannst du einen zufällig generierten Wert erzeugen den du für den Nutzer vorhältst. Diesen zufälligen String steckst du in die kryptographische Einwegfunktion um den BCrypt Hash in die Datenbank zu speichern. Den Zufällig generierten String kannst du dem Nutzer einfach via Privatnachricht ausgeben, dies ist das Initialpasswort des Accounts. Das Passwort sollte natürlich nach erstmaligem Login geändert werden.

... escape user output properly
Generell bietet es sich an seine Webanwendungen nach bekannten Design Patterns wie MVC oder ADR zu entwickeln. Damit spart man sich hier eine Menge arbeit. Ebenfalls nehmen einem hier Template Engines wie Twig, Blade oder Smarty eine Menge ab. Twig escaped beispielsweise jede Ausgabe eine Variable, außer wenn man Twig explizit anweist dies nicht zutun. Das ist besonders hilfreich, da es schnell passieren kann eine Ausgabe zu vergessen.
Arbeitet man ohne Template Engine ist es wichtig jede Ausgabe mehrfach zu überprüfen.

Um hier das XSS Problem anzusprechen, da du nachgefragt hast:
Code:
<h3>Willkommen <?php echo $_SESSION["username"]; ?></h3>

Prepared Statements vs mysqli_real_escape_string
Zunächst dazu, warum die Funktion mysqli_real_escape_string keinen ausreichenden Schutz vor SQL Injections darstellt.
Die Funktionsweise der Funktion ersetzt rekursiv den Inhalt eines übergebenen Strings. Hierbei werden potentiell gefährliche Symbole wie NUL (ASCII 0), \n, \r, \, ', " und Control-Z. Intern wird, wenn diese Zeichen gefunden werden ein Backslash vor das Zeichen gesetzt. Man kann die Funktion umgehen, allerdings nur unter sehr spezifischen Umständen auf die ich jetzt nicht näher eingehen werde. Wichtiger als das ist sowieso, dass beim der wahre Mehrwert beim Escaping mit dieser Funktion nicht durch das nutzen der Funktion kommt, sondern durch die verwendeten Singlequotes in den SQL Statements. Hierfür reicht ein Blick in die Dokumentation um zu verstehen wieso. Werden einfache Anführungszeichen verwendet muss man einen Backslash vor eine sogenannte Escape-Sequenz einfügen. Da die Funktion dies für uns macht wird also bspw. statt einem \n ein \\n im Code stehen, was dazu führt, dass wir hier zwei unabhängige Zeichen ausgegeben bekommen und keine Escape-Sequenz.

Prepared Statements auf der anderen Seite benutzen Platzhalter für Parameterwerte. In MySQLi werden hierfür Fragezeichen verwendet und in PDO variable Bezeichnernamen. Dadurch, dass das Datenbanksystem die Gültigkeit von Parametern prüft bevor diese verarbeitet werden, verhindert man mit Prepared Statements effektiv SQL Injections. Hierfür ein kleines Beispiel.

Code:
<?php

$selectQuery = $pdoObject->prepare('SELECT username, email, avatar FROM users WHERE username=:username'); // Wir setzen :username als Platzhalter.
$selectQuery->bindParam(':username', $username); // Wir binden den Platzhalter an den Wert aus der Username Variable.
$selectQueryResult = $selectQuery->execute(); // Wir führen die SQL Query aus und speichern das Ergebnis.
In PDO ist es ebenfalls möglich mit ? zu arbeiten, hierfür würde man dann in der bindParam Funktion den Platzhalter durch den Index ersetzen. Wichtig hierbei ist, dass der Index nicht bei 0 beginnt sondern bei 1.
Allgemein sollte MySQLi nicht mehr verwendet werden, da viele wichtige Funktionen als Deprecated markiert wurden.
Die Dokumentation zu PDOs Prepared Statements erklärt nochmal besser warum Prepared Statements sicher sind.


Weiterführende Ressourcen:
Composer
Objektorientierung in PHP
PHP Data Objects (PDO)
Should I Use mysqli_real_escape_string With Prepared Statements in PHP?
Schön erklärt, allerdings sollte man bei PDO#bindParam als letzten Parameter den Typ der Variable übergeben. Die PDO Klasse hat dafür Konstanten.
 

Tutorialwork

Minecrafter
Mitglied seit
19 November 2018
Beiträge
3
Alter
18
Minecraft
ManuGun
Tutorialwork hat die Ressource ProfessionalBans Reloaded • Webinterface aktualisiert:

Update 1.2

Update 1.2
  • Im Webinterface kann jetzt gebannt/gemutet werden
  • Spieler die einen Webinterface Account haben mit dem Rang Admin können nicht mehr gebannt/gemutet werden
  • Das Zugangspasswort bei einer Accounterstellung über /webaccount wird jetzt dem Spieler für den der Account bestimmt ist zugesendet
  • Das Passwort im Webinterface...
Mehr über diese Aktualisierung...
 

Taminoful

Minecrafter
Mitglied seit
3 August 2012
Beiträge
20
Alter
22
Minecraft
Taminoful
Beim Überfliegen des Codes sind mir keine weiteren offensichtlichen Lücken aufgefallen.
Mittlerweile wird PDO mit Prepared Statements verwendet, CSRF Tokens sind nicht mehr in den Cookies und XSS sieht auch ganz gut aus.

Der nächste Schritt wäre die Entkopplung der einzelnen Aufgaben und das wegkommen von einem prozeduralen und hin zu einem objektorientierten Stil. Allerdings ist dieser Schritt nicht so notwendig wie die vorherigen, ich kann es lediglich empfehlen.

Es freut mich, dass die Kritik beachtet und entsprechend nachgebessert wurde.
 

Tutorialwork

Minecrafter
Mitglied seit
19 November 2018
Beiträge
3
Alter
18
Minecraft
ManuGun

Tutorialwork

Minecrafter
Mitglied seit
19 November 2018
Beiträge
3
Alter
18
Minecraft
ManuGun

Tutorialwork

Minecrafter
Mitglied seit
19 November 2018
Beiträge
3
Alter
18
Minecraft
ManuGun

Tutorialwork

Minecrafter
Mitglied seit
19 November 2018
Beiträge
3
Alter
18
Minecraft
ManuGun
Tutorialwork hat die Ressource ProfessionalBans Reloaded • Webinterface aktualisiert:

Update 1.8

Update 1.8
  • Das Webinterface kann jetzt auch auf mobilen Geräten (Handy, Tablet etc.) benutzt werden
  • Beim Livechat wird jetzt der komplette Chat angezeigt
  • Bei Bans und Mutes kann jetzt nach Spieler gesucht werden
  • Der Chatverlauf kann nun als Textdatei heruntergeladen & gelöscht werden
  • Alle bereits erstellten Chatlogs können jetzt im Webinterface gesucht und angeschaut werden...
Mehr über diese Aktualisierung...
 
Allgemein
Hilfe Benutzer
  • ❤️可愛いちゃん️❤️ ❤️可愛いちゃん️❤️:
    Ich glaub ich hab auf PVP Servern immer falsch gespielt
  • MrSpock78 MrSpock78:
    Was meint ihr warum die 1.8.x so dumm ist? ^^
  • ❤️可愛いちゃん️❤️ ❤️可愛いちゃん️❤️:
    Weil sie scheiße alt ist und grundlegende API Methoden einfach fehlen.
  • MrSpock78 MrSpock78:
    Das hat nichts mit Schnittstellen zu tun, wenn der Client ausrastet^^
  • MrSpock78 MrSpock78:
    Sowas kannst du auch in 1.14.x nicht lösen
  • ❤️可愛いちゃん️❤️ ❤️可愛いちゃん️❤️:
    Minecraft hat halt auch keine Serverseitig Verifizierung der Eingaben
  • ❤️可愛いちゃん️❤️ ❤️可愛いちゃん️❤️:
    Meinte aber eher, dass die 1.8 einfach scheiße alt und total verbuggt ist. Das halt als ob man heute Windows 98 nutzt
  • MrSpock78 MrSpock78:
    Die Schnittstellen bleiben die Gleichen... man kann nur das Spielprinzip ändern. Und das versucht Mojang derzeit, um so mehr sich daran beteiligen um so besser.
  • Hadde-chan Hadde-chan:
    Die schnittstellen haben sich nicht geändert owo erzähl das mal den drölf hunderten plugins, die inkompatibel sind xD
  • SirYwell SirYwell:
    Das Video zeigt ziemlich deutlich, wie dumm dieses sog. PvP in Minecraft ist. Ich finde das irgendwie richtig unnötig, wenns nur darum geht, schnell zu klicken
  • MrSpock78 MrSpock78:
    Es bezog sich auf grob "Alle API methoden sind scheisse usw" ... klar ändert sich etwas.
  • MrSpock78 MrSpock78:
    Der Versuch des neuen Combats ist halt genau dass superschnelles Klicken keinen Vorteil mehr bringt^^
  • ❤️可愛いちゃん️❤️ ❤️可愛いちゃん️❤️:
    Ich fand ja Exploits in den Plugins suchen immer deutlich effektiver als schnelles klicken.
  • maybeto maybeto:
    das ist aber schade für @iTz_Proph3t , auch flinker Finger genannt.....
  • iTz_Proph3t iTz_Proph3t:
    Du meinst der flinkeste Finger im Festen?
  • iTz_Proph3t iTz_Proph3t:
    So nennt man mich auch
  • ❤️可愛いちゃん️❤️ ❤️可愛いちゃん️❤️:
    Press F to pay respect
  • Stern☆ Stern☆:
    F F F
  • Matthias Matthias:
    A A A
  • Matthias Matthias:
    Gute Nacht
  • Matthias Matthias:
    Guten Morgen
  • Stern☆ Stern☆:
    Morgen :)
    Stern☆ Stern☆: Morgen :)
    Oben