Sitzung: Jeden Freitag in der Vorlesungszeit ab 16 Uhr c. t. im MAR 0.005. In der vorlesungsfreien Zeit unregelmäßig (Jemensch da?). Macht mit!

Benutzer:Grey/UDP-Testskript EN: Unterschied zwischen den Versionen

(breadboard constructions)
(What does the transceive-function exactly?)
 
(16 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 59: Zeile 59:
  
  
Da bei unserem defaultPacket noch nicht das Protokoll spezifiziert ist, passen wir es mit der ''set''-Funktion unserer wrapper-Klasse ''fwt_ip'' an. Alle [[Benutzer:Grey/Security_Tool_Developement_Projekt/set-Funktion-IP | Felder ]] des IP-Paket können mit der ''set''-Funktion geändert werden.
+
* The default IP-packet has to be modified, e.g. the correct protocol is not set. To do so, we use the ''set''-funcition of our wrapper-class ''fwt_ip''. All [[Benutzer:Grey/Security_Tool_Developement_Projekt/set-Funktion-IP | fields]] of the IP-packet can be set by the ''set''-function.
  
 
  ip_packet.set ({
 
  ip_packet.set ({
Zeile 66: Zeile 66:
  
  
Da zum Beispiel das Berechnen der ''IHL(Internet Header Length)'' und der ''Header Checksum'' nicht durchgeführt wurden, lassen wir das von unserer FIXUP-Funktion erledigen. Die FIXUP-Funktion wird von unserer wrapper-Klasse zur Verfügung gestellt. Das FIXUP_ALL bewirkt, daß alle Felder('''TODO: WELCHE?''') korrigiert oder angepaßt werden. Unser IP-Paket wird später noch zum Beispiel mit der SourceIP und der DestinationIP bestückt.
+
* The next step is to calculate the ''IHL(Internet Header Length)'' and the ''Header Checksum''. An easy way to do it is to call the FIXUP-function of our wrapper-class. THe FIXUP corrects the fields('''TODO: WELCHE?''') of IP-packet. Our IP-packet will be loaded later with the SourceIP and the DestinationIP.  
  
 
  ip_packet.fixup (fwt_ip.FIXUP_ALL)
 
  ip_packet.fixup (fwt_ip.FIXUP_ALL)
  
  
Momentan haben wir ein IP-Paket als Grundlage für beide UDP-Paket, benötigen aber noch die UDP-Pakete selbst. Wir definieren uns mit Hilfe unserer wrapper-Klasse zwei UDP-Pakete, einmal von Achen nach Bchen und zurück. Diese Pakete werden später der Payload der IP-Pakete sein und haben momentan nur Grundeinstellungen.
+
* Currently we have an IP-packet as basis for both UDP-packets, but be also need the UDP-packets itself. We define with our wrapper-class two UDP-packets, the one for the way from achen to bchen and one for the reversed way. Each of these UDP-packets will be the payload for the IP-packets. They also have now only the base preferences, which have to be modified.
  
 
  udp_pkt_ab = fwt_udp.Packet(fwt_udp.defaultPacket)
 
  udp_pkt_ab = fwt_udp.Packet(fwt_udp.defaultPacket)
Zeile 77: Zeile 77:
  
  
Zwar sind die Grundeinstellungen schon ganz gut, aber trotzdem müssen wir einige Änderungen vornehmen. Als erstes beim UDP-Paket von Achen nach Bchen...
+
* The base preferences are good beginning, but the UDP-packets get to be modified now, e.g.: sourceport, destinationport. At first we modify the UDP-packet from achen to bchen...
  
 
  udp_pkt_ab.set({
 
  udp_pkt_ab.set({
Zeile 85: Zeile 85:
 
     fwt_udp.PAYLOAD:         '\x0a'
 
     fwt_udp.PAYLOAD:         '\x0a'
 
  })
 
  })
...und dann von Bchen nach Achen.
+
* ...and then from bchen to achen.
 
  udp_pkt_ba.set({
 
  udp_pkt_ba.set({
 
     fwt_udp.HEADER_CHECKSUM:      0,
 
     fwt_udp.HEADER_CHECKSUM:      0,
Zeile 93: Zeile 93:
 
  })
 
  })
  
 +
Pay attention that you take the right Destination Port of the service you will use. The payload of the UDP-packet have to be hardcode-implemented in hex.
  
Achten Sie darauf, daß wenn Sie einen bestimmten Dienst eines Servers oder Rechners in Anspruch nehmen, an den korrekten Destinationport das Paket zu schicken. Den Payload eines UDP-Paketes müssen Sie hardcoden in Hexadezimal.
 
  
Wie bei dem IP-Paket machen wir ebenfalls ein FIXUP_ALL beider UDP-Pakete, was die Länge und die ''Header Checksum'' korrigiert oder anpaßt.
+
* Likewise a FIXUP of both UDP-packets have to be done, like the IP-packets. So the length and the ''Header Checksum'' will be corrected or changed:
  
 
  udp_pkt_ab.fixup(fwt_udp.FIXUP_ALL, ACHEN, BCHEN);
 
  udp_pkt_ab.fixup(fwt_udp.FIXUP_ALL, ACHEN, BCHEN);
Zeile 102: Zeile 102:
  
  
Nachdem wir nun unser IP-Grundpaket und unseren UDP-Pakete von Achen nach Bchen und zurück erstellt haben, wollen wir die Pakete vereinen.
+
* After we created our default IP-packet and our modified default UDP-packets, we want to merge these packets to an UDP/IP-packet froma achen to bchen and reverse. The IP-packet listed befor act as a template for the UDP/IP-packet from achen to bchen. The constructor get the IP-packet as a dictionary and retruns a UDP/IP-packet.
Das IP-Paket von oben dient uns als Vorlage für unser UDP/IP-Paket von Achen nach Bchen. Wir übergeben unserem Konstruktor das IP-Paket als Dictionary.  
 
  
 
  ip_udp_pkt_ab = fwt_ip.Packet(ip_packet.as_dict())
 
  ip_udp_pkt_ab = fwt_ip.Packet(ip_packet.as_dict())
  
  
Das UDP/IP-Paket braucht natürlich das Ziel, daß es ansteuern soll und der Empfänger muß auch wissen wohin er die Antwort schicken müßte. Als Payload, wie schon weiter oben erwähnt, übergeben wir das UDP-Paket in Form eines String.  
+
* The UDP/IP-packet needs a destination- and source-IP. As the payload, mentioned above, we refer the UDP-packet(as string).
  
 
  ip_udp_pkt_ab.set({
 
  ip_udp_pkt_ab.set({
Zeile 117: Zeile 116:
  
  
Da jetzt im IP-Paket die SourceIP- und die DestinationIP-Adresse gesetzt wurde, muß auch die ''Header Checksum'' neu berechnet werden. Genau das machen wir mit unserem FIXUP.
+
* Yet we have set the IP-packet with the destination- and source-IP, but the ''Header Checksum'' must be generate as once again. This will do the FIXUP.
 
   
 
   
 
  ip_udp_pkt_ab.fixup(fwt_ip.FIXUP_ALL)
 
  ip_udp_pkt_ab.fixup(fwt_ip.FIXUP_ALL)
  
  
Das gleiche müsssen wir nun mit dem UDP-Paket von Bchen nach Achen machen.
+
* The same must be done for the UDP-packet from bchen to achen.
  
 
  ip_udp_pkt_ba = fwt_ip.Packet(ip_packet.as_dict())
 
  ip_udp_pkt_ba = fwt_ip.Packet(ip_packet.as_dict())
Zeile 133: Zeile 132:
  
  
Zum Ausgeben der empfangenen Pakete brauchen wir eine print-Funktion (''printResult''). Sie prüft, ob an Achen oder Bchen ein Paket ankam und gibt es aus, andernfalls wenn gar kein Paket ankam, wird der Fehler ''Timeout'' ausgegeben.
+
* For printing the received packets a print-function(''printResult'') is needed. The function checks if achen or bchen received any packet and print it on the standard out otherwise an error(''timeout'') is returned.
  
 
  def printResult (result):
 
  def printResult (result):
Zeile 144: Zeile 143:
  
  
Wir schauen, ob die Option dry_run gleich 1 ist. Sollte sie 1 sein, werden lediglich die Pakete auf der Konsole ausgegeben.
+
* If the dry_run option is 1, the packets are printed out to the console.
  
 
  if dry_run == 1:
 
  if dry_run == 1:
Zeile 152: Zeile 151:
  
  
Ab diesem Punkt wird es ernst und die Pakete werden wirklich gesendet.
+
* At this point it gets more serious and the packets will be send
  
 
'''TODO'''
 
'''TODO'''
Zeile 160: Zeile 159:
 
     fwt_ip.set_coarse_filter_and_arp (fwt_ip.IFACE_B, [ ("10.128.0.2", "10.255.255.255")])
 
     fwt_ip.set_coarse_filter_and_arp (fwt_ip.IFACE_B, [ ("10.128.0.2", "10.255.255.255")])
  
Auch hier kommt eine der Zwei Variablen von oben ins Spiel, so daß bei response_only gleich 1 nur das UDP/IP-Paket von Bchen nach Achen gesendet wird. Mittels [[Benutzer:Grey/UDP-Testskript#transceive-Funktion|transceive-Funktion]] wird dann unser UDP/IP-Paket von Bchen nach Achen versendet. Das angekommene Paket wird in ''result'' an die erste Stelle gespeichert und ausgegeben.
+
 
 +
* If the second variable(response_only) is 1 only the packet from bchen to achen will be send by the [[Benutzer:Grey/UDP-Testskript#transceive-Funktion|transceive-function]], the packet from achen to bchen is skipped. The received packet is stored in ''result''.
 
'''TODO''':an welche stelle wird paket in result gespeichert?
 
'''TODO''':an welche stelle wird paket in result gespeichert?
  
 
     if response_only == 1:
 
     if response_only == 1:
 
           print 'Will send IP packet b->a:\n%r\n' % ip_udp_pkt_ba
 
           print 'Will send IP packet b->a:\n%r\n' % ip_udp_pkt_ba
           result = fwt_ip.transceive (fwt_ip.IFACE_B, ip_udp_pkt_ba, filterA=FILTER_A, filterB=FILTER_B, timeoutA=500, timeoutB=0)
+
           result = fwt_ip.transceive (
 +
                        fwt_ip.IFACE_B,  
 +
                        ip_udp_pkt_ba,  
 +
                        filterA=FILTER_A,  
 +
                        filterB=FILTER_B,  
 +
                        timeoutA=500,  
 +
                        timeoutB=0
 +
                  )
 
           printResult (result)
 
           printResult (result)
 
   
 
   
Andernfalls wird erst das UDP/IP-Paket von Achen nach Bchen und dann zurück gesendet. Die Ergebnissse werden ebenfalls in ''result'' gespeichert.
+
 
 +
* Otherwise the UDP/IP-packet from achen to bchen is send and than the packet from bchen to achen. The received packet are stored again in ''result''.
  
 
     else:
 
     else:
 
           print 'Will send IP packet a->b:\n%r\n' % ip_udp_pkt_ab
 
           print 'Will send IP packet a->b:\n%r\n' % ip_udp_pkt_ab
           result = fwt_ip.transceive (fwt_ip.IFACE_A, ip_udp_pkt_ab,  filterA=FILTER_A, filterB=FILTER_B, timeoutA=0, timeoutB=500)
+
           result = fwt_ip.transceive (
 +
                        fwt_ip.IFACE_A,  
 +
                        ip_udp_pkt_ab,   
 +
                        filterA=FILTER_A,  
 +
                        filterB=FILTER_B,  
 +
                        timeoutA=0,  
 +
                        timeoutB=500
 +
                  )
 
           printResult (result)
 
           printResult (result)
 
           if result[1] is not None:
 
           if result[1] is not None:
 
               print 'Will send IP packet b->a:\n%r\n' % ip_udp_pkt_ba
 
               print 'Will send IP packet b->a:\n%r\n' % ip_udp_pkt_ba
               result = fwt_ip.transceive (fwt_ip.IFACE_B, ip_udp_pkt_ba, filterA=FILTER_A, filterB=FILTER_B, timeoutA=500, timeoutB=0)
+
               result = fwt_ip.transceive (
 +
                              fwt_ip.IFACE_B,  
 +
                              ip_udp_pkt_ba,  
 +
                              filterA=FILTER_A,  
 +
                              filterB=FILTER_B,  
 +
                              timeoutA=500,  
 +
                              timeoutB=0
 +
                        )
 
               printResult (result)
 
               printResult (result)
 
           else:
 
           else:
Zeile 183: Zeile 205:
  
  
[http://www.freitagsrunde.org/~grey/sonstiges/std/netdate.py  kompletter Code von netdate].
+
[http://www.freitagsrunde.org/~grey/sonstiges/std/netdate.py  complete code of netdate].
 +
 
 +
== transceive-function ==
 +
The transceive-function is mostly the core of our testscript. It is responsable for sending the packets from source to destination. For a better understanding of the transceive-function we need to answer some questions:
 +
 
 +
=== What does the transceive-function exactly? ===
 +
 
 +
'''TODO:''' Erklärung
 +
 
 +
=== Which parameters are expected of the transceive-function? ===
 +
 
 +
A typical call of the transceive-function is listed below:
 +
 
 +
result = fwt_ip.transceive (
 +
                fwt_ip.IFACE_B,
 +
                ip_udp_pkt_ba,
 +
                filterA=FILTER_A,
 +
                filterB=FILTER_B,
 +
                timeoutA=500,
 +
                timeoutB=0
 +
        )
 +
 
 +
The first parameter defines the interface from which the packet is send, followed by the complete UDP/IP-packet (here from bchen to achen or generaly from source to destination). The third and fourth defines the filters for achen and bchen, followed by the timeouts for achen and bchen.
  
== transceive-Funktion ==
+
=== Which result is returned by transceive? ===
 +
After transceive send the packet, it returns a python-dictionary with the values of the packet received on the other side.
 +
In our netdate-example the first received packet is stored in result[1], so we can check if a packet is arrived or not by validating result[1].

Aktuelle Version vom 15. Oktober 2005, 20:40 Uhr

UDP-testscript

breadboard constructions

There are different variations of breadboard constructions for FWTEST and the FWAGENT, see here: breadboard constructions

netdate-example

On the basis of an example we want to illustrate an implementation of a testscript. For example, we want to make a draft on the netdate-service of www.heise.de (we don't really to make a draft on www.heise.de, but we only simulate the traffic) for getting the actual time. Netdate exists for UDP and TCP, we take here the UDP-variation.

if we would eavesdrop the traffic with etereal or tcpdump, the packets should look like that they are real and not generated(more to this topic here: Limits of tests).

Basically we are processing following credits:

  1. creating default IP-packet(achen -> bchen)
  2. creating default IP-packet(bchen -> achen)
  3. creating default UDP-packet(achen -> bchen)
  4. creating default UDP-packet(bchen -> achen)
  5. adjusting IP-packet
  6. adjusting UDP-packet
  7. merging IP- and UDP-packets
  8. sending UDP/IP-packets via transceive-function
  9. evaluation



Now we take a closer look at the testscript, at the end will be the link to the complete source code of the netdate-script:

  • At first we have to import our wrapper-classes (with prefix fwt_) and other needed classes:
import fwt_ip      # wrapper-Klasse zum erstellen/ändern von IP-Paketen
import fwt_udp     # wrapper-Klasse zum erstellen/ändern von UDP-Paketen
import fwt_tcp     # wrapper-Klasse zum erstellen/ändern von TCP-Paketen
import posix       # TODO: Erklärung


  • After that we define two variables for debugging. dry_run is for run called dry-run, which do the packet creation, but the finally sending is skipped. The second effects, that only bchen will send their packets, packets from achen are skipped.
dry_run=0	    # if set the transceive function is skipped
response_only=0    # send time protocol response only


  • TODO Wir müssen die Beiden Agenten Achen und Bchen mit einer IP-Adresse festlegen.
ACHEN='10.000.2.2'
BCHEN='10.128.2.2'


  • TODO
FILTER_A="not tcp port 1500 and src " + BCHEN + " and dst " + ACHEN + " or icmp"
FILTER_B="not tcp port 1500 and src " + ACHEN + " and dst " + BCHEN + " or icmp"


  • As basis we need our IP-packet as we generated here. We can use our wrapper-class fwt_ip to create the default IP-packet.
ip_packet = fwt_ip.Packet(fwt_ip.defaultPacket)


  • The default IP-packet has to be modified, e.g. the correct protocol is not set. To do so, we use the set-funcition of our wrapper-class fwt_ip. All fields of the IP-packet can be set by the set-function.
ip_packet.set ({
    fwt_ip.HEADER_PROTOCOL: 17,
})


  • The next step is to calculate the IHL(Internet Header Length) and the Header Checksum. An easy way to do it is to call the FIXUP-function of our wrapper-class. THe FIXUP corrects the fields(TODO: WELCHE?) of IP-packet. Our IP-packet will be loaded later with the SourceIP and the DestinationIP.
ip_packet.fixup (fwt_ip.FIXUP_ALL)


  • Currently we have an IP-packet as basis for both UDP-packets, but be also need the UDP-packets itself. We define with our wrapper-class two UDP-packets, the one for the way from achen to bchen and one for the reversed way. Each of these UDP-packets will be the payload for the IP-packets. They also have now only the base preferences, which have to be modified.
udp_pkt_ab = fwt_udp.Packet(fwt_udp.defaultPacket)
udp_pkt_ba = fwt_udp.Packet(fwt_udp.defaultPacket)


  • The base preferences are good beginning, but the UDP-packets get to be modified now, e.g.: sourceport, destinationport. At first we modify the UDP-packet from achen to bchen...
udp_pkt_ab.set({
    fwt_udp.HEADER_CHECKSUM:      0,
    fwt_udp.HEADER_SOURCEPORT:   53,
    fwt_udp.HEADER_DESTPORT:     37,
    fwt_udp.PAYLOAD:	         '\x0a'
})
  • ...and then from bchen to achen.
udp_pkt_ba.set({
    fwt_udp.HEADER_CHECKSUM:      0,
    fwt_udp.HEADER_SOURCEPORT:   37,
    fwt_udp.HEADER_DESTPORT:     53,
    fwt_udp.PAYLOAD: '\x69\xdc\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x77\x77\x77\x05\x68\x65\x69\x73\x65\x02\x64\x65\x00\x00\x01\x00\x01',
})

Pay attention that you take the right Destination Port of the service you will use. The payload of the UDP-packet have to be hardcode-implemented in hex.


  • Likewise a FIXUP of both UDP-packets have to be done, like the IP-packets. So the length and the Header Checksum will be corrected or changed:
udp_pkt_ab.fixup(fwt_udp.FIXUP_ALL, ACHEN, BCHEN);
udp_pkt_ba.fixup(fwt_udp.FIXUP_ALL, BCHEN, ACHEN);


  • After we created our default IP-packet and our modified default UDP-packets, we want to merge these packets to an UDP/IP-packet froma achen to bchen and reverse. The IP-packet listed befor act as a template for the UDP/IP-packet from achen to bchen. The constructor get the IP-packet as a dictionary and retruns a UDP/IP-packet.
ip_udp_pkt_ab = fwt_ip.Packet(ip_packet.as_dict())


  • The UDP/IP-packet needs a destination- and source-IP. As the payload, mentioned above, we refer the UDP-packet(as string).
ip_udp_pkt_ab.set({
    fwt_ip.HEADER_SOURCEIP:	ACHEN,
    fwt_ip.HEADER_DESTIP:	BCHEN,
    fwt_ip.PAYLOAD: udp_pkt_ab.as_str()
})


  • Yet we have set the IP-packet with the destination- and source-IP, but the Header Checksum must be generate as once again. This will do the FIXUP.
ip_udp_pkt_ab.fixup(fwt_ip.FIXUP_ALL)


  • The same must be done for the UDP-packet from bchen to achen.
ip_udp_pkt_ba = fwt_ip.Packet(ip_packet.as_dict())
ip_udp_pkt_ba.set({
    fwt_ip.HEADER_SOURCEIP:	BCHEN,
    fwt_ip.HEADER_DESTIP:	ACHEN,
    fwt_ip.PAYLOAD: udp_pkt_ba.as_str()
})
ip_udp_pkt_ba.fixup(fwt_ip.FIXUP_ALL)


  • For printing the received packets a print-function(printResult) is needed. The function checks if achen or bchen received any packet and print it on the standard out otherwise an error(timeout) is returned.
def printResult (result):
    if result[0] is not None:
         print 'Received on A:\n%r\n' % result[0]
    if result[1] is not None:
         print 'Received on B:\n%r\n' % result[1]
    if result[0] is None and result[1] is None:
         print 'Timeout'


  • If the dry_run option is 1, the packets are printed out to the console.
if dry_run == 1:
    print 'dry_run: skip all transceive functions'
    print 'Would send IP packet a->b:\n%s\n' % repr(ip_udp_pkt_ab.as_dict())
    print 'Would send IP packet b->a:\n%s\n' % repr(ip_udp_pkt_ba.as_dict())


  • At this point it gets more serious and the packets will be send

TODO

else:
    fwt_ip.set_coarse_filter_and_arp (fwt_ip.IFACE_A, [ ("10.000.0.2", "10.127.255.255")])
    fwt_ip.set_coarse_filter_and_arp (fwt_ip.IFACE_B, [ ("10.128.0.2", "10.255.255.255")])


  • If the second variable(response_only) is 1 only the packet from bchen to achen will be send by the transceive-function, the packet from achen to bchen is skipped. The received packet is stored in result.

TODO:an welche stelle wird paket in result gespeichert?

    if response_only == 1:
         print 'Will send IP packet b->a:\n%r\n' % ip_udp_pkt_ba
         result = fwt_ip.transceive (
                        fwt_ip.IFACE_B, 
                        ip_udp_pkt_ba, 
                        filterA=FILTER_A, 
                        filterB=FILTER_B, 
                        timeoutA=500, 
                        timeoutB=0
                  )
         printResult (result)

  • Otherwise the UDP/IP-packet from achen to bchen is send and than the packet from bchen to achen. The received packet are stored again in result.
    else:
         print 'Will send IP packet a->b:\n%r\n' % ip_udp_pkt_ab
         result = fwt_ip.transceive (
                        fwt_ip.IFACE_A, 
                        ip_udp_pkt_ab,  
                        filterA=FILTER_A, 
                        filterB=FILTER_B, 
                        timeoutA=0, 
                        timeoutB=500
                  )
         printResult (result)
         if result[1] is not None:
              print 'Will send IP packet b->a:\n%r\n' % ip_udp_pkt_ba
              result = fwt_ip.transceive (
                             fwt_ip.IFACE_B, 
                             ip_udp_pkt_ba, 
                             filterA=FILTER_A, 
                             filterB=FILTER_B, 
                             timeoutA=500, 
                             timeoutB=0
                       )
              printResult (result)
         else:
              print 'Lost origin packet -- Skip sending answer'


complete code of netdate.

transceive-function

The transceive-function is mostly the core of our testscript. It is responsable for sending the packets from source to destination. For a better understanding of the transceive-function we need to answer some questions:

What does the transceive-function exactly?

TODO: Erklärung

Which parameters are expected of the transceive-function?

A typical call of the transceive-function is listed below:

result = fwt_ip.transceive (
               fwt_ip.IFACE_B, 
               ip_udp_pkt_ba, 
               filterA=FILTER_A, 
               filterB=FILTER_B, 
               timeoutA=500, 
               timeoutB=0
        )

The first parameter defines the interface from which the packet is send, followed by the complete UDP/IP-packet (here from bchen to achen or generaly from source to destination). The third and fourth defines the filters for achen and bchen, followed by the timeouts for achen and bchen.

Which result is returned by transceive?

After transceive send the packet, it returns a python-dictionary with the values of the packet received on the other side. In our netdate-example the first received packet is stored in result[1], so we can check if a packet is arrived or not by validating result[1].