![]() |
Данная статья является райтапом на задание "128 кассир" из категории "Форензика". В задании рассмотрены внутреннее строение файлов растровых изображений в формате BMP, алгоритм RLE-кодирования и структура штрих кода стандарта Code 128. В качестве инструментов используются hex-редактор ImHex и графический редактор MSPaint.
Ссылка на задание: Игры Кодебай | CTF-платформа https://forum.antichat.xyz/attachments/29109260/0.png К заданию прилагается архив с файлом task.bmp. Расширение намекает, что данный файл, возможно, предназначен для хранения растрового изображения. Посмотрим в hex-редакторе что внутри: https://forum.antichat.xyz/attachments/29109260/1.png Действительно, данные в файле очень похожи на графические данные. Пробуем открыть файл и терпим неудачу. Вернемся в hex-редактор и более детально проанализируем содержимое файла. Если в файле всё же растровое изображение, то данные в формате BMP должны состоять из следующих блоков: 1) Заголовок - содержит структуры BITMAPFILEHEADER (всегда первые 14-байт) и BITMAPINFO. 2) Таблица цветов 3) Цветовой профиль 4) Пиксельные данные Рассмотрим заголовок нашего файла: В первых двух байтах (адреса 0x0 : 0x1) указана сигнатура файла [00 4D]. Мы же предположили что у нас BMP - меняем на [42 4D]. https://forum.antichat.xyz/attachments/29109260/2.png В следующих четырех байтах (0x2 : 0x5) указан размер файла в байтах [CE B0 02 00] = 0x2B0CE = 176334 байта. Проверим размер нашего файла - все сходится. После размера 4 байта зарезервированы и должны быть занулены. Далее 4 байта с адресом пиксельных данных (imageData) = 0x48A. На этом описание структуры BITMAPFILEHEADER завершено, следом идет описание структуры BITMAPINFO: В четырех байтах по адресу 0xE : 0x11 указан размер данной структуры в байтах (DIB Header Size), согласно которому мы можем определить версию самой структуры: [7C 00 00 00] = 124 байта, значит версия структуры - BITMAPV5HEADER. Количество версий, их описания и различия можно потом легко загуглить, мы же рассмотрим только наиболее важные поля для решения Таска: https://forum.antichat.xyz/attachments/29109260/3.png С 0x12 по 0x15 и с 0x16 по 0x19 байт должны быть указаны ширина и высота изображения в пикселях: [64 00 00 00] [14 00 00 00] = 100px на 20px. В двух байтах по адресу 0x1C указана битность изображения - 0x08, т.е. на каждый пиксель приходится 8 бит (1 байт). В 31-м байте (адрес 0x1E) указан способ хранения пикселей: 0x01 - используется RLE-кодирование. По адресу 0x22 : 0x25 указан размер пиксельных данных (imageData) в байтах: [24 AA 02 00] = 174628 байт. Далее идет описание разрешения изображения (0x26 : 0x2D), характеристики таблицы цветов (0x2E : 0x35) [00 01 00 00] - 256 ячеек, описание битовых масок (0x35 : 0x45), цветового пространства (0x46 : 0x79), предпочтения при рендинге (0x7A : 0x7D), указано смещение в байтах цветового профиля от начала BITMAPINFO [A0 AE 02 00] (следовательно его адрес 0x02AEAE) и его размер [20 02 00 00] - 544 байта). Описание Заголовка bmp-файла завершается четырьмя нулевыми байтами по адресу 0x86 : 0x89 - а это как раз 124 как и было указано в DIBHeaderSize (0x89-0xD=0x7C). На данном этапе мы изучили заголовок нашего файла и исправили его сигнатуру - давайте попробуем открыть файл: https://forum.antichat.xyz/attachments/29109260/4.png Видим черный прямоугольник размером 100 на 20 пикселей. Смотрим в хекс-редакторе что там дальше после заголовка. А далее в файле, согласно описанию структуры версии BITMAPV5HEADER, по адресу 0x8A должна находиться Таблица цветов, представляющая собой одномерный массив четырехбайтной структуры, в которой указывается цвет в модели RGB. Размер Таблицы 256 ячеек (см. 0x2E : 0x35) - следовательно следующие за Заголовком 1024 байта (256*4) являются Таблицей цветов. Тут ничего интересного - смотрим дальше. Итак мы на 0x48A - а это согласно заголовку начало пиксельных данных (см. 0xA : 0xD), размер которых 174628 байт (см. 0x22 : 0x25). Помечаем 0x2AA24 байта в хекс-редакторе как ImageData и в конце файла остается 544 байта по адресу 0x02AEAE : 0x02B0CD, которые являются цветовым профилем (см. описание ICC Profile в 0x7E:0x81 и 0x82 : 0x85). Вроде все корректно, но 174628 сжатых байт пиксельных данных для изображения площадью в 2000 пикселей как-то слишком много. Давайте посмотрим данные из ImageData, но прежде разберемся в способах хранения и алгоритме прорисовки пикселей изображения в bmp-формате. В формате Windows Bitmap хранение пикселей допускается тремя способами: 1) Двумерный массив. 2) RLE - сжатие кодированием повторов. 3) В форматах JPEG или PNG (выходит за рамки данной статьи). При хранении данных в двумерном массиве, пиксели растра записываются однопиксельными горизонтальными строками, начиная с самого нижнего и строго только от левого пикселя к правому. Для наглядности создадим картинку в формате BMP размером 6px на 5px с произвольными цветами пикселей и посмотрим в hex-редакторе каким образом цвета пикселей хранятся в ImageData: https://forum.antichat.xyz/attachments/29109260/5.png Как мы видим все просто: перечислены значения пикселей по горизонтали начиная с самой нижней, а строки разделены двумя нулевыми байтами [00 00]. В RLE-кодировании прорисовка производится также по горизонтали, начиная с левого нижнего пикселя и заканчивая правым верхним, при этом дозволено прерывание прорисовки горизонтали и перемещение прорисовки на другую позицию, а формирование изображения осуществляется двухбайтовыми командами: Код: Код:
[01..FF][байт] - прорисовать пиксели со значением из второго байта столько раз сколько указано в первом байтеВозьмем байты первой горизонтали (т.е. самой нижней) и посмотрим что они прорисовывают - расположены они от начала ImageData до первого разделителя строк [00 00] по адресу 0x48A : 0x497: Код: Код:
FF 00 FF 00 FF 00 FF 00 FF 00 05 00 00 00Таким образом нарисована горизонтальная полоса в 1280 черных пикселей (значение цвета в ячейке таблицы цветов с индексом 00 = #000000 = black). Но как это возможно ведь мы знаем что ширина нашего изображение 100px (см. 0x12 : 0x15)!? Пока не паникуем - в RLE допускается рисовать пиксели за пределами размера растра, анализируем следующие горизонтали. Далее аналогичным образом прорисовываются еще 44 аналогичных строк - возможно это фон. Анализируем 46 строку : Код: Код:
03 00 01 01 01 11 04 15 01 13 01 03 01 00 01 02 .. 00 0001 01 - рисуется один пиксель с цветом из ячейки таблицы цветов с индексом "01": #010101 01 11 - один пиксель с цветом из ячейки таблицы цветов с индексом "11": #111111 04 15 - четыре пикселя с цветом из ячейки с индексом "15": #151515 01 13 - один пиксель с цветом #131313 и так далее до команды [00 00] всего прорисовывается 1280 пикселей, а ввиду того что пиксели разные, посмеем предположить, что это начало изображения. https://forum.antichat.xyz/attachments/29109260/6.png Бегло проанализируем остальные горизонтали - везде 1280px. Следовательно ширина картинки не 100px, а 1280px. Высоту изображения можно вычислить посчитав количество горизонталей - я насчитал 193. Заменим в заголовке значения ширины и высоты изображения на 0x500 и 0xC1 соответственно: https://forum.antichat.xyz/attachments/29109260/7.png Сохраняем изменения и пробуем открыть файл: https://forum.antichat.xyz/attachments/29109260/8.png Видим изображение похожее на штрих код. Попытки распознать его различными сканерами не увенчались успехом, возвращаемся к истокам - к названию и тексту задания. В названии Таска число 128 наталкивает на мысли, что этот штрих код создан по стандарту Code-128 или GS1-128, ну или какого-то другого стандарта в названии которого фигурирует это число. В тексте описания к заданию что-то про черно-белое или про бело-черное и требования вызвать кассира, что наводит на мысли попробовать инвертировать цвета - инвертируем: https://forum.antichat.xyz/attachments/29109260/9.png Снова пытаемся прочитать штрих код каким-нибудь сканером и получаем Флаг! (если не удается отсканировать, следует добавить белые поля в начале и конце штрихкода - они обязательны) Надеюсь статья была полезна для Вас! Если найдете неточности или ошибки - обязательно напишите об этом в комментариях к статье. |
Спасибо!)
Ещё руки не дошли до него, но судя по райтапу он больше на хард стягивает А какой ты hex-редактор используешь? У него автоматическая подсветка структуры файла (фото 4)? |
Цитата:
|
Цитата:
Я пользовался 010 Editor с template BMP, там подтягиваются BITMAPFILEHEADER и BITMAPHEADERы https://forum.antichat.xyz/attachmen...a1ad5b50bf.png По сути пофиксить BMP, подогнать размер и готово. Точно не хард. PS Буду знать про ImHex, надо будет попробовать. |
Цитата:
|
Да,это жёстко Первый раз такое вижу)) решил
|
| Время: 14:00 |