Seite 1 von 1
Python Code-Hacking Game
Verfasst: Montag 24. August 2015, 09:21
von CrytoChris
Hallo zusammen,
ich habe mich in letzter Zeit etwas mit den Kryptowährungen beschäftigt und fand das ganze Prinzip recht interessant.
Daraus entstand eine Idee. Ich würde gern ein kleines Experiment starte:
I möchte einen Server hosten, der ein "Passwort" bereithält. Der Server soll von aussen erreichbar sein und mehrere Clients aufnehmen.
Nun soll jeder Client, der mit dem Server verbunden ist, per einfacher Iteration versuchen das Passwort zu lösen.
Der Client, der zuerst gelöst hat, gewinnt
Server- und Clientsoftware soll in Python laufen.
Meine Idee ist:
Der Server ist ein Pythonprogramm, dass durch "sockets" einen Server erstellt.
Ich werde ebenfalls eine Client-Software zur Verfügung stellen, die die Clients nutzen sollen um das Passwort zu lösen.
Jeder Lösungsversuch soll dann an den Server gesendet werden, der dann das Empfangene mit dem Passwort abgleicht und entsprechend darauf antwortet.
Schema:
Code: Alles auswählen
if client_guess == passphrase:
answer:"You win"
else:
answer "Try again"
Die Software der Clients läuft in einer Endlosschleife.
Hierbei handelt es sich lediglich um eine Idee zu der es noch keinerlei Code gibt.
Ist mein Vorhaben so machbar?
Kann ich in der Client-Software evtl. einfach eine simple random() -Funktion nutzen um den Code zu lösen?
Im Prinzip ist das Ganze wohl ähnlich eines Bruteforce-Angriffs, der allerdings gewollt ist
Danke schonmal
Re: Python Code-Hacking Game
Verfasst: Montag 24. August 2015, 09:31
von sparrow
Warum sollte es nicht machbar sein?
Wenn dein Server-Programm auf einen Netzwerkport lauscht und dort eine Zeichenkette entgegennimmt um dann zu antworten ob diese identisch mit der vorhandenen ist, dann ist es egal in welcher Sprache das Programm geschrieben ist, das sich als Client auf diesen Port verbindet.
Als Fingerübung ist das vielleicht ganz interessant, ich gebe aber zu bedenken, dass gut administrierte Systeme solche Brutefoce-Angriffe in der Regel verhindern.
Re: Python Code-Hacking Game
Verfasst: Montag 24. August 2015, 17:03
von CrytoChris
Hey,
danke für die Antwort.
Ich habe mal etwas zusammengezimmert, allerdings super simpel. Generell funktioniert es auch. Bei einem vierstelligen Passwort, kann die Lösung zwischen 30 Sekunden und 1 Minute erfolgen.
Hat jemand Ideen um das Ganze etwas spannender zu gestalten? Gibt es z.B. andere Möglichkeiten als random(), so dass die Clients z.B. jede Kombination nur einmal versuchen?
Gibts eine Grundlage die Lösungszeit zu berechnen, z.B. bei zehnstelligem Passwort?
Server:
Code: Alles auswählen
import socket
Quelle='' # Offen fuer alle
Port=123
e_udp_sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
e_udp_sock.bind( (Quelle,Port) )
def listen():
passwort = "123"
while 1:
data, addr = e_udp_sock.recvfrom( 1024 )
print "empfangene Nachricht:", data
print "Clientadresse:", addr
if data == passwort:
Nachricht2= "geloest"
e_udp_sock.sendto( str(Nachricht2), (addr) )
print "geloest"
break
else:
Nachricht2= "weiter versuchen"
e_udp_sock.sendto( str(Nachricht2), (addr) )
print "antwort gesendet ", Nachricht2, "an ", addr
continue
listen()
Client:
Code: Alles auswählen
import socket
import random
import sys
Ziel='IP des Servers'
Quelle=' '
Port=123
s_udp_sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
s_udp_sock.bind( (Quelle,Port) )
def sende():
Nachricht= random.randint(1, 999)
print "Nachricht:", Nachricht
s_udp_sock.sendto( str(Nachricht), (Ziel,Port) )
data, addr = s_udp_sock.recvfrom( 1024 )
if data == "geloest":
print "fertig"
sys.exit()
else:
print data
while True:
sende ()
Re: Python Code-Hacking Game
Verfasst: Montag 24. August 2015, 18:21
von Dav1d
CrytoChris hat geschrieben:Hat jemand Ideen um das Ganze etwas spannender zu gestalten? Gibt es z.B. andere Möglichkeiten als random(), so dass die Clients z.B. jede Kombination nur einmal versuchen?
In dem du das ganze nicht mit random machst sondern kombinatorisch (bzw. Markov Chains?) löst, also einfach der Reihe nach alle Möglichkeiten durchgehen (Tipp: itertools-Modul).
Du solltest statt UDP lieber TCP verwenden, denn du willst ja dass alle deine Versuche ankommen und nicht manche verloren gehen.
Außerdem solltest du einen Blick in die
PEP-8 wagen

.
Um die Dauer des Testens aller möglichen Passwörter kannst du einen Durchschnitt von ca. 100.000 Versuchen nehmen und den mit der Anzahl aller Möglichen Versuche multiplizieren.
Re: Python Code-Hacking Game
Verfasst: Montag 24. August 2015, 19:56
von CrytoChris
Hey,
vielen Dank. Werde ich mir anschauen.
Eine Frage habe ich noch vorab
Im lokalen Netzwerk funktioniert das Ganze super und vor allem schnell.
Greife ich nun von "Aussen" auf den Server zu (mittels Umleitung im Router), so ist das ganze echt langsam. Ca. 1-2 Lösungsversuche pro Sekunde.
Und zusätzlich hört die Kommunikation nach 10-20 Versuchen auf.
Jedoch ohne Fehlermeldung. Client und Server warten beiden auf Antwort.
Gibt`s dafür eine spontane Erklärung?
Danke
Re: Python Code-Hacking Game
Verfasst: Montag 24. August 2015, 19:58
von BlackJack
@CrytoChris: Vielleicht genau das Problem mit UDP: Die Pakete dürfen verloren gehen und man muss seine Programme so schreiben dass das nichts ausmacht.
Re: Python Code-Hacking Game
Verfasst: Montag 24. August 2015, 22:43
von CrytoChris
Jau, danke.
Das war es.
Hab nun eine stabile Lösung mit TCP

Re: Python Code-Hacking Game
Verfasst: Dienstag 25. August 2015, 07:26
von Sirius3
@CrytoChris: zeig mal den Code. Ich habe den Verdacht, die "stabile Lösung mit TCP" ist nur scheinbar stabil.
Re: Python Code-Hacking Game
Verfasst: Dienstag 25. August 2015, 09:17
von CrytoChris
Aber nur, wenns keine doofen Kommentare bezüglich meiner Holzhammer-Prozessbeendungsmethode gibt

Vielleicht hat in dem Zuge ja noch jemand eine schönere Idee. Ich hab`s mit .join() / .terminate() sowie mit Thread, Threading und Multiprocessing probiert, bekomme die Prozesse allerdings nicht beendet. Sobald ein Client das Passwort gelöst hat, soll der Server natürlich komplett dichtmachen. Anderenfalls lösen die anderen Clients weiter, bis am Ende jeder gewonnen hat
Sever.py
Code: Alles auswählen
import socket
from multiprocessing import Process
import sys
import os
Quelle='' # Offen fuer alle
Port=80
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('', 80)
sock.bind(server_address)
sock.listen(10)
def listenf(connection):
passwort = "5064"
while 1:
data = connection.recv(1024)
print "empfangene Nachricht:", data
if data == passwort:
connection.sendall("Gewinner!")
winmsg=("Super, du hast gewonnen! Passwort: ", data)
connection.sendall(str(winmsg))
print "Der Gewinner ist: ", client_address[0], str(client_address[1])
os.system("killall python")
else:
Nachricht3 = "Dein Loesungsversuch: ", data, " ist falsch."
connection.sendall(Nachricht3)
continue
while True:
connection, client_address = sock.accept()
print("[-] Connected to " + client_address[0] + ":" + str(client_address[1]))
process=Process(target=listenf, args=(connection,))
process.start()
Client.py
Code: Alles auswählen
import socket
import random
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('Server-IP', 80)
sock.connect(server_address)
def sende():
Nachricht= random.randint(1, 9999)
sock.sendall(str(Nachricht))
data = sock.recv(1024)
if data == "Gewinner!":
data = sock.recv(1024)
print data
sys.exit()
else:
print data
while True:
sende ()
Mittlerweile habe ich auch mit itertools eine weitaus schnellere Möglichkeit zur Lösung gefunden. Dieser Code ist aber noch nicht angepasst. Falls Interesse besteht, kann ich heute Nachmittag einmal die Itertools-Variante posten.
Ich werde das Ganze noch etwas erweitern und mehrere Lösungsblöcke erstellen. Sobald von einem Client, ein Block gelöst wurde, soll der nächste Block an der Reihe sein. Am Ende zählen die Anzahl der gelösten Blöcken pro Client.
Re: Python Code-Hacking Game
Verfasst: Dienstag 25. August 2015, 09:43
von BlackJack
@CrytoChris: Also den Kommentar bezüglich des beendens kann man hier leider nicht ersparen, denn das ist wirklich so gar keine gute Idee. Wenn ich das laufen lassen würde, dann würden mir am Ende wichtige Programme beendet die überhaupt nichts mit diesem Code zu tun haben!
Ich würde ja Threads verwenden und da müsste es eigentlich reichen wenn man das `daemon`-Attribut entsprechend setzt damit die zusammen mit dem Hauptthread beendet werden wenn das Programm endet. Und den müsste man aus einem Thread informieren können das Ende ist. Dafür gibt es im `threading`-Modul zum Beispiel das `Event`-Objekt über das man kommunizieren könnte.
Das was Sirius3 wahrscheinlich vermutet hat (und ich auch) ist das falsche verwenden von `recv()`. Ein Aufruf garantiert nicht das die gesamten Daten gelesen wurden, sondern man muss so lange lesen bis man auch ganz bestimmt eine komplette Nachricht gelesen hat. Und wenn über die Leitung mehrere Nachrichten kommen, dann muss man auch damit rechnen das man schon Teile der nächsten Nachricht mitliest und muss sich die merken. Ausser das Protokoll ist strikt Halbduplex, dann kommt man damit aus nur sicherzustellen das man eine Nachricht komplett hat bevor man sie verarbeitet.
Un das mit den kompletten Nachrichten sicherzustellen gibt es im Grunde zwei Verfahren: Man sendet am Anfang die Länge der Nachricht (in einer festen Länge kodiert) damit der Empfänger weiss wieviele Bytes er lesen muss, oder man beendet eine Nachricht mit einem Byte oder einer Bytefolge die garantiert nicht innerhalb der Nachricht vorkommen kann. Beispielsweise ein Zeilenendezeichen oder ein Nullbyte. Dann weiss der Empfänger das er solange lesen muss, bis so ein Byte oder eine Bytefolge angekommen ist bevor er die Nachricht weiterverarbeiten kann.
Schau Dir mal den
Style Guide for Python Code an was die Namenschreibweise und einiges andere an Konventionen bei Python angeht.
Auf Modulebene sollte eigentlich kein Code stehen, ausser welcher der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm gehört in eine Funktion. Die heisst üblicherweise `main()` und wird mit folgendem Idiom aufgerufen:
Dann kann man das Modul importieren ohne das automatisch das Hauptprogramm abläuft. Zum Beispiel um Funktionen in einer Shell zu testen oder automatisiert testen zu lassen, oder in anderen Modulen wiederzuverwenden. Und einige Werkzeuge die mit Python-Modulen arbeiten, erwarten auch das man die ohne Nebeneffekte importieren kann.
Wenn man Wahrheitswerte meint sollte man keine Zahlen benutzen. Also ``while True:`` statt ``while 1:``.
Re: Python Code-Hacking Game
Verfasst: Dienstag 25. August 2015, 11:01
von CrytoChris
Ich habe sowas vermutet
Aber danke, für die konstruktive Kritik.
Ich werde mich heute noch einmal dransetzten.
Würden sich wohl auch eine handvoll Leute bereiterklären, dem "Server" ordentlich zuzusetzen?

Der Server würde auf einem Raspberry laufen und in einem separaten Netzwerk.
Client kann selbst gebaut werden. Gern auch mit Negativbeispielen, die den Server ggf. lahmlegen,
um mir danach ein paar Tips zu geben, die Sicherheitslücke zu schließen?
Vielen Dank