Все началось в январе 2013, когда местная транспортная компания в Турине начала развертывать систему использования билетов на базе технологии NFC (Near field communication или «коммуникация ближнего поля»). Чипы, используемые в билетах, базировались на двух стандартах: NXP Ultralight и Calypso.
Автор: Matteo Beccaro
Предыстория вопроса
Все началось в январе 2013, когда местная транспортная компания в Турине начала развертывать систему использования билетов на базе технологии NFC (Near field communication или «коммуникация ближнего поля»). Чипы, используемые в билетах, базировались на двух стандартах: NXP Ultralight и Calypso.
Стандарт Ultralight использовался в дешевых билетах для одной или нескольких поездок. Стандарт Calypso использовался в более дорогих билетах (годовых). Вначале я и мой друг приступили к исследованию Calypso, но эта технология оказалась закрытой. Чтобы получить доступ к документации, необходимо заплатить около 10 тысяч евро.
Мы переключились на исследование чипов на основе технологии Ultralight (документация находится здесь).
Рисунок 1: Пример билета на несколько поездок с чипом NFC Mifare UL
В чипах NXP Mifare Ultralight объем памяти 64 байта. Весь объем распределяется следующим образом:
1. UID – 7-ми байтовый идентификатор. Устанавливается компанией NXP.
2. Checksum – 2-х байтовая контрольная сумма. Рассчитывается путем применения функции XOR к полю UID.
3. OTP – 4-х байтовый однократно программируемый сектор.
4. Lock – каждый из 16-ти битов этого сектора устанавливает одну страницу в режим «только чтение» (по сути, блокирует).
5. Data – самый большой сектор. Обычно используется для хранения временных меток и другой информации.
Атака при помощи блокировки страницы
Первая мысль - увеличить количество поездок, но это невозможно, поскольку в большинстве случаев информация о поездках хранится в поле OTP.
0000 0000 0111 1111 – осталось 9 поездок
Сектор OTP изменяет свое содержимое при помощи операции OR, и как только бит установлен в 1, в него нельзя установить 0.
Наша задача – сохранить неизменным количество поездок и валидность билета. Ту же самую цель мы будем преследовать и на протяжении всех остальных экспериментов. Нам потребуются две уязвимости, находящиеся в протоколе Mifare Ultralight и большинстве моделей устройств.
1. У команды WRITE нет обратной связи.
2. В устройствах не реализована обратная связь через программное обеспечение.
Используя сектор Lock, мы можем установить OTP-страницу в режим «только чтение», а поскольку обратная связь отсутствует, устройство по считыванию билетов установит правильную временную метку, но не сможет уменьшить количество поездок. Таким образом, у нас будет безлимитный билет.
Атака на основе эксплуатации временных меток
Идея основана на предположении, что после очередного использования, билет на некоторое время остается пригодным. Скажем, в течение 100 минут. Поскольку в билете предусмотрено множество поездок, в чипе должно изменяться несколько раз актуальная временная метка (та метка, которая последний раз обрабатывалась устройством). Вся фишка в том, что в примерно 80 процентах устройств не реализовано шифрование на уровне программного обеспечения, и мы можем легко декодировать и подделать временную метку, записав ее в корректную страницу без уменьшения количества поездок в секторе OTP. В конце концов, у нас будет билет, валидный в течение 100 минут с неизменным количеством поездок. Как только 100 минут закончится, можно записать новую временную метку и так до бесконечности.
Пример
Допустим, мы нашли временную метку, хранимую на странице 10. Нам нужно декодировать ее:
Page 0x0A --> 45 98 7B 00
Конвертируя в int, получаем:
0x45987b00 = 1167620864
Число слишком маленькое, и не соответствует формату Unix EPOCH.
После записи еще пары меток, обнаруживается, что последний байт (00) не изменяется. Убрав последний байт, получаем следующее:
0x45987b = 4561019
Поскольку мы также знаем, что билет валиден в течение фиксированного количества минут (без секунд), то можно предположить, что значение, найденное выше, - количество минут, пройденное с момента фиксированной даты (назовем ее точкой отсчета).
Зная точное время, когда мы «проштамповали» билет, вычисляем начальную точку отсчета. Эта дата - 01.01.2005.
Теперь мы можем подделать корректную временную метку и записать ее на правильную страницу.
Атака на основе клонирования билета
Для примера предположим, что мы получили временную метку, зашифрованную по алгоритму AES256 при помощи надежного ключа, и перебор в лоб не представляется возможным. Обнаруживается, что в некоторых реализациях устройств временная метка не «подсаливается» уникальным идентификатором (например, значением UID билета). Фишка в том, что мы штампуем билет и записываем зашифрованную временную метку на другой билет. Таким образом, у нас будет валидная временная метка. Теоретически так можно делать бесконечно.
В некоторых реализациях устройств при шифровании некоторых данных используется UID как вектор инициализации. Как обойти эту защиту?
Нам потребуется китайский клон UL-чипа, позволяющий модифицировать любую страницу (включая UID/OTP). Используя китайскую версию, обход защиты осуществляется в несколько шагов:
1. Клонируем билет.
2. Добавляем одну поездку в сектор OTP клонированного билета.
3. Штампуем клонированную версию.
4. Копируем все данные с клона на реальный билет.
Примечание: после штамповки клонированного билета, он станет полностью идентичным реальному, включая сектор OTP.
Приложение NFCulT
NFCulT – Android-приложение, где реализовано использование всех вышеуказанных уязвимостей. Программа помогает в исследовании устройств на базе NFC UL по всему миру.
NFCulT – приложение с открытым исходным кодом. Собранная версия находится на Google Play.
Рисунок 2: Блокировка страницы
Рисунок 3: Манипуляции с временными метками
Рисунок 4: Редактирование данных
В разделе Custom Edit можно отредактировать любой бит каждой странице. Очень полезна фишка для вычисления точки отсчета и нахождения корректной страницы при манипуляции временными метками.
Устали от того, что Интернет знает о вас все? Присоединяйтесь к нам и станьте невидимыми!