Пару лет назад я писал об использовании базы PAF (Postcode Address File) британской Королевской почты (Royal Mail) для приведения почтовых адресов, вводимых пользователями, к стандартному виду. Поскольку PAF — основная интеллектуальная собственность Royal Mail, то заполучить её не так-то просто: годовая подписка стоит от £400 в зависимости от полноты базы и от частоты апдейтов. Спустя неделю-другую после оформления подписки по почте приходит солидная красная коробочка с CD-диском:
На диске — EXE-файл, который запрашивает «серийный номер» и распаковывает базу (набор CSV-файлов) на диск. Серийный номер присылают отдельно, чтобы злоумышленник, перехвативший посылку, не смог бы воспользоваться базой. (Вот выдумают же — текстовый файл с серийным номером!) Номер у каждого клиента свой, чтобы в случае «утечки» было ясно, к кому предъявлять претензии. Впрочем, организовать «утечку» самих данных серийный номер никак не мешает, и на WikiLeaks в 2009 г. появилась база Postzon (одна из составляющих PAF). В комментариях к ней отмечено, что "данная база составлена на средства налогоплатильщиков, и активисты, в их числе газета The Guardian и сэр Тим Бернерс-Ли, уже давно пытаются убедить Royal Mail открыть свободный доступ к PAF; но до сих пор эти попытки не увенчались успехом". Впрочем, через год после появления Postzon на WikiLeaks аналогичная по содержанию база появилась в открытом доступе от имени британской картографической службы Ordnance Survey и под названием OS Code-Point Open — таким образом и Royal Mail сохранила лицо, не уступив требованиям активистов, и утёкшие данные официально получили статус общедоступных. Тем не менее, полностью PAF до сих пор необщедоступна. (Пока я готовил эту статью, Postzon и с WikiLeaks куда-то пропала; но гугл всё помнит.)
Спустя год после получения PAF мне понадобилось в неё снова заглянуть, но листочек с серийным номером, присланный отдельно от диска, за год успел куда-то затеряться. Тут мне и стало интересно — насколько сложно будет обойти проверку серийного номера в продукте таком солидном и так яростно защищаемом от «освободителей информации»? Через полчаса данные были у меня на винте, а сама программа-распаковщик мне показалась неплохим демонстрационным примером для начинающих реверс-инженеров. Никакая IDA не потребуется — только бесплатные и быстроустанавливаемые инструменты.
Суровые ассемблерщики, которых боится даже Касперский, наверняка сочтут данный пример игрушечным, и, позёвывая, пролистают весь остаток статьи. Ну и ладно — туториалы в стиле «как нарисовать сову» меня раздражают намного больше, чем те, в которых разжёвываются простые вещи.
Начнём с того, что запускаем программу под windbg:
Забиваем поле для серийника мусором, и нажимаем «Begin». Появляется сообщение о том, что серийник неверный.
Жмём в отладчике на break:
Переключаемся на основной поток (~0s
) и смотрим стек вызовов (k
):
Видим, что выполнение остановлено где-то внутри цикла сообщений, запущенного из MessageBox
, а адрес возврата из MessageBox
— 0041f086. Посмотрим, что было в коде перед вызовом MessageBox
, например за 0x40 байт до возврата (команда u 041f086-40 l 1f
):
Итак, MessageBox
вызывается (с адресом возврата 0041f086), если в байте [ebp-45h]
оказался ноль, а значение этого байта записывается всего несколькими инструкциями раньше — туда сохраняется результат вызова функции 00402adc, очевидно, проверяющей значение серийника.
Восхитительно! Запускаем файл сызнова, задав точку останова сразу же после вызова проверяющей функции: g 0041f051
.
Как только мы нажимаем «Begin» на первом экране, отладчик останавливает программу, а в регистре eax мы видим результат проверки серийника: ноль.
«Исправляем» его на единицу: r ax=1
, и возобновляем выполнение: g
Ура! Видим второй экран — лицензионное соглашение Royal Mail.
Щёлкаем на дальше-дальше-дальше, и в конце концов, программа рапортует об успешной распаковке базы.
Но… что же это такое она нам распаковала?!
Вот хитрецы! Похоже, введённый серийник где-то проверяется повторно.
Как найти где?
Возьмём дизассемблер dumppe, натравим на наш файл, и поищем в листинге строку «INVALID KEY»
В моём любимом Фаре это делается командой edit:<dumppe /disasm SetupRM.exe
, а любителям других файловых менеджеров придётся перенаправлять вывод в файл.
Строка нашлась по адресу 00481AE6, и на неё ссылаются (Xref) по адресу 00401CB2:
Видим проверку и jz
по адресу 00401CAD. Здесь уже нет смысла «исправлять» значение регистра перед проверкой, потому что проверка вызывается много тысяч раз — для каждой распаковываемой строчки. Значит, надо исправить сам код.
Запускаем программу в третий раз, уже привычными движениями: g 0041f051
, «Begin», r ax=1
.
Затем исправим проверку: заменяем опкод jz
(74) на jmp short
(eb) при помощи команды eb 401cad eb
. У Рэймонда Чена есть удобная подборка часто пригождающихся опкодов x86.
Продолжаем выполнение (g
) и радостно соглашаемся со всеми требованиями Royal Mail.
Вот и наши данные, долгожданные!
Итак, необходимый минимум команд windbg:
~ xs |
set active thread | переключиться к контексту потока x |
k |
stack | показать стек вызовов |
u адрес l длина |
unassemble | показать код по адресу |
g адрес |
go | выполнять, пока не достигнем адреса |
r регистр=значение |
register | изменить значение регистра |
eb адрес значение |
enter byte | изменить значение байта по адресу |
Для любителей «программировать мышкой» всему этому есть аналоги где-то в меню и на тулбарах; и, как видите, этих шести команд уже достаточно, чтобы справиться с программами уровня Royal Mail. Реверс-инженеринг доступен каждому!
… Из спортивного интереса я потом повторил свои изыскания и со следующим выпуском PAF, от 2012 года. Оказалось, что там защиту существенно усилили — вместо двух проверок je/jne
требуется исправить аж семь!
Автор: tyomitch