Ist nun häufiger vorgekommen, dass jemand mit einem Spam-Bot eine Sicherheitslücke des BC-Servers ausgenutzt hat.
Wie funktioniert die Sicherheitslücke?
Ganz einfach. Das Chatprotokoll läuft (normalerweise) nach einem Schema ab.
1. Der Client Connected
2. Der Client gibt einen Handshake ab
3. Der Client bekommt Channellist, etc..
4. Weitere Chatinterne Protokolle (Public message, etc..)
Mit einem aushebeln des Handshakes ist es möglich, ohne wirklich angemeldet zu sein, diverse interaktionen zu gestalten.
Der Client konnected zwar, sendet aber kein handshake oder sonstiges, sondern überspirngt diese, nutzt dann aber diverse Opcodes.
Wie fixe ich diese Lücke?
Relativ einfach. Man lässt einfach nicht zu, die anderen Opcodes ansprechen zu lassen.
Der Client ist dann gezwungen einen Handshake zu senden und sich mit einem Nicknamen einzuloggen.
In der SessionHandler wird bei
JEDEM OPCODE-Check,
außer der Handshake-Opcode sowie den Join_Channel-Opcode noch eine weitere Prüfung
|
Java-Quelltext
|
1
2
3
4
|
// Folgendes muss überall eingefügt werden: && client.isAuth()
//[...]
} else if (opcode.equals(ReceiveOpcode.CHAT.getValue()) && client.isAuth()) {
//[...]
|
Achtung:
Nochmal - Das && client.isAuth() muss überall rein, außer beim handshake und beim join-handler!
Wir erstellen nun eine Funktion im Clienten.
In der Client.java setzen wir nun am Anfang eine Variable:
|
Java-Quelltext
|
1
|
private boolean authenticated = false;
|
Und setzen dann die dazugehörigen Methoden:
|
Java-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
|
public void setAuth() {
if(this.authenticated) {
this.authenticated = false;
} else {
this.authenticated = true;
}
}
public boolean isAuth() {
return this.authenticated;
}
|
Jetzt müssen wir nur noch in der JoinChannelHandler anpassen:
|
Java-Quelltext
|
1
2
|
client.setAuth(); // Diese Zeile wird hinzugefügt
client.setLogin();
|
Fertig!
Somit ist der Client gezwungen sich mit einem exitierenden Nicknamen einzuloggen.
In der Beschreibung übernommen:Da dies aber noch keine sicherheit ist, den Spam zu unterbinden, (was ich mir gerade überlegt habe), könnte man die Methode client.setAuth(); erst aufrufen, sobald ein erfolgreicher Login erfolgte.