Вскрываем защиту Tally ERP 9

7 сентября, 2020, Oleg Afonin
Рубрика: «Разное»
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Tally ERP 9 – аналог системы 1С: Предприятие, разработанный и получивший широкое распространение в Индии. Производитель описывает продукт как «программное обеспечение для управления бизнесом нового поколения для бизнеса нового поколения», которое, снова процитирую создателей, «создано для наслаждения». В сегодняшней статье мы ознакомимся с особенностями шифрования данных в Tally ERP 9 и расскажем о том, как разрабатывался способ вскрытия защиты.

О продукте Tally ERP 9

Tally ERP 9 – популярный в Индии программный продукт с более чем двумя миллионами пользователей. С учётом размера целевой аудитории программы, Tally – одно из самых популярных решений такого рода в Индии.

В марте 2020 к нам обратились представители правоохранительных органов с просьбой помочь получить доступ к защищённому хранилищу Tally ERP 9. При обработке подобных обращений мы стараемся не просто взломать конкретную базу данных, но добавить поддержку соответствующего формата в один из наших продуктов. По этому сценарию и начали развиваться события.

Каким образом обычно поступают производители программного обеспечения, в котором нужно обеспечить безопасность данных пользователя? В подавляющем большинстве случаев используется симметричное шифрование. В качестве алгоритма выбирается стандартный AES с ключом длиной 128, 192 или 256 бит. AES – отличный выбор: он проверен временем, а набор процессорных инструкций AES-NI, доступный во всех процессорах Intel, позволяет достичь совершенно избыточных скоростей шифрования.

Для шифрования данных используется ключ Media Encryption Key (MEK). Как правило, этот ключ – совершенно случайная двоичная последовательность, которая создаётся одним из стандартных алгоритмов генерации случайных чисел. Уже этот ключ будет зашифрован ключом шифрования ключа шифрования Key Encryption Key (KEK). KEK, в свою очередь, генерируется на основе комбинации пароля пользователя и соли посредством одной из стандартных хеш-функций (чаще всего это SHA-1, SHA-256 или SHA-512, но нам попадались и другие варианты). Стойкость алгоритма усиливается увеличением числа итераций хеш-функции; нам попадались варианты от 10,000 итераций (это очень быстрый перебор) до миллиона (соответственно, перебор очень медленный) включительно. Таким образом, для того, чтобы добавить поддержку нового формата защиты, нам нужно просто определить, каким именно алгоритмом шифрования воспользовался производитель и восстановить функцию преобразования ключа (определить алгоритм хеширования, число итераций и место в файле, куда сохраняется соль).

Шифрование Tally Vault

В состав Tally ERP 9 входит реализация безопасного хранилища под названием Tally Vault. Шифрование в ERP 9 – опциональное; пароль задавать пользователю не обязательно. Пароль хранилища можно задать как при создании компании, так и в любой момент после этого:

Когда пользователь задаёт пароль, система создаёт новое, защищённое хранилище. Старое, незащищённое, остаётся; впоследствии пользователь может его удалить. Эта схема чрезвычайно удобна для исследования: зашифрованную копию хранилища можно напрямую сравнить с незашифрованной. Так выглядит выбор компании, если есть и зашифрованная, и незашифрованная версия данных:

Данные в последних версиях Tally ERP 9 по умолчанию сохраняются в c:\Users\Public\Tally.ERP9\Data\(1nnnn)

Зашифрованы будут все файлы с расширением .900, размер которых превышает 512 байт. Основной файл хранилища – Company.900. В этом файле сохраняется информация о пользователях, если включена опция “Use security control”. Так выглядит этот файл в hex-редакторе до шифрования:

А так – после:

Формат файла

Файл логически разбит на секторы (страницы) по 512 байт. В начале каждой страницы записаны 4 байта контрольной суммы (CRC). При проверке блока на целостность вычисляется контрольная сумма остальных (512-4) байт и сравнивается с первыми четырьмя байтами.

Ключ шифрования

Ключ шифрования получается из пароля напрямую; никакой соли, а тем более – разделения на Media Encryption Key и Key Encryption Key, здесь нет.

Интересен и выбор алгоритма шифрования. Разработчики Tally Vault решили не полагаться на существующие криптографические преобразования и создали свой собственный вариант, настоящий кошмар криптографа. Все существующие алгоритмы хеширования без исключений гарантируют, что изменение всего одного бита в хешируемой последовательности приведёт к полному изменению всей контрольной суммы. Индийским разработчикам удалось сделать невероятное: они создали хеш-функцию, в которой при небольшом изменении пароля результат тоже меняется очень незначительно. Более того, у нас создалось впечатление, что при определённых условиях этот хеш можно обратить, получив из него оригинальный пароль (разумеется, если энтропия пароля не превышает энтропии его контрольной суммы). Вишенка на торте: преобразование применяется ровно один раз.

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

Пароль Ключ
pwd1 0x653C68AC 0x4BA84BA8 (ac 68 3c 65 a8 4b a8 4b)
pwd2 0x653C69A7 0x4BA84BA8 (a7 69 3c 65 a8 4b a8 4b)
password1 0x74258DD3 0x57CE36D7 (d3 8d 25 74 d7 36 ce 57)
password2 0x90A78DD3 0xB34C36D7 (d3 8d a7 90 d7 36 4c b3)
password12345678 0xC6C57C3D 0xE52EC739 (3d 7c c5 c6 39 c7 2e e5)
password12345679 0xC6C51936 0xE52EA232 (36 19 c5 c6 32 a2 2e e5)
qwertyui123456789 0xD15D72DD 0x06309E8D (dd 72 5d d1 8d 9e 30 06)
qwertyuj123456789 0xD15D4D77 0x0630A127 (77 4d 5d d1 27 a1 30 06)

 

Алгоритм шифрования

Страницы шифруются алгоритмом, принцип работы которого сильно напоминает обычный DES. Для шифрования используется 64-битный ключ (который в процессе работы разворачивается в расширенный 128-битный, как и у «настоящего» DES). Шифрование блочное, размер блока – привычные для алгоритма DES 64 бита. Алгоритм используется в режиме CBC с первоначальной инициализацией IV нулями. Напомню, DES (Data Encryption Standard) — алгоритм симметричного шифрования, утверждённый правительством США в 1977 году в качестве официального стандарта. В 2001 от использования DES отказались; ему на смену пришёл привычный нам алгоритм AES. Что заставило индийских разработчиков взять за основу принципы работы именно этого давно устаревшего алгоритма – для нас загадка.

Уже на этом месте можно прекратить исследование и реализовать простейшую атаку на ключ. На современном оборудовании всё пространство ключей можно перебрать за считанные дни. При желании можно осуществить рефакторинг ключей; впрочем, принцип «неуловимого Джо» надёжно защищает Tally от подобных атак.

Проверка пароля

В коде Tally Vault проверка пароля осуществляется путём расшифровки страницы (всех 512-4 байт), вычисления её контрольной суммы (CRC) и её сравнения со значением, записанным в начале страницы. По замыслу разработчиков, для расшифровки всей страницы и полной проверки пароля потребуется расшифровать 64 блока по 8 байт (64 бита). Однако в данном случае дьявол кроется в деталях, и для проверки пароля вычислять контрольную сумму всей страницы совершенно не обязательно.

Вернёмся к первому скриншоту:

В начале каждой страницы есть некая служебная информация, содержимое которой фиксировано или может быть известно заранее. Например, сразу после CRC, по смещению 4, находится 32-битная фиксированная последовательность DWORD 0x00000001. Назначение этой последовательности нам неизвестно; предположительно, это флаг страницы данных. Соответственно, для ускорения проверки правильности пароля в процессе перебора можно прервать расшифровку страницы сразу после первого блока, если содержимое этих 32-бит байтах не 0x00000001. Разумеется, 32 бита данных гарантированно дадут некоторое число коллизий, которые потенциально приведут к ложным срабатываниям. Поэтому в случаях, когда значение расшифрованных очередным ключом 32 бита данных совпало со значением 0x00000001, мы проведём расшифровку блока до конца, вычислим CRC и сравним контрольную сумму со значением, записанным в первых 4 байтах страницы. Однако количество таких коллизий будет порядка 1 к 4 миллиардам, что практически не влияет на скорость перебора паролей.

Кстати, если после прочтения этой статьи разработчики изменят или вовсе уберут фиксированное значение по смещению 4, можно использовать и другие константы. Например, по смещению 12 записывается последовательный номер страницы, если страница – не последняя.

Результат

Вооружившись знанием об использованных алгоритмах хеширования и шифрования, мы разработали две версии плагина для Elcomsoft Distributed Password Recovery. В первой версии плагина реализована «лобовая» атака, в которой правильность пароля проверяется именно так, как задумали индийские разработчики. Во второй – для проверки используется константа в первом зашифрованном блоке. Как и ожидалось, разница в скорости впечатляет.

Сравнение скорости на двух CPU:

Скорость (п/с) При полной расшифровке страницы При проверке константы в первом блоке

(используется в EDPR)

Intel Core i7 6700 170 000 5 400 000
Intel Core i7 9700K 345 000 11 400 000

 

11 миллионов паролей в секунду на одном процессоре, без использования GPU – много это или мало? Для сравнения, скорость атаки на CPU для документов в формате .docx, созданных в Microsoft Office 2016, составляет порядка 40 паролей в секунду, OpenOffice — 9000. Скорость атаки на контейнеры VeraCrypt – чуть больше 1 пароля в секунду. Атака на резервные копии iTunes – порядка 1 пароля в 10 секунд. Архивы RAR – порядка 64 паролей в секунду, 7zip – около 25.

Взлом

Для взлома паролей Tally Vault воспользуемся Elcomsoft Distributed Password Recovery с соответствующим плагином. Для проведения атаки откроем файл Company.900:

Далее настроим атаку по словарю. Можно использовать как обыкновенный словарь русского или английского языка, так и один из специфических словарей, в котором содержатся самые распространённые пароли или пароли, которые были извлечены из браузера пользователя. В данном случае мы воспользовались паролями, которые извлекли из браузера Chrome, установленного на компьютере пользователя:

Пароль обнаружился менее, чем за секунду:

Усложнив задачу, запустили полный перебор, чтобы посмотреть скорость атаки, которая стабилизировалась на 11.1 миллионах паролей в секунду.

Как было бы правильно

Как можно было бы реализовать шифрование правильным образом? В данном случае достаточно было бы сделать «как все», а именно:

  1. В качестве алгоритма шифрования использовать стандартный AES с длиной ключа 256 бит.
  2. Для шифрования данных использовать ключ Media Encryption Key (MEK), созданный криптографически стойким генератором случайных чисел.
  3. MEK сохранять в зашифрованном виде. Шифрование этого ключа осуществлять при помощи дополнительного ключа Key Encryption Key (KEK).
  4. Key Encryption Key вычислять посредством одной из готовых KDF (Key Derivation Function), использующих многочисленные (порядка сотен тысяч) итерации хеш-функции SHA-256 или SHA-512 на основе пароля пользователя и соли.

Кроме того, если есть возможность изменить формат файла, то стоит тщательно проанализировать страницы на предмет наличия констант или данных, которые легко вычислить (например, номеров страниц или внутренних идентификаторов). От таких данных нужно избавиться.

Заключение

Tally ERP 9 полностью оправдал заявку маркетологов «создано для наслаждения». Мы получили редкое удовольствие, создавая атаку на данные Tally Vault, словно вернувшись на 20 лет назад во времена слабой, зарегулированной экспортными ограничениями защиты.

Что же касается самого Tally Vault, то разработчики совершили все возможные и невозможные ошибки. Мы не смогли найти ни одного аспекта защиты, который был бы реализован на уровне хотя бы школьника-энтузиаста. Беспросветно плохо здесь абсолютно всё. Здесь и прямое преобразование пароля в ключ шифрования, и пренебрежение солью, и единственная итерация доморощенного (и безграмотно реализованного) алгоритма хеширования. Использование алгоритма на основе DES более чем 40-летней давности в комбинации с коротким ключом шифрования делают возможной атаку на ключ (а не на пароль), и только отсутствие спроса защищает продукт от полного рефакторинга. Исправить эти алгоритмы принципиально невозможно, можно лишь сделать заново.

Впрочем, здесь тот случай, когда и «сделать заново», вероятно, не поможет. Фиксированные данные, находящиеся в самом начале страницы данных, позволяют ограничиться расшифровкой единственного 64-битного блока, что более чем в 30 раз ускоряет проверку. Нам же остаётся порадоваться очередному установленному рекорду: более 11 миллионов паролей в секунду на единственном CPU, без использования даже аппаратного ускорения – наш абсолютный рекорд за всё время работы.


  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

REFERENCES:

Elcomsoft Distributed Password Recovery

Производительное решение для восстановление паролей к десяткам форматов файлов, документов, ключей и сертификатов. Аппаратное ускорение с использованием потребительских видеокарт и лёгкое масштабирование до 10,000 рабочих станций делают решение Элкомсофт оптимальным для исследовательских лабораторий и государственных агентств.

Официальная страница Elcomsoft Distributed Password Recovery »

НАШИ НОВОСТИ