Компания
306,35
рейтинг
8 июля 2014 в 14:56

Разработка → Разбор заданий конкурса Hash Runner на PHDays IV

В этом году конкурс Hash Runner проводился в течение трех дней перед форумом Positive Hack Days, с семи вечера 16 мая до семи вечера 19 мая (время московское, UTC+4). Тем самым мы постарались учесть интересы всех команд, разбросанных по земному шару, и позволить участникам эффективно использовать все 48 часов выходных дней, в каком бы часовом поясе они ни находились. Многие написали нам, что играть на выходных действительно было очень удобно, так что постараемся делать так и впредь.

Итак, поздравляем победителей!

  1. InsidePro с результатом 22.81% (write-up: www.phdays.ru/download/Write-up.pdf) выиграли две видеокарты R290x.
  2. Hashcat с результатом 21.23% (write-up: hashcat.net/forum/thread-3397.html) выиграли видеокарту R290x.
  3. John-users с результатом 12.78% (write-up: openwall.com/lists/john-users/2014/05/29/2) взяли бронзу.

Всем призерам мы вручили сувениры на память о форуме.

За трехлетнюю историю проведения конкурса победителями становились команды hashcat (выступавшие под названием teardrop в 2012 году), john-users (в 2013) и InsidePro (в 2014). Каждый раз бОльшую часть расшифрованных паролей участники загружали в последние 15 минут соревнования, поэтому только в самом конце становилось ясно, кто же победит. В прошлые два года команда InsidePro довольствовалась вторым местом: в 2012 их обошли hashcat, а в 2013 — john-users. В этом году ребята из InsidePro наконец-то стали первыми!

Типы и стоимость хэшей


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

image
* коэффициент для хэшей в бонусных заданиях

Правила соревнований


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

Одной из особенностей конкурса в этом году стало то, как именно участники получали хэши для взлома. Раньше командам просто предоставлялся текстовый файл. В этом году мы организовали целую лабораторию с реальными системами. Чтобы собрать хэши, участники следовали выданным инструкциям и использовали эксплойты как при пентесте. Команды получили исчерпывающее описание прохождения этих заданий, ошибиться было практически невозможно. Разумеется, с самим взломом хэшей участникам уже никто не помогал. Таким образом, команды могли работать с PCAP-файлами, Lotus Domino, различными веб-приложениями, файлами проектов SCADA и т.д. Баллы за получение хэшей не начислялись, но сам процесс был призван создать атмосферу тестирования на проникновение. Признаться честно, больше всего сил мы потратили именно на то, чтобы реализовать эту часть конкурса.

Обычно при оценке уровня защищенности нас не интересуют непривилегированные пользователи, нам нужна учетная запись с повышенными правами. Поэтому мы добавили в каждое задание по 23 хэша паролей администраторов, отличавшихся максимальной энтропией (23 — это просто число; 966/42 тут ни при чем). После взлома такого хэша команда получала 250 бонусных хэшей (Raw-SHA-1, GOST, bcrypt и Raw-MD5), которые были недоступны в основном задании.

Не все прошло гладко


Ошибки, о которых участники узнали во время соревнования:

  1. При загрузке результатов возникала ошибка, если расшифрованный текст содержал двоеточие ":". Не сказать, что мы этого не ожидали :)
  2. Из-за того, что при формировании дампа хэшей для задания №3 (md4 mt_rand) мы допустили некоторые ошибки, содержимое user.db.php и hashrunner_2014_hashes.zip не совпадало. Верные данные содержались в архиве hashrunner_2014_hashes.zip, и хэши из него принимались как правильные ответы. Таким образом, задание стало в два раза проще. Во время проведения конкурса мы не могли опубликовать подробности, т.к. одна из команд уже успела обнаружить эту ошибку самостоятельно. Другим участникам предлагалось также обнаружить и использовать этот сбой, чтобы загрузить хэши для данного задания.


Ошибки, которые были исправлены во время соревнования и о которых мы не стали сразу сообщать участникам:

  1. Хэши Cisco были случайно сформированы дважды и поэтому были разными (из-за применения разной соли в алгоритмах).
  2. База данных содержала неверную оценку для одного из бонусных хэшей (1 балл вместо 15). К счастью, ошибка была обнаружена в первый день соревнований, когда эти бонусные хэши еще практически никто не успел взломать.
  3. Кроме того, были обнаружены незначительные различия между файлом со всеми хэшами и собственно системами.


Словари и мутации


Мы составили словари исходя из опыта реальной работы и разнообразили их плодами нашей буйной фантазии: случайные последовательности длиной 6 и 8 символов, арабские слова в английской раскладке, слова с арабского форума, арабские имена, канадские города, химические вещества, китайские имена и фамилии, термины игры го, слова из греческой мифологии, голливудские звезды, итальянские города, мифические существа, персонажи комиксов Marvel, сайты многопользовательских ролевых игр, психические расстройства, слово «помидор» на разных языках, баннеры веб-приложений, а также случайные выборки из словарей packetstorm и xato 10k.

Далее мы использовали мутации, которые обычно встречаются специалистам во время консалтинга, а также добавили несколько необычных вариантов:

• Переписать все на языке Leet, переписать на Leet только некоторые буквы, переписать на Leet случайные части слов.
• Простые мутации: «word»«year», «word»«digit1»«digit2»«digit3», «word»«spec»«year«, «word»«date», «word»«date»«month».
• Заменить регистр символов в слове «word»: например, «WoRD» и «wORD». Такие мутации использовались в основном в словарях психических расстройств и мифических существ.
• «Злые» мутации «word1»«WORD2» и «word1»«word2»«word3».
• Добавить специальные символы: «special1»«word»«special2», «word»«special1»«special2»«special3»«special4».
• Запись арабских слов латинскими буквами также может считаться мутацией. Слова из словаря простых арабских слов были набраны теми же клавишами на клавиатуре, но латинскими буквами в английской раскладке. Пример применения такого алгоритма к кириллическим словам: если слово «пароль» напечатать в английской раскладке, получится «gfhjkm».

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

Разбор некоторых заданий


TIA Portal

Это был самый простой конкурс в соревновании. Система SCADA c обычными хэшами SHA-1, длина паролей известна — вот, собственно, и все. Изменяя предоставленный сценарий, можно было получать длину паролей, что существенно упрощало задачу взлома данных хэшей (см. рисунок ниже).

image

Lotus H-хэш

Помимо хэшей двух хорошо известных типов, lotus5 и dominosec (g-hash), были также сгенерированы хэши для версий >8. Хэши первых двух типов пользовались у участников большой популярностью, а вот хэши для версий >8 никто так и не попробовал взломать. Что ж, хорошо, что на практике мы пока с такими хэшами не встречались.

image

Арабский форум


Это задание был посвящено целевым атакам. Нельзя просто так взять и подобрать хэш, полученный итерационным прохождением MD5, не зная ничего об открытом тексте. Да, в нашем задании были «простые» хэши паролей, состоявших менее чем из пяти латинских букв, но такие пароли были сформированы переключением арабской раскладки на английскую. Большинство словарей (если не все) становятся бесполезны при переходе на другой национальный алфавит. Единственный способ решить задачу — создать свой словарь путем разбора других словарей или целевых сайтов. Форум в данном случае отлично подходит, на нем можно найти огромное количество слов, которые люди используют в реальной жизни, и составить на основе собранной информации базу возможных паролей. Однако иногда простого автоматического разбора текстов с сайта оказывается недостаточно. Всегда бывает полезно подумать о необычном использовании обычных вещей. Например, существует по меньшей мере четыре типа Unicode-символов только для кодирования арабских чисел, и в качестве одной из масок мутаций мы выбрали как раз добавление к паролю арабских цифр в кодировке Unicode. На самом деле, мы использовали только три мутации:

  1. Добавление трех арабских цифр не в кодировке Unicode в начало слова.
  2. Добавление двух арабских цифр в кодировке Unicode в конец слова.
  3. Перевод арабских букв в латинские путем изменения раскладки клавиатуры.

mtrand()

Это задание было посвящено плохим «случайным» числам, которые любят использовать неопытные разработчики. Предположим, у нас есть форум, блог или какой-то другой веб-сайт. Нам необходимо безопасное средство для формирования токенов, которые будут использоваться для смены пользовательских паролей. Можно было бы использовать линейный конгруэнтный генератор, но для задания мы выбрали Вихрь Мерсенна. На бумаге этот метод генерации псевдослучайных чисел выглядит весьма неплохо: он дает период 219937. Начальное число имеет длину 32 бита и является слабым местом с точки зрения безопасности. Зная его, злоумышленник может полностью воспроизвести последовательность псевдослучайных чисел. Однако эта проблема отчасти решается в стандартной реализации алгоритма: как только генератор получает начальное значение, он начинает формировать всевдослучайные числа, отличные от тех, которые были бы получены из другого начального значения. Таким образом, злоумышленнику придется полностью реализовать Вихрь Мерсенна и подобрать не только начальное (относительно короткое) значение, но и положение целевого случайного числа в потоке псевдослучайных чисел.

Такой подход должен одинаково работать и для хэшей h-типа, и для хэшей l-типа, но мы специально сформировали хэши обоих типов. Разработчик может навредить себе не только используя криптографически небезопасный генератор псевдослучайных чисел, но и некорректно обрабатывая полученный поток чисел. Работая с целыми числами или с числами с плавающей запятой в выбранном языке программирования, всегда нужно помнить о том, какова максимальная точность представления чисел выбранного типа и каким будет текстовое представление этих чисел. Например, при возведении в куб числа 123456789 мы должны получить 1881676371789154860897069 (если речь идет о классической десятичной арифметике) и ~79 битов энтропии в текстовом представлении этого результата. Однако если в вашем языке программирования для работы с такими большими числами используется представление с плавающей запятой, то результатом операции будет что-то вроде 1.8816763717892E+24, и энтропия понизится всего до ~45 бит. Такой пароль может быть легко подобран для любого быстрого алгоритма хэширования.

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

Давайте взглянем на код формирования открытых текстов.

Формирование простых открытых текстов (для l-хэшей)

function generate_password($length)
{
    $result = 1;
    for($i=0; $i<$length; ++$i) $result *= mt_rand();
    return $result;
}

for ($i=0; $i<$argv[1]; ++$i)
{
    if (($i % 32) == 0){
        mt_srand(get_real_rand());
        $skip = get_real_rand() & 0xFFFF + 8192; // Fix for easy attack
        for ($j=0; $j<$skip; ++$j)
            mt_rand();
    }
    echo generate_password(3)."\n";
    $skip = get_real_rand() & 0xFF; // Fix for easy attack
    for ($j=0; $j<$skip; ++$j)
        mt_rand();
}


Формирование сложных открытых текстов (для h-хэшей)

function generate_password($length)
{
    $result = 1;
    for($i=0; $i<$length; ++$i) $result .= mt_rand();
    return $result;
}

for ($i=0; $i<$argv[1]; ++$i)
{
    if (($i % 32) == 0){
        mt_srand(get_real_rand());
        $skip = get_real_rand() & 0xFFFF + 128; // Fix for easy attack
        for ($j=0; $j<$skip; ++$j)
            mt_rand();
    }
    echo generate_password(3)."\n";
    $skip = get_real_rand() & 0xFF; // Fix for easy attack
    for ($j=0; $j<$skip; ++$j)
        mt_rand();
}

Как можно заметить, в коде есть операция конкатенации с непустой строкой, содержащей цифру 1, поэтому числа, сформированные таким образом, не могли быть взломаны перебором, даже если бы участникам удалось воссоздать генератор MT_rand или воспользоваться кодом от Solar Designer (http://www.openwall.com/php_mt_seed/).

Tomato

Ντομάτα, домат, Парадајз, Помідор, томат, улаанлооль, Լոլիկ, პომიდორი, टमाटर, टोमॅटो, हिण्डीरः, ਟਮਾਟਰ, ಟೊಮೇಟೊ, தக்காளி, තක්කාලි, 番茄, 蕃茄, …

Без комментариев.

Wonderful

Мы получили очень вопросов по поводу этого задания, все хотят узнать, как нужно было его решать. Честно говоря, мы и не знаем. Этот конкурс (как и mt_rand с арабскими словами) был призван привлечь внимание участников к некоторым недостаткам современных утилит подбора паролей. Во время работы нам иногда попадаются различные старые или непопулярные приложения. Во многих из них используется обычный MD5, но в некоторых реализуются достаточно замысловатые схемы, например, SHA1(base64(MD5(base64(SHA1())))). SHA1 широко используется, base64 вообще ничего не стоит применить, но взломать полученный в результате хэш оказывается очень сложно. Тратить силы на создание сложного самообслуживаемого модуля для решения такой задачи неразумно, но вот получить инструмент, который комбинирует различные модули подбора в необходимом порядке, было бы неплохо. Да, и не забудьте оптимизировать HMAC для ключевого файла размером 1 МБ, т.к. в этом случае сам файл можно заменить его однократным хэшем :)

Статистика


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

График по количеству набранных баллов:

image

График по количеству взломанных хэшей:

image

Общий процент хэшей, взломанных всеми участниками:

image

Общий процент хэшей, взломанных всеми участнками, по типу хэшей:

image

Часть 1

image

Часть 2 (обратите внимание на максимальное значение по оси Y)

Хэши, взломанные InsidePro, по типам:

image

Хэши, взломанные hashcat, по типам:

image

Хэши, взломанные john-users, по типам:

image

Эпилог


Все началось с кружки пива в гамбургском кафе во время проведения конгресса 30C3 и получилось в результате не совсем таким, как задумывалось :)

image
Автор: @ptsecurity
Positive Technologies
рейтинг 306,35

Комментарии (1)

  • +1
    К сожалению, это задание преследовал злой рок. Во-первых, хэши в базе данных были закодированы только однократным прохождением алгоритма MD4; во-вторых, исходный код формирования h-хэшей немного отличался от кода на веб-странице.


    Что означает фраза «были закодированы только однократным прохождением алгоритма MD4»? Почему это злой рок?

    P.S. спасибо за конкурс, bay в таблице — это я.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка