Netzwerkverkehr aufzeichnen



  • Hallo zusammen,

    ich würde gerne ein Programm schreiben mit dessen Hilfe ich Daten aus dem Netzwerk aufzeichnen kann. Es ist nicht notwendig sie manipulieren zu können und es würde mir auch vollkommen ausreichen die Daten zu protokollieren die auch meinen PC betreffen.
    Das ganze soll dann am Ende ein wenig graphisch aufbereitet und auf einem seperaten Monitor angezeigt werden, also mehr ein "Hobby-/Kunstprojekt" wenn man es so nennen mag.

    Auf der Suche nach Infos wie ich an den Datenstrom komme, treffe ich aber vor allem auf Wireshark und andere Programme, die ich aber nicht nutzen kann da ich die Daten selbst aufbereiten möchte. Zur (absoluten) Not würde ich sogar etwas zwischen PC und Router stecken das mitliest, nur bin ich mir da nicht ganz sicher ob ich das Datengewusel selbst auseinander nehmen kann.

    Ist die Idee umsetzbar, wenn ja, hätte jemand einen Tipp für mich wie ich den Datenstrom kommen kann?

    Danke schonmal 🙂
    Narase



  • Wireshark ist schon das richtige Stichwort.
    Wenn du die Daten selbst analysieren willst, dann nimmst du halt nicht Wireshark direkt sondern das was Wireshark verwendet um an die Daten dranzukommen: libpcap
    http://www.tcpdump.org/



  • klar ist das Umsetzbar

    wie hustbaer schon gesagt hat kannst du eine Wireshark-Logdatei(pcap) einlesen

    aber bendenke: die TCP/IP-Pakete sind noch nicht reassembliert(defragementiert) - d.h. das was du in Wireshark siehst ist so nicht direkt in dem pcap drinn

    such mal in google nach "github tcp reassembling" da gibt es ein paar nette Libraries



  • Hab kurz durch die beiden Dinge durchgeschaut, das sieht gut aus. Hätte ich bei Wireshark vlt nicht direkt abschalten sollen

    Danke euch 🙂



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



  • Wie denn genau? Kann ich den einfach auf einen Port setzen und alles mithören was da durch geht?



  • Narase schrieb:

    Wie denn genau? Kann ich den einfach auf einen Port setzen und alles mithören was da durch geht?

    Ja.



  • Auch auf die Gefahr hin ungebildet zu wirkenm, aber warum geht das so einfach?
    Macht einem da nicht das OS einen Strich durch die Rechnung? Bzw warum kann ein Programm einfach so den Traffic mitlesen der an andere Programme geht?



  • 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)



  • 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?


Log in to reply