К заданию приложен pdf-файл в котором (возможно) флаг скрыт под черными прямоугольниками.
Задача: получить флаг.
Наверное, существует масса вариантов получить флаг в этом задании. С удовольствием почитаю ваши.
Тут же предлагаю рассмотреть 4 пришедших мне в голову.
Рассмотренный под первым спойлером вариант самый менее трудозатраный, но неинтересный.
Так же флаг можно добыть прибегнув к редакторам PDF-файлов, коих огромное множество.
У меня уже стоял свободный офисный пакет, который замечательно справился с задачей - смотрим под спойлер:
Для Pythona написана уйма библиотек, умеющих читать, записывать, редактировать pdf-файлы.
Под следующим спойлером использовал первую нагугленную библиотеку - PyPDF2.
Готовые решения это, конечно, замечательно, но предлагаю поглубже вникнуть в устройство формата pdf.
Под следующим спойлером я чуток вспотел.
Задача: получить флаг.
Наверное, существует масса вариантов получить флаг в этом задании. С удовольствием почитаю ваши.
Тут же предлагаю рассмотреть 4 пришедших мне в голову.
Рассмотренный под первым спойлером вариант самый менее трудозатраный, но неинтересный.
Открываем pdf-файл в браузере. Далее Ctrl+A, Ctrl+C. Открываем блокнот и Ctrl+V. Флаг.
(Примечание: в Chrome сочетания Ctrl+A отрабатывается чуть некорректно, поэтому выделяем мышкой текст вместе с квадратами, а далее копируем и вставляем в любой текстовый редактор)
(Примечание: в Chrome сочетания Ctrl+A отрабатывается чуть некорректно, поэтому выделяем мышкой текст вместе с квадратами, а далее копируем и вставляем в любой текстовый редактор)
Так же флаг можно добыть прибегнув к редакторам PDF-файлов, коих огромное множество.
У меня уже стоял свободный офисный пакет, который замечательно справился с задачей - смотрим под спойлер:
Открываем файл в LibreOffice Draw и добираемся до флага.
Тут мы можем изменять прозрачность элементов, удалять объекты и перемещать их мышью или клавиатурой.
Сдвигаем или удаляем элементы и получаем флаг.
Тут мы можем изменять прозрачность элементов, удалять объекты и перемещать их мышью или клавиатурой.
Сдвигаем или удаляем элементы и получаем флаг.
Для Pythona написана уйма библиотек, умеющих читать, записывать, редактировать pdf-файлы.
Под следующим спойлером использовал первую нагугленную библиотеку - PyPDF2.
Тут предлагаю воспользоваться готовой библиотекой PyPDF2 в Python для работы с файлами PDF.
Изучаем документацию, например
Устанавливаем библиотеку:
Пишем скрипт для извлечения текста из PDF-страницы:
Сдаем флаг.
Изучаем документацию, например
Ссылка скрыта от гостей
или
Ссылка скрыта от гостей
.Устанавливаем библиотеку:
$ pip install PyPDF2
Пишем скрипт для извлечения текста из PDF-страницы:
Python:
from PyPDF2 import PdfReader
reader = PdfReader('Сделка.pdf')
page = reader.pages[0]
text = page.extract_text().replace(" ", "")
print(text)
Сдаем флаг.
Готовые решения это, конечно, замечательно, но предлагаю поглубже вникнуть в устройство формата pdf.
Под следующим спойлером я чуток вспотел.
Открываем pdf-файл в текстовом редакторе и изучаем содержимое.
Сразу же обращаем внимание на то, что версия формата PDF-1.4 и без особого труда гуглим документацию для этой версии (Adobe Portable Document Format Version 1.4), чтобы подглядывать в неё в непонятных ситуаиях (сюда прикладывать не вижу смысла, да и там 978 стр).
Структура PDF файлов состоит из строк, массивов, потоков, словарей и объектов. Строки обрамляются в круглые скобки, массивы в квадратных скобках, словари записыватся в двойных треугольных скобках в виде пар <<ключ>> <<значение>>, потоки это любые бинарные данные записанные между ключевыми словами “stream“ и “endstream“, а объекты могут содержать в себе любой ранее перечисленный тип данных и обрамляются тегами “object” и “endobj”.
Посмотрим на наш файл:
Видим, что файле содержатся три объекта с потоками данных длинной (/Length) 789 байт, 23551 байт и 413 байт, потоки сжаты (/Filter) в gzip (/FlateDecode). Попробуем разжать потоки данных чтобы посмотреть что там.
Блокнотом мы ничего тут сделаем, поэтому прибегнем к питону:
В результате работы скрипта получаем человекочитаемые данные.
Каждая строка состоит из аргументов, за которыми следует их оператор.
Рассмотрим отрывок:
В рассмотренном отрывке удалось расшифровать слово «АКТ».
Проанализировав текст полученный в результате работы скрипта не составляет труда определить место где зашифрован флаг.
Пробуем расшифровать:
[/CODE]
Конечно можно написать скрипт, который быстро и максимально удобно сопоставит символы и выдаст готовый текст, но зачем — в сети полно готовых решений, а целью же данного способа было получить представление о формате pdf.
Флаг получен.
Сразу же обращаем внимание на то, что версия формата PDF-1.4 и без особого труда гуглим документацию для этой версии (Adobe Portable Document Format Version 1.4), чтобы подглядывать в неё в непонятных ситуаиях (сюда прикладывать не вижу смысла, да и там 978 стр).
Структура PDF файлов состоит из строк, массивов, потоков, словарей и объектов. Строки обрамляются в круглые скобки, массивы в квадратных скобках, словари записыватся в двойных треугольных скобках в виде пар <<ключ>> <<значение>>, потоки это любые бинарные данные записанные между ключевыми словами “stream“ и “endstream“, а объекты могут содержать в себе любой ранее перечисленный тип данных и обрамляются тегами “object” и “endobj”.
Посмотрим на наш файл:
Видим, что файле содержатся три объекта с потоками данных длинной (/Length) 789 байт, 23551 байт и 413 байт, потоки сжаты (/Filter) в gzip (/FlateDecode). Попробуем разжать потоки данных чтобы посмотреть что там.
Блокнотом мы ничего тут сделаем, поэтому прибегнем к питону:
Python:
import zlib
import re
pdf = open("Сделка.pdf", "rb").read()
stream = re.compile(b'.*?FlateDecode.*?stream(.*?)endstream', re.S)
for s in re.findall(stream,pdf):
s = s.strip(b'\r\n')
try:
print(zlib.decompress(s).decode('UTF-8'))
print("")
except:
pass
В результате работы скрипта получаем человекочитаемые данные.
Код:
1 0 0 -1 0 842 cm
q
.75 0 0 .75 0 0 cm
1 1 1 RG 1 1 1 rg
/G3 gs
0 0 794 1123 re
f
Q
q
.75 0 0 .75 72 188.37012 cm
0 0 0 RG 0 0 0 rg
/G3 gs
8.1511078 0 77.396164 16.865234 re
f
Q
q
.75 0 0 .75 72 217.46265 cm
0 0 0 RG 0 0 0 rg
/G3 gs
8.1511078 0 298.19177 16.865234 re
f
Q
q
.75 0 0 .75 72 275.64771 cm
0 0 0 RG 0 0 0 rg
/G3 gs
8.1511078 0 77.367538 16.865234 re
f
Q
q
.75 0 0 .75 72 304.74023 cm
0 0 0 RG 0 0 0 rg
/G3 gs
8.1511078 0 293.18213 16.865234 re
f
Q
q
.75 0 0 .75 72 72 cm
0 0 0 RG 0 0 0 rg
/G3 gs
BT
/F4 14.666667 Tf
1 0 0 -1 0 .47981739 Tm
0 -13.2773438 Td <023A> Tj
9.7756042 0 Td <0244> Tj
8.5375519 0 Td <024C> Tj
ET
BT
/F4 14.666667 Tf
1 0 0 -1 31.337753 .47981739 Tm
0 -13.2773438 Td <0249> Tj
10.5341797 0 Td <024A> Tj
9.7756042 0 Td <0242> Tj
10.5341797 0 Td <023F> Tj
9.7756042 0 Td <0246> Tj
12.2087708 0 Td <023A> Tj
9.7756042 0 Td <0010> Tj
4.8806458 0 Td <0249> Tj
10.5341797 0 Td <023F> Tj
9.7756042 0 Td <024A> Tj
9.7756042 0 Td <023F> Tj
9.7756042 0 Td <023E> Tj
9.9258881 0 Td <023A> Tj
8.629776 0 Td <0251> Tj
9.7684479 0 Td <0242> Tj
ET
BT
/F4 14.666667 Tf
1 0 0 -1 181.6136 .47981739 Tm
0 -13.2773438 Td <0015> Tj
ET
Q
q
.75 0 0 .75 72 115.638794 cm
0 0 0 RG 0 0 0 rg
/G3 gs
BT
/F4 14.666667 Tf
1 0 0 -1 0 .47981739 Tm
0 -13.2773438 Td <0249> Tj
10.5341797 0 Td <0248> Tj
11.0778351 0 Td <023E> Tj
9.9258881 0 Td <0249> Tj
10.5341797 0 Td <0242> Tj
10.5341797 0 Td <024B> Tj
10.5842743 0 Td <0242> Tj
ET
BT
/F4 14.666667 Tf
1 0 0 -1 77.796692 .47981739 Tm
0 -13.2773438 Td <024B> Tj
10.09729 0 Td <024C> Tj
8.2937622 0 Td <0248> Tj
11.4001007 0 Td <024A> Tj
9.4533386 0 Td <0248> Tj
11.4001007 0 Td <0247> Tj
ET
Q
q
.75 0 0 .75 72 159.277588 cm
0 0 0 RG 0 0 0 rg
/G3 gs
BT
/F4 14.666667 Tf
1 0 0 -1 0 .47981739 Tm
0 -13.2773438 Td <0249> Tj
10.5341797 0 Td <026A> Tj
8.1511078 0 Td <0268> Tj
7.8288422 0 Td <025E> Tj
8.5518646 0 Td <025A> Tj
8.1511078 0 Td <025C> Tj
7.6214142 0 Td <025F> Tj
8.1511078 0 Td <0270> Tj
8.3944244 0 Td <001D> Tj
ET
Q
q
.75 0 0 .75 72 188.37012 cm
0 0 0 RG 0 0 0 rg
/G3 gs
BT
/F4 14.666667 Tf
1 0 0 -1 0 .47981739 Tm
0 -13.2773438 Td <0042> Tj
ET
BT
/F4 14.666667 Tf
1 0 0 -1 8.1511078 .47981739 Tm
0 -13.2773438 Td <0024> Tj
9.7756042 0 Td <0051> Tj
8.1511078 0 Td <0052> Tj
8.1511078 0 Td <0051> Tj
8.1511078 0 Td <005C> Tj
7.328125 0 Td <0050> Tj
12.2087708 0 Td <0052> Tj
8.1511078 0 Td <0058> Tj
8.1511078 0 Td <0056> Tj
ET
BT
/F4 14.666667 Tf
1 0 0 -1 85.547272 .47981739 Tm
0 -13.2773438 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
ET
Q
q
.75 0 0 .75 72 217.46265 cm
0 0 0 RG 0 0 0 rg
/G3 gs
BT
/F4 14.666667 Tf
1 0 0 -1 0 .47981739 Tm
0 -13.2773438 Td <0042> Tj
ET
BT
/F4 14.666667 Tf
1 0 0 -1 8.1511078 .47981739 Tm
0 -13.2773438 Td <0026> Tj
10.5842743 0 Td <0032> Tj
11.4001007 0 Td <0027> Tj
10.5842743 0 Td <0028> Tj
9.7756042 0 Td <0025> Tj
9.7756042 0 Td <003C> Tj
9.7756042 0 Td <005E> Tj
4.8949585 0 Td <0056> Tj
7.328125 0 Td <0016> Tj
8.1511078 0 Td <0046> Tj
7.328125 0 Td <0052> Tj
8.1511078 0 Td <0051> Tj
8.1511078 0 Td <0047> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0017> Tj
8.1511078 0 Td <0046> Tj
7.328125 0 Td <0057> Tj
4.0719757 0 Td <0042> Tj
8.1511078 0 Td <005A> Tj
10.5842743 0 Td <0017> Tj
8.1511078 0 Td <0056> Tj
7.328125 0 Td <0042> Tj
8.1511078 0 Td <0056> Tj
7.328125 0 Td <0058> Tj
8.1511078 0 Td <0046> Tj
7.328125 0 Td <0046> Tj
7.328125 0 Td <0016> Tj
8.1511078 0 Td <0056> Tj
7.328125 0 Td <0056> Tj
7.328125 0 Td <0049> Tj
4.0719757 0 Td <0058> Tj
8.1511078 0 Td <004F> Tj
3.2561493 0 Td <0042> Tj
8.1511078 0 Td <0047> Tj
8.151123 0 Td <0013> Tj
8.151123 0 Td <0051> Tj
8.151123 0 Td <0016> Tj
8.151123 0 Td <0060> Tj
ET
BT
/F4 14.666667 Tf
1 0 0 -1 306.3429 .47981739 Tm
0 -13.2773438 Td <0042> Tj
8.1511078 0 Td <0042> Tj
ET
Q
q
.75 0 0 .75 72 246.55518 cm
0 0 0 RG 0 0 0 rg
/G3 gs
BT
/F4 14.666667 Tf
1 0 0 -1 0 .47981739 Tm
0 -13.2773438 Td <0249> Tj
10.5341797 0 Td <0268> Tj
8.1511078 0 Td <0264> Tj
6.576828 0 Td <026D> Tj
7.328125 0 Td <0269> Tj
7.9364166 0 Td <025A> Tj
7.8288422 0 Td <026C> Tj
6.5479584 0 Td <025F> Tj
7.6641235 0 Td <0265> Tj
8.5518646 0 Td <0276> Tj
7.635849 0 Td <001D> Tj
ET
Q
q
.75 0 0 .75 72 275.64771 cm
0 0 0 RG 0 0 0 rg
/G3 gs
BT
/F4 14.666667 Tf
1 0 0 -1 0 .47981739 Tm
0 -13.2773438 Td <0042> Tj
ET
BT
/F4 14.666667 Tf
1 0 0 -1 85.518646 .47981739 Tm
0 -13.2773438 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.1511078 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
8.151123 0 Td <0042> Tj
ET
Q
q
.75 0 0 .75 72 304.74023 cm
0 0 0 RG 0 0 0 rg
/G3 gs
BT
/F4 14.666667 Tf
1 0 0 -1 0 .47981739 Tm
0 -13.2773438 Td <0042> Tj
ET
BT
/F4 14.666667 Tf
1 0 0 -1 301.33325 .47981739 Tm
0 -13.2773438 Td <0042> Tj
8.1511078 0 Td <0042> Tj
ET
Q
/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
/CIDSystemInfo
<< /Registry (Adobe)
/Ordering (UCS)
/Supplement 0
>> def
/CMapName /Adobe-Identity-UCS def
/CMapType 2 def
1 begincodespacerange
<0000> <FFFF>
endcodespacerange
19 beginbfchar
<0010> <002D>
<0013> <0030>
<001D> <003A>
<0032> <004F>
<003C> <0059>
<0042> <005F>
<0049> <0066>
<005A> <0077>
<005C> <0079>
<005E> <007B>
<0060> <007D>
<023A> <0410>
<0242> <0418>
<0244> <041A>
<0251> <0427>
<025A> <0430>
<025C> <0432>
<0270> <0446>
<0276> <044C>
endbfchar
11 beginbfrange
<0015> <0017> <0032>
<0024> <0028> <0041>
<0046> <0047> <0063>
<004F> <0052> <006C>
<0056> <0058> <0073>
<023E> <023F> <0414>
<0246> <024C> <041C>
<025E> <025F> <0434>
<0264> <0265> <043A>
<0268> <026A> <043E>
<026C> <026D> <0442>
endbfrange
endcmap
CMapName currentdict /CMap defineresource pop
end
end
Каждая строка состоит из аргументов, за которыми следует их оператор.
Рассмотрим отрывок:
Код:
q // сохранить текущее графическое состояние (помещая его в стек).
.75 0 0 .75 72 72 cm
0 0 0 RG 0 0 0 rg // установить текущий цвет обводки на (0,0,0) rgb. Это черный.
/G3 gs
BT // начать текст.
/F4 14.666667 Tf // установите шрифт на /F4 (из словаря ресурсво) с размером 14,6.
1 0 0 -1 0 .47981739 Tm // установить текстовую матрицу (система координат PDF начинается в левом нижнем углу страницы. Подробнее в руководстве.)
0 -13.2773438 Td <023A> Tj // вывести символ «А» (см. таблицы преобразований)
9.7756042 0 Td <0244> Tj // вывести символ «К» (см. таблицы преобразований)
8.5375519 0 Td <024C> Tj // вывести символ «Т» (см. таблицы преобразований)
ET // конец текста.
BT // начать новый текст.
…
…
19 beginbfchar // описание таблицы преобразований символов
<0010> <002D> // <0010> соответствует <002D> (HEX “2D” = “-”)
<0013> <0030> // <0013> соответствует <0030> (HEX “30” = “0 ”)
<001D> <003A> // <001D> соответствует <003A> (HEX “3A” = “:”)
<0032> <004F> // <0032> = <004F> (HEX “4F” = “O ”)
<003C> <0059> // <003C> = <0059> = “Y”
<0042> <005F> // <0042> … = “_”
<0049> <0066> // <0049> … = “f”
<005A> <0077> // <005A> … = “w”
<005C> <0079> // <005C> … = “y”
<005E> <007B> // <005E> … = “{”
<0060> <007D> // <0060> … = “}”
<023A> <0410> // <023A> … = “А”
<0242> <0418> // <0242> … = “И”
<0244> <041A> // <0244> … = “К”
<0251> <0427> // <0251> … = “Ч”
<025A> <0430> // <025A> … = “а”
<025C> <0432> // <025C> … = “в”
<0270> <0446> // <0270> … = “ц”
<0276> <044C> // <0276> … = “ь”
endbfchar //конец таблицы преобразований символов.
11 beginbfrange // описание таблицы преобразований диапазонов символов
<0015> <0017> <0032> // каждое значение из промежутка от 0015 до 0017 преобразуется в значения от 0032 до 0034: 0015 преобразуется в 0032, 0016 преобразуется в 0033, 0017 преобразуется в 0034
<0024> <0028> <0041> // <0024>...<0028> == <0041>...<0045>
<0046> <0047> <0063> // <0046>...<0047> == <0063>...<0064>
<004F> <0052> <006C> // <004F>...<0052>==<006C>...<006F>
<0056> <0058> <0073> // 56 … 58 == 73 … 75
<023E> <023F> <0414> // 23E … 23F == 414 … 415
<0246> <024C> <041C> // 246 … 24С == 41С … 422
<025E> <025F> <0434> // 25E … 25F == 434 … 435
<0264> <0265> <043A> // 264 … 265 == 43A … 43B
<0268> <026A> <043E> // 268 … 26A == 43E … 440
<026C> <026D> <0442> // 26C … 26D == 442 … 443
endbfrange // конец таблицы преобразований диапазонов символов
В рассмотренном отрывке удалось расшифровать слово «АКТ».
Проанализировав текст полученный в результате работы скрипта не составляет труда определить место где зашифрован флаг.
Пробуем расшифровать:
Код:
[CODE]...
BT // начать текст.
/F4 14.666667 Tf // шрифты
1 0 0 -1 8.1511078 .47981739 Tm // матрица
0 -13.2773438 Td <0026> Tj // “C” (0026 == 0043 = HEX “43” = “C”)
10.5842743 0 Td <0032> Tj // “O” ( 0032 == 004F (HEX “4F” = “O”)
11.4001007 0 Td <0027> Tj // “D”
10.5842743 0 Td <0028> Tj // “E”
9.7756042 0 Td <0025> Tj // “B”
9.7756042 0 Td <003C> Tj // “Y”
9.7756042 0 Td <005E> Tj // “{”
….
Конечно можно написать скрипт, который быстро и максимально удобно сопоставит символы и выдаст готовый текст, но зачем — в сети полно готовых решений, а целью же данного способа было получить представление о формате pdf.
Флаг получен.