Титла: Mp3-базирана автентикация
Публикувано от: gat3way в Mar 30, 2007, 10:56
Идеята е проста и донякъде позната - върху някакъв достатъчно голям файл, съдържащ съдържание, за което няма да е фатално да понесе известен data loss, се "imprint"-ва текстова информация, така че от една страна обратната операция (да извадиш текста) да е възможна, а от друга страна това трябва да се направи сложно за злите елементи, които искат да я извадят. Има такива занимавки с jpeg файлове доколкото съм чувал. Моята идея е проста - при положение че имаш мп3-ка и текстов файл (който е скритото послание и "ключа", благодарение на който правим автентикацията), да може текста да се "вгражда", съответно "изважда". За да се затруднят злите хахори, въвеждам и целочислена стойност, която ако не се знае от страна на декодиращият, изваждането на текста е невъзможно. Вместо да обяснявам нашироко, по-добре да пейстна кода, защото е кратък: това е "вграждащата" програмка: Цитат | #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <fcntl.h>
#define BUFSIZE 256*256*16*4 //large enough
int seed; char *inmp3, *outmp3, *secret;
// boring void printusage(char **arg0) { printf("\nUsage:\n\n%s <input.mp3> <secret.txt> <random_seed> <output.mp3>\n\n",arg0); printf("Where <input.mp3> is the name of input mp3 file\n"); printf("<secret.txt> should be replaced with a 'secret' text file\n"); printf("<random_seed> is an integer you use to seed the random func (e.g. 5051)\n"); printf("<output.mp3> is the name of output mp3 file\n\n"); }
// entrypoint int main(int argc, char **argv[]) {
// fds int im, om; FILE *sm; // text file streamed // cntrs int a,b,c; unsigned short d; // bufs char *buf=malloc(BUFSIZE); char *bufs=malloc(BUFSIZE); // bufpointers unsigned int bp,sp;
// code if (argc != 5) { printusage(argv[0]); exit(1); } // gotcha inmp3=argv[1]; secret=argv[2]; seed=strtod(argv[3],NULL); outmp3=argv[4]; // debug printf("inmp3: %s , secret: %s , seed: %d, outmp3: %s\n",inmp3,secret,seed,outmp3); // init io im=open(inmp3,O_RDONLY); sm=fopen(secret,"r"); om=creat(outmp3,S_IWRITE | S_IREAD |S_IRGRP | S_IWGRP|S_IWOTH|S_IROTH); // misc init srand(seed); sp=bp=0; memset(buf,0,BUFSIZE); // eq bzero // Fetch first BUFSIZE buffers read(im,buf,BUFSIZE); // Fetch 'secret' while (feof(sm)==0) { b=fgetc(sm); if (b!=EOF) memset((bufs+sp),b,1); sp++; } fclose(sm); printf("sp=%d\n",sp); // 'Embody' secret data in buffer d=seed; memcpy(buf+d,&sp,sizeof(sp)); for (a=0;a<=sp;a++) { d=rand();//printf("%d\n",d*16*4); memcpy((buf+d*16*4),(bufs+a),1); } // Flush buffer in outfile write(om,buf,BUFSIZE); // Copy rest of.. a=read(im,buf,BUFSIZE); while ( a!=0) {write(om,buf,a);a=read(im,buf,BUFSIZE);} close(om);close(im); // free buffers free(buf); free(bufs); printf("Done!\n"); }
|
Това е "декодиращата" програмка:
Цитат | #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <fcntl.h>
#define BUFSIZE 256*256*16*4
int seed; char *inmp3, *outmp3, *secret;
// boring void printusage(char **arg0) { printf("\nUsage:\n\n%s <input.mp3> <random_seed> \n\n",arg0); printf("Where <input.mp3> is the name of input mp3 file\n"); printf("<random_seed> is an integer you use to seed the random func (e.g. 5051)\n"); }
// entrypoint int main(int argc, char **argv[]) { // fds int im; // cntrs int a,b,c; unsigned short d; // bufs char *buf=malloc(BUFSIZE); char *bufs=malloc(BUFSIZE); int *spp=malloc(2); // bufpointers unsigned int sp;
// code if (argc != 3) { printusage(argv[0]); exit(1); } // gotcha inmp3=argv[1]; seed=strtod(argv[2],NULL); // init io im=open(inmp3,O_RDONLY); // misc init srand(seed); sp=0; memset(bufs,0,BUFSIZE); // eq bzero // Fetch first BUFSIZE buffers read(im,buf,BUFSIZE); d=seed; memcpy(spp,buf+d,2); sp=*(spp); // 'Decode' secret data from buffer for (a=1;a<=sp;a++) { d=rand(); strncat(bufs,(buf+d*16*4),1); }
printf("%s",bufs); // free buffers free(buf); free(bufs); }
|
Компилират се лесно (cc program.c -o program). "Разбъркването" на текста в мп3-ката се постига чрез pseudorandom функция, която генерира *уникални* редици от числа спрямо зададен seed. Тези числа от редицата са дефакто позициите в мп3 файла на всеки символ от файла.
Недостатъци: по този начин направено има много. Този алгоритъм по този начин няма да сработи с мп3-ки по-малки от 4МБ. Форматът на мп3-ката не се "уважава", като резултат се пише и в хедърчетата, не само във audio frames, което малко или много влошава качеството (чат-пат се чува изпукване). За да станат нещата по-зле, разпределението на числата в pseudorandom редиците не е *равномерно*, повечето стойности са по-ниски, при което с голяма вероятност, в началото на мп3-ката може да се чуят изпуквания. И накрая: това няма да сработи с прекалено големи текстови файлове, защото никой не гарантира че няма да има повтарящи се числа в редицата в един момент. За всички тези проблеми обаче има разрешение, при това не е безкрайно сложно 
И накрая: примерна (рудиментарна) уеб-автентикация базирана на това: качваш една мп3-ка и ако "secret-a" й съвпадне с този в /tmp/secret, то потребителя бива *автентициран*:
грозен html код
Цитат | <html><body> <h2> <center>mp3 auth PoC</center> <form enctype="multipart/form-data" action="upload.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="18000000" /> Choose a mp3 to upload: <input name="uploadedfile" type="file" /><br /> <input type="submit" value="Upload Mp3" /> </body></html>
|
И грозен upload.php:
Цитат | <?php $target_path = "/tmp/"; $target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) { echo "The file ". basename( $_FILES['uploadedfile']['name']). " has been uploaded, pending checks...<br>"; }
else { echo "There was an error uploading the file, please go back and try again!"; die(); }
system("/tmp/decode ".$target_path." 100 > /tmp/secret1.txt"); exec("cmp /tmp/secret.txt /tmp/secret1.txt",$a); echo "$a[0]";
if ((strlen($a[0])<4) && (filesize("/tmp/secret1.txt")>4)) { echo "<h1><font color=red>Bravo, bravo, bravo, uspehte da se avtenticirate s mp3-ka!"; } else { echo "<h1><font color=red>Sorry, kachili ste greshnata mp3-ka Probvaite otnovo "; } system ("rm /tmp/secret1.txt");
|
Цялата тази работа не е особено практически полезна, по-скоро ми щукна в главата и реших да видя какво ще излезе. Иначе, забавно е това с което се автентицираш да си го държиш на мп3 плейъра...а сийд-а да го знаеш наум. Злите лоши хахори например бая биха си блъскали главата, докато разгадаят някаква такава малоумна схема също така 
Титла: Mp3-базирана автентикация
Публикувано от: zeridon в Mar 30, 2007, 12:07
|