Периодически мне приходится работать с "известными" уязвимостями техническая
информация о которых отсутствует. Как правило точные сведения о таких
уязвимостях известны лишь их открывателям и производителям программ, которые их
и исправляют. Для нас же есть только общая информация об их существования, но не
более того. С того времени как уязвимость закрыта никому - ни вендору, ни
исследователю - не интересно раскрывать все подробности о существовавшей ошибке.
Таким образом они оставляют всех остальных в неведении - затрагивает ли
уязвимость другие продукты, присутствует ли она в других версиях - все это для
нас остается неизвестным.
С таким подходом я столкнулся и сегодня, когда наша команда пыталась обновить
сканер уязвимостей для проверки определенной платформы. Версия показывала, что
проблема с уязвимостями есть, однако подтвердить это было невозможно из-за
неадекватного описания. Проверка же только версии - прямой путь к многочисленным
ложным срабатываниям.
Вот какая информация была доступна:
Функция 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