Авторские статьи стеганография для новичков

Discussion in 'Статьи' started by DooD, 7 Jun 2013.

  1. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    Здрасте форумчане.вот пока выдалось свободное время, и перед тем когда мне наступит конец в связи с сессией, решил попробовать поделиться информацией по интересной для меня теме-стеганографии.Материалец не претендует на какую то мега-статью, скорее личные наблюдения или что.

    тема навеяна этим https://forum.antichat.ru/thread375855-miniduke.html
    и является продолжением этой http://bydood.blogspot.com/2013/05/hell-yeah.html
    т.к. доселе я не мог вразуметь как же так в мультимедиа заседают другие файлы.оказалось можно.хотя методика создана не для этого,но очевидно что тут применилась.

    В общем-то план таков:

    1)немного истории,что являет собой стеганография, етц.
    2)виды стеганографии( то что применим мы)
    3)анализ застенографированных файлов.

    Писать будем на делфи, более-менее вменяемые куски кода нашел на делфи и С++


    ТЕОРИЯ

    Итак стеганография- некий вид науки о сокрытой передаче информации, т.е. утаивании самого факта присутствия сообщения.Если криптография - это шифрование информации, то стеганография скрывает сам факт.обычно в данное время застеганографированная информация выглядит как нечто иное - к примеру файлы мультимедиа (изображения,звук,видео, даже исполняемые файлы).

    некоторые примеры стеганографии в допотопном мире можно прочесть на вики (довольно интересно я вам скажу;) )

    современная стеганография подразделяется на несколько таких вот видов:

    1)компьютерная стеганография: как правило сокрытие в зарезервированных полях файлов,пустых местах дисков,флешек етц, особенности файловых систем.

    (как пример- формат jpg имеет т.н. потоки данных (выделяет потоки для информации) т.е. можно создать отдельный поток в который записать сообщение- однако недостатки состоят в том что jpeg использует сжатие, во вторых объем файла увеличивается,в третьих производя манипуляции с изображением-можно угробить информацию)

    2)современный наиболее распространенный вариант - внедрение информации в объекты вроде изображений,аудио,видео… Вызывает некоторые искажения в файлах-контейнерах, однако , как правило, не подвластно человеческому взгляду.

    Существует несколько алгоритмов, но самое простое и распростаненное для изображений - изменение последнего бита.

    суть методики в замене последнего бита файла-контейнера на биты нашей информации.

    рассмотрим на примере битмапа - у него там на одну точку приходится 3 байта- red , green, blue. и согласитесь что если будут точки допустим 135,58,44 и точки 136,58,45 то взгляд среднего (да любого) человека не отличит визуально.

    Попробуем написать разного рода код для сокрытия информации в: секторе, битмапе,тексте.


    1)СЕКТОР.

    заранее определим нужные нам сектора, это могут быть также сектора заполненные подставными файлами, строки могут быть зашифрованы каким то не сложным алгоритмом.Подробно останавливаться не буду, т.к. тут все просто:

    открываем диск:

    Code:
    CreateFile ('\\.\PhysicalDrive0',GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
    (для примера системный диск, ну вообще указываем тот что нам нужен).

    идем на нужную позицию:

    Code:
    SetFilePointer(f,10*512,nil,FILE_BEGIN);
    11 сектор в примере.

    И запись в общем то как в обычный файл:

    Code:
    WriteFile(f,somedata,sizeof(somedata),nw,nil);


    2)И вот самое интересное - сохраняем в битмап.
    Тут напишем уже полноправную программку)

    Рассмотрим запись в «лоб» и замену битов.

    Заголовок битмапа=14 байтам + ширина*высоту - после этого смещения мы можем писать все что угодно,что бы при этом битмап открывался. но нужно создавать некий разброс если сообщение большое,потому что получается вот такой вот прикол:

    [​IMG]

    [​IMG]

    видим что изображение искажается. понятно что писать в ряд нельзя, что бы скрыть придется писать по 1-2 байта с определяющим знаком (для считывания) и через несколько байт\десятков байт, так что здесь описывать я подробно не буду.

    Заметил,что при дописывании в файле - рисунок не искажается (искажения идут снизу-вверх)

    [​IMG]

    [​IMG]

    что в целом может подойти как один из наипростейших методов.

    напишем тогда код

    алгоритм следующий:

    1)открыть битмап
    2)считать из хидера 2 параметр-размер битмапа (то есть получим нужное смещение)
    3)сместиться на полученное смещение
    4)записать строку с определенным идентификатором

    по считыванию назад

    1)открыть битмап
    2)считать из хидера 2 параметр
    3)читать строку от начала конца (простите за тавтологию) до идентификатора
    4)выдрать строку.


    имеем след. код:

    Code:
    type bmpheader=packed record
    bftype:word;
    bfsize:dword;
    bfres1:word;
    bfres2:word;
    bfoffbits:dword;
    end;
    
    var  Form1:Tform1;
    …………………………………..
    
    var size:bmpheader;
    f:hfile;
    tmp:dword;
    str:pchar;
    
    begin
    
    str:='fuck you bitch sosi kirpich :D';
    
    F := CreateFile(PChar('C:\input.bmp'), GENERIC_READ or GENERIC_WRITE , FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
    
    ReadFile(F, size, sizeof(size), tmp, nil);
    
    setfilepointer(f,size.bfSize,nil,FILE_BEGIN);
    
    WriteFile(f,str^,length(str),tmp,nil);
    
    CloseHandle(F);
    вот такой не большой код. для чтения все точно также.


    Следующий метод-замена младших бит.
    алгоритм его работы таков:
    есть изображение 24 битов. 1 пиксель кодируется 3 каналами (=3 байтам) RGB
    меняя наименее значащий бит мы инкрементируем значение байта на 1.

    Сама методика считается простой, т.к. должны использоваться форматы данных без потерь.Как недостаток-любые манипуляции с файлом контейнером не допустимы.Как достоинства-простота, кол-во данных для внедрения.

    Естественно что обнаружить сокрытое сообщение закодированное таким методом можно только с помощью стегоанализа. если провести небольшие расчеты то можно подсчитать что каждая точка кодируется числом в диапазоне от 0 до 255
    т.е. 3 байта на пиксел что составит 256^3 числа цветов. человеческий глаз различает около 4000 цветов\оттенков, так же человеческое зрение воспринимает лучше вариации зеленого цвета , по этому замену лучше проводить в синей или красной компоненте.

    окей;) и сейчас я начну писать как в этих симпотных книжках по делфи =^^=

    бросьте на форму: edit, label, 3 кнопочки, изображение, openpicturedialog, savepicturedialog что бы получилось примерно так:

    [​IMG]

    у image cв-ва proportional и stretch ставим в true
    в диалогах убираем все кроме битмапки.

    и сразу пишем обработчики событий кнопочег

    Code:
    // загружаем картинку
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    if OpenPictureDialog1.Execute then begin
    Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
    end;
    end;
    
    //застеганографируем сообщение
    
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    steanographthemall(Image1.Picture.Bitmap, sign+(edit1.Text));
    if SavePictureDialog1.Execute then
    Image1.Picture.SaveToFile(SavePictureDialog1.FileName);
    end;
    // извлекаем сообщение
    
    
    procedure TForm1.Button3Click(Sender: TObject);
    var
    s: string;
    begin
    if openpicturedialog1.Execute then
    image1.Picture.LoadFromFile(openpicturedialog1.FileName);
    showmeyourself(Image1.Picture.Bitmap, s);
    showmessage(s);
    end;
    ну и самый замес- процедуры кодировки\раскодировки, но сначала пишем в константах:

    Code:
    const 
    sign:string=’dood’;
    по ней будем идентифицировать информацию в картинке

    процедура стеганографирования (нужные комментарии непосредственно в коде)

    Code:
    procedure steanographthemall (BMP: TBitmap; Message: string);
    var
      i,j,psz,fromhead  : integer;
      rowl   :  pByteArray;
      PB    : pByte;
      incc: PChar;
      bcode,Nbcode,intc,bc: byte;
    begin
      psz:=3; // разрядность изображения, не проверял сколько может поддерживаться, только делал на 24 битном, попробуйте поиграть
    
      if not Assigned(BMP) then exit;
      Message:=sign+Message;
      fromhead:=Length(Message)+2; 
      with BMP do begin
    
        incc:=@Message[1];  // указатель на начало сообщения 
        BC:=0;
        for i:=0 to Height-1 do begin
          rowl:=ScanLine[i];   // указатель на строку пикселей
          pb:=@rowl[0]; // смещаем 1 бит на пиксель (можно и больше для большей вместимости шифруемой информации, однако это даст заметно сильные искажения видимые не вооруженным глазом
    
          for j:=0 to Width-1 do begin
             intc:=Ord(incc^);
    
            asm
            mov al,0feh     // сбрасываем нулевой бит
            mov bcode,al
    
            xor al,al
            mov al,bcode
            not al
            mov nbcode,al //сдвигаем что бы записывался младший бит
    
            mov cl,8       
            ror Intc,cl
            mov cl,BC    // проход по битам символа
            ror IntC,cl
            end;
            PB^:=(PB^ and BCode) 
                 or (IntC and NBCode); // 7 бит не изменяем, а изменяем только 0 или 1 в зависимости от того какой бит установлен в данный момент и какой бит в строке
    
             
            if (BC = 7) then begin  // прошел весь символ?
              inc(incC);  // след. символ
              dec(fromhead); // декрементируем число оставшихся
              BC:=0;  // очищаем счетчик битов
    
    
            end
            else
              inc(BC);
            if fromhead = 0 then exit;
    
            inc(PB, PSz);  // перемещаем указатель буфера битмапа.
          end;
          end;
          end;
          end;
    
    для битовых операций применился встроенный ассемблер, как бы для студенческой поделки оно и не требуется, однако под напором окружающей среды мозг начинает сохнуть и мне захотелось его пое*ать.)


    процедура извлечения

    Code:
    procedure showmeyourself(BMP: TBitmap; var msg: string);
    var
      i,j,psz: integer;
      c: Byte;
      pb    : pByte;
      rowl   : pByteArray;
      bc,bit,bit2,bitc: byte;
    
    
    begin
      psz:=3; // 24bit bitmap
      msg:=''; // сообщение пока пусто
    
      if not Assigned(BMP) then exit;
      with BMP do begin
    
        c:=0;
        BC:=0;
        for i:=0 to Height-1 do begin
         rowl:=ScanLine[i];
          pb:=@rowl[0];
          for j:=0 to Width-1 do begin
    
    
            asm
            xor al,al // 1 бит сообщения на пиксель
            inc al
            mov bit,al
            end;
    
             Bit:=PB^ and Bit;
    
             asm
             mov al,bit
             shr al,0
             mov bit2,al
             end;
    
    
    // проверяем установленные биты
            Bit2:=Bit2 shl BC; // операции противополжны процедуре выше
            [COLOR=Red]BitC:=1;
            asm
            mov cl,BC
            add BitC,cl
            end;[/COLOR]
    
            C:=C or (BitC and Bit2);
            if BC = 7 then // прошли байт
            begin  
            if C <> 0 then  //- 0? конец данных
            begin
            msg:=msg+Chr(C);
            if (Length(msg) = 4) then  // длинна сигнатуры?
            begin
            if msg = sign then // да,- сигнатура совпала- да.
            begin
    
            msg:='';
            end;
    
            end;
            end
            else if (i + j) > 0  then // если не первый пиксель
            exit;
            C:=0;
            BC:=0;  // сбрасываем счетчик битов
            end
            else
            inc(BC);  // читаем след. бит.
            inc(PB, Psz);
          end;
          end;
          end;
          end;
    
    А ВОТ ТУТ ТО И ПРИКОЛ!!!
    я решил устроить просто небольшую фишку (если это вообще хоть кому-то интересно) я допустил ошибку в строке расшифровки, а именно вот тут

    Code:
      Bit2:=Bit2 shl BC; // операции противополжны процедуре выше
            BitC:=1;
            asm
            mov cl,BC
            add BitC,cl
            end;
    ее найти очень просто (подсказка в коменте). кто сможет найти тот сможет кой чего посмотреть,это я укажу в конце статьи.

    МЕТОДЫ АНАЛИЗА

    как правило если это не такая студенческая поделка, как у меня, которую вскроет любая стегоаналитическая софтина, то методы атаки основаны на нехеровых мат. расчетах что мне объяснить не доступно ибо я не математик.

    если же это что то простое то обычно можно применить:
    прослушивание-просматривание файла
    известен пустой контейнер - например добавить шумы к изображению, проанализировать звуковой спектр в аудиофайле етц…

    я провел свое микроисследование этого же метода НЗБ
    вот что мы видим:

    [​IMG]

    размер одинаков.

    а теперь засовываем в хекс редактор.

    [​IMG]

    как можно наблюдать слева- зашированное, программа меняла последний бит картинки и ставила в соответствие

    00 - 0
    01 - 1
    FF - 1
    FE - 0

    строчки снизу вверх, а так же в винде по-моему не как у людей RGB , а BGR.


    даа забыл указать, объемы скрываемых сообщений зависят от применяемых алгоритмов и обычно бывают ~ 1\5 от объема файла контейнера.

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

    вот и подошел момент истины что называется.Это такой миниквест если кому интересно(не только ж я себе мозги ебу). с помощью программки по НЗБ в этой картинке

    [​IMG]

    зашифрован адрес на архив.


    а с помощью вот этого кода

    Code:
    program Project1;
    
    {$APPTYPE CONSOLE}
    uses sysutils;
    
    
      var
      inn, outt : textfile;
      i, j, cnt : integer;
      OneSymbol : byte;
      sIn, s, sOne : string;
      inpt:string = 'C:\1.txt';
      otp:string= 'C:\2.txt';
    
    
    procedure encrypt;
    begin
    
    Assign(inn, inpt);
    Assign(outt, otp);
    WriteLn('input the encode string: ');
    Readln(sIn);
    Reset(inn);
    
    cnt:=0;
    while (Not EOF(inn)) do
    begin
    Readln(inn);
    inc(cnt);
    end;
    Close(inn);
    begin
    Reset(inn);
    Rewrite(outt);
    for i:=1 to Length(sIn) do begin
    OneSymbol := ord(sIn[i]);
    for j:=1 to 8 do begin
    ReadLn(inn, s);
    
    while ( Length(s)>0 ) and (s[Length(s)]=' ') do Delete(s,Length(s),1);
    
    if (OneSymbol and 1) = 1 then s:= s+' ';
    WriteLn(outt, s);
    
    
    OneSymbol := OneSymbol shr 1;
    
    end;
    end;
    
    ReadLn(inn, s);
    while ( Length(s)>0 ) and (s[Length(s)]=' ') do Delete(s,Length(s),1);
    
    
    s:= s+'  ';
    WriteLn(outt, s);
    
    
    while Not EOF(inn) do begin
    ReadLn(inn, s);
    WriteLn(outt, s);
    end;
    
    
    Close(outt);
    Close(inn);
    
    end;
    end;
    
    procedure decrypt;
    
    begin
    Assign(inn, inpt);
    Assign(outt, otp);
    
    sIn := '';
    Reset(outt);
    i:= 0;
    OneSymbol := 0;
    
    while Not EOF(outt) do begin
    Readln(outt, s);
    if Length(s)>=2 then
    
    if copy(s,Length(s)-1,2)='  '
    then Break;
    inc(i);
    if (Length(s)>0) and (Copy(s, Length(s),1)=' ') then OneSymbol := OneSymbol or $80;
    if i=8 then begin
    sIn := sIn + chr(OneSymbol);
    i:=0;
    OneSymbol := 0;
    end
    else OneSymbol := OneSymbol shr 1;
    end;
    WriteLn('detected: ', sIn);
    WriteLn;
    Readln;
    end;
    
    begin
    // uncomment what u need
    //encrypt;
    decrypt;
    
    end.
    из архива из текстового файла извлекается пароль к папке;);) вот тяк от.

    всем спасибо за внимание. баклажанами не бросаться!)
     
    6 people like this.
  2. randman

    randman Members of Antichat

    Joined:
    15 May 2010
    Messages:
    1,366
    Likes Received:
    610
    Reputations:
    1,101
    Пожалуй придется оставить сообщение, знаю, напишешь статью, она идет вниз, рейтинга просмотров почти нет, никто ничем не поинтересуется, не спросит, не предложит написать/добавить.

    Почти не сталкивался с стеганографией поскольку это не было нужно, тема очень интересная, но её приходится использовать, как и искать в очень редких случаях, которые я практически за исключением основных не могу припомнить, - хотелось бы расширить область применения.


    DooD, эта статья - неплохое введение, но все её содержание больше относится к программированию на Dephi и ASM, что будет безусловно интересно читателем, но вероятно не при изучении стенографии. Так-же можно было-бы рассказать больше о используемых технологиях, структуре файлов, а не комментировать блоки кода подобным типом:
    Оформление у предложений практически никакое(Вы сломали обе клавиши Shift?), я понимаю, это ваш стиль, но не стиль других людей. Текста вполне достаточно, однако когда я его читал, я не нашел взаимосвязи его большей части с содержанием и темой статьи.

    Если вы будете писать продолжение, хотелось бы больше узнать о повседневном применении стенографии, ей обнаружении, и о том, как её применять что-бы никто и не думал что она используется, а она используется, и не просто так.
     
    #2 randman, 7 Jun 2013
    Last edited: 7 Jun 2013
  3. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    2ХАМЕНА скажу,что я взял что то наиболее простое,потому что тема сложная,хорошие алгоритмы требуют математических знаний на высоком уровне. метод LSB подходит для множества форматов, однако опять же я взял bmp потому что это ОЧЕНЬ простой формат и тут не должно возникнуть больших сложностей с пониманием.
    согласен что к оформлению отношусь небрежно,ну такой я;)
    а общие принципы применения я думаю не сильно важны или интересны,т.к. это может быть все что угодно,как шифрование для себя,так и обмен информацией между террористами.
     
  4. randman

    randman Members of Antichat

    Joined:
    15 May 2010
    Messages:
    1,366
    Likes Received:
    610
    Reputations:
    1,101
    Как-то абстрактно это все, вот если бы её использовать так активно, как уязвимости :D Без этого скучно очень и читать, и делать. Сделал бэкап ценных данных, пустил по сети и все, больше и сказать нечего.
     
  5. sud0

    sud0 Banned

    Joined:
    1 Jan 2013
    Messages:
    263
    Likes Received:
    40
    Reputations:
    20
    D00D , спасибо за статью , очень интересно почитать!

    \\ до этого юзал так в консоли
    Code:
    copy /b 1.jpg + 2.rar 3.jpg.
    2.rar конечно под паролем ))

    было интересно узнать глубже про стенографию в целом! :)