Автор Тема: Mp3-базирана автентикация  (Прочетена 1281 пъти)

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Mp3-базирана автентикация
« -: 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-ката може да се чуят  изпуквания. И накрая: това няма да сработи с прекалено големи текстови файлове, защото никой не гарантира че няма да има повтарящи се числа в редицата в един момент. За всички тези проблеми обаче има разрешение, при това не е безкрайно сложно '<img'>

И накрая: примерна (рудиментарна) уеб-автентикация базирана на това: качваш една мп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 '<img'> Probvaite otnovo '<img'>";
}
system ("rm /tmp/secret1.txt");


Цялата тази работа не е особено практически полезна, по-скоро ми щукна в главата и реших да видя какво ще излезе. Иначе, забавно е това с което се автентицираш да си го държиш на мп3 плейъра...а сийд-а да го знаеш наум. Злите лоши хахори например бая биха си блъскали главата, докато разгадаят някаква такава малоумна схема също така '<img'>
Активен

"Knowledge is power" - France is Bacon

zeridon

  • Killmode enabled
  • Administrator
  • Напреднали
  • *****
  • Публикации: 1398
  • Distribution: Debian/Ubuntu
  • Window Manager: console/Gnome
  • BOfH
    • Профил
    • WWW
Mp3-базирана автентикация
« Отговор #1 -: Mar 30, 2007, 12:07 »
За справка Стеганография
http://www.steganos.com/
http://www.google.com/search?q=steganography&btnG=Search
Активен

Внмимавай имам клещи за кабел
http://www.netsecad.com/
http://theregister.co.uk/odds/bofh/