Sei sulla pagina 1di 21

==============================================================================

--------------------[ bfi11-dev - file 12 - 10/09/2002 ]----------------------


==============================================================================

-[ hacking ]------------------------------------------------------------------
---[ fastweb: v0rrete dirl0 a tutti (r0und 2)
-----[ the recidjvo <recidjvo@s0ftpj.org>

-=[ fastweb: vorrete dirlo a tutti (round 2) ]=-

* 0x00 - index

* 0x00 - index
* 0x01 - intro
* 0x02 - ancora una volta. sogno e visione
* 0x04 - un po' di storia, che non fa mai male
* 0x08 - finalmente ci siamo
* 0x10 - alla fine era tutto qui
* 0x20 - dai, qualcosa in piu`!
* 0x40 - tanti formati, ma alla fine ci siamo
* 0x80 - ancora piu` terra terra
* 0xff + 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

<asx version="3">
<param name="server" value="fastweb/3.1337" />
<entry>
<ref href="http://1.2.3.4:12345/video/fastweb/unicast.mpg" />
</entry>
</asx>

beh credo che questo esempio parli da solo :d

- pseudo-asx - streaming mpeg

<multicast_playlist>
<general_information>
<agent_ip>10.20.30.40</agent_ip>
<client_id>webdvd</client_id>
<txn_id>9877</txn_id>
<player>c:\agent\iplayer.exe</player>
<vs_type>bb</vs_type>
<composer_resolution>720 576</composer_resolution>
<start_channel>fastboystv</start_channel>
<creation_date>05-31-2002</creation_date>
<author>fastboys</author>
</general_information>
<startup_actions>
<a1>playvideo</a1>
</startup_actions>
<gold_bouquet>
<fastboystv>
<d_address>224.0.0.1</d_address>
<udp_port>12345</udp_port>
<ch_number>1</ch_number>
</fastboystv>
</gold_bouquet>
<keyboard_events>
<play>
<map_to_key>p</map_to_key>
<click_actions>
<a1>playvideo</a1>
</click_actions>
</play>
<stop>
<map_to_key>s</map_to_key>
<click_actions>
<a1>stopvideo</a1>
</click_actions>
</stop>
<pause>
<map_to_key>h</map_to_key>
<click_actions>
<a1>pausevideo</a1>
</click_actions>
</pause>
<zappingup>
<map_to_key>f</map_to_key>
<click_actions>
<a1>changechannelup</a1>
</click_actions>
</zappingup>
<zappingdown>
<map_to_key>r</map_to_key>
<click_actions>
<a1>changechanneldown</a1>
</click_actions>
</zappingdown>
</keyboard_events>
</multicast_playlist>

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 - <recidjvo@s0ftpj.org> *
* *
* *** 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 asx_uni "<asx "


#define asx_multi "<mult"
#define tok_uni "<ref href="
#define tok_multi1 "<d_address>"
#define tok_multi2 "<udp_port>"

#include <stdio.h>
#include <string.h>
#include <unistd.h>

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 - <recidjvo@s0ftpj.org> *
* (unerasable thanks to nextie :>) *
* *
* *** devel/untested/unstable *** *
* *
******************************************** fastboys, 2002 ***/

#ifdef fastream_debug
#define debug(x...) fprintf(stderr, x)
#else
#define debug(x...)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.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[1],
argv[2], atoi(argv[3]));
}
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 - <recidjvo@s0ftpj.org> *
* *
* *** 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 http_proto "http://"


#define http_port 80
#define header_agent "user-agent: mozilla/4.78 [en] (x11; u; linux.2.4.12.i586;
nav)\n"
#define header_agent_keylen 12
#define header_keepalive "connection: keep-alive"
#define header_cookie "cookie: " videostation_authcode
#define header_cookie_keylen 8

#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.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);

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, " "),
path);

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;
}

if(!strcmp(firstline, "\r\n")) {
if(port) {
send(sock, header_cookie, strlen(header_cookie),
0);
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 - recidjvo@pkcrew.org *
@@ -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 progname "a-team"


+#define code1 "000000000000"
+#define code2 "00:00:00:00:00:00"
+#define code4 "000000000000000"
+
#define 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 <pcap.h>
#include <libnet.h>
#include <pthread.h>
@@ -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(" * videos.patch detected.. turned %s\n", ((runpatch) ? "on" :


"off"));
+
/* fork && go! */
if(!debug) {
/* go in the daemon land */
@@ -95,7 +118,7 @@
setsid();
}

- debugf("logging traffic ( . -> from external to internal | o -> from


internal to external)\n");
+ debugf("logging traffic ( . -> from external to internal | o -> from
internal 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 *payload;
+ u_char packetcp[snaplen];
+ struct libnet_ip_hdr *iphdr;
+ struct 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);
+ 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);
+}
<-x->

(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 ]------------------------------------
==============================================================================