Steganografia e social network

Immagine originale
Piano di attacco (cambia il colore per via delle proprietà di compressione del JPEG)

Tantissimi anni fa ricordo di aver letto un interessante articolo sulla steganografia, cioè l’arte di nascondere l’informazione (si badi bene: non crittografie, ma nascondere) per comunicare con un interlocutore in modo riservato tramite un canale pubblico.

Forse per colpa del caldo mi è venuta alla mente una serie di pensieri, che riporto qua sul blog.

1) Ecco perché Facebook ricomprime le immagini

Ipotizziamo che io sia una cellula di Al-Qaeda e che sia iscritto ad una pagina Facebook jihadista che ogni tanto pubblica qualche foto. Supponiamo che io conosca uno schema che ad esempio prevede che ogni n byte dell’immagine ci sia una lettera di un messaggio codificato. Supponiamo poi che io abbia a disposizione un manuale di codici di guerra, che consentono di scrivere parole poco “rilevabili” con un dizionario.

Codici operativi:
0001 Attacco
0002 Rapimento

Target:
0001 Aeroporto tal dei tali

Come fare per comunicare a tutte le cellule come me questa cosa per organizzare ad esempio un attacco sincronizzato? Basterebbe mandare sulla pagina Facebook l’informazione, camuffata come foto! Immaginate una bella foto in formato JPEG, e supponete che io alteri il colore di un pixel (cioè di un punto dell’immagine) ogni 2000 punti… chi se ne accorgerebbe? L’importante è usare uno schema conosciuto: ad esempio un carattere ogni 2000 byte o cose del genere. Bene, Facebook ricomprime le immagini che inviate, e quindi non c’è nessuna probabilità che una cosa così semplice funzioni, a meno che non si inseriscano delle ridondanze che però rischierebbero di rovinare pesantemente l’immagine. La ricompressione, infatti, di fatto modifica di nuovo l’immagine, anche se ce ne rendiamo poco conto.
Ad ogni modo questa tecnologia è veramente alla portata di tutti… In 10 minuti si possono scrivere, anche se in forma “grezza”, sia il codificatore che il decodficatore, in un linguaggio come il C, che trovate in coda a questo post. Con un po’ di tempo si potrebbe costruire un sistema molto più raffinato e difficilmente individuabile.

2) Non ci resta che sperare nei servizi segreti
Ora se Facebook ricomprime, lo stesso non è detto per altri social network, e soprattutto non è così per i siti web. Questo è un esempio del perché Internet possa essere decisamente fuori controllo per i governi e i servizi di intelligence, cosa che sinceramente non mi fa moto piacere. Tuttavia sono sicuro che le normali investigazioni portino comunque ad individuare soggetti pericolosi, che pubblichino o meno le foto sul web.

3) Steganografia o crittografia?

Suona un po’ come “omeopatia o medicina ufficiale?” In realtà credo che questi due strumenti siano entrambi eccezionali per proteggere la riservatezza. La crittografia è sicuramente più comoda, perché ci sono strumenti che consentono di non rendersi nemmeno conto del fatto che si sta usando tale tecnologia; essa è tuttavia molto più appariscente della steganografia, perché quest’ultima nasconde anche l’intenzione di voler comunicare, e dato che non si può controllare tutto, vale il principio in base al quale il miglior modo di nascondere una cosa è metterla sotto agli occhi di tutti. Non dimentichiamoci comunque che è possibile nascondere un messaggio cifrato, cioè combinare le due modalità di comunicazione, per un mix decisamente impenetrabile.

Codificatore

Si noti: questo codificatore è decisamente elementare e non consente di passare del tutto inosservati, in quanto ad esempio il JPEG è un formato poco resistente alle modifiche (nell’esempio postato in alto cambia il colore di quasi tutta la foto).

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

int main(int argc, char** argv)
{
const char* message =”0001 0001@22:00:UTC”;
if(argc != 2)
{
printf(“Errore, devi specificare un file jpegn”);
}
FILE *fp = fopen(argv[1],”rb”);
FILE *fp_o = fopen(“modificato.jpg”,”wb”);
int cntr = 0;
int len = strlen(message);
int done = 0;
char *buff;
buff=(char*)malloc(sizeof(char));
fseek(fp, 0L, SEEK_END);
int sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
for(int i=0;i<sz;i++)
{
fseek(fp, i,SEEK_SET);
fread(buff,1,sizeof(char),fp);
                //Salto i primi 16K per evitare problemi con 
                //i programmi che visualizzano immagini
if(i>16384 && i % 2000 == 0 && done < len)
{
*buff = message[done];
done++;
}
fwrite(buff,1,1,fp_o);
}
free(buff);
fclose(fp_o);
fclose(fp);
}

Decodificatore


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

int main(int argc, char** argv)
{
if(argc != 2)
{
printf(“Errore, devi specificare un file jpegn”);
}
FILE *fp = fopen(argv[1],”rb”);
int len = 128; //Limito la ricezione massima
int done = 0;
char *buff;
buff=(char*)malloc(sizeof(char));
fseek(fp, 0L, SEEK_END);
int sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
for(int i=0;i<sz;i++)
{
fseek(fp, i,SEEK_SET);
fread(buff,1,sizeof(char),fp);
if(i>16384 && i % 2000 == 0 && done < len)
{
printf(“%c”, *buff);
done++;
}
}
free(buff);
fclose(fp);
}