Периодически мне приходится работать с "известными" уязвимостями техническая
информация о которых отсутствует. Как правило точные сведения о таких
уязвимостях известны лишь их открывателям и производителям программ, которые их
и исправляют. Для нас же есть только общая информация об их существования, но не
более того. С того времени как уязвимость закрыта никому — ни вендору, ни
исследователю — не интересно раскрывать все подробности о существовавшей ошибке.
Таким образом они оставляют всех остальных в неведении — затрагивает ли
уязвимость другие продукты, присутствует ли она в других версиях — все это для
нас остается неизвестным.

С таким подходом я столкнулся и сегодня, когда наша команда пыталась обновить
сканер уязвимостей для проверки определенной платформы. Версия показывала, что
проблема с уязвимостями есть, однако подтвердить это было невозможно из-за
неадекватного описания. Проверка же только версии — прямой путь к многочисленным
ложным срабатываниям.

Вот какая информация была доступна:

Функция get_server_hello function в клиенте SSLv2 в OpenSSL версии
0.9.7 до 0.9.7l, 0.9.8 до 0.9.8d и предыдущих позволяет удаленному серверу
вызвать отказ в обслуживании (падение клиента), при передаче неизвестного
вектора срабатывает переопределение указателя на ноль.

Мне и предстояло определить этот "неизвестный
вектор" и понять в конце концов — продукт который я тестирую уязвим или нет.

Первым моим шагом было определить что же такое
SSLv2 и как мне его получить. Все тут получилось
достаточно просто, мне всего лишь понадобился "openssl s_client", типовой
SSL клиент использующий функцию get_server_hello().

Вторым пунктом надо было создать SSLv2 сессию, что
оказалось более трудным, так как SSLv2 сейчас
считается небезопасным и в большинстве программ он выключен — даже
Firefox больше не позволяет соединяться с сайтами,
поддерживающими его… Однако Apache 2 все еще
работает с ним и поддержку SSLv2 можно легко в нем
включить.

Собрав это все, я запустил
beSTORM
и
заставил его перехватывать весь SSLv2 трафик. Вся
сессия может быть довольно объемной , но мне нужны были только первые пакеты так
как именно они работают с функцией get_server_hello(). Как только они были
получены я использовал возможности pcap для экспорта и
загрузил их в Wireshark. В самом же Wireshark я пытался понять какие поля чем
являются — что было длинной чего, что флагами и т.д.

Затем я перевел beSTORM на прослушку входящего трафика и начал играться со
значениями, сконцентрировавшись в основном на параметрах ServerHello:

  • Packet Length (общая длинна)
  • Session ID Hit (действительно при установке 0×01 или 0×00)
  • Certificate Type (перечисление трех возможных типов)
  • Certificate Length
  • Certificate Value
  • Cipher Spec Length
  • Cipher Spec Value
  • Connection ID Length
  • Connection ID Value

После перебора нескольких тысяч комбинаций — что заняло у меня около 50 минут
— я нашел требуемое: Session ID Hit равный 0×00, Certificate Type равный NULL
(0×00), Certificate Length равный 0, Certificate Value установленный в none,
Cipher Spec Length равный 0, Cipher Spec Value установленный в none и
стандартными Connection ID, полученными при перехвате.

В такой ситуации клиент OpenSSL падал:

Program received signal SIGSEGV, Segmentation
fault.
0×0808638d in get_server_hello (s=0×81aed90) at s2_clnt.c:542
542 if (s->session->peer != s->session->sess_cert->peer_key->x509)

Теперь все, что мне надо было лишь в beSTORM сделать модуль из полученных
данных — работа была завершена.

От получения пустого описания до создания эксплоита прошло около часа. Его
вы можете найти тут:


http://www.securiteam.com/exploits/6H00O00KKA.html

Источник:


http://blogs.securiteam.com/index.php/archives/1051

 

Оставить мнение

Check Also

Цифровой паноптикум. Настоящее и будущее тотальной слежки за пользователями

Даже если ты тщательно заботишься о защите своих данных, это не даст тебе желаемой приватн…