Netzwerkverkehr aufzeichnen



  • hustbaer schrieb:

    rawsock schrieb:

    Mit Raw Sockets könntest du auch alles von Haus aus machen.

    Echt? Wäre mir neu. Hast du nen Link zu dem Thema? (Doku der entsprechenden Funktionen oder so)

    Gibt haufenweise Beispiele im Internet. Bloß die Header (ETH, IP, TCP, ...) muss man selber schreiben und dann benutzt man den Socket ganz normal mit sendto() und recvfrom().



  • @rawsock

    sehr schöne Tips - passt nur leider nicht zur Frage - er will nicht senden/empfangen - er will ein Trace der Netzwerk-Kommunikation machen - so wie Wireshark und das dann auswerten



  • Ich versuche das mal hier, zumal ich mir gerade frustriert die Haare rausreiße...
    Ich hab ein wenig mit pcap rumgespielt und bekomme auch Daten von der API, aber sie ergeben einfach keinen (vollständigen) Sinn.

    http://www.bilder-upload.eu/show.php?file=8f92b3-1463064014.png
    Die beiden MAC- und IP-Adresse konnte ich herauslesen. Aber da sind Bytes die eig nicht sein dürften. Ich hab sie Byte für Byte als Integer dargestellt (andere Formate kann ich auf Wunsch nachreichen).
    Weder die Bytes am Anfang noch die zwischen MACs und IPs machen für mich irgendeine Art von Sinn.

    (Daten stammen von einem Ping auf www.google.com)



  • 1. pcap-Beispiel?
    2. machst du schon das TCP-Reassembling (und wie?)
    3. Wireshark zeigt dir doch für absolut jedes Byte was es ist (+Bedeutung)



  • #include <iostream>
    #include <stdio.h>
    #include <pcap.h>
    
    using namespace std;
    
    void gotPacket(u_char *args, const struct pcap_pkthdr *header,
    		const u_char *packet);
    
    int main() {
    	bpf_u_int32 net;
    	bpf_u_int32 mask;
    
    	char errbuff[PCAP_ERRBUF_SIZE];
    	char* device = pcap_lookupdev(errbuff);
    
    	printf("Device: %s\n", device);
    
    	pcap_t* handle = pcap_open_live(device, BUFSIZ, 1, 1000, errbuff);
    
    	// Wenn das Device nicht geoeffnet werden kann, wird eine Fehlerausgabe gemacht
    	if (handle == NULL) {
    		printf("Couldn't open device %s: %s\n", device, errbuff);
    		return (2);
    	}
    
    	// Einstellungen finden
    	if (pcap_lookupnet(device, &net, &mask, errbuff) == -1) {
    		printf("Couldn't get netmask for device %s: %s\n", device, errbuff);
    	}
    
    	pcap_loop(handle, 5, gotPacket, NULL);
    
    	pcap_close(handle);
    	printf("Finished!\n");
    	return 0;
    }
    
    void gotPacket(u_char *args, const struct pcap_pkthdr *header,
    		const u_char *packet) {
    	static int count = 0;
    	printf("%d\n", count);
    
    	cout << "int";
    	for (int i = 0; i < header->len; i++) {
    		int z = (int) *(packet+i);
    		cout << "-" << z;
    	}
    	cout << endl;
    
    	count++;
    	printf("Leaving gotPacket()\n");
    }
    

    TCP-Reassambling hab ich nicht, das auslesen der IP- und MAC-Adressen fand per Hand statt aufgrund der Ausgabe.

    Ich hab gerade mal mit Wireshark verglichen und die Bytes die mir hier so Kopfzerbrechern verursachen gibt es bei Wireshark nicht zu sehen, dort sieht der Ethernet-Frame richtig aus.



  • Hier noch einmal zum Verlgeich:
    Ausgabe mein Programm:
    08-00-27-f4-d4-01-52-54-00-12-35-02-08-00-45-00-00-4c-a0-5c-00-00-40-11-0d-8d-c0-a8-00-01-0a-00-02-0f-00-35-b6-a4-00-38-fb-6c-ee-52-81-80-00-01-00-01-00-00-00-00-03-77-77-77-06-67-6f-6f-67-6c-65-03-63-6f-6d-00-00-01-00-01-c0-0c-00-01-00-01-00-00-01-13-00-04-ac-d9-15-04

    Ausgabe Wireshark:
    08-00-27-f4-d4-01-52-54-00-12-35-02-08-00-45-00-00-54-a0-5d-00-00-37-01-15-60-ac-d9-15-04-0a-00-02-0f-00-00-7f-d2-37-c1-00-01-99-07-34-57-00-00-00-00-ae-39-0e-00-00-00-00-00-10-11-12-13-14-15-16-17-18-19-1a-1b-1c-1d-1e-1f-20-21-22-23-24-25-26-27-28-29-2a-2b-2c-2d-2e-2f-30-31-32-33-34-35-36-37



  • Warum int. Der wertbreich von char ist 0-255 und das reicht...so bekommst dus auch von libcap. Char!



  • Du vergleichst völlig falsche pakete miteinander.der ethernet header stimmt nähmlich



  • hustbaer schrieb:

    rawsock schrieb:

    Mit Raw Sockets könntest du auch alles von Haus aus machen.

    Echt? Wäre mir neu. Hast du nen Link zu dem Thema? (Doku der entsprechenden Funktionen oder so)

    Dies ist sehr wohl möglich. Obwohl nicht bis Layer 2.

    int InitWinSock2(void)
    {
    	WSADATA iws;
    
    	if( WSAStartup(MAKEWORD(2,2), &iws) != 0 ) {
    		printf("\nWSAStartup() error : %i\n",WSAGetLastError());
    		return 1;
    	}
    
    	return 0;
    }
    
    int main(int argc, char **argv)
    {	
    	SOCKET socksniffer;
    
    	fprintf(stdout, "Sniffing...\n\n");
    
    	/* Init Winsock */
    	if( InitWinSock2() ) {
    		getchar();
    		return 1;
    	}
    
    	/* Create raw socket for sniffing */
    	if( CreateRawSocket(&socksniffer ,AF_INET ,IPPROTO_IP) ) {
    		getchar();
    		return 1;
    	}
    
    	/* Launch sniffing */
    	LaunchSniffing(socksniffer);
    
    	return 0;
    }
    
    int LaunchSniffing(SOCKET sock)
    {
    	DWORD dwBufferLen[10], dwBufferInLen = 1, dwBytesReturned = 0, dwSize;
    	struct sockaddr_in dest;
    	struct hostent *hp;  
    	int sread, i, destlen = sizeof(dest);  
    	unsigned char packet[MAXPKSIZE+1], *Hostname = NULL;
    
    	Hostname = (char *)malloc(32 * sizeof(char *));
    	dwSize = 32 * sizeof(char *);
    
    	if(GetComputerName(Hostname, &dwSize) == 0) {
    	    fprintf(stderr, "GetComputerName(), %s", DisplayError());
    		return 1;
    	}
    
    	if((hp = gethostbyname(Hostname)) == NULL) {
    		fprintf(stderr, "gethostbyname(), %s", DisplayError());
    		return 1;  
    	}
    
    	free(Hostname);
    
    	memset(&dest ,0 ,sizeof(dest));  
    	memcpy(&dest.sin_addr.s_addr ,hp->h_addr_list[0], hp->h_length);
    	dest.sin_family = AF_INET;  
    	dest.sin_port = htons(PORT);
    
    	if( bind(sock ,(PSOCKADDR)&dest ,sizeof(dest)) == SOCKET_ERROR) {
    		fprintf(stderr, "bind(), %s", DisplayError());
    		return 1;
    	}
    
    	if( WSAIoctl(sock ,SIO_RCVALL ,&dwBufferInLen ,sizeof(dwBufferInLen) ,&dwBufferLen ,sizeof(dwBufferLen) ,&dwBytesReturned ,NULL ,NULL) == SOCKET_ERROR) {
    		fprintf(stderr ,"WSAIoctl(), %s" ,DisplayError());
    		return 1;
    	}
    
    	while(1) {
    
    		sread = recvfrom(sock ,packet ,MAXPKSIZE ,0 ,(struct sockaddr*)&dest ,&destlen);  
    
    		if(sread == SOCKET_ERROR || sread < 0) {
    
    			if(WSAGetLastError() == WSAETIMEDOUT)  
    				continue;  
    
    			printf_s("recvfrom() failed: %d\n", WSAGetLastError());  
    			return 1;  
    		}
    
    		// ParsePacket(packet);
    	}
    
    	return 0;
    }
    

    Natürlich mit Admin rechten starten.
    Dies ist sehr alter Code von mir, also bitte nicht wundern. 😉



  • Interessant, danke.



  • unglaublicher schrieb:

    Du vergleichst völlig falsche pakete miteinander.der ethernet header stimmt nähmlich

    Inwiefern denn falsche Pakete? Wenn ich das richtig verstanden habe kommt zuerst der Ethernet-Header, dann die Payload. In der Payload befindet sich der IP-Header mit dessen Payload.
    Wie kann es denn sein dass ich falsche Pakete vergleiche?


Anmelden zum Antworten