Адам Лэнгли объяснил причины бага в iOS: лишняя строчка кода поломала всю безопасность

в 14:48, , рубрики: iOS, OS X, SSL, TLS, баг, информационная безопасность, криптография, ненормальное программирование, подпись, сертификат, шифрование, метки: , , , , , , ,

Вчера компания Apple выпустила обновление безопасности iOS 7.0.6 для iPhone 4 и более поздних моделей, iPod touch 5-го поколения и iPad 2+. Одновременно выпущен аналогичный патч 6.1.6 для iPhone 3GS и iPod touch 4-го поколения.

Обновление закрывает уязвимость CVE-2014-1266, которая позволяет злоумышленнику из «привилегированной позиции в сети» перехватывать и модифицировать пакеты в сессиях, защищённых SSL/TLS. Речь идёт о MiTM-атаке с подменой трафика.

В лаконичном пояснении Apple говорит, что при установке защищённого соединения по SSL/TLS система не способна определить аутентичность соединения. Проблему решили путём «добавления недостающих этапов валидации».

Хотя по лаконичному описанию не совсем понятно, каких конкретно «этапов» не хватало, но можно говорить об отсутствии полноценной защиты соединений. Так или иначе, но отсутствие необходимых этапов аутентификации означает, что раньше на все устройства Apple третьи лица, вероятно, могли устанавливать поддельные/модифицированные апдейты ОС на смартфоны и планшеты пользователей.

Сегодня известный криптограф Адам Лэнгли опубликовал статью с анализом бага в iOS. Он обращает внимание на разницу в коде OS X 10.8.5 (Security-55179.13) и 10.9 (Security-55471), где, вероятно, исправлен тот же самый баг.

Собственно, вот он.

static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
                                 uint8_t *signature, UInt16 signatureLen)
{
	OSStatus        err;
	...

	if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
		goto fail;
	if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
		goto fail;
		goto fail;
	if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
		goto fail;
	... 

облом:

	SSLFreeBuffer(&signedHashes);
	SSLFreeBuffer(&hashCtx);
	return err;
}

Процитировано с опубликованных исходников Apple.

Обратите внимание на две строки goto fail подряд. Первая из них корректно связывается с оператором if, а вторая вообще не имеет никакого отношения к делу. В результате, выполнение программы всегда завершается на этом этапе, со второго goto fail. Значение err содержит правильное значение, потому что операция обновления SHA1 была успешной и верификация подписи всегда даёт «добро».

Речь идёт о проверке подписи в сообщении ServerKeyExchange, что используется в шифрах DHE и ECDHE для передачи одноразового ключа соединения. Сервер говорит: «Вот одноразовый ключ, а вот подпись от моего сертификата, так что ты знаешь, что ключ от меня». В случае с Apple, если связь между одноразовым ключом и сертификатом сломана, то вся система разваливается. Теперь вообще ничего не работает: можно отправить клиенту правильный сертификат, но подписать рукопожатие произвольным секретным ключом, или вообще его не подписывать! Отсутствуют любые доказательства, что сервер, который присылает сертификат, вообще владеет секретным ключом для этого сертификата.

Уязвимость, вероятно, присутствует во всех версиях iOS до 7.0.5 и во всех версиях OS X до 10.9.1 включительно.

Автор: alizar

Источник

Поделиться

* - обязательные к заполнению поля