Moin 
Vorgeschichte:
Ich habe mich in letzter Zeit mit der RAW Socket Programmierung unter Linux beschäftigt und bin auf das folgende Problem gestoßen, auf welches ich bisher keine Lösung gefunden habe.
Ich habe ein C++ Programm geschrieben, welches ein RAW Socket erstellt und die Felder des IP- und TCP-Headers ausfüllt. Dann wird das Paket abgesendet.
Problem:
Dieses von mir generierte TCP/IP Paket (mit SYN-Flag) wird nur in Wireshark oder auch anderen Sniffern anzeigt, wenn die Zieladresse die des sendenden Computers ist. Die Absenderadresse ist hierbei völlig irrelevant und kann auch "gespooft" werden.
Sobald ich als Zieladresse eine andere im Subnetz verfügbare angebe und auf diesem Computer Wireshark laufen lasse, kommt kein Paket an. (unabhängig von der Absenderadresse, also auch nicht "gespoofte" Pakete kommen nicht an.)
Quelltext:
Für Hilfe und Tipps bin ich sehr dankbar, da ich an dieser Stelle hier nicht weiterkomme.
MFG
bl0xx

Vorgeschichte:
Ich habe mich in letzter Zeit mit der RAW Socket Programmierung unter Linux beschäftigt und bin auf das folgende Problem gestoßen, auf welches ich bisher keine Lösung gefunden habe.
Ich habe ein C++ Programm geschrieben, welches ein RAW Socket erstellt und die Felder des IP- und TCP-Headers ausfüllt. Dann wird das Paket abgesendet.
Problem:
Dieses von mir generierte TCP/IP Paket (mit SYN-Flag) wird nur in Wireshark oder auch anderen Sniffern anzeigt, wenn die Zieladresse die des sendenden Computers ist. Die Absenderadresse ist hierbei völlig irrelevant und kann auch "gespooft" werden.
Sobald ich als Zieladresse eine andere im Subnetz verfügbare angebe und auf diesem Computer Wireshark laufen lasse, kommt kein Paket an. (unabhängig von der Absenderadresse, also auch nicht "gespoofte" Pakete kommen nicht an.)
Quelltext:
Code:
// Letzte Änderung: 11.04.2010
// Status: V1.0 [90 %]
#include <stdio.h> // Standard I/O Funktionen wie printf()
#include <stdlib.h> // Standard Funktionen wie exit() und malloc()
#include <string.h> // String und Memory Funktionen wie strcmp() und memset()
#include <unistd.h> // System Calls wie open(), read() und write()
#include <errno.h> // Detailliertere Fehlermeldungen
#include <sys/socket.h> // Socket Funktionen wie socket(), bind() und listen()
#include <arpa/inet.h> // Funktionen wie inet_addr()
#include <netinet/in.h> // IP Protokolle, sockaddr_in Struktur und Funktionen wie htons()
#include <netinet/ip.h> // IP Header Struktur
#include <netinet/tcp.h> // TCP Header Struktur
unsigned short csum(unsigned short *buf, int nwords) // Berechnet Checksumme (nach RFC)
{
unsigned long sum;
for (sum=0; nwords>0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum &0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
int main(int argc, char *argv[])
{
int rawsock, uid; // Variablen deklarieren
struct sockaddr_in addr;
struct iphdr ipheader;
struct tcphdr tcpheader;
unsigned int packetsize = sizeof(struct iphdr) + sizeof(struct tcphdr);
unsigned char packet[packetsize];
struct iphdr *ip = (struct iphdr *)packet;
struct tcphdr *tcp = (struct tcphdr *)(packet + sizeof(struct iphdr));
int one = 1,i,j;
char newip[17];
if (argc!=7) // falls zu wenig Argumente: Anleitung
{
printf("\nUsage: %s <Quelladresse> <Quellport> <Zieladresse> <Zielport> <Paketanzahl> <Zufallsquelladressen?>\n\n",argv[0]);
printf("Beispiele: %s 192.168.0.1 1234 192.168.0.15 80 5000 0\n",argv[0]);
printf(" %s 211.213.4.5 3241 145.321.7.33 21 9999 1\n\n",argv[0]);
exit(1);
}
uid = getuid(); // Ist der User ROOT?
if(uid != 0) // falls nicht, Fehlermeldung u. beenden
{
printf("UID 0 ben\x84tigt!\n",uid);
exit(1);
}
memset(packet,0,packetsize); // Paketbuffer initialisieren
if( (rawsock = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) == -1 ) { perror("socket"); exit(1); } // IP RAW Socket erstellen
if( setsockopt(rawsock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) == -1 ) { perror("setsockopt"); exit(1); } // Kerneleingriff verhindern
ip->version = 4; // IP Version
ip->ihl = 5; // IP-Headerlänge
ip->id = htonl(random()); // IP ID
ip->saddr = inet_addr(argv[1]); // Quelladresse [kann gespooft werden]
ip->daddr = inet_addr(argv[3]); // Zieladresse
ip->ttl = 123; // time-to-live
ip->protocol = IPPROTO_TCP; // nachfolgendes Protokoll [TCP=6 o. IPPROTO_TCP]
ip->tot_len = packetsize; // Größe des IP Pakets
ip->check = 0; // IP Checksumme [0=Kernel übernimmt]
tcp->source = htons(atoi(argv[2])); // Quellport
tcp->dest = htons(atoi(argv[4])); // Zielport
tcp->seq = htonl(1000000000); // Sequenz nummer
tcp->ack_seq = 0; // Acknowledgement nummer
tcp->ack = 0; // TCP Flags
tcp->syn = 1;
tcp->window = htons(4096); // Windowgröße
tcp->check = 0; // TCP Checksumme [0=Kernel übernimmt]
tcp->doff = 5; // TCP-Headerlänge
addr.sin_family = AF_INET; // Adressfamilie u. Adressen angeben
addr.sin_port = tcp->source;
addr.sin_addr.s_addr = ip->saddr;
printf("\nSende...\n"); // Statusmeldung für User
for (i=0;i<atoi(argv[5]);i++) // Schleife für Paketversand
{
if (argv[6]==1) // Modus: Zufallsadressen gewählt?
{
for (j=0;j==3;j++) // Zufallsadresse berechnen
{
strcat(newip,random()%255);
strcat(newip,".");
}
ip->saddr = htons(newip); // Neue Adresse in den IP-Header eintragen
}
if( (sendto(rawsock,packet,packetsize,0,(struct sockaddr*)&addr,sizeof(struct sockaddr_in))) == -1 ) //Paket absenden
{
perror("Fehler beim Versenden der Pakete!"); // Falls Fehler beim senden: Fehlermeldung + Beenden
exit(1); // Programm beenden
}
}
printf("Pakete erfolgreich versendet!\n\n"); // Statusmeldung für User
close(rawsock); // IP RAW Socket schließen und freigeben
return 0; // Programm beenden
}
MFG
bl0xx
