[python] socket programmeren met 1 kant data op

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Hoi allemaal,

Ik ben bezig met een CTFje te schrijven (normaal doe ik ze) en ik ben nu eens met sockets aan het pielen in Python. Punt is dat ik daar nog nooit wat mee gedaan heb en niet voor elkaar krijg wat ik wil.

Mijn CTF doet alsof hij een number station is, op bepaalde momenten (elke paar minuten) moet hij data sturen naar alle clients. Soms is het dus ook even stil.
Het aantal clients gaat niet gek hoog zijn, en performance is dus geen issue. Wel is het zo dat omdat het soms stil is ik geen timeouts wil hebben en de clients zo simpel mogelijk wil houden (lees mensen moeten zelf maar wat in elkaar beunen met netcat/socat/python).


Nu wil je bij een reguliere TCP verbinding telkens data heen en weer sturen. Dat wil ik niet doen, mensen moeten gewoon kunnen luisteren. Ik heb het nu lokaal prima werkend gekregen met deze opstelling:

code:
1
2
3
4
5
6
7
8
while True:
    MESSAGE='a'
    print ( MESSAGE)
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
    sock.sendto(MESSAGE, (127.0.0.1, 1602))
  else: 
   print(seconds, "NOTHING SENT")
  time.sleep(1)

En dan met
socat UDP-RECV:1602 STDOUT
krijg ik netjes elke seconde wat data binnen.

Maar goed, dan stuur ik zelf gericht naar mijn socat de data terwijl ik het eigenlijk omgedraaid wil. Ik heb UDP gekozen omdat ik dan niet over handshakes enzo hoef na te denken, maar iets in me zegt me dat me dit hier op kan breken (hoe weet de server welke clients er luisteren...).
Dan maar TCP?
Het verveldende met een TCP-socket in dit soort voorbeelden (https://docs.python.org/3/howto/sockets.html) is dat je telkens moet wachten tot de client je data heeft gestuurd. Ik wil eigenlijk dat de client helemaal niets hoeft te zenden als de connectie er eenmaal is.

Als alternatief zou ik op het netwerk kunnen broadcasten maar dat vind ik niet zo supersjiek bij een CTF. Kan iemand me een duw de goeie kant op geven?

[ Voor 10% gewijzigd door Boudewijn op 06-07-2018 21:43 ]

i3 + moederbord + geheugen kopen?

Alle reacties


Acties:
  • 0 Henk 'm!

  • plukke
  • Registratie: Februari 2005
  • Laatst online: 19-09 18:39
Je zult een vorm van handshaking moeten gaan doen om je connectie op te zetten. Dit kan heel simpel, door in je python script een listening UDP socket te maken op poort xxx. Zodra er daar een connectie binnen komt (geinitieerd door de client) sla je dat IP address op in een lijstje van aangemelde clients. Vervolgens stuur je in je huidige programma een UDP bericht naar de clients die in je lijstje staan. :)

Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Ach dat is eigenlijk best een elegant idee. Dank je wel... stom dat ik daar niet aan gedacht heb.

i3 + moederbord + geheugen kopen?


Acties:
  • 0 Henk 'm!

  • kluyze
  • Registratie: Augustus 2004
  • Niet online
Is er een reden waarom je dit met sockets wil oplossen? En niet naar iets als een MQTT verbinding kijkt? MQTT werkt namelijk met topics.

Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Nee dat maakt ook eigenlijk best wel veel kans. De eigenlijke reden voor sockets was weten dat ik daar nog weinig server-side mee gedaan heb... en dus wil leren.

Maar dit klinkt wel een stuk makkelijker. Heb niet zoveel zin om allerlei threads enzo te bouwen.

i3 + moederbord + geheugen kopen?


Acties:
  • 0 Henk 'm!

  • Lone Gunman
  • Registratie: Juni 1999
  • Niet online
ik zou het gewoon bij plain text over tcp houden, lekker makkelijk voor de clients. deze kunnen dan met telnet/putty/etc verbinding maken en de doorgestuurde informatie direct lezen. alleen luisteren (vanuit het perspectief van de client) is trouwens gewoon mogelijk via tcp, er is geen verplichting dat er vanuit de client iets gestuurd wordt.

je zou bv. eens kunnen kijken naar twisted voor python, dit is een event driven framework dat een groot deel van het werk van connecties opzetten, bijhouden etc voor je regelt waardoor je je niet bezig hoeft te houden met threads en low level tcp code. in principe implementeer je vooral callback functies die automatisch aangeroepen worden als er iets gebeurd, bv. als een nieuwe client connect, of als een bepaalde geplande taak actief wordt.

Zie ook een korte inleiding over het schrijven van een server en taken gebruiken om terugkerende acties uit te voeren.

Experience has taught me that interest begets expectation, and expectation begets disappointment, so the key to avoiding disappointment is to avoid interest.


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Om timeouts te voorkomen zou je spaties (of 0-bytes of whatever) kunnen sturen als "stilte" (heartbeat). Ook zou je kunnen kijken naar udp broadcast/multicast (want dat is eigenlijk wat je wil en dichter bij je voorbeeld), maar dat beperkt je wel weer tot je LAN. Ik weet niet of dat een probleem is.

(Overigens; ík moest CTF googlen, maar ik ben misschien oud :X maar wellicht toch even verduidelijken in je TS?)

[ Voor 33% gewijzigd door RobIII op 07-07-2018 08:50 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
@RobIII Geen probleem :)
CTF (capture de flag) is een hackwedstrijdje op daarvoor klaargezette doelen, ik doe dat al jaren als deelnemer maar nu voor het eerst wat dingen in elkaar zetten.

LAN is geen probleem, dus broadcast kan ook ja. Lelijke van spaties moeten sturen is dat mensen niet makkelijk met netcat kunnen connecten en mee blijven lurken. Vraag me af hoe de andere CTFs zoiets bouwen.

@Lone Gunman ik zal ook eens naar twisted kijken. Hele administratie en threads gaat een beetje voorbij aan het coden van een leuke challenge.
Die publish/subscribe demo ziet er wel goed uit (doet redelijk wat ik wil en niet teveel code :) )
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from twisted.internet import reactor, protocol, endpoints
from twisted.protocols import basic

class PubProtocol(basic.LineReceiver):
    def __init__(self, factory):
        self.factory = factory

    def connectionMade(self):
        self.factory.clients.add(self)

    def connectionLost(self, reason):
        self.factory.clients.remove(self)

    def lineReceived(self, line):
        for c in self.factory.clients:
            source = u"<{}> ".format(self.transport.getHost()).encode("ascii")
            c.sendLine(source + line)

class PubFactory(protocol.Factory):
    def __init__(self):
        self.clients = set()

    def buildProtocol(self, addr):
        return PubProtocol(self)

endpoints.serverFromString(reactor, "tcp:1025").listen(PubFactory())
reactor.run()
Eens kijken of ik die om kan katten.

[ Voor 46% gewijzigd door Boudewijn op 07-07-2018 13:41 ]

i3 + moederbord + geheugen kopen?


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
TCP keepalive doet volgens mij precies wat je wilt.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Boudewijn schreef op zaterdag 7 juli 2018 @ 11:16:
Lelijke van spaties moeten sturen is dat mensen niet makkelijk met netcat kunnen connecten en mee blijven lurken. Vraag me af hoe de andere CTFs zoiets bouwen.
Geen idee hoe andere CTF's dat doen, maar een "heartbeat" is vrij normaal. En i.p.v. spaties kun je natuurlijk iedere willekeurige byte(s) versturen.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Ik heb het uiteindelijk heel simpel gedaan met een UDP-broadcast:

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# set up socket
cs = socket(AF_INET, SOCK_DGRAM)
cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)

buffer = []
buffer = createBuffer()

while True:
    seconds = getSeconds()
    if seconds == 0:
        buffer = createBuffer()

    if seconds < len(buffer):
        MESSAGE = buffer[seconds]
        if DEBUG:
            print(seconds, MESSAGE)
        cs.sendto(str.encode(MESSAGE), ('255.255.255.255', PORT))
    time.sleep(1)
negeer dat buffer-verhaal maar. dat bevat mijn varierende CTF-flag ;).

[ Voor 6% gewijzigd door Boudewijn op 07-07-2018 13:39 ]

i3 + moederbord + geheugen kopen?

Pagina: 1