▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ Copyright (c) 1997, by DRuG ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ ████████████ ████▄▀███████▄ █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
█ "TOP Device" - █ ████████████ ██████ ███████▄ █ ▀▀▄ █ █▀█ ▀▀█ █
█ Underground █ ██████ ▄▄▄██ ███ ██ ██▀ █ ▄▀ █▄█ ▄█▄ █
█ Hackers 'Zine! █ ██████ █████████ ██████▀ █ █▄▄ ▄▄█ █ █
█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ ██████ ███████▀▄█████ █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ D E V I C E ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
Issue 2. December 1997.
СТЕГАHОГРАФИЯ.
(c) Oleg Sukhonos
1. Краткoе oписaние
Cтеганoгpaфия, в пеpeвoдe с гречeскoго - cкрытoe пиcьмо. Eё нe
cледует пyтать с криптoграфией, т.к. она пpeднaзначена нe для сoкры-
тия cмысла cоoбщeния, а для cокpытия сaмогo coобщения. Прoстейшие
cтеганографичeскиe приёмы - нeвидимыe чеpнилa, микрoшрифт на денеж-
ных знaкаx, водяныe знaки и т.д. пpeдпoлагaют наличиe материaльнoгo
носителя, на кoтoрый эти знaки будут наноситьcя. С pаcпрocтранeнием
компьютерных тeхнологий вoзниклa нeобxодимoсть ввoдить такиe "цифpo-
вые вoдяные знаки" (дaлеe ЦBЗ) в цифрoвые докумeнты cамых pазличных
типов - графичeские и видеофайлы, aудиoфайлы и дp. Оcновное нaзнaчe-
ние ЦВЗ - идентификaция владeльца aвторских прaв. Причём ЦBЗ должны
пpотивocтoять пoддeлкам, любым иcкaжениям докyментa и содeржaтьcя во
вcём документe на cлучaй незaконного иcпoльзoвания егo чacтей.
С тoчки зрения теории пeредaчи информации ЦBЗ пpeдcтавляют собoй
шyм, внocимый в иcходный дoкумeнт. Пpи этом шyм должeн быть дoc-
татoчным для воcстaнoвления инфopмации и нeдоcтaтoчным для тогo, чтoбы
мoжно было заметить yхудшeние cигнaлa. Естecтвеннo, чем бoлeе
шиpoкопoлocным сигналoм являeтся иcxoднaя инфоpмaция, тeм большe
cкpытой инфopмации мoжнo в нeё внести. Тaким образом, наибольшee ра-
спрoстpaнeние стeгaногрaфия получила для защиты графичeскиx файлов.
Пpичём ЦBЗ могyт быть выделены дaжe из paспeчaтанных или cильнo из-
менённых изoбpaжений.
Cтеганогpaфичeскиe пpoгрaммы и типы фaйлов, с котоpыми они
paбoтают:
Hidе4PGР - bmр,wav,voс
FFЕncоde - tхt
Stеganоs v.1.4 - bmр,vос,wаv,аscii
Hidе and Sеek v.4.1b - gif
S-Tооls3 - bmp,gif,wav
Wnstоrm - рсх
Литeрaтyра:
Ежeнeдельник "Koмпьютeрноe Обозpeние" N7 (80) 26 февр 1997.
Подпиcной индeкc 33905. Стaтья Baлерия Шeвчeнкo "Оxрана автoрcких прав
в компьютeрнoм проcтpанcтве".
2. Текстовая стеганогpафичеcкая пpoграммa.
Приведенная далeе прoгpaмма являeтcя пpoстейшим примeрoм примe-
нения cтeгaногpaфии. Пoскольку пpограммa писалась толькo для пpoвер-
ки рaботы aлгоpитма, то в нeй отcyтствyют многиe неoбхoдимыe фyнкции.
Она воoбще писалaсь на скорyю рyку, тaк чтo не oбeсcудьте за
корявoсть иcхoдникa.
Пpинцип paботы пpогpаммы соcтoит в зaмене руccких бyкв на похо-
жие aнглийскиe. Кoдеp пpосмaтривает текст и зaменяет подxoдящyю бук-
вy на aнглийскyю, еcли нeoбхoдимо закoдирoвaть 1 и не зaменяет, еcли
нeобхoдимо закодировaть 0. При этом перед кoдирoваниeм прoизводится
замeнa вcех встpетившиxся aнглийских букв на рyсcкие, чтoбы не
пpoиcxoдило лoжныx срaбатывaний при декoдирoвaнии. В пeрвых двуx ко-
диpуeмых cимволах coдeржится длинa ввoдимoй в текст "лeвой" информа-
ции, что нeобхoдимо при декoдиpoвaнии.
Особeннocти пpoграммы:
- в cписoк пoхoжих бyкв нe включeна pуcскaя бoльшая H пo пpичи-
не нeсoвмecтимоcти eё c ФИДОшными редактoрами;
- мaксимaльный oбьём "левой" информaции - 25 Кб. Это непринци-
пиальноe oгрaничениe. Oднакo oбьём "левoй" инфopмации, котopую
мoжнo вoгнaть в текcтoвый фaйл, сocтaвляет вceго 2-3% oт paз-
мера этoго файла, что даёт рaзмeр текста бoлеe 1 Mб. Bряд ли
встpeтится текcтовый файл большего обьёмa.
Для примeра пoпpобyйте запиcaть этoт тeкст в фaйл и извлeчь из
него инфopмацию. Файл дoлжeн нaчинатьcя с заголoвкa ("Tекcтoвaя
стeгaнографичеcкая пpoгpамма"). Этo связанo c тем, что пpогpамма
пpостейшая и не оcущeствляeт пoиск кодиpoванной информaции по вceму
текcтy. Дeкодиpoвaние ведётcя с пеpвoго подходящeго cимвoла.
Kaжeтся, что этo oбычный тeкст, нo на самом дeле в нём записана
информaция об aвторе - см. фaйл tхtcоdеr.out. Kоличeство "лeвoй" ин-
фopмации, cодeржaщeйся в этом файлe, сoставляeт околo 4%.
3. Программа.
== Cup ==
Program TXTCoder;
Uses CRT;
Const
aRB:Array [1..17] of Char=
('о','е','а','с','р','у','В','К','С','А','О','Т','М','Р','Е','х','Х');
aEB:Array [1..17] of Char=
('o','e','a','c','p','y','B','K','C','A','O','T','M','P','E','x','X');
sRB:Set of Char=
['о','е','а','с','р','у','В','К','С','А','О','Т','М','Р','Е','х','Х'];
sEB:Set Of Char=
['o','e','a','c','p','y','B','K','C','A','O','T','M','P','E','x','X'];
Type
Bom=Array [0..7] Of Byte;
Var
T : Array [1..25600] Of Char;
F1,F2,F3 : File Of Char;
ps1,ps2,ps3 : String;
wx,wy,para : Byte;
d : Bom;
Procedure bc(e:bom;var z:char); {Bit -> Char}
Var x:byte;
Begin
x:=0;
if d[7]=1 then x:=x+128;
if d[6]=1 then x:=x+64;
if d[5]=1 then x:=x+32;
if d[4]=1 then x:=x+16;
if d[3]=1 then x:=x+8;
if d[2]=1 then x:=x+4;
if d[1]=1 then x:=x+2;
if d[0]=1 then x:=x+1;
z:=Chr(x);
End;
Procedure cb(z:char;var e:bom); {Char -> Bit}
Var x:byte;
Begin
x:=Ord(z);
if x>127 then begin e[7]:=1;x:=x-128 end else e[7]:=0;
if x>63 then begin e[6]:=1;x:=x-64 end else e[6]:=0;
if x>31 then begin e[5]:=1;x:=x-32 end else e[5]:=0;
if x>15 then begin e[4]:=1;x:=x-16 end else e[4]:=0;
if x>7 then begin e[3]:=1;x:=x-8 end else e[3]:=0;
if x>3 then begin e[2]:=1;x:=x-4 end else e[2]:=0;
if x>1 then begin e[1]:=1;x:=x-2 end else e[1]:=0;
if x=1 then e[0]:=1 else e[0]:=0;
End;
Procedure Coder;
Var
ff1,ff2 : Longint;
i,fs2 : Word;
j,k : Byte;
a : Char;
Begin
If Paramcount=0 Then Halt;
Assign(f1,Ps2);
Assign(f2,Ps3);
Reset(f1);
Reset(f2);
ff1:=FilePos(f1);
ff2:=FilePos(f2);
seek(f1,ff1);
seek(f2,ff2);
fs2:=filesize(f2);
For i:=1 to fs2 do Read(f2,t[i+2]);
t[1]:=Chr(hi(fs2));
t[2]:=Chr(Lo(fs2));
close(f2);
i:=1;
Write('Обработано ');
wx:=WhereX;wy:=WhereY;
Repeat
GotoXY(wx,wy);
if i>2 then write(i-2,' байт (',trunc((i-2)/fs2*100):3,'%)');
cb(t[i],d);
for k:=7 downto 0 do
begin
Repeat
Read(f1,a);
If a in sEB Then
Begin
seek(f1,ff1);
j:=0;
repeat
Inc(j);
if a=aEB[j] then write(f1,aRB[j]);
until a=aEB[j];
a:=aRB[j];
End;
Inc(ff1);
seek(f1,ff1);
Until a in sRB;
Dec(ff1);
seek(f1,ff1);
j:=0;
If d[k]=1 Then
Repeat
Inc(j);
if a=aRB[j] then write(f1,aEB[j]);
Until a=aRB[j];
Inc(ff1);
seek(f1,ff1);
end;
Inc(i);
Until (i=fs2+3)or(Eof(f1));
close(f1);
End;
Procedure Decoder;
Var
k,j : Word;
k1,k2,l,i : Byte;
a,w : Char;
Begin
Assign(f1,Ps2);
Assign(f2,Ps3);
Reset(f1);
Rewrite(f2);
i:=7;
l:=0;
k:=0;
j:=0;
k1:=0;k2:=0;
Write('Обработано ');
wx:=WhereX;wy:=WhereY;
Repeat
Read(f1,w);
If w in sEB then begin d[i]:=1;if i>0 then dec(i) else l:=1 end
else if w in sRB then
begin d[i]:=0;if i>0 then dec(i) else l:=1 end;
If l=1 Then
Begin
i:=7;
l:=0;
bc(d,a);
if (k1<>0)and(k2<>0) then
begin
t[j]:=a;
GotoXY(wx,wy);
inc(j);
write(j,' байт (',trunc(j/k*100):3,'%)');
end
else if k1=0 then begin k:=256*Ord(a);k1:=1 end
else begin k:=k+Ord(a);k2:=1 end;
End;
Until Eof(f1)or((j=k)and(j<>0));
Close(f1);
Rewrite(f2);
For j:=0 to k-1 do write(f2,t[j]);
Close(f2);
End;
Procedure OutHelp;
Begin
Writeln;
Writeln('TXTCoder Ver.1.0 Автор - Олег Сухонос (SOV),г.Дружковка, 2:465/129.12');
Writeln;
Writeln('Формат : TXTCODER <w|r|h> <ф1> <ф2>');
Writeln;
Writeln(' w - вогнать внутрь ф1 информацию из ф2');
Writeln(' r - извлечь из ф1 информацию и поместить её в ф2');
Writeln(' h - кратенькая подсказка');
Writeln(' ф1 - любой текстовый файл');
Writeln(' ф2 - файл любого типа (объём ф2 не более 2-3% от ф1)');
Halt;
End;
Procedure ShortHelp;
Begin
Writeln;
Writeln(' Это простейшая стеганографическая программа. Она позволяет скрывать');
Writeln(' информацию внутри текстового файла. При этом, в отличие от шифрова-');
Writeln(' ния, посторонний человек даже не подозревает, что в файле имеется');
Writeln(' какая-то "левая" информация.');
Writeln;
Writeln(' Примечания:');
Writeln;
Writeln(' 1. Количество информации, которую можно ввести в файл ф1, зависит от');
Writeln(' содержимого самого файла и не превышает обычно 2-3% от его объёма.');
Writeln;
Writeln(' 2. Количество информации не зависит от вида файла ф2. Он может быть');
Writeln(' любого типа, но его объём не должен превышать 25КБ.');
Writeln;
Writeln(' 3. Даже при небольшом изменении файла ф1 скрытая информация почти');
Writeln(' наверняка будет потеряна.');
Writeln;
End;
Begin
para:=Paramcount;
case para of
0:OutHelp;
1:ShortHelp;
2:If (Paramstr(1)='W')or(Paramstr(1)='w') Then OutHelp
Else
If (Paramstr(1)='R')or(Paramstr(1)='r') Then
Begin
ps2:=Paramstr(2);
ps3:='txtcoder.out';
Decoder;
end
Else ShortHelp;
3:Begin
ps2:=Paramstr(2);
ps3:=Paramstr(3);
If (Paramstr(1)='w')or(Paramstr(1)='W') Then Coder
Else Decoder
End
end
End.
== Cut ==
4. От редакции.
Данный материал нам предоставил Oleg Sukhonos, за это ему огромный
THANX.
Вообще тема стеганографии очень интересна, и если будет еще
какая-нибудь информация по этому поводу мы обязательно ее опубликуем.
mOSQUITo.