Уязвимость алгоритма хеширования в платформе MIGS

Уязвимость алгоритма хеширования в платформе MIGS

В прошлом году я нашел ошибку в архитектуре метода хеширования, использующего алгоритм MD5, в платформе MIGS (Mastercard Internet Gateway Service). Эта уязвимость позволяет изменять размер транзакции.

Автор: Yohanes Nugroho

В прошлом году я нашел ошибку в архитектуре метода хеширования, использующего алгоритм MD5, в платформе MIGS (Mastercard Internet Gateway Service). Эта уязвимость позволяет изменять размер транзакции. Компания Mastercard наградила меня премией за отчет о данной проблеме. В этом году стала использоваться технология HMAC-SHA256, однако и здесь не обошлось без проблем, хотя от MasterCard до сих пор никакой реакции не последовало.

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

Что такое MIGS?

Кода вы совершаете платеж на веб-сайте, происходит подключение к промежуточному платежному шлюзу (вы будете перенаправлены на другой сайт). Затем этот платежный шлюз подключается к нескольким платежным системам, доступным в конкретной стране. При оплате кредитной картой, шлюзы будут подключаться к другому шлюзу (один из которых – MIGS), работающего со многими банками с целью предоставления службы 3DSecure.

Схема работы

Если вы используете платформу MIGS процедура платежа выглядит следующим образом:

  1. Вы выбираете товары в онлайн-магазине (или мерчанте).
  2. Вы вводите номер кредитной кары на веб-сайте.
  3. Номер кредитной карты, размер платежа и другие параметры подписываются и возвращаются в браузер, который автоматически формирует POST-запрос к промежуточному платежному шлюзу.
  4. Промежуточный платежный шлюз конвертирует полученную информацию в формат, поддерживаемый платформой MIGS, подписывает при помощи MIGS-ключа и возвращает полученное в браузер. Браузер опять формирует POST-запрос, но на этот раз к серверу MIGS.
  5. Если служба 3D secure использоваться не будет, переходим к шагу 6. В противном случае MIGS перенаправляет запрос к банку, который выпустил карту. Затем банк спрашивает OTP и далее генерирует HTML, который создает POST-запрос для сервера MIGS.
  6. MIGS возвращает подписанные данные в браузер и формирует POST-запрос для промежуточного платежного шлюза.
  7. Промежуточный платежный шлюз проверяет корректность данных и правильность подписи. Если данные некорректны, сформируется страница с ошибкой.
  8. На базе ответа от MIGS платежный шлюз передает статус получателю платежа (магазину).

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

Ошибка в алгоритме хеширования на базе MD5

Ошибка чрезвычайно проста. В методе хеширования используется следующая формула:

MD5(Secret + Data)

Этот алгоритм устойчив к атаке, связанной с удлинением хеша (hash length extension attack), поскольку вначале выполняются некоторые защитные проверки. Секция Data формируется следующим образом: все параметры запроса, начинающиеся с vpc_, вначале сортируются, а потом соединяются значения без использования разделителя. Например, у нас есть следующие данные:

Имя: Joe
Размер: 10000
Карта: 1234567890123456

vpc_Name=Joe&Vpc_Amount=10000&vpc_Card=1234567890123456
Сначала параметры сортируются:
vpc_Amount=10000
vpc_Card=1234567890123456
vpc_Name=Joe

Потом извлекаются и объединяются значения параметров:
100001234567890123456Joe
Если я изменю значения параметров:
vpc_Name=Joe&Vpc_Amount=1&vpc_Card=1234567890123456&vpc_B=0000
Произойдет сортировка:
vpc_Amount=1
vpc_B=0000
vpc_Card=1234567890123456
vpc_Name=Joe

А затем извлечение и объединение значений:
100001234567890123456Joe

В итоге имеем то же самое значение, используемое в формуле хеширования. Таким образом, когда данные отсылаются в MIGS, мы может добавить еще один параметр после размера транзакции, чтобы урезать последние цифры параметра vpc_Amount, или вначале, чтобы урезать первые цифры. В итоге, размер будет уменьшен, и вы можете заплатить 2 доллара за MacBook стоимостью 2000 долларов.

Промежуточные шлюзы и мерчант магазина могут без проблем работать и всегда проверять, что размер возвращаемый MIGS всегда совпадает с размером, который запрашивается.

За обнаружение этой уязвимости компания MasterCard наградила меня премией в размере 8500 долларов.

Ошибка в алгоритме хеширования на базе HMAC-SHA256

В HMAC-SHA256 также имеется уязвимость, которую можно использовать, если мы сможем инжектировать некорректные значения в промежуточный платежный шлюз. Во время тестирования выяснилось, что как минимум один платежный шлюз (Fusion Payments) имеет эту брешь. От Fusion Payments я получил вознаграждение в размере 500 долларов. Возможно, другие платежные шлюзы, подсоединенные к MIGS, также подвержены этой уязвимости.
В новой версии, вдобавок к HMAC-SHA256, при объединении значений добавлены разделители (&) между полями и имена полей. Для тех же самых параметров, которые использовались выше, объединенная строка выглядит так:

Vpc_Amount=10000&vpc_Card=1234567890123456&vpc_Name=Joe

Теперь мы не можем выполнить сдвиг как раньше, и, на первый взгляд, проблем нет. Но что если значение параметра содержит & или = или другой специальный символ?

В документации говорится следующее:

Примечание: Значения во всех парах имя/значения при хешировании не должны содержать символы, используемые при кодировании URL’а.

Вышеприведенная фраза означает, что если у нас есть следующие поля:

Amount=100
Card=1234
CVV=555

Алгоритмом хеширования будет обработана следующая строка: HMAC(Amount=100&Card=1234&CVV=555)

С другой стороны, если у нас есть такие поля (поле amount содержит символы & и =):

Amount=100&Card=1234
CVV=555

Алгоритмом хеширования будет обработана следующая строка: HMAC(Amount=100&Card=1234&CVV=555)

В итоге оба варианта идентичны, и на первый проблемы на наблюдается.

Естественно, я подумал, что возможно в документации ошибка, и при хешировании следует использовать кодировку. Однако после проверки выяснилось, что MIGS-сервер работает так, как описано в документации. Возможно, разработчики не захотели иметь дело с различными кодировками (например, + вместо %20).

На первый взгляд кажется, что проблемы отсутствуют. Любые некорректные символы проверяются на стороне MIGS-сервера и выдается ошибка (например, некорректный размер, указанный выше, не прокатит).

Однако я заметил, что в некоторых платежных шлюзах, вместо проверки входных параметров на стороне сервера, происходит просто подпись и отправка на MIGS-сервер. Намного проще выполнить проверку на стороне клиента при помощи JavaScript, подписать данные на стороне сервера и далее отправить информацию в MIGS, чтобы тот сервер уже проверял, корректен ли номер карты и дата истечения срока, сколько цифр должно быть в поле CVV и так далее. Логика строится на том, что MIGS-сервер повторно выполнит проверку и намного качественнее.

В шлюзе Fusion Payments обнаружилась именно такая ситуация: в поле CVV разрешались любые символы и любой длины (происходила только проверка на стороне клиента в JavaScript). Затем запрос подписывался и отправлялся в MIGS.

Эксплоит

Чтобы использовать эту уязвимость, мы должны сконструировать строку, которая будет представлять собой правильный запрос, а также правильный ответ MIGS-сервера. Нам не нужно контактировать с MIGS-сервером, поскольку на стороне клиента будет осуществляться подпись корректной информации.

Базовый запрос выглядит так:

 vpc_AccessCode=9E33F6D7&vpc_Amount=25&vpc_Card=Visa&vpc_CardExp=1717&vpc_CardNum=4599777788889999&vpc_CardSecurityCode=999&vpc_OrderInfo=ORDERINFO&vpc_SecureHash=THEHASH&vpc_SecureHashType=SHA256

Базовый ответ сервера будет выглядеть так:

 vpc_Message=Approved&vpc_OrderInfo=ORDERINFO&vpc_ReceiptNo=722819658213&vpc_TransactionNo=2000834062&vpc_TxnResponseCode=0&vpc_SecureHash=THEHASH&vpc_SecureHashType=SHA256 

В случае с Fusion Payment эксплуатация осуществлялась посредством инжектирования в поле vpc_CardSecurityCode (CVV):

 vpc_AccessCode=9E33F6D7&vpc_Amount=25&vpc_Card=Visa&vpc_CardExp=1717&vpc_CardNum=4599777788889999&vpc_CardSecurityCode=999%26vpc_Message%3DApproved%26vpc_OrderInfo%3DORDERINFO%26vpc_ReceiptNo%3D
22819658213%26vpc_TransactionNo%3D2000834062%26vpc_TxnResponseCode%3D0%26vpc_Z%3Da&vpc_OrderInfo=ORDERINFO&vpc_SecureHash=THEHASH&vpc_SecureHashType=SHA256

Клиент/платежный шлюз будут генерировать корректный хеш для этой строки.

Теперь мы можем отправить эти данные обратно клиенту (без подключения к MIGS-серверу), но перед этим внесем небольшие изменения так, чтобы клиент считал корректные переменные (большинство клиентов будут проверять только параметры vpc_TxnResponseCode и vpc_TransactionNo):

 vpc_AccessCode=9E33F6D7%26vpc_Amount%3D25%26vpc_Card%3DVisa%26vpc_CardExp%3D1717%26vpc_CardNum%3D4599777788889999%26vpc_CardSecurityCode%3D999
vpc_Message=Approved&vpc_OrderInfo=ORDERINFO&vpc_ReceiptNo=722819658213&vpc_TransactionNo=2000834062&vpc_TxnResponseCode=0&vpc_Z=a%26vpc_OrderInfo%3DORDERINFO&vpc_SecureHash=THEHASH&vpc_SecureHashType=SHA256 

Теперь:

  1. Эти данные будут захешированы в точности так же, как и в предыдущем случае.
  2. Клиент будет игнорировать vpc_AccessCode и значение этого параметра.
  3. Клиент будет обрабатывать vpc_TxnResponseCode (и другие параметры) и полагать, что транзакция корректна.

Можно сказать, что это ошибка MIGS-клиента, но алгоритм хеширования был выбран MasterCard. Если бы значения при хешировании были закодированы, этой уязвимости не было бы.

Ответ от MasterCard

От MasterCard я не получил ответа относительно бреши в алгоритме HMAC-SHA256. Я отправил письма нескольким людям, с которыми общался при обнаружении предыдущей уязвимости. Я даже не получил отписку в духе «мы проверяем информацию». У них также есть мой Facebook на случай, если представители компании захотят связаться со мной.

Некоторые сотрудники пытаются сделать вид, что не видели моего отчета. Вначале я защитил статью паролем, и с того момента было как минимум 3 просмотра с IP-адресов компании MasterCard (то есть как минимум 3 человека вводили пароль). Для прочтения отчета необходимо было ввести пароль в обязательном порядке, что исключает случайные клики без прочтения. Я отправлял письма еженедельно.

Предполагаю, что сотрудники MasterCard предупредили всех, кто подключен к системе MIGS для проверки и фильтрации инъекции.

Уязвимости в платежных шлюзах

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

Кроме того, я нашел несколько уязвимостей в реализации шлюзов. Например, связанные с удлинением хеша, или ошибки при проверке XML-сигнатуры. Одна из простейших уязвимостей была найдена в Fusion Payments. Самая первая проблема заключалась в отсутствии проверки сигнатуры от MIGS. В этом случае мы можем изменять данные, возвращаемые MIGS-сервером, и помечать транзакцию как успешную. В последнем случае нужно поменять символ F, связанный с неудачной транзакций, на 0, связанный с успешной транзакцией.

То есть мы можем ввести любой номер кредитной карты, получить ответ об ошибке от MIGS, изменить этот ответ, и платеж окажется успешным. За найденную уязвимость я получил 400 долларов от компании стоимостью в 20 миллионов долларов.  Это не первый платежный шлюз с такой брешью. Во время пентестов я нашел в точности такую же проблему в другом платежном шлюзе. Несмотря на относительно небольшое вознаграждение, на данный момент Fusion Payments – единственный платежный шлюз, с которым я контактировал и у которого самые прозрачные и честные условия относительно программы вознаграждения. Представители компании быстро отвечали на мои письма и оперативно исправляли уязвимости.

Заключение

Платежные шлюзы не настолько безопасны, как может показаться на первый взгляд. При относительно небольшом вознаграждении за найденные уязвимости (в некоторых случаях я не получал вообще ничего) у меня возникает закономерный вопрос: сколько людей уже воспользовались найденными уязвимостями.

Ньютон уронил яблоко. Мы роняем челюсти!

Гравитация научных фактов сильнее, чем вы думаете

Подпишитесь и испытайте интеллектуальное падение