Шукати в цьому блозі

четвер, 31 травня 2012 р.

Шифруемся и прячемся: стеганография

Кратко о предметной области.
Стеганография - в переводе с греческого дословно означает «тайнопись». Это наука о скрытой передаче информации путём сохранения в тайне самого факта передачи. В отличие от криптографии, которая скрывает содержимое секретного сообщения, стеганография скрывает само его существование.
Для достижения преследуемых в этой заметке целей в Debian GNU/Linux есть замечательный пакет - steghide:
A steganography hiding tool
Steghide is steganography program which hides bits of a data file in some of the least significant bits of another file in such a way that the existence of the data file is not visible and cannot be proven.

Steghide is designed to be portable and configurable and features hiding data in bmp, wav and au files, blowfish encryption, MD5 hashing of passphrases to blowfish keys, and pseudo-random distribution of hidden bits in the container data.
установим его:
$ aptitude install steghide
Теперь можем попробовать спрятать любой текст в изображении. Спрячем текст взяв его со стандартного ввода:
$ echo "Текст спрятанного сообщения" | steghide embed -cf image.jpg -p passw0rd -ef -
"Текст спрятанного сообщения" будет имплементирован в файл image.jpg поэтому если оригинал изображения дорог вам как память то предварительно создайте его копию.
Чтобы увидеть спрятанный текст проделаем обратную операцию:
$ steghide extract -sf image.jpg -p passw0rd -xf -
Ничего сложного! Можно посмотреть информацию о спрятанных данных:
$ steghide info image.jpg
"image.jpg":
  format: jpeg
  capacity: 4,9 KB
Try to get information about embedded data ? (y/n) y
Enter passphrase: 
  embedded data:
    size: 53,0 Byte
    encrypted: rijndael-128, cbc
    compressed: yes
А также получить список всех поддерживаемых алгоритмах шифрования, которые можно использовать совместно с опцией -e (--encryption):
$ steghide encinfo
encryption algorithms:
<algorithm>: <supported modes>...
cast-128: cbc cfb ctr ecb ncfb nofb ofb
gost: cbc cfb ctr ecb ncfb nofb ofb
rijndael-128: cbc cfb ctr ecb ncfb nofb ofb
twofish: cbc cfb ctr ecb ncfb nofb ofb
arcfour: stream
cast-256: cbc cfb ctr ecb ncfb nofb ofb
loki97: cbc cfb ctr ecb ncfb nofb ofb
rijndael-192: cbc cfb ctr ecb ncfb nofb ofb
saferplus: cbc cfb ctr ecb ncfb nofb ofb
wake: stream
des: cbc cfb ctr ecb ncfb nofb ofb
rijndael-256: cbc cfb ctr ecb ncfb nofb ofb
serpent: cbc cfb ctr ecb ncfb nofb ofb
xtea: cbc cfb ctr ecb ncfb nofb ofb
blowfish: cbc cfb ctr ecb ncfb nofb ofb
enigma: stream
rc2: cbc cfb ctr ecb ncfb nofb ofb
tripledes: cbc cfb ctr ecb ncfb nofb ofb
Спрятанный текст можно брать не только из стандартного ввода, но и из заранее подготовленного файла:
$ steghide embed -cf image.jpg -p passw0rd -ef secretfile.txt
Равно как и восстанавливать его из картинки:
$ steghide extract -cf image.jpg -p passw0rd -ef secretfile.txt
Кстати, интересный момент, можно прятать не только текст, но и изображение в изображении, главное чтобы размер того в чём прячем изначально был больше того, что прячем (не знаю на сколько - не проверял), а иначе рискуем получить ошибку следующего вида:
steghide: the cover file is too short to embed the data.
Для примера "спрячем" мой аватар в другой красивой картинке:
$ steghide embed -cf image.jpg -p passw0rd -ef gremlin-gizmo.jpg
Оригинал от полученного изображения по размеру не сильно отличается, равно как и по качеству:
$ ls -l image.*
-rw-r--r-- 1 olden olden 260660 Май 31 15:55 image.jpg
-rw-r--r-- 1 olden olden 250538 Май 31 15:55 image.orig.jpg
$ md5sum image.*
5c3dfbd17d4e8bfbe15006e2282e17c2  image.jpg
b2d51cdf620b9180daebb5a2dad4a186  image.orig.jpg
Аватарка:

Оригинал:

А вот тут спрятана аватарка:

Всё тайное рано или поздно становится явным!
$ steghide extract -sf image.jpg -p passw0rd -xf avatar.jpg
Сравним результаты:
$ md5sum gremlin-gizmo.jpg avatar.jpg 
4c9106a839c2e0c6d7e4ccd8b095ff6e  gremlin-gizmo.jpg
4c9106a839c2e0c6d7e4ccd8b095ff6e  avatar.jpg
и визуально:

Кстати, помимо сравнения размеров и md5sum для оригинального изображения и изображения со стеганограммой, интересно сравнить их ещё и визуально:
$ compare -verbose image.orig.jpg image.jpg diff.png
Прелюбопытнейший результат. А с первого взгляда на изображения и не скажешь, что в них столько различий.

У вас до сих пор не было паранойи?! Тогда мы идём к вам!!!

3 коментарі:

sash-kan сказав...

а не имея пароля факт наличия стеганограммы детектируется?

т.е.:
1. известно, что параноик _мог_ воспользоваться программой steghide
2. анализируем все картинки, выложенные в блоге параноика с помощью steghide
3. находим те, что со стеганограммой
4. …
5. profit!!11

Alexander Russkih сказав...

а не имея пароля факт наличия стеганограммы детектируется?
Вот это вопрос из вопросов. Скажем так, с первого взгляда, средствами самого steghide вроде как и нет. Вот, что выдаёт если я знаю правильный пароль:

$ steghide info image.jpg
"image.jpg":
format: jpeg
capacity: 12,7 KB
Try to get information about embedded data ? (y/n) y
Enter passphrase:
embedded file "gremlin-gizmo.jpg":
size: 6,1 KB
encrypted: rijndael-128, cbc
compressed: yes

А вот, что выдаёт если я говорю, что знаю, но реально ввожу что-угодно только не нужный пароль:

$ steghide info image.jpg
"image.jpg":
format: jpeg
capacity: 12,7 KB
Try to get information about embedded data ? (y/n) y
Enter passphrase:
steghide: could not extract any data with that passphrase!

Т.е. ровно то же самое, что и для оригинального файла, в котором ничего не спрятано:

$ steghide info image.orig.jpg
"image.orig.jpg":
format: jpeg
capacity: 12,7 KB
Try to get information about embedded data ? (y/n) y
Enter passphrase:
steghide: could not extract any data with that passphrase!

Кстати, весьма забавный результат получается при сравнении двух файлов - оригинального и со стеганограммой:

$ compare -verbose image.orig.jpg image.jpg diff.png
image.orig.jpg JPEG 1500x750 1500x750+0+0 8-bit DirectClass 251KB 0.030u 0:00.030
image.jpg JPEG 1500x750 1500x750+0+0 8-bit DirectClass 261KB 0.030u 0:00.039
Image: image.orig.jpg
Channel distortion: Undefined
image.orig.jpg=>diff.png JPEG 1500x750 1500x750+0+0 8-bit DirectClass 1.421MB 3.050u 0:02.959

(Добавлю-ка я это дело в статью ;))

Alexander Russkih сказав...

И ещё забавно проделать другой "фокус" - сначала увеличим изображение, а затем сожмём его до оригинального размера и проведём сравнение:

$ cp image.orig.jpg image.im.jpg
$ mogrify -resize 2250x1125 image.im.jpg
$ mogrify -resize 1500x750 image.im.jpg
$ compare -verbose image.orig.jpg image.im.jpg diff2.png

Различий между изображениями получилось значительно больше нежели при внедрении стенограммы.

Даже если изображение увеличить не на 50%, а на 1px то всё-равно различий получается значительно больше чем при внедрении стенограммы.

$ cp image.orig.jpg image.im2.jpg
$ mogrify -resize 1501x751 image.im2.jpg
$ mogrify -resize 1500x750 image.im2.jpg
$ compare -verbose image.orig.jpg image.im.jpg diff3.png

Не менее забавно сравнить image.im.jpg с изображением содержащим стеганограмму, а затем сравнить между собою diff'ы:

$ compare -verbose image.jpg image.im.jpg diff4.png
$ compare -verbose diff.png diff4.png diff5.png

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

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

Есть ещё предположения как найти тайное в явном? ;)