|
Source manager | |
|
Elenco funzioni : Clear_Scree Client_WP CounterInPh doubleNB ShelldiWindow MontaDischiLinu CriptaHTM ClearScreenPytho FunzionePin OpenAndClos N.A.K Bluetooth Finde calcolatrice! Lascia il tuo sorgente |
Autore : eagle[at]hackroom[dot]org
#include <sys/types.h> /* predefined types */ #include <unistd.h> /* include unix standard library */ #include <arpa/inet.h> /* IP addresses conversion utilities */ #include <sys/socket.h> /* socket library */ #include <stdio.h> /* include standard I/O library */ #include <stdlib.h> #include <string.h> //tipi di dato usati... si preferisce usare tutti unsigned #define WORD unsigned short #define BYTE unsigned char #define DWORD unsigned int #define BOOL int #define FALSE 0 #define TRUE 1 #include "wpnenc.h" //file contenente le funzioni di winmx //questa funzione e' fatta per ricever dati, se li riceve frammentati si preoccupa di ricostruirli int recvit(int s, char *buff, int len, int flags){ int ret=1; int done=0; while (ret > 0 && done < len) { ret = recv(s,buff+done,len-done,flags); if (ret > 0) done = done + ret; } return done; } int main(int argc, char *argv[]){ int s, //socket ip, //ip a cui mi connettero' port, //porta su cui mi connettero' n, //variabile dove salvo i risultati di send() e recv() i, //variabile per il for type, //dove salvo il tipo di pacchetto len; //dove salvo la lunghezza del pacchetto DWORD upkey, //chiave successivamente usata x crittare dwkey; //chiave successivamente usata x decrittare char nick[50]; //nick (andra' scritto comprensivo di cifre finali... nick123_12345 char room[100]; //stanza nella quale entrerò char buf[1000]; //buffer usato per salvare dati da mandare/ricevere gets(nick); //leggo il nick (fate finta che non sia una gets:) gets(room); //leggo la stanza(comprensiva di hash finale _XXXXXXXXXXXX ) sscanf(room+strlen(room)-12,"%8X%4X",&ip,&port); //ricavo l'ip e la porta dall'hash finale s = socket( AF_INET, SOCK_STREAM, 0 ); //creo un socket struct sockaddr_in cs; //solite robe da far x connettersi cs.sin_family = AF_INET; //... cs.sin_addr.s_addr = ip; //...(dico a che ip connettermi) cs.sin_port = htons(port);//...(e su che porta) if( connect( s, (struct sockaddr*) &cs, sizeof(cs) ) < 0 ) //mi connetto return 0; //se fallisce chiudo il programma printf("Connected\n"); n = recvit( s, buf, 1, 0 ); //ricevo l'uno '1' if( n != 1 ) //se non ho ricevuto un byte return 0; //chiudo il programma printf("Sending keyblock\n"); /* La funzione CreateCryptKeyId crea 16 byte dove "nasconde" un byte (0x57 in questo caso) ecco cosa significano i vari byte che gli si puo passare 0x0050 - Primary Client 0x0051 - Primary Server 0x0052 - Secondary Client 0x0053 - Secondary Server 0x0054 - Peer Cache 0x0057 - Chat Client 0x0058 - Chat Server */ CreateCryptKeyID(0x57, (BYTE*)buf); //creo i 16 byte dove dico che sono un chat client n = send( s, buf, 16, 0 ); if( n != 16 ) return 0; printf("Receiving keyblock\n"); n = recvit( s, buf,16, 0 ); //il server mi risponde con altri 16 byte dove nasconde un 0x58 if( n != 16 ) return 0; // a questo punto dovrei controllare che GetCryptKeyId() mi restituisca un 0x58 // ma lo do per scontato e proseguo /* La funzione GetCryptKey va a generare le chiavi successivamente usate x crittare e decrittare servendosi dei 16 byte precedentemente ricevuti dal server */ GetCryptKey((BYTE *)buf, &upkey, &dwkey); //creo le chiavi printf("Sending 3.53 compatibility\n"); *(WORD*)buf = 0x13ed; //mando un pacchetto di tipo 0x13ed che sta a indicare che supporto il protocollo 3.53 *(WORD*)(buf+2) = 0x0001; //un pacchetto lungo 1 buf[4]=0x31; //contenente un '1' (così vuole il protocollo) /* NOTA BENE la lunghezza non è comprensiva dei primi 4 byte (tipo e lunghezza) se il pacchetto in tutto e' lungo 5 la lunghezza sara' 1 */ /* La funzione EncryptMXTCP va a crittare il pacchetto appena creato servendosi della chiave precedentemente creata la chiave cambia ogni volta che viene crittato un dato e quindi viene restituita e salvata */ upkey = EncryptMXTCP((unsigned char*)buf, 5, upkey); //critto i dati creati n = send( s, buf, 5, 0 ); //li mando if( n != 5 ) //se non ce la faccio return 0; //chiudo la connessione printf("Sending join request\n"); /* un modo usato per comporrei pacchetti e' questo parto con una lunghezza del paccetto pari a 4 man mano aggiungo i dati scrivendo in buffer+lunghezza e incremento la lunghezza solo alla fine vado a riempire i primi 4 posti mettendo il tipo e la lunghezza-4 (leggere il NOTA BENE di prima) critto e mando per un valore pari alla lunghezza */ /* ora vado a chiedere al server di entrare il pacchetti va così formato [NomeStanza:N][Linea:2][PrimaryIP:4][PrimaryPort:2][Files:4][UserName:N] ovviamente primadi cio ci va tipo e lunghezza */ len = 4; //parto da 4 strcpy(buf+len,room); //copio il nome della stanza len += strlen(room)+1; //incremento la lunghezza per la lunghezza del nome della stanza +1 (lo '\0') *(WORD*)(buf+len) = rand() % 10; //metto una linea a caso (valori alti facevano crashare fxserv137 len += 2; //incremento di 2 (la linea occupa 2 byte) *(DWORD*)(buf+len) = rand(); //l'ip della mia primaria, lo metto a caso len += 4; //incremento di 4 (l'ip occupa 4 byte) *(WORD*)(buf+len) = rand(); //porta della primaria.. a caso len += 2; //incremento di 2 *(DWORD*)(buf+len) = rand() & 0x0000FFFF; //file a caso, minori di 65536 len += 4; //incremento di 4 strcpy(buf+len,nick); //copio il nick len += strlen(nick)+1; //incremento la lunghezza per il la lunghezza del nick +1 (lo '\0') *(WORD*)buf = 0x0064; //metto il tipo, 0x0064 = richiesta di entrare *(WORD*)(buf+2) = len-4; //metto la lunghezza-4, per il motivo sopra spiegato upkey = EncryptMXTCP((unsigned char*)buf, len, upkey); //critto n = send( s, buf, len, 0 ); //e mando if( n != len ) //se fallisco return 0; //esco printf("Receiving join reply\n");//se la richiesta e' corretta e non sono bannato n = recvit( s, buf,5, 0 ); //il server mi dice che sono stato accettato (un 0x0066)... ricevo if( n != 5 ) return 0; /* La funzione DecryptMXTCP funziona come l'EncryptMXTCP solo che al posto di crittare... decritta */ dwkey = DecryptMXTCP((unsigned char*)buf, 5, dwkey); //e decritto //dovrei controllare che il pacchetto sia effettivamente uno 0x0066 //ma ignoro cio, perchè se non lo ricevo il server chiude la connesisone e me ne accorgo printf("Joined!\n"); //sono dentro la chat :) //Ora come esempio mandero' scritto "Salve" alla stanza len = 4; strcpy(buf+len,"Salve!"); //mando scritto "Salve!" len += strlen("Salve")+1; //come lunghezza metto la lunghezza di cio che voglio scrivere, +1 (lo '\0') *(WORD*)buf = 0x1450; //il tipo 0x1450 serve per scrivere qualcosa il protocollo vuole che sia formato così: [Testo:N] *(WORD*)(buf+2) = len-4; //come lunghezza metto la lunghezza di cio che voglio scrivere, +1 (lo '\0') upkey = EncryptMXTCP((unsigned char*)buf, len, upkey); //critto n = send( s, buf, len, 0 ); //e mando if( n != len ) //se fallisco return 0; //esco //da qui in poi scrivo a video cio che ricevo /* metodo solitamente usato: ricever i primi 4 byte decrittarli salvarsi tipo e lunghezza ricevere un numero di dati pari alla lunghezza */ while(1){ n = recvit( s, buf,4, 0 ); //ricevo i primi 4 byte if( n != 4 ) //se non li ho ricevuto break; //esco else{ dwkey = DecryptMXTCP((unsigned char*)buf, 4, dwkey); //li decritto type = *(WORD*)buf; //salvo il tipo len = *(WORD*)(buf+2); //e la lunghezza printf("[%04X %d] ",type,len); //scrivo tipo e lunghezza if( len>1000 ) //se la lunghezza e' troppo alta (non dovrebbe capitare) (e uscirei dal buffer) break; //me ne vado if( len == 0 ) //se la lunghezza è 0 (non ho altro da ricevere) continue; //torno a ricever altri 4 byte n = recvit( s, buf+4,len, 0 ); //ricevo dati per un numero pari alla lunghezza prima ricevuta if( n != len ) //se non li ho ricevuti tutti (otrei esser caduto) break; //me ne vado dwkey = DecryptMXTCP((unsigned char*)buf+4, len, dwkey);//decritto i dati ricevuti for( i=4; i<len+4; i++ ) //vado a scriverli (ho sostituito con spazi i caratteri non stampabili) e poi vado a capo if( buf[i] >= 0 && buf[i] < 32 ) putchar(' '); else putchar(buf[i]); putchar('\n'); } } close(s); return 0; } /* NOTA BENE Mettendo questo client in una chat hostata con winmx dopo un po' cadra' (verra' cacciato automaticamente) perche' cio non succeda, va mandato periodicamente (ogni minuto) un 0xFDE8 (PING) */ |