PDA

Просмотр полной версии : стеганография для новичков


DooD
07.06.2013, 03:44
Здрасте форумчане.вот пока выдалось свободное время, и перед тем когда мне наступит конец в связи с сессией, решил попробовать поделиться информацией по интересной для меня теме-стеганографии.Материалец не претендует на какую то мега-статью, скорее личные наблюдения или что.

тема навеяна этим /thread375855-miniduke.html (https://antichat.live/threads/375855/)

и является продолжением этой 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)СЕКТОР.

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

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


CreateFile ('\\.\PhysicalDrive0',GENERIC_WRITE,FILE_SHARE_WRI TE,0,OPEN_EXISTING,0,0);

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

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


SetFilePointer(f,10*512,nil,FILE_BEGIN);

11 сектор в примере.

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


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


2)И вот самое интересное - сохраняем в битмап.

Тут напишем уже полноправную программку)

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

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

http://images.vfl.ru/ii/1370558000/8f03136d/2478987_m.jpg (http://vfl.ru/fotos/8f03136d2478987.html)

http://images.vfl.ru/ii/1370557997/17388720/2478981_m.jpg (http://vfl.ru/fotos/173887202478981.html)

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

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

http://images.vfl.ru/ii/1370557997/4e6e1a40/2478982_m.jpg (http://vfl.ru/fotos/4e6e1a402478982.html)

http://images.vfl.ru/ii/1370557998/5c770f94/2478984_m.bmp (http://vfl.ru/fotos/5c770f942478984.html)

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

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

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

1)открыть битмап

2)считать из хидера 2 параметр-размер битмапа (то есть получим нужное смещение)

3)сместиться на полученное смещение

4)записать строку с определенным идентификатором

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

1)открыть битмап

2)считать из хидера 2 параметр

3)читать строку от начала конца (простите за тавтологию) до идентификатора

4)выдрать строку.

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


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 что бы получилось примерно так:

http://images.vfl.ru/ii/1370557998/7bd40f80/2478983_m.jpg (http://vfl.ru/fotos/7bd40f802478983.html)

у image cв-ва proportional и stretch ставим вtrue

в диалогах убираем все кроме битмапки.

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


// загружаем картинку

procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then begin
Image1.Picture.LoadFromFile(OpenPictureDialog1.Fil eName);
end;
end;

//застеганографируем сообщение

procedure TForm1.Button2Click(Sender: TObject);
begin
steanographthemall(Image1.Picture.Bitmap, sign+(edit1.Text));
if SavePictureDialog1.Execute then
Image1.Picture.SaveToFile(SavePictureDialog1.FileN ame);
end;
// извлекаем сообщение

procedure TForm1.Button3Click(Sender: TObject);
var
s: string;
begin
if openpicturedialog1.Execute then
image1.Picture.LoadFromFile(openpicturedialog1.Fil eName);
showmeyourself(Image1.Picture.Bitmap, s);
showmessage(s);
end;

ну и самый замес- процедуры кодировки\раскодировки, но сначала пишем в константах:


const
sign:string=’dood’;

по ней будем идентифицировать информацию в картинке

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


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;

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

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


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; // операции противополжны процедуре выше
BitC:=1;
asm
mov cl,BC
add BitC,cl
end;

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;

А ВОТ ТУТ ТО И ПРИКОЛ!!!

я решил устроить просто небольшую фишку (если это вообще хоть кому-то интересно) я допустил ошибку в строке расшифровки, а именно вот тут


Bit2:=Bit2 shl BC; // операции противополжны процедуре выше
BitC:=1;
asm
mov cl,BC
add BitC,cl
end;

ее найти очень просто (подсказка в коменте). кто сможет найти тот сможет кой чего посмотреть,это я укажу в конце статьи.

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

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

если же это что то простое то обычно можно применить:

прослушивание-просматривание файла

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

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

вот что мы видим:

http://images.vfl.ru/ii/1370557998/fdcc78a5/2478985_m.jpg (http://vfl.ru/fotos/fdcc78a52478985.html)

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

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

http://images.vfl.ru/ii/1370557998/5b5f0779/2478986_m.jpg (http://vfl.ru/fotos/5b5f07792478986.html)

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

00 - 0

01 - 1

FF - 1

FE - 0

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

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

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

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

http://splashed.ucoz.ru/tomas.bmp

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

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


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.

из архива из текстового файла извлекается пароль к папке вот тяк от.

всем спасибо за внимание. баклажанами не бросаться!)

XAMEHA
07.06.2013, 16:18
Пожалуй придется оставить сообщение, знаю, напишешь статью, она идет вниз, рейтинга просмотров почти нет, никто ничем не поинтересуется, не спросит, не предложит написать/добавить.

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

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


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

procedure showmeyourself



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

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

DooD
07.06.2013, 16:27
2ХАМЕНА скажу,что я взял что то наиболее простое,потому что тема сложная,хорошие алгоритмы требуют математических знаний на высоком уровне. метод LSB подходит для множества форматов, однако опять же я взял bmp потому что это ОЧЕНЬ простой формат и тут не должно возникнуть больших сложностей с пониманием.

согласен что к оформлению отношусь небрежно,ну такой я

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

XAMEHA
07.06.2013, 16:37
а общие принципы применения я думаю не сильно важны или интересны,т.к. это может быть все что угодно,как шифрование для себя,так и обмен информацией между террористами.


Как-то абстрактно это все, вот если бы её использовать так активно, как уязвимости Без этого скучно очень и читать, и делать. Сделал бэкап ценных данных, пустил по сети и все, больше и сказать нечего.

sud0
07.06.2013, 17:25
D00D , спасибо за статью , очень интересно почитать!

\\ до этого юзал так в консоли


copy /b 1.jpg + 2.rar 3.jpg.

2.rar конечно под паролем ))

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