понедельник, 6 августа 2012 г.

Курьезы стеганографии: Фракталы для скрытной передачи сообщений

Ни за что не догадаешься, что тут скрыта фраза
Test steganography message!!!!
 Глядя на приведенные изображения, можно подумать, что это очередные чудовищные эксперименты какого нибудь сумасшедшего профессора-фотошопщика. А тем не менее, как ни удивительно, это одна из методик стеганографии - создание своего контейнера и формата для передачи данных, неприметных для стороннего наблюдателя. Как ни покажется удивительным, в изображении, вынесенном в заголовок закодировано послание  Test steganography message!!!! Для скрытия данных эта программа использует специально сгенерированные  фрактальные изображения. 
Как нас убеждает Википедия: Фрактал — геометрическая фигура, обладающая свойством самоподобия, то есть составленная из нескольких частей, каждая из которых подобна всей фигуре целиком. Фрактальные изображения популярны из-за их эффектного внешнего вида и простоты их компьютерной генерации. 
Такие изображения генерирует программный комплекс MandelSteg v 1.0, исходные коды которой можно скачать тут. Цитирую описание на русском:
Позволяет скрывать информацию во фрактальных изображениях формата gif. MandelSteg создаст изображение и поместит в него секретную информацию, извлечь которую пользователь сможет с помощью утилиты GIFExtrac, входящей в пакет. Разработан для FreeBSD, Linux, NetBSD, OpenBSD и Solaris. 

Изображение, не содержащие скрытого сообщения
Немного об установке программного комлекса. Программа разработана под ОС LINUX и распространяется с открытыми исходными кодами. Сборка программы под LINUX-подобные системы проблемы не составляет - нужно только запустить команду make. Для сборки программы под ОС Windows необходимо запустить файл comp.bat после чего сборка будет осуществляться  компилятором cl.exe. Для создания фрактального изображения на базе скрываемого сообщения используется программа mandelsteg. Программа по умолчанию использует cout  для вывода результатов своей работы - содержимого GIF файла и cin чтобы получить скрываемое сообщение.
Чтобы скрыть сообщение, записанное в файле message.txt надо набрать в командной строке
mandelsteg -e hidemessage.gif < message.txt
Данная команда формирует фрактальное изображение на базе текста, содержащегося в message.txt и записывает его в файл hidemessage.gif размером 400х400 пикселей.
Параноики могут предварительно зашифровать сообщение при помощи pgp, для этого надо набрать следующую команду 
pgp -ef <secrets.dat | stealth | mandelsteg -bp 23 -fp -r -e \
hidemessage.gif
Чтобы получить пустой контейнер без скрытого сообщения нужно выполнить команду
mandelsteg -e empty.gif < /dev/null
Если необходимо более подробную информацию об опциях можно получить из файла README, входящего в архив или из подсказки программы.
Для извлечения сообщения из скрытого файла нужно использовать входящую в пакет программу gifextract. Для извлечения сообщения, скрытого в первом примере следует выполнить команду
gifextract hidemessage.gif
Для извлечения шифрованного сообщения, которое было скрыто во втором примере, при условии что ключ 0x23ffff нужно выполнить команду
gifextract -bp 23 hidemessage.gif  | stealth -a 0x23ffff | pgp -f > message.txt

Анализ исходных кодов программы.

Чтобы понять, как работает алгоритм сокрытия информация, изучим исходные коды программы mandelsteg проанализируем файл mangdelsteg.c. Начнем анализ естественно с функции main(). Итак что мы видим?
Первое что бросается в глаза - код разделен на два блока - тот что работает если при компиляции установлена опция компиляции LOW_MEM и где не она установлена. Просмотрим Makefile - в нем есть запись
CFLAGS=-o -DLOW_MEM
следовательно, в исследуемом алгоритме эта опция по умолчанию включена и можно исключить из анализа то что расположено внутри блока
#ifndef LOW_MEM
....
#else
Из кода видно, что программа делает следующие вещи:
1. Разбирает параметры командной строки, в соответствии с ними выставляет переменные переключатели.
2. Подготавливает значения для палитры RGB, заполняя их случайными значениями. Если указан параметр -fp то палитра содержит 256 цветов, иначе 128. Для этого используется следующий кусок кода:


//Формирование начального значения для псевдослучайной 
//последовательности
srandom(time(0)+getpid()); 
//Заполнение трех массивов, содержащих значения красной, зеленой
//и голубой компонент  палитры RGB случайными числами
for (i=0; i<256; i++) {
r[i] = random()&0xFF;
g[i] = random()&0xFF;
b[i] = random()&0xFF;
}


3. Вызывается функция save_gif_image(w,h,256,NULL,output_name,r,g,b) которая содержится в файле gif_comp.c Она выполняет основную работу по генерации фрактала, содержащего скрытое сообщение. В качестве параметров функция принимает:

  • Ширину и высоту изображения
  • Размер палитры GIF
  • Скрываемое сообщение
  • Имя файла, в которое будет записано получившееся GIF - изображение
  • Значение палитры RGB в виде трех отдельных одномерных массивов r[], g[], b[]


Перейдем к функции save_gif_image, и восстановим алгоритм работы программы.
Первоначально в функции формируется заголовок GIF файла, в который входит служебная информация вначале файла, показывающая что файл является изображением формата GIF87a, ширину и высоту изображения, а также сгенерированную на предыдущем шаге палитру цветов, записанных случайным образом.
Далее начинается непосредственная работа по сокрытию заданного нами сообщения. При анализе исходного кода важно помнить, что данное программное обеспечение для построения фрактала использует слегка модифицированное множество Мандельброта. Алгоритм построения множества Мандельброта давно и хорошо известен, например хорошо описан на этом сайте. Наша задача разобраться какие изменения внесли в этот стандартный алгоритм создатели стеганографической программы mandelsteg.
Прежде всего отметим, что первый шаг в рисовании фрактала - определить его центр. В интересующей нас программе центр определяется переменными dxs = -0.555; dys = -0.555;
Как известно множество описывается уравнением c участием комплексных чисел:
Z(n)=Z(n)^2+C, где Z(0)=0, C = dxs + i * dys
Таким образом, у каждой точки на плоскости есть свой потенциал - значение Z(n), который при рисовании фрактала обычно отображается цветом.
Ключевой функцией для понимания принципа сокрытия информации во фрактале является функция, расположенная в исходном файле mangdelsteg.c
int16   calc_pixel (off)
которая является модифицированной функцией вычисления потенциала точки множества Мандельброта, заданного параметром offset, который далее раскладывается на координаты x, y  при помощи выражения

rx = (dxs + dw * (double)(off % w));
ry = (dys + dh * (double)(off / w));
После этого осуществляется стандартный алгоритм подсчета потенциала точки на множестве, под который подразумевается число шагов n, за который точка достижима из центра множества. Если точка не достижима за какое то предельное количество шагов (в листинге это переменная lim), то считается что она не входит в множество. Для этого используется стандартный алгоритм, который я привожу ниже:
for (z = 0 ; z <= lim; z++) {
nx = nx2-ny2+rx;
ny = x*y*2.0+ry;

if ((nx2=nx*nx)+(ny2=ny*ny) > 4.0)
break;

x = nx;
y = ny;
}

if (z > lim)
pix = (int16) lim;
else
pix = (int16) z;
Подробнее его комментировать я не вижу смысла, он  довольно понятен и многократно описан.


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


mpix = pix & ~data_bit;

if (encoding) {
if (!in_count) {
in_count = 8;
        write_state = WRITE_DATA;
inc = getchar();
                        }
in_count--;
if (random_pad || write_state == WRITE_DATA) {
pix = mpix;
if ((inc & 0x80))
pix = mpix | data_bit;
inc <<= 1;
}
}
steg_count++;
}
Мы видим, что программный код осуществляет модификацию младщего бита

Комментариев нет:

Отправить комментарий