Hinweise

Transcription

Hinweise
IT-Sicherheit WS 07/08
Aufgabenblatt 10
1
TCP-Protokoll-Kapselung
Beim Senden werden die Protokoll-Elemente eines Netz-Paketes
auf unterschiedlichen System-Ebenen erstellt und gekapselt:
Ethernet
IP
TCP
Daten
Betriebssystem /
Netz-Adapter
E
T
Netz-Adapter
Betriebssystem,
optional Anwendung
(mit IP_HDRINCL)
Anwendung
Betriebssystem,
optional Anwendung
(mit SOCK_RAW)
2
FIN-Paket erstellen
Analog zu Kapitel 7.5.1, Beispiel hier speziell für Linux:
#define _BSD_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#define
#define
#define
#define
DEST_HOST
DEST_PORT
SOURCE_HOST
SOURCE_PORT
BSD-Version der
Protokoll-Datentypen
verwenden
IP-Header-Definition und
TCP-Header-Definition
"192.168.0.2"
513
"192.168.0.1"
23300
3
Puffer / Zieladresse vorbereiten
char buffer[4096];
struct ip
*ihd = (struct ip *) buffer;
struct tcphdr *thd = (struct tcphdr *)
(buffer+sizeof(struct ip)); Schablone
int buflen
= sizeof(struct ip) +
über den Puffer
legen
sizeof(struct tcphdr);
memset(buffer,0,4096); // clear buffer
Namensstruct sockaddr_in server;
Auflösung
server.sin_family
= PF_INET;
server.sin_addr.s_addr = inet_addr(DEST_HOST);
server.sin_port
= htons(DEST_PORT);
4
IP-Header füllen
0
vom System ausgefüllt
in 32-Bit-Worten
8
4
Version
IHL
IPVERSION
5
16
19
24
Type Of Service
Packet Length
IPTOS_LOWDELAY
Flags
Packet Identifier
Fragment Offset
IP_DF
Time To Live
Protocol
IPDEFTTL
IPPROTO_TCP
31
Header Checksum
Source Address
SOURCE_HOST
Destination Address
DEST_HOST
Achtung: Alle Werte in network byte order (Big-Endian) !
Zuweisung immer mit htons(short) bzw. htonl(long)
5
TCP-Header füllen
0
3
8
10
Source Port
16
SOURCE_PORT
24
Destination Port
31
DEST_PORT
Sequence Number
Acknowledgement Number
Offset
5
0
U A P R S F
R C S S Y I
G K H T N N
TCP Checksum
Window Size
Urgent Pointer
Achtung: TCP-Prüfsumme muss manuell berechnet werden !
TCP-Paket wird sonst vor der Auswertung verworfen.
6
IP-Header füllen (Code)
ihd->ip_v = IPVERSION;
ihd->ip_id = htons(random());
ihd->ip_src.s_addr = inet_addr(SOURCE_HOST);
ihd->ip_dst.s_addr = server.sin_addr.s_addr;
ihd-> ...
thd->th_sport
thd->th_dport
thd->th_flags
thd->th_sum =
thd-> ...
= htons(SOURCE_PORT);
= htons(DEST_PORT);
= TH_FIN;
...
7
TCP/IP-Prüfsummen
RFC 793: "The checksum field is the 16 bit one's complement of the
one's complement sum of all 16-bit words in the header and text."
Zur Erinnerung:
●
Bei der Einerkomplement-Darstellung wird eine negative Zahl
durch die bitweise Invertierung der positiven Zahl dargestellt
●
Es gibt damit zwei Nullen: +0=00000000 und -0=11111111
●
Berechnung in C mit Operator ~
Einerkomplement-Addition auf
Zweierkomplement-Maschine:
Addiere Zahlen regulär, dann
addiere Übertrag zum Ergebnis
1110 (-1 )
+
0011 ( 3 )
= 1 0001 ( 1!)
+
0001 (carry)
=
0010 ( 2 )
Übrigens: byteorder dabei unerheblich, da zyklische Operation!
8
Einerkomplement-Addition (Code)
// add b to accumulator a
void ocadd(u_short *a, u_short b)
{
u_int val = *a + b; // expand to int
val += val >> 16;
// add carry
*a = (u_short)val; // reduce back to short
}
// add nelm elements of elm list to accumulator
void ocsum(u_short *sum, u_short *elm, int nelm)
{
// count down elements, advance list pointer
while (--nelm >= 0) ocadd(sum, *(elm++));
}
// tcpsum = ~ ocsum( headerdata )
9
TCP-Prüfsumme berechnen
0
3
8
10
inklusive
PseudoHeader
0
3
16
Source Address
SOURCE_HOST
Destination Address
DEST_HOST
8
IPPROTO_TCP
10
Source Port
31
TCP Length (Header+Data)
Protocol
0
24
16
sizeof(struct
24 tcphdr)
SOURCE_PORT
Destination Port
31
DEST_PORT
Sequence Number
Acknowledgement Number
Offset
5
U A P R S F
R C S S Y I
G K H T N N
0
0
Window Size
Urgent Pointer
10
Paket abschicken (endlich!)
// create raw IP socket
int sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
// indicate that IP header is included in buffer
int one = 1; // enable option
setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL,
&one, sizeof(one));
und dann wiederholt:
// ...construct TCP/IP message...
// send message
sendto(sockfd, buffer, buflen, 0,
(struct sockaddr *)&server, sizeof(server));
11
Pakete abhören mit libpcap
●
Prozedur für packet sniffing aufwendig und plattform-spezifisch
●
libpcap bietet plattformunabhängige Alternative
●
inzwischen von fast allen Sniffern verwendet (tcpdump, ethereal, ...)
●
Dokumentation: man 3 pcap
●
Tutorial: http://www.tcpdump.org/pcap.htm
char* dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
bpf_u_int32 maskp;
bpf_u_int32 netp;
struct bpf_program fp;
//
//
//
//
//
//
name of network device
buffer for error messages
packet capture handle
subnet mask of device
ip address of device
compiled filter program
12
PCAP-Initialisierung
// find the first suitable capture device
dev = pcap_lookupdev(errbuf);
if(dev==NULL) { printf("%s\n",errbuf); exit(1); }
// determine network address and mask
pcap_lookupnet(dev,&netp,&maskp,errbuf);
// open device for reading
descr = pcap_open_live(dev,CAPSIZE,1,-1,errbuf);
gespeicherter Inhalt
in Bytes, pro Paket
abhören im
promiscuous mode
Pufferungs-Optimierung
(nicht Lese-Timeout!)
13
Filter-Programme
●
●
●
●
Filter-Programme ermöglichen effiziente Vorauswahl
Komplexe Boolsche Kombinationen von Filtern möglich
Nur übereinstimmende Pakete erreichen Anwendungs-Code
Details der Filtersprache: man 1 tcpdump
// define some filter program
char* filter = "src host 192.168.0.1";
// compile the filter program, non-optimized
pcap_compile(descr, &fp, filter, 0, netp);
// set the compiled program as the filter
pcap_setfilter(descr, &fp);
14
Paket-Behandlung
Paket-Annahme einzeln:
struct pcap_pkthdr header;
const u_char* packet = pcap_next(descr, &header);
... oder kontinuierlich:
alternativ: Behandle genau n Pakete
pcap_loop(descr, -1, callback, NULL);
optionales Argument
void callback(u_char *args,
const struct pcap_pkthdr* header,
const u_char* packet)
{
// handle captured packet
if (...) { pcap_close(descr); exit(0) }
}
15
Timeouts
Achtung, kontinuierliche Paket-Behandlung erlaubt keinen Timeout!
Stattdessen z.B. Signal-Unterbrechung einstellen:
signal(SIGALRM, timeout);
alarm(5); // time in seconds
pcap_loop(....);
mit Behandlungs-Routine:
void timeout(int sig) {
// handle timeout
signal(SIGALRM, timeout);
timeout(5); // restart timer
}
16
Ethernet-Header
Empfangene Pakete enthalten komplette Protokoll-Elemente
inklusive Ethernet-Header !
Definition: struct ether_header in <net/ethernet.h>
0
(Offset in Bytes)
6
Source MAC Address
12
Destination MAC Address
13
EtherType
00:11:22:33:44:55
aa:bb:cc:dd:ee:ff
ETHERTYPE_IP(0x0800)
17