Raw Socket - send



  • Guten Abend,

    ich versuche per RawSocket TCP, genauer Syn-Pakete abzuschicken. Ziel bin ich selber (127.0.0.1).
    Um zu schauen ob alles auch schön ankommt, benutze ich Wireshark.
    Jedoch will das alles nicht so wie ich das möchte 😉

    typedef struct IP_HEADER
    {
    	unsigned char	header_len :4;
    	unsigned int	version :4;
    	unsigned char	tos;
    	unsigned short	total_len;
    	unsigned short	id;
    	unsigned short	flags_and_frag_offset;
    	unsigned char	ttl;
    	unsigned char	protocol;
    	unsigned short	checksum;
    	unsigned int	source_ip;
    	unsigned int	dest_ip;
    };
    typedef struct TCP_HEADER
    {
    	unsigned short	source_port;
    	unsigned short	destination_port;
    	unsigned int	sequence_number;
    	unsigned int	acknowledgement_number;
    	unsigned char	data_offset :4;
    	unsigned char	reserved :6;
    	unsigned char	flag_urg :1;
    	unsigned char	flag_ack :1;
    	unsigned char	flag_psh :1;
    	unsigned char	flag_rst :1;
    	unsigned char	flag_syn :1;
    	unsigned char	flag_fin :1;
    	unsigned short	window;
    	unsigned short	checksum;
    	unsigned short	urgent_pointer;
    };
    #define MAX_PACKET_SIZE 1024
    #define PORT		12345
    #define	TARGET_IP		"127.0.0.1"
    #define	LOOPS			10
    
    unsigned short checksum (unsigned short* buffer, int size)
    {
    	//...
    }
    void fill_ip_header(IP_HEADER* ip_header)
    {    
    	ZeroMemory(ip_header, sizeof(IP_HEADER));
    	ip_header->header_len = 5;
    	ip_header->tos = 0;    
    	ip_header->total_len = sizeof(IP_HEADER) + sizeof(TCP_HEADER);
    	ip_header->id = 12345;
    	ip_header->ttl = 255; // max ttl
    	ip_header->protocol = 6; //TCP
    }
    void fill_tcp_header(TCP_HEADER *tcp_header)
    {
    	ZeroMemory(tcp_header, sizeof(TCP_HEADER));
    	tcp_header->sequence_number = rand() % RAND_MAX + 1;
    	tcp_header->data_offset = 5;
    	tcp_header->flag_syn = 1;
    	tcp_header->window = 5000;
    }
    int main(int argc, char *argv[ ])
    {   
    	char			data[MAX_PACKET_SIZE];
    	char			ip[16];
    	sockaddr_in		addr;
    	unsigned int	flood_port;
    	IP_HEADER*		ip_header = (IP_HEADER*)data;
    	TCP_HEADER*		tcp_header = (TCP_HEADER*)((char*)ip_header + (5 * sizeof(int)));
    	SOCKET			socket_handle;
    	WSADATA			wsadata;
    	int			tmp;
    	unsigned int	loops;
    
    	if(WSAStartup(MAKEWORD(2, 2), &wsadata))
    		return 1;
    	srand((unsigned int)time(NULL));
    
    	socket_handle = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);    
    	if(socket_handle == SOCKET_ERROR){
    		WSACleanup();
    		return 1;
    	}
    
    	tmp = TRUE;
    	if(setsockopt(socket_handle, IPPROTO_IP, IP_HDRINCL, (const char*)&tmp, sizeof(tmp)) == SOCKET_ERROR){
    		WSACleanup();
    		return 1;
    	}
    
    	port = PORT;
    	addr.sin_family = AF_INET;
    	addr.sin_port = htons(port);
    	addr.sin_addr.s_addr = inet_addr(TARGET_IP);
    	ZeroMemory(&data, MAX_PACKET_SIZE);
    	fill_ip_header(ip_header);
    	fill_tcp_header(tcp_header);   
    	tcp_header->destination_port = htons(port);
    	ip_header->dest_ip = addr.sin_addr.s_addr;    
    	ip_header->checksum = checksum((unsigned short*)data, ip_header->total_len >> 1);
    
    	for(loops = 0; loops < LOOPS; ++loops)
    	{
    		strcpy(ip, "123.456.789.123"); //als muster
    		ip_header->source_ip = inet_addr(ip);       
    		tcp_header->source_port = htons(rand() % USHRT_MAX + 1);
    		ip_header->checksum = checksum((unsigned short*)data, ip_header->total_len >> 1);
    
    		if(sendto(socket_handle, data, ip_header->total_len, 0, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) // siehe unten...
    			cout << "error: " << WSAGetLastError() << endl;
    		else
    			cout << "... " << TARGET_IP << " at " << PORT << endl;
    	}
    	//...
    }
    

    So...sendto sagt 10022 -> invalid argument.
    wenn ich send nehmen, gibts keinen error, aber es kommt natürlich auch nichts an.
    Ansonsten treten keine fehler auf...
    Bin leider am ende, kenne mich in der socket- bzw. netzwerkprogrammierung auch noch nicht wirklich gut aus.
    Das das hier nicht für "böse" zwecke gedacht ist, muss ich glaube ich nicht erwähnen, das "sieht" man auch so 😉

    Vielen dank soweit!



  • Kann es an der nicht gültigen IP Adresse liegen? "123.456.789.123"



  • Ohne mir deinen code durchgelesen zu haben.

    Vielleicht liegt's daran:

    When Microsoft released Windows XP in 2001 with raw socket support implemented in the Winsock interface, the media criticized Microsoft asserting that raw sockets are only of use to hackers to perform TCP reset attacks. Three years after the Windows XP release, Microsoft silently limited Winsock's raw socket support in a non-removable hotfix and offered no further support or workarounds for applications that used them.

    http://en.wikipedia.org/wiki/Raw_socket



  • Du kannst die source IP nicht Spoofen mit Windows raw socket!
    Siehe EOP post.

    Source:MSDN

    Limitations on Raw Sockets

    On Windows 7, Windows Vista, Windows XP mit Service Pack 2 (SP2), and Windows XP mit Service Pack 3 (SP3), the ability to send traffic over raw sockets has been restricted in several ways:

    TCP data cannot be sent over raw sockets.
    UDP datagrams with an invalid source address cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. This change was made to limit the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets (TCP/IP packets with a forged source IP address).
    A call to the bind function with a raw socket for the IPPROTO_TCP protocol is not allowed.

    Hinweis The bind function with a raw socket is allowed for other protocols (IPPROTO_IP, IPPROTO_UDP, or IPPROTO_SCTP, for example).

    These above restrictions do not apply to Windows Server 2008 R2, Windows Server 2008 , Windows Server 2003, or to versions of the operating system earlier than Windows XP mit SP2.

    Hinweis The Microsoft implementation of TCP/IP on Windows is capable of opening a raw UDP or TCP socket based on the above restrictions. Other Winsock providers may not support the use of raw sockets.

    There are further limitations for applications that use a socket of type SOCK_RAW. For example, all applications listening for a specific protocol will receive all packets received for this protocol. This may not be what is desired for multiple applications using a protocol. This is also not suitable for high-performance applications. To get around these issues, it may be required to write a Windows network protocol driver (device driver) for the specific network protocol. On Windows Vista and later, Winsock Kernel (WSK), a new transport-independent kernel mode Network Programming Interface can be used to write a network protocol driver. On Windows Server 2003 and earlier, a Transport Driver Interface (TDI) provider and a Winsock helper DLL can be written to support the network protocol. The network protocol would then be added to the Winsock catalog as a supported protocol. This allows multiple applications to open sockets for this specific protocol and the device driver can keep track of which socket receives specific packets and errors. For information on writing a network protocol provider, see the sections on WSK and TDI in the Microsoft Windows-Treiberkit (WDK).

    Applications also need to be aware of the impact that firewall settings may have on sending and receiving packets using raw sockets.



  • Also doch...
    Ich hatte das schon gelesen, allerdings hat es mich verwirrt, dass der Code doch "funktionierte" (hatte ihn für Linux gefunden und für Windows "umgeschrieben"). Die Fehlermeldung "Ungültiges Argument" hat mich nicht überzeugt, ich hätte sowas in richtung "Nicht Unterstützt" bzw. "Nicht Erlaubt" erwartet.
    Ist ja an sich eine ganz gute Sache, auch wenn das den (friedlichen) Programmiere einschränkt...

    Unter dem Strich heißt das also, dass ich Raw Socket nicht mit dem TCP verwenden kann und somit keine Sys-Pakete versenden kann?
    Hab gelesen, dass es mit "WinPcap" klappen soll, aber das wäre mir dann doch etwas zu weit gegriffen... eine andere Möglichkeit gibt es nicht, korrekt?



  • Dein Fehler liegt eindeutig hier:

    socket_handle = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);

    muss nämlich heissen:

    socket_handle = socket(PF_INET, SOCK_RAW, IPPROTO_RAW );

    Lenzlenz


Anmelden zum Antworten