Как готовят пентестеров? Разбор вступительных испытаний для стажеров «Digital Security»

    Summer of Hack 2019 в Digital Security уже идёт полным ходом, а значит самое время рассказать, как мы набирали людей.



    Под катом объемный и интересный материал о том, как мы отбираем молодых специалистов к нам на стажировку «Summer of Hack 2019», а конкретно — в департамент аудита защищенности.

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

    Разберём ряд непростых задачек, которыми мы мучали ребят, в том числе и от лица одного из них.

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

    В этом году мы отталкивались от следующих требований:

    • Базовое знание устройства web-приложений и атак на них;
    • Базовое знание браузерных механизмов защиты и разграничения доступа (да-да, тот самый SOP и CORS, куда же без них);
    • Базовые навыки чтения кода и умение видеть за ним логику;
    • Понимание работы компьютерных сетей и маршрутизации в них;
    • Опыт взаимодействия с Linux-подобными системами;
    • Умение не бояться незнакомых технологий. Умение гуглить и систематизировать полученную информацию;
    • И щепотка Android (впрочем, необязательно, но это наша небольшая прихоть).

    После были разработаны вопросы. Частично мы их позаимствовали из вопросов, задаваемых нами на собеседованиях, но более половины были специально подготовлены для данной анкеты. Наши специалисты тратили своё личное время на подготовку дампов трафика, спорили, как лучше сформулировать вопрос, а какие уязвимости “слишком специфичны, зачем мучать стажеров”. За подобное рвение мы не можем не снять перед ними шляпу (белую, само собой).

    Разбор каждого вопроса состоит из двух частей. Первая часть представляет собой ответ одного из наших стажеров — Данила Korgik_0 Леонтьева (он же автор публикации), а вторая — комментарии специалистов, корпевших над анкетой.



    Привет, Хабр!

    Для начала немного лирического отступления.
    А конкретней “Откуда я узнал о Summ3r 0f h4ck”.
    Об анонсе стажировки я услышал из выступления Дениса Рыбина и Ильи Булатова на конференции RuCTF2019.

    Буквально через 4 дня был выложен пост на habr-е об открытии набора на стажировку.

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




    №1. PHP Source code


    Изучите код. Опишите, какие недостатки вы видите и как бы вы их исправили.



    Разбор задания
    4 строка — использование md5 хеша.
    Проблематика — md5 можно брутить за приемлемое время с использованием hashcat.
    How to fix?

    Использование более «ресурсоемких» алгоритмов хеширования.
    В данном случае необходимо полностью отказаться от куки user и подвязать всю логику к phpsession.

    5 строка — PostgreSQL-injections.
    How to fix?
    Использование prepared statement.
    Реализация prepared statement для проверка login-а

    $query = "SELECT username FROM login WHERE username=?";
        $stmt = $conn->prepare($query);
    	$stmt->execute(array($username));
    	$username = $stmt->fetchColumn();
    	if($username == FALSE)
    	{
    		die("Неверный логин!");
    	}
    

    11 строка — ряд неудачных решений.

    1. Слишком длинная жизнь сессии. Целый год — это много. При успешном “угоне” cookie возможен длинный доступ к учетной записи пользователя со стороны злоумышленника.
    2. Отсутствие флага httpOnly. Если задано TRUE, cookie будут доступны только через HTTP-протокол. То есть cookie в этом случае не будут доступны скриптовым языкам, вроде JavaScript.
    3. Отсутствие хеширование cookie.
    4. Отсутствие установки флага secure. Флаг secure указывает на то, что значение cookie должно передаваться от клиента по защищенному соединению HTTPS. Если задано TRUE, cookie от клиента будет передано на сервер, только если установлено защищенное соединение.

    How to fix?
    По умолчанию в php время жизни сессий всего 24 минуты, давайте это и реализуем.
    Установим флаг secure, httpOnly.

    В данной случае стоит отказаться от странной куки user и подвязать всю логику к phpsession.

    18 строка — XSS (англ. Cross-Site Scripting — «межсайтовый скриптинг»).
    How to fix? Преобразовывать все возможные символы в соответствующие HTML-сущности.

    $query = htmlentities($query, ENT_QUOTES, "UTF-8");

    Явно укажем кодировку, для того чтобы избежать её подмены на UTF-7.

    header("Content-Type: text/html; charset=utf-8");

    20 строка — недочеты системы аутентификации и хранения сессий.

    Проблематика — если установить в cookie user id-шник пользователя, закодированный в base64, можно войти в его аккаунт!

    How to fix? При авторизации пользователя записываем сессию в БД и при установке сессии проверяем её наличие в БД.

    	$query = "SELECT sessions FROM login WHERE sessions=?";
    	$stmt = $conn->prepare($query);
    	$stmt->execute(array($_COOKIE["user"]));
    	$session = $stmt->fetchColumn();
    	if($session == TRUE)
    	{
    		do_login($_COOKIE["user"]);
    	}
    


    Комментарий эксперта D:
    Первый вопрос, которым анкета встречала будущих стажеров, касался основных и широко известных веб-уязвимостей. Единственной сложностью тут является необходимость увидеть их в исходном коде на PHP. Впрочем, задачу “прятать баги” никто не ставил.

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

    Хэширование паролей с использованием алгоритма MD5 замечали даже далекие от веба кандидаты. Впрочем, тут тоже были интересные нюансы, например, многие кандидаты использовали очень некорректные термины, пытаясь своими словами описать проблематику. В бой шли “уязвимости алгоритма”, “односторонние функции”, “существование коллизий” и другие странные обороты, при ближайшем рассмотрении оказывающимися не более чем набором громких слов, не раскрывающих сути. Конечно, тут мы шли на встречу и не придирались к тем людям, кто только готовится вступить на путь познания премудростей информационной безопасности. Для получения же “зачета” хватило бы и упоминания угрозы, что в случае компрометации базы данных md5-хеши могут быть перебраны злоумышленником за приемлемое время и получены пароли (или эквивалентные им строки) в открытом виде. А, ну и конечно же, многие упоминали отсутствие соли и перебор, основанный на использовании радужных таблиц. Таких комментарии тоже воспринимались нами положительно, особенно, если отвечающий пояснял, почему это является угрозой.

    Потенциальная SQL-инъекция. Сложно что-то добавить; при формировании обращения к базе пользовательский ввод логина и пароля напрямую конкатенируются с запросом. Если же манипулировать значением пароля на данном этапе вряд ли получится (от него берётся хэш), то внедрить инъекцию в username не составит труда для потенциального злоумышленника.

    Вывод лишней debug информации приводящей к XSS-атаке. Внимательно читая листинг, можно было обратить внимание на вызов echo, отображающий сформированный запрос к базе в HTML-комментарии на страницу. Конечно, подобный вывод дополнительной информации на страницу совсем необязателен и, скорее всего, просто забыт разработчиком после проведения тестов. Такая дополнительная информация очень на руку злоумышленнику и позволяет намного лучше понять принцип работы приложения. Однако, к сожалению, это только полбеды. Дело в том, что злоумышленник может манипулировать содержимым переменной query, а её содержимое никак не фильтруется или экранируется перед выводом на страницу пользователю — налицо потенциальная XSS-атака. Впрочем, эксплуатация её может оказаться той ещё головной болью из-за неудачно расположенной функции strtoupper. Внедряемый злоумышленником вектор будет приведён в верхний регистр, и если для HTML-тегов это не проблема, то вот Javascript сильно обижается на подобное обращение. В этом легко убедиться, воспользовавшись консолью браузера.



    Что ж хоть, видимо, злоумышленнику придётся обратиться к так называемым «scriptless-атакам» или изощренным техникам обхода фильтрации (в данном случае подошел бы JSFUCK), так что факт наличия угрозы безопасности это не отменяет.

    Ошибка в логике механизма управления сессий являлась наиболее интересной частью задания. Её обнаружение требовало не просто читать исходник построчно, но и понимать логику работы всего листинга. Почувствовать неладное можно было, заметив выставление cookie, содержащей base64-кодированный id пользователя в блоке remember-me. Дальнейший анализ логики работы данного механизма приводит нас к мысли: “Получается, злоумышленник, знающий или перебравший id, может войти в любой аккаунт без ввода логина и пароля?!”. Да, действительно, злоумышленник может на своей стороне самостоятельно сформировать cookie user и присвоить ей любое значение id, закодированное base64. Отправление запроса с такой cookie без username и password привело бы к срабатыванию функции do_login и к входу в чужой аккаунт.

    Упоминание этих 4 уязвимостей в ответе кандидатов напрямую влияло на набранные ими баллы.

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




    №2. JWT


    В ходе исследования веб-приложения вы обнаружили, что приложение в качестве авторизации использует JWT-токен.

    Какие проблемы безопасности вы видите, какие проверки вы бы сделали?

    JWT-токен:

    eyJhbGciOiJOb25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InNla2EiL CJpYXQiOjE1MTYyMzkwMjIsInJvbGUiOiJub2JvZHkiLCJpc0FkbWluIjoiRmFsc2UiLCJwYX Nzd29yZCI6IjFkMDBjYUgifQ.F7Y1mCAmg5-QFok-rkpLdwe8prCyiKsCyJ-3Z5f7luI

    Разбор задания
    Дан JSON Web Tokens (JWT).
    Его структура -> [base64url(HEADER)].[base64url(PAYLOAD)].[base64url(SIGNATURE)]
    [base64url(HEADER)] = eyJhbGciOiJOb25lIiwidHlwIjoiSldUIn0
    base64url decode -> {«alg»:«None»,«typ»:«JWT»}
    Сразу можно отметить тот факт, что не используется алгоритм подписи («alg»:«None») сигнатурки. Некоторые библиотеки JWT не поддерживают алгоритм “none”, то есть алгоритм подписи. Когда заголовок alg равен “none”, серверная часть не будет выполнять проверку подписи.
    Т.е можно записать любой payload в base64url, и подпись к нему не будет проверяться.
    Что позволяет нам создать пользователя с правами admin-а.

    Также нам упрощает жизнь тот факт, что в части payload не используются такие заголовки как aud (определяет получателей, для которого предназначен JWT-токен) и exp (время жизни токена).

    Предполагаемая полезная нагрузка
    eyJhbGciOiJOb25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6ImhhY2siLCJpYXQiOjE1MTYyMzkwMjIsInJvbGUiOiJub2JvZHkiLCJpc0FkbWluIjoiVHJ1ZSIsInBhc3N3b3JkIjoiaGFjayJ9

    base64url decode payload -> {«sub»:«1234567890»,«name»:«hack»,«iat»:1516239022,«role»:«nobody»,«isAdmin»:«True»,«password»:«hack»}

    Комментарий эксперта D:
    В работе аудитора часто приходится сталкиваться с новыми технологиями, и умение разбираться в них очень важно. Включая этот вопрос в анкету мы предполагали, что большая часть кандидатов вряд ли слышало о технологии JWT-токенов что-то, кроме названия. Поэтому этот вопрос, в первую очередь, был направлен на умение искать и анализировать информацию из публичных источников. В итоге, человек, пропустивший через себя выдачу гугла по запросу “JWT” и “jwt vulnerability”, мог прийти к следующим выводам:

    1. У данного токена отсутствует алгоритм подписи, поэтому злоумышленник способен модифицировать любые поля внутри токена, что не предполагается концепцией JWT-токенов.

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

    3. Помня про отсутствие подписи и нашу возможность модифицировать поля внутри токена, логично предположить, что изменение значения isAdmin может повысить наши привилегии до привилегий администратора.

    4. Ещё одна интересная мысль, которую мало кто упоминал в своем ответе, касается самого факта возможности передавать пользовательский ввод в полях JWT-токена. В обычной ситуации злоумышленник никак не может повлиять на данные в токене, а значит, зачастую разработчики могут пренебрегать введением дополнительных проверок в код обработчиков. Отсюда напрашивается простая идея: а давайте попробуем провести классические атаки не через GET/POST-параметры, а через поля токена. Это может дать неожиданно неплохой результат. Подобный креативный подход с правильным обоснованием своих действий высоко ценился нами при оценивании как данного, так и других вопросов.

    Многие кандидаты в своих ответах устраивали краткий пересказ того, как устроен JWT токен, и где он используется, нам было интересно почитать, и всё же, в первую очередь оценивались аспекты ответа касательно безопасности.




    №3. CORS/CSRF/IDOR/???



    В веб-приложении пароль пользователя меняется с помощью следующего запроса (см. Вариант 1). Какие потенциальные угрозы безопасности вы видите? Какие проверки вы бы осуществили? Изменится ли ситуация в случае следующего поведения (см. Вариант 2)? Объясните свой ответ.

    Разбор задания
    Вариант 1.
    «Какие потенциальные угрозы безопасности вы видите?»

    1) Отсутствие контроля доступа.
    Если не проверяется номер user-a, к которому осуществляется запрос на изменение пароля, то можно изменить пароль любому зарегистрированному пользователю в системе.
    How to fix? — Сопоставление JSESSION из БД и запрашиваемого id-шника.

    2) Возможность проведения CSRF атаки
    Завлекаем авторизованного пользователя на подконтрольный нам хост и сделав запрос, на сайт example.com от имени жертвы, на изменение пароля.
    How to fix? — Добавление CSRF токена.

    Вариант 2.
    «Какие потенциальные угрозы безопасности вы видите?»
    Недочет в CORS политике.
    Рекомендуется настроить белый список заголовку Аccess-Control-Allow-Origin.

    How to fix? —

    1) Изменение файла .htaccess

    <ifmodule mod_headers.c>
      Header always set Access-Control-Allow-Origin: "https://whitelist.domain.ru"
      Header always set Access-Control-Allow-Methods "PUT"
    </ifmodule>
    

    2) PHP

    <?php
    header('Access-Control-Allow-Origin: “https://whitelist.domain.ru”);
    header('Access-Control-Allow-Methods: PUT');
    ?>
    

    «Изменится ли ситуация в случае следующего поведения?»

    Да. Поскольку во втором случае используется PUT запрос, что важно, поскольку использование PUT запроса делает CORS запрос “сложным”, а это в свою очередь полностью лишает нас возможности провести CSRF атаку + отсутствие такого заголовка как Access-Control-Allow-Credentials: true лишает нас возможности отсылать в месте с другими http заголовками и cookie пользователя.

    Комментарий эксперта I:
    Рассмотрим по порядку, какие основные проблемы видны на приводимых запросах:

    1) Действительно, раз в запросе наблюдается числовой идентификатор пользователя «10012», то первым делом стоит проверить, а можно ли сменить пароль другому пользователю? Может достаточно указать чужой id?
    Уязвимости класса «IDOR» достаточно легко эксплуатируются и часто имеют высокую критичность.

    2) Запрос на смену пароля происходит методом POST, CSRF-токена не наблюдается, а тип содержимого — «text/plain». Налицо возможность подделки такого запроса.

    Следовательно, злоумышленнику, чтобы сменить пароль жертве, достаточно убедить её всего лишь посетить «зловредную» ссылку.

    3) В заголовках ответа сервер раскрывает версию используемого ПО. Уязвимостью это назвать можно с большой натяжкой, но подобные баннеры лучше скрывать — злоумышленники по ним могут легко найти известные 1-day эксплойты, плюс значение используемого ПО значительно упрощает планирование дальнейших атак.

    4) Нам было бы очень приятно увидеть предложение «А что будет, если поменять формат данных с JSON на XML

    Дело в том, что современные фреймворки умные, всеядные и могут обрабатывать данные в разных форматах. А в при парсинге XML часто допускается опасная уязвимость XXE. C её помощью нарушитель может и во внутреннюю сеть «сходить», может и файлы конфигурации с сервера прочитать, а изредка и RCE исполнить.

    5) Также хотелось увидеть замечание вида «А почему при смене пароля не проверяется знание старого

    Что касается «Варианта №2», то в нём кроется «ловушка» — тут используются CORS-заголовки, а Content-Type запроса уже выставлен в «application/json».

    Ошибкой, которую допустили абсолютное большинство кандидатов, является ответ вида "-Вот тут в Allow-Origin «звездочка», а значит с любого сайта запросы отправлять можно!"

    Нет, нельзя. Во-первых, отсутствует заголовок Allow-Credentials:True означающий, что браузеру следует выполнить запрос «с куками», так что запрос был бы анонимный, без сессии. А во-вторых, даже если бы такой заголовок присутствовал, браузер все равно бы запретил отправку кук — как раз из-за «звездочки». Их комбинация является запрещенной, и браузером игнорируется.



    №4. Network Dump


    Представьте, что вы попали во внутреннюю сеть компании и перехватили трафик, дамп которого приложен ниже. Распишите, какие атаки вы бы попробовали провести и какими инструментами?

    Дамп: yadi.sk/d/qkLcfwSCzdxcwg

    Разбор задания
    1) LLMNR Spoofing<
    Злоумышленник в локальной подсети может прослушивать широковещательные сообщения и отвечать на них, утверждая, что запрошенное имя хоста — это его собственный IP-адрес.
    Это приводит к тому, что запрашивающий клиентский компьютер подключается к компьютеру злоумышленника и, в зависимости от протокола, может попытаться выполнить аутентификацию.

    Используемые утилиты — Intercepter-NG, проект на githab VindicateTool.

    2) Злоупотребление протоколом HSRP.
    Проблематика — при установленном параметре ”preempt” в 1 атакующему доступна возможность “вытеснять” другие роутеры, благодаря более высокому приоритету. После рассылки HSRP по мультикасту подконтрольный роутер становится главным роутером (Active Router) в сети, и весь трафик будет проходить через него. По сути, мы пришли к реализации mitm атаки.

    Для данного вектора атаки нам необходимо знать группу и пароль.
    Из данного нам дампа трафика мы узнаём группу (она равна — 3) и пароль. Пароль в нашем случае дефолтный — cisco.

    Используемые утилиты — yersinia, scapy.


    Комментарий эксперта X:
    Задачей вопроса являлось определение ознакомленности стажера с современными (и не очень) методиками проведения MitM-атак. Давайте рассмотрим потенциально возможные сценарии, основываясь на имеющемся дампе трафика:

    1) ARP спуфинг
    ARP-spoofing является самым старым и простым в реализации способом проведения MitM-атак. Заключается он в отправке gratuitous ARP запроса на хост А.

    В качестве IP-адреса, указывается IP-адрес хоста B, а в качестве MAC-адрес — наш MAC-адрес. Такой запрос позволяет модифицировать ARP-таблицу на хосте A, заставляя его отправлять запросы на наше устройство, при попытке обратиться к хосту B. Хостом B обычно является шлюз по-умолчанию.

    Рекомендуемые инструменты: bettercap, arpspoof

    2) LLMNR, NBNS спуфинг
    Link-Local Multicast Name Resolution и NetBIOS Name Service — это протоколы, используемые для резолва хостнеймов в локальной сети. В отличие от протокола DNS, тут отсутствует выделенный сервер, хранящий всю информацию, вместо этого запрос отправляется широковещательно на все хосты в сети, если хостнейма в запросе совпадет с хостнеймом устройства — оно отправит ответ.

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

    Рекомендуемые инструменты: Responder

    3) WPAD спуфинг
    WPAD spoofing можно отнести к частному случаю LLMNR- и NBNS-спуфинга. Web Proxy Auto Discovery protocol служит для автоматической конфигурации HTTP-прокси сервера.

    Устройство отправляет LLMNR/NBNS запрос с хостнеймом wpad, получает соответствующий IP-адрес и пытается обратиться по HTTP к файлу wpad.dat, в котором хранится информация о настройках прокси.

    Как следствие, злоумышленник может выполнить LLMNR/NBNS-спуфинг и предоставить жертве свой файл wpad.dat, в результате весь HTTP- и HTTPS-трафик пойдет через злоумышленника.

    Рекомендуемые инструменты: Responder, mitm6

    4) Router Advertisement
    Как видно из дампа, в сети присутствуют устройства с включенным IPv6. Находясь в сети, можно попробовать отправить жертве IPv6 Router Advertisement сообщения с целью сменить шлюз по-умолчанию или DNS-сервер.

    Router Advertisement (RA) сообщения являются частью механизма SLAAC (Stateless Address Autoconfiguration), который необходим для автоматического получения IPv6 адресов в сети, без использования DHCPv6 сервера, или совместно с ним. Достигается это путем периодической отправки мультикаст RA сообщений маршрутизатором, которые содержат в себе адрес шлюза по-умолчанию, префикс сети, адрес DNS-сервера, префикс домена.

    Рекомендуемые инструменты: raw-packet

    5) DHCP-спуфинг
    Также в дампе с некоторой периодичностью повторяются DHCP Discover-запросы от одного и того же устройства. Можно сделать выводы об отсутствии DHCP-сервера в данной сети и ответить на следующий Discover-запрос, указав жертве свое устройство как шлюз по-умолчанию.

    Рекомендуемые инструменты: Yersinia

    6) HSRP спуфинг
    Помимо этого, в дампе можно заметить HSRP-пакеты. Hot Standby Router Protocol позволяет увеличить доступность маршрутизаторов, выполняющих роль шлюза по-умолчанию. Маршрутизаторы объединяются в одну группу и получают один общий IP-адрес, который используется как шлюз по-умолчанию. С помощью Hello мультикаст-пакетов маршрутизаторы обнаруживают друг друга и добавляются в группу, как раз эти пакеты и присутствуют в имеющемся у нас дампе. На основании этого можно сделать выводы о включенном в сети HSRP, и, как было верно сказано в ответе, можно притвориться маршрутизатором с включенным HSRP и анонсировать себя в качестве главного маршрутизатор в группе.

    Рекомендуемые инструменты: Yersinia

    7) STP-спуфинг
    Spanning Tree Protocol необходим для защиты от возникновения L2-петель в сети. Коммутаторы отправляют специальные BPDU-пакеты, чтобы определить корневой коммутатор и отключить все избыточные пути до него, оставив их в качестве резервных. Так как в дампе мы можем увидеть те самые BPDU-пакеты, можно сделать вывод, что порт коммутатора, смотрящий в сторону устройства, не настроен должным образом, и злоумышленник может анонсировать себя в качестве корневого коммутатора, тем не менее, для достижения успеха, в виду особенностей работы STP, необходимо контролировать не один, а два таких порта.

    Рекомендуемые инструменты: Yersinia



    №5. NGINX config



    Перед вами конфигурация веб-сервера nginx. Подробно опишите, какие проблемы безопасности вы в ней видите?

    Конфигурация: pastebin.com/nYp7uVbB

    Разбор задания
    Дан конфиг nginx, после просмотра конфига мне удалось найти множественные недочеты контроля доступа:
    1) В 86 строке, если установить http заголовок X-Managed и присвоить это хедеру значение secured, то nginx пустит нас в директорию /management/
    2) Отсутствие какой либо авторизации при доступе к API в 70 и 105 строке.


    Комментарий эксперта J:
    Задание было добавлено в анкету с целью узнать, насколько хорошо стажеры умеют разбираться в новых для них вещах. Хоть с nginx косвенно знакомы практически все, кто имел дело с web-приложениями, но в большинстве случаев знания об nginx сводятся к настройке web-сервера по примеру/гайду. В больших и архитектурно сложных проектах зачастую можно увидеть запутанные nginx конфиги, через которые, например, связаны друг с другом микросервисы.

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

    Найти небольшое количество багов можно было воспользовавшись утилитой gixy.

    Gixy находит 4 проблемы в нашим конфиге:

    1) Alias travesal:

    Со строки 80 можно увидеть следующий блок кода:

    location /static {
              	alias /prod_static/;
       	}
    

    Такая конструкция позволяет почесть какой-либо файл, находящийся на директорию ниже. Пример эксплуатации: //host/static../etc/passwd. Происходит это из-за особенностей обработки путей директивой alias: в нашем случае часть пути, стоящая после /static, конкатенируется с /prod_static/, и по итогу мы получим такой путь: /prod_static/../etc/passwd, что приведет нас к чтению /etc/passwd. Подробнее прочитать про alias traversal можно здесь

    2) Http Splitting (CRLF injection)
    Некоторые директивы в nginx доверяют данным, передаваемым в заголовок, и не валидируя их при подстановке в запрос. Это может повлечь инъекцию в сам HTTP-запрос.
    Подробнее: github.com/yandex/gixy/blob/master/docs/ru/plugins/httpsplitting.md

    3) Плохая валидация из-за некорректного регулярного выражения
    На строчке 75 можно увидеть проверку значения заголовка «Оrigin» по регулярному выражению. Регулярное выражение обрабатывается некорректно, из-за этого можно получить выполнение условия при использовании, например, домена production.host.evil.com.
    Подробнее: github.com/yandex/gixy/blob/master/docs/ru/plugins/origins.md

    4) Переопределение заголовков с вложенным add_header
    У nginx есть особенность: если во вложенном условии сделать add_header, когда вне условия уже использована эта директива, заголовки, которые прописаны вне условия, не поставятся. То есть в нашем случае CSP не будет при вхождении в условие.
    Подробнее: github.com/yandex/gixy/blob/master/docs/ru/plugins/addheaderredefinition.md


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

    1) В строке 17 можно заметить использование директивы default_type с аргументом text/html. Данная директива работает следующим образом: если тип файла, к которому обращается пользователь неизвестен, то nginx вернет его с Content-Type, равным установленному в default_type. В нашем случае, любой файл с неизвестным расширением будет приходить с Content-Type: text/html. Вкупе с загрузкой файлов эта ошибка может позволить злоумышленнику загружать произвольные HTML-файлы на сервер, которые могут содержать, например, XSS-вектор или фишинговую страницу.

    2) Общедоступные логи с POST-параметрами
    На 29-30 строке можно заметить, что логи посещений записываются в корневую директорию одного из виртуальных хостов. Более того, в логах “оседают” POST-параметры. Это может повлечь серьезные утечки пользовательских данных. Но! Этот недостаток можно эксплуатировать либо получив SSRF с выводом, либо доступ к файловой системе, так как хост, где будет хранится лог файл, локальный.

    3) Потенциально общедоступный php-fpm
    На строчке 48 можно увидеть, что FastCGI-сервер находится не на unix сокете, а на порту 9000. Можно предположить, что порт не локальный, а доступен снаружи. Если это так, то существует возможность исполнять произвольный PHP-код.

    4) “Плохой” CSP
    Для production.host установлен Content-Security-Policy, который позволяет исполнять Javascript, встроенный напрямую в страницу.

    5) “Плохой” CORS
    На строках 76-77 задается динамический CORS, который позволяет делать запросы к нашему хосту с любого другого, при этом браузер автоматически будет подставлять cookie в запрос.

    6) Выше в ответе верно отмечено, что на 86 строке присутствует слабая проверка доступа в директорию. Просто установив определенный заголовок со значением secured позволит войти в директорию /managed.

    7) Второй пункт ответа также частично корректный, но отвечающий не учел, что проверка зачастую находится именно на стороне приложения, а не самого веб-сервера. Но, тем не менее, стоит проверить, уязвимы ли роуты /user/{userid} к IDOR.

    Задание было непростым, в нем есть достаточно много спорных моментов, и мы хотели посмотреть, как ребята справятся с этим.



    №6. Linux Permissions


    В каких случаях пользователь Linux может читать домашние директории других пользователей?

    Разбор задания
    Оператор ~ (тильда) в Debian
    C помощью этого оператора можно получить путь до домашней директории любого пользователя в системе (при условии, что пользователь прописан в файле /etc/passwd).
    Например, посмотреть содержимое домашнего каталога пользователя ftp можно так, поставив перед ним тильду ~.

    Пример:
    * root@server:~# ls ~ftp
    * welcome.msg
    А теперь посмотреть содержимое этого файла:
    * root@server:~# cat ~ftp/welcome.msg
    * Welcome, archive user %U@%R!
    Ну и то, к чему мы стремились: посмотреть путь к домашней директории пользователя:
    * root@amorale:~# echo ~ftp
    * /srv/ftp


    Комментарий эксперта K:
    Этот вопрос довольно простой, и критерием оценки на него было несколько пунктов:

    • Описание устройства прав в файловой системе
    • Упоминание ACL и описание принципов их работы
    • Упоминание дополнительных свойств
    • Какая стоит по умолчанию маска
    • Упоминание capabilities

    Самым частым ответом, который не может быть оценен высоко, является фраза вида:
    “Можно читать, когда пользователь root” и её вариации.

    Вопрос сводится к простому пониманию того, как устроены права в Linux/Unix.
    Для начала надо оговориться, что мы имеем в виду под словосочетанием “прочитать директорию” — в данном случае нас интересует только получение списка файлов внутри директории.
    Чтобы наглядно представить, о чем будет идти речь, возьмем некоторый файл funky_test.txt и посмотрим на его права

    -rwxrw-r-x  1 alice interns   12 июл  4 13:00 funky_test.txt

    Известно, что права в Linux/Unix выражаются тремя группами:

    • права пользователя-владельца — в данном случае “rwx” для alice
    • права группы — в данном случае “rw” для группы interns
    • права всех остальных — в данном случае “r-x” для others

    Для каждой из группы возможна любая комбинация из прав read, write, execute.

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

    • Пользователь является владельцем файла, и для владельца есть право read
    • Пользователь принадлежит группе файла, и для группы есть право read
    • Для остальных есть право read

    Следует заметить, что если наличие одного только права read на папку дает возможность только посмотреть список имен содержащихся внутри нее файлов. Узнать их размер или права нельзя, для этого необходимо обладать правом execute для папки.

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

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

    1. Как на самом деле ядро ОС смотрит и применяет права, которые мы видим с помощью команды ls.

    2. Возможность наличия списков контроля доступа — POSIX Access Control Lists.

    Уточнения работы ОС c правами на файл.


    Пример 1

    Предположим, вы пользователь alice и вы принадлежите группе interns. Ниже представлены права на файл funny_test.txt и попытка его прочитать:

    $ whoami
    alice
    $ id
    uid=1001(alice) gid=1001(alice) groups=1001(alice),1002(interns)
    $ ls -la
    ----rwx---  1 alice interns   12 июл  4 13:00 funky_test.txt
    $ cat funky_test.txt
    cat: funky_test.txt: Permission denied
    $ 
    

    Пример 2

    Следующий пример — меняем права funky_test.txt на 604. Заходим под пользователем bob, который принадлежит группе interns и пытаемся прочитать файл:

    $ whoami
    bob
    $ id
    uid=1002(bob) gid=1003(bob) groups=1003(bob),1002(interns)
    $ ls -la funky_test.txt
    -rw----r--  1 alice interns   12 июл  4 13:00 funky_test.txt
    $ cat funky_test.txt
    cat: funky_test.txt: Permission denied
    

    Замечания

    В первом примере alice владелец файла и потому может поменять права, как хочет. Таким образом, permission_denied для нее не ограничение:

    $ id               
    uid=1001(alice) gid=1001(alice) groups=1001(alice),1002(interns)
    $ ls -la
    ----rwx---  1 alice interns   12 июл  4 13:00 funky_test.txt
    $ chmod 777 funky_test.txt
    $ ls -la funky_test.txt
    -rwxrwxrwx 1 alice interns 12 июл  4 13:00 funky_test.txt
    $ cat funky_test.txt
    secret_pass
    

    А вот во втором примере bob сделать ничего не может.

    Почему так

    Все дело в том, что ядро берет только один набор прав который наиболее «подходит для пользователя», а именно:

    • Если ID владельца файла совпадает с вашим effective UID — тогда используются права для владельца
    • Если GID группы файла совпадает с одним из ваших effective GID — тогда используются права для группы
    • В остальных случая используются права others.

    Дополненный ответ

    Таким образом, дополненный ответ бы содержал оговорку — в силу того, что ОС не будет искать самые “сильные” права для текущего пользователя, а вместо этого пойдет по описанному выше алгоритму, то необходимо учитывать сценарий, когда:

    • пользователь владелец без прав, но принадлежит группе, у которой есть права на чтение или же для others есть права на чтение
    • пользователь не владелец, но принадлежит группе без прав, однако для others существуют права на чтение

    В каждом из описанных случаев пользователь не сможет прочитать содержимое папки.

    POSIX Access Control Lists


    Еще одно возможное дополнение ответа — это когда выставлены списки контроля доступа для конкретного файла/директории. При просмотре прав, можно увидеть что выполняются ACL, благодаря тому, в конец списка прав добавляется знак “+

    Не вдаваясь в подробности работы POSIX ACLs, можно сказать следующее — их главная возможность в том, что мы можем задавать отдельные права для пользователей и групп на файл. То есть когда файл с ACL, то для него могут действовать права нескольких групп.

    Пример

    Как это работает. Вернемся к нашему изначальному примеру с пользователем alice и файлом funky_test.txt с правами, представленными ниже

    -rwxrw-r-x 1 alice interns 12 июл  4 13:00 funky_test.txt

    Для данного файла не установлены ACL. Команда getfacl, используемая, для просмотра списка ACL, покажет лишь то, что мы увидели в ls.

    $ getfacl funky_test.txt
    # file: funky_test.txt
    # owner: alice
    # group: interns
    user::rwx
    group::rw-
    other::r-x
    

    Как говорилось ранее, ACL дает нам возможность установить отдельные права для файла. К примеру, добавим права для пользователя bob на чтение:

    setfacl -m u:bob:rwx funky_test.txt
    

    Теперь в правах на файл появился “+” в конце

    ls -l funky_test.txt
    -rwxrwxr-x+ 1 alice interns 12 июл  4 13:00 funky_test.txt
    

    А атрибуты выглядят следующим образом:

    getfacl funky_test.txt
    # file: funky_test.txt
    # owner: alice
    # group: interns
    user::rwx
    user:bob:rwx
    group::rw-
    mask::rwx
    other::r-x
    

    Для ACL также есть алгоритм применения правил. Он следующий:

    1. Просматривается список прав для файла. При первом совпадении для текущего effective UID или effective GID пользователя — применяется правило. При этом если пользователь состоит в нескольких группах, для каждой из которых есть свой ACL, то результирующими правами будет объединение разрешающих прав. То есть, если одной группе можно читать, а другой писать, то пользователь, состоящий в каждой из этих групп сможет и читать, и писать в файл.
    2. Если в ACL стоит mask, то она преобладает над остальными ACL за исключением прав owner, group, others

    Дополненный ответ

    Для пользователя, который является владельцем файла или входит в группу владельцев, действуют правила, описанные в предыдущем пункте — классические правила файловой системы в ОС.

    В других случаях, для ACL, пользователь может получить содержимое папки, когда:

    • пользователю отдельной строкой разрешено чтение на уровне ACL, при этом нет запрещающей маски;
    • пользователь принадлежит группе, для которой отдельной строкой разрешено чтение на уровне ACL, при этом нет запрещающей маски.





    №7. Network Dump II


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

    Дамп трафика: yadi.sk/d/e3gNme4MBo6tFQ

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



    Из скриншота следует, что файлы передаются по SMB-протоколу, что хорошо, ведь можно сразу посмотреть, какие файлы были переданы по данному протоколу. Для этого необходимо перейти во вкладку SMB object list (File -> Export objects -> SMB… ).

    И о чудо — нам выпадает целый список файлов.


    (результат работы SMB object list)


    (NotTruePass.jpg)

    Это здоровый вариант решения таска.

    Я же в силу своей неопытности решил “выловить” изображение прямо из TCP-трафика… Что не дало ожидаемого результата. Картинка просто не открывалась. :(

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


    (Конфигурационный файл desktop.ini)

    Далее мне стало интересно “выловить” аутентификацию пользователя или сессионные ключи. Обнаружив, что аутентификация проходила с использованием NTLM, и немного погуглив, я понял, что NTLM уязвим к такой атаке как “Pass-the-hash”. В итоге моя задача сводилась к поиску хеша на этапе ответа в схеме аутентификации «Вызов-ответ».

    По итогу мне удалось “выудить” информацию о трёх пользователях:

    1)User - 1
    Account: IEUser
    Domain: WIN7
    Host: WIN7
    hex dump session key - 49 0c 38 3e f8 eb 63 88 79 0f 62 84 09 84 d2 dc
    
    2) User - 2
    Account: winwin
    Domain: WIN7
    Host: WIN7
    hex dump session key - 8d f6 1b 35 79 a3 78 d3 2e 81 09 f1 95 4f 71 0a
    
    3) User - 3
    Account: 192.192.192.29
    Domain: WIN7
    Host: WIN7
    hex dump session key - c3 19 e0 21 1b e2 63 c6 03 9e e7 38 1b 56 f0 d1
    

    В нашем случае мы имеем на руках сессионные ключи трёх наших пользователей. Что позволяет получить доступ к серверу MSEDGEWIN10.

    И последнее задание — это найти предполагаемые векторы атак:

    1) SMB Relay.
    Суть данной атаки заключается в прослушивании сетевого трафика и перехвата аутентификации.
    Как только запрос на аутентификацию обнаружен, атакующий реализует MITM-атаку
    (т.е перехватывает запрос на аутентификацию от обратившегося узла и передает его на атакуемый сервер).

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

    Злоумышленник аутентифицируется на сервере, а узлу, запросившему аутентификацию, отправит ответ об ошибке подключения.

    2) NTLM Relay.
    Атакующий провоцирует клиента на подключение к себе по протоколу, позволяющему NTLM-аутентификацию.

    После чего атакующий подключается к серверу по любому протоколу, позволяющему провести NTLM-аутентификацию.

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

    Комментарий эксперта K:
    Данный вопрос сводился, по сути, к трем основным моментам:

    1. Найти переданные файлы (в частности картинку с котиком)
    2. Найти все критичные данные передаваемые в трафике — хеши/ключи
    3. Описать атаки на основе предоставленного трафика, а также найденных ранее критичных данных

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

    1. Узнать статистику конечных узлов
    2. Узнать статистику используемых протоколов
    3. Узнать статистику используемых портов

    Для этого воспользуемся функционалом Wireshark, а именно опциями Protocol Hierarchy Statistics и Conversations.

    Protocol Hierarchy Statistics — В этом окне мы видим используемые протоколы в виде понятной иерархии.



    Conversations — дает возможность узнать, какие из узлов в сети ведут самый шумный диалог.





    Эти три окна дают сделать следующие выводы:

    1. Большая часть трафика (60%) — это TCP, причем, скорее всего, SMB. В картинке Protocol hierarchy у SMB только 40%, но поскольку нет другого протокола во вкладке TCP, то это говорит о том, что скорее всего остальные 20% есть передаваемые файлы в рамках SMB.
    2. Большая часть общения происходит между 192.192.192.128 и 192.192.192.129. Скорее всего SMB сообщения имеют место быть именно здесь.

    Поиск переданных данных

    Начнем с поиска данных.

    Из сделанных выводов напрашивается логичный следующий шаг — поиск переданных файлов внутри SMB.

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

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

    Поиск критичных данных.
    Для передачи данных по SMB клиент должен был аутентифицироваться на другом хосте.

    Все запросы по NTLM-аутентификации можно отфильтровать с помощью “ntlmssp”. Отсортировав по полю info, видим 3 различных запроса на аутентификацию:



    Однако, только одному из пользователей удалось удачно пройти аутентификацию.







    Для каждого из пользователей мы можем получить их значения Net-NTLMv2-аутентификации, состоящее из:

    • challenge сервера
    • response клиента
    • имени клиента

    Полученные Net-NTLMv2 значения можно дальше перебирать с помощью hashcat.

    Очевидно, что даже если мы найдем пароли для WIN7\winwin и WIN7\192.192.192.129 — это не даст нам возможности аутентифицироваться, так как для другой машины эти учетные записи не валидны. А вот запись WIN7\IEUser — валидна, и если мы сумеем подобрать её значение, то дальше, в теории, сможем атаковать машину, используя SMB.

    Извлечь Net-NTLM можно как автоматизированно, так и вручную, копируя поля из Wireshark. Автоматизировано это легко сделать, используя PCredz (https://github.com/lgandx/PCredz)



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



    Описать атаки на основе предоставленного трафика, а также найденных ранее критичных данных.

    Поскольку для чисто сетевых атак отведен вопрос 6, будем рассматривать атаки, связанные с SMB/NTLM, DNS.

    Первая, очень важная оговорка заключается в том, что необходимо различать NT и LM от NTLMv1 (Net-NTLMv1), NTLMv2 (Net-NTLMv2) (хорошая короткая статья на эту тему).

    Из-за схожего наименования иногда NT и LM называют NTLM, это дает очень не нулевой шанс затем спутать NTLM с NTLMv1 или NTLMv2. Кажется, что это как будто разные версии одного и того же протокола. Но это не так.

    Главное различие заключается в том, что NTLMv1/NTLMv2 — это результат работы challenge-response протокола. То есть их конечные значения меняются каждый раз, когда пользователь запрашивает ресурс.

    А NT и LM — это как “классическая хеш функция” — результат которой всегда одинаков для одинаковых входных значений.

    Атаки сводятся к нескольким большим классам:

    • PassTheHash — атака, при которой не обязательно знать исходное значение пароля, достаточно только обладать его хешем. Но. Это должен быть статичный хеш, например NT. Сделать PassTheHash с NTLMv2 нельзя — это частая ошибка. В текущем случае такая атака не имеет смысла, так как полученный из трафика “хеш” использовать нельзя, а если мы сможем получить исходный пароль, то будем использовать его.
    • NTLM Relay — атака, при которой злоумышленник может представиться для жертвы сервером, который поддерживает аутентификацию по NTLM. Для разных сервисов есть свои тонкости, связанные с возможностью релея.
    • Spoofing, связанный с широковещательными запросами Windows: LLMNR, NetBios
    • Различные атаки на сами сервисы: MS17-010, поиск доступных на запись/чтение сетевых дисков, и так далее.

    Резюме

    Идеальный ответ содержал в себе:

    • Описание найденных файлов (включая котика)
    • Описание происходящих сетевых запросов в сети
    • Перечисление найденных исходных паролей пользователей с описанием, как они были получены и для чего дальше могут использоваться
    • Анализ используемых сервисов и ОС на предмет эксплуатации известных уязвимостей вроде eternalBlue
    • Возможность NTLM relay
    • Как работает NTLM relay для различных сервисов — в частности SMB
    • Описание возможных атак на широковещательные запросы
    • Любые сетевые атаки, которые могли иметь место (ARP-spoofing, подмена DNS и так далее) засчитывались




    №8. SSH Pivoting Tricks



    Вы находитесь в сети А (10.0.10.0/24), вы смогли получить доступ по SSH к Linux-хосту (10.0.20.5) в сети Б (10.0.20.0/24). Однако вы обнаружили, что у вас нет полного доступа к сети Б. Придумайте и подробно опишите способ, с помощью которого вы бы смогли просканировать сеть Б, не устанавливая никаких дополнительных скриптов/утилит/программ на Linux-хост.

    Разбор задания
    Итак, у нас есть ограничения, которые запрещают нам:
    лепить собственные скрипты
    nmap и подобные тулзяки вне правил

    Тогда что мне остаётся?

    Вариант:

    1) Команда ping.
    Реализация -> ping -b 10.0.20.255
    Метод ping не гарантирует, что будут найдены все системы, подключенные к локальной сети.
    Это связано с тем, что некоторые компьютеры могут быть настроены НЕ отвечать на широковещательные запросы или вообще пинговать запросы.
    Но на этом я не остановился и решил проверить данный приём.
    Итак, имеем три идентичные системы CentOS 7.
    Все три машины объединены в одну локальную сеть.


    (Единая локальная сеть)

    По отдельности машинки пингуются, но вот на мультикаст ни одна тачка так и не ответила. :(



    2) Посылаем широковещательный ARP-запрос в сеть.
    Реализация ->
    Для Debian — arp-scan --interface=/*имя интерфейса*/ 10.0.0.0/16
    В Linux в некоторых дистрибутивах есть утилита arp, а в некоторых (например Debian) почему-то такой утилиты нет, и вместо нее можно использовать arp-scan.
    arp-scan, насколько я знаю, отсутствует в принципе на всех дистрибутивах, кроме всяких кали линуксов.

    Комментарий эксперта KryaKrya:
    Данный вопрос был направлен на проверку того, как потенциальный стажер будет решать поставленную задачу в условиях некоторых ограничений, в частности, вопрос о знании простых техник Pivoting. На практике часто встречаются похожие ситуации, в которых есть доступ на хост, но есть ограничения, не позволяющие поднять привилегии или разложить любимые инструменты на сервере, однако есть необходимость попытаться атаковать хосты, расположенные в том же сетевом сегменте рядом с захваченным хостом.

    Итак, для первичной разведки вполне подходит использовать ping для обнаружения соседних хостов, посмотреть ARP-таблицу (arp -a), посмотреть доступные маршруты (route). Далее можно проверить, присутствует ли в системе netcat (nc -h), если есть, то можно пробовать сканировать порты (nc -vnz 10.0.20.3 0-1000). Также в условиях говорится, что нельзя устанавливать скрипты или программы, однако никто не мешает попробовать воспользоваться скриптовым языком, который, возможно, есть в системе, простейший сканер хостов-портов можно набросать и на bash, и на python без необходимости сохранять сами файлы скриптов.

    Но самое очевидное решение — это попробовать воспользоваться SSH-туннелированием, а именно SOCKS-прокси через SSH, и уже с атакующего хоста запускать весь свой арсенал утилит.
    ssh -D 1337 user@10.0.20.5 -f -N

    Однако здесь и закралась одна из самых частых ошибок в ответах стажеров. Многие предложили просто запустить nmap через SOCKS-прокси с помощью proxychains или указав прокси флагом.

    proxychains nmap 10.0.20.0/24
    nmap 10.0.20.0/24 --proxy socks4://10.0.20.5:1337

    Но в таком случае nmap не сможет просканировать целевую сеть именно из-за SOCKS-прокси. Проблема в невозможности совершить SYN-сканирование (которое nmap и запускает по умолчанию) через SOCKS-прокси, поскольку SOCKS-прокси должен установить полноценное TCP-соединение с целевым хостом, а SYN-сканирование как раз не устанавливает полноценное соединение, а просто посылает SYN, ожидая в ответ SYN ACK. В таком случае необходимо использовать CONNECT-сканирование (-sT), иначе nmap даже не будет пытаться использовать SOCKS-прокси.

    nmap -sT 10.0.20.0/24 --proxy socks4://10.0.20.5:1337

    Порадовало, что в ответах все-таки встречались люди, которые сталкивались с похожей ситуацией и решали ее правильно, что говорит об их опыте в этом направлении. Ответы, в которых было описано использование стандартных Linux-утилит, или использованием nmap без -sT тоже засчитывались, однако больше всего ценился ответ, в котором максимально подробно описано, какие инструменты и зачем нужно использовать, какие могут быть проблемы, связанные с их использованием, или приложены ли простейшие скрипты для сканирования портов.



    №9. Android SSL pinning bypass


    Вы исследуете мобильное приложение для Android. Вы обнаружили, что приложение отправляет запросы по защищенному протоколу HTTPS.

    1) Опишите, каким образом вы бы попробовали обойти защиту и получить незащищенный HTTP трафик.

    2) Что изменится, если в приложении будет включен SSL-pinning, как можно попытаться обойти защиту в этом случае?

    Разбор задания
    «Опишите, каким образом вы бы попробовали обойти защиту и получить незащищенный HTTP-трафик.»

    Добавление заранее созданного ЦС в хранилище доверенных сертификатов.
    После добавления сертификата в хранилище необходимо изменить proxy host в настройках wifi.

    В Android есть два встроенных хранилища сертификатов, которые отслеживают, какие из них одобрила операционная система.

    Первое — это системное хранилище (содержит предустановленные сертификаты) и второе — пользовательское хранилище (содержит сертификаты, установленные пользователем).
    Если приложение, к которому мы хотим применить MITM, работает на Android 6.0, то достаточно просто добавить свой ЦС, в в пользовательское ЦС хранилище.

    Если приложение работает на версиях позже 6.0, то сертификат из пользовательского хранилища не получит статус доверенного.

    «Что изменится, если в приложении будет включен SSL-pinning, как можно попытаться обойти защиту в этом случае?»

    Для начала, что такое вообще SSL-pinning.

    SSL-pinning — это защитная мера, которая заключается в том, что разработчик «зашивает» в приложение отпечаток эталонного доверенного сертификата.

    При соединении с сервером приложение сравнит отпечаток HTTPS-сертификата, полученного от сервера, с «зашитым». Если отпечатки будут соответствовать друг другу, то работа приложения происходит в штатном режиме.

    Если отпечатки различаются, то это свидетельствует о потенциальной MITM-атаке, и соединение будет разорвано.

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

    Самое простое — использование Frida.
    Frida — это так называемый Dinamic Instrumentation Toolkit, то есть набор инструментов, позволяющих на лету внедрять собственный код в другие приложения.
    Собственно, Frida позволяет на ходу изменять код приложения на Javascript.
    Конкретно в нашем случае с помощью Frida мы можем перехватить вызов функции, проверяющий цепочку сертификатов и, например, вернуть «True» вместо «False», тем самым обойдя соответствующие проверки.

    Есть два способа использования Frida:

    1. Запустить Фриду как отдельное независимое приложение, а затем внедрится в тестируемый процесс. Но это требует устройство с рут-привилегиями.

    2. Пересобрать тестируемое приложение с библиотекой Frida. В этом случае можно обойтись и без Root.

    Переписать сертификат приложения на свой сертификат.
    Открываем APK-шку как обычный архив и находим в нём хранилище с нашими сертификатами. Удаляем его, создаём своё хранилище с интересующими нас СА, и ставим его за место старого.
    В конце подписываем приложения сертификатом разработчика. Для этого удаляем из apk папку META-INF со старой подписью приложения.

    “Отревёрсить” APK-шку.
    Для этого нам нужно будет разархивировать APK и конвертировать smali обратно в Java, чтобы мы смогли найти код, отвечающий за управление проверкой сертификатов.
    Как только вы определите код, отвечающий за проверку сертификата, вы можете полностью его вырезать.


    Комментарий эксперта I:
    Действительно, первым шагом при попытке MITM HTTPS будет добавление нового корневого сертификата в хранилище.

    Еще один важный нюанс в том, что не все приложения используют системный Proxy из настроек WiFi. В этом случае поможет утилита ProxyDroid, которая на уровне iptables заворачивает трафик.

    Правда, тут уже не обойтись без Root привилегий, но у нас же собственный рутованный телефон для исследований, верно?

    Что касается обхода SSL-Pinning, то сложно найти способ, быстрее, чем “Frida+Objection”. Пожалуй, удобнее будет только запросить у разработчиков отладочную сборку без пиннинга :)



    №10. Какая ваша любимая атака?


    Расскажите про самую интересную вам технику атаки или опубликованную уязвимость, о которой вы узнали за последнее время.

    Единственное задание в “свободном формате”. Атака, которая мне приглянулась в последнее время, это dns-rebinding.

    На этом у меня всё. Спасибо за внимание!



    Заключительное слово от компании Digital Security

    Теперь немного приоткроем завесу, как же происходил сам процесс оценивания ребят.
    Каждый ответ независимо оценивали не менее 3 специалистов (надо же как-то развлекаться в свободное от аудитов время). Диапазон допустимых оценок был от 0 до 5 баллов с возможностью при желании ставить хоть 2.5, или даже 3.1337.

    В итоге оценки усредняются и суммируются. Таким образом, максимально можно было набрать 50 баллов. Наши специалисты старались быть максимально лояльными и понять, что же имел в виду очередной кандидат говорят о “взломе через код формы” или ещё что-нибудь в таком духе)

    Проходной балл мы устанавливаем уже после закрытия приема заявок. В этом году он составил 29 баллов, а лучший результат оказался 43.5. В итоге на стажировку к нам прошли примерно 24% от всех подавших заявку.

    Статистика выглядит следующим образом:



    Впрочем, и для этих счастливчиков всё так просто не кончилось, потому что далее их ждало очное собеседование, где мы расспрашивали ребят, что им понравилось в анкете, на какие вопросы было труднее всего ответить и сколько времени у них заняло заполнение. Таким образом мы убеждались, что ребятам никто не помогал с анкетой, и они заполняли её сами. Заодно мы получали полезную обратную связь для следующих лет.

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

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



    Со своей же стороны мы предоставляем множество разнообразных лекций (почти каждый день!), доступ к нашей маленькой, но гордой внутренней лаборатории с кучей интересных задач для взлома, составленных опытными специалистами, где можно оттачивать свои практические навыки и тренировать “хакерское чутье”.

    Главным же занятием в рамках стажировки является совместное исследование с опытным куратором какого-нибудь интересного и значимого аспекта безопасности, будь то уязвимости в новой технологии или инструмент, позволяющий решить существующие трудности при проведении анализа защищенности. Впрочем, больше об этом мы расскажем в наших материалах, посвященных окончанию Summer of Hack 2019.

    В качестве заключения хочется сказать, что мы второй год проводим отбор с использованием подобной системы и всё больше убеждаемся в её эффективности. С помощью неё нам действительно удается отобрать сильных стажёров и получить информацию о среднем уровне знаний среди студентов и выпускников.
    Digital Security
    Безопасность как искусство

    Similar posts

    Comments 8

      0
      Как соотносятся между собой флаги secure, httpOnly. Про secure понятно, что передается по защищенному соединению на сервер, а что насчет httpOnly, «доступны только через HTTP-протокол». Кому доступны? Передаются через HTTP на сервер или на клиент? И почему такой ограниченный выбор: или доступны скриптовым языкам, или доступны на сбор по пути между сервером и клиентом?
        +4
        Лучше сразу на примере покажу:
        Set-Cookie: SessionId="c4ca4238a0b923820dcc509a6f75849b"; Domain=account.test.com; Secure; HttpOnly


        Наличие флага HttpOnly — кука не будет доступна для браузерного Javascript. То есть через <script>document.cookie</script> её не извлечь. Полезно в контексте защиты от XSS.
        Наличие флага Secure — кука будет передаваться браузером только по https (если зайти на сайт по http, то браузер куку не подставит)

        А ограниченный выбор опций обусловлен браузерными спецификациями. Вот тут можно их поглядеть
          0
          Secure — передается по https.
          httpOnly — передается по http или как?
            +4
            httpOnly будет передаваться и по http и по https.
            Но через JS её не извлечь (типа no js, http only)

            Эти две опции могут сочетаться, следовательно комбинация Secure+HTTPOnly будет означать «куку передавать только по https, а для Javascript её сделать недоступной»

            P.S. Да, они непонятно называются, увы :(
        0
        Мне кажется или в конфиге nginx ошибка(https://pastebin.com/nYp7uVbB)?
        ```
        if ngx.header[«X-Managed»] ~= nil and ngx.header[«X-Managed»] ~= «secured») then
        ngx.exit(ngx.HTTP_FORBIDDEN)
        end
        ```

        Такое условие ожидает: хедер не равен nil и не равен 'secured'.
        Поправьте меня если ошибаюсь.
          0
          В конфиге много разных ошибок.
          Действительно, текущее условие НЕ пропустит запрос содержащий заголовок X-Managed с отличным от secured значением, при этом в случае отсутствия заголовка X-Managed запрос БУДЕТ пропущен.
          Таким образом смысл в подобной «защите» отсутствует т.к. злоумышленник получит доступ к защищаемой директории просто не выставив заголовок X-Managed. Отдельно стоит отметить, что использовать подобный «ключ» secured в качестве средства ограничения доступа не является лучшим решением с точки зрения безопасности, даже если бы она была корректно имплементирована.

          Пример корретной имплементации:
          if ngx.header[«X-Managed»] ~= «secured» then 
          ngx.exit(ngx.HTTP_FORBIDDEN) 
          end


          P.S. А ещё там ')' лишняя
          0
          Такой вопрос по пункту 9. Почему бы было не указать программу SSLUnpinning? Если у нас рутованный телефон, то скорее всего на нём стоит TWRP, через него накатываем Magisk и Xposed, через Xposed модуль SSLUnpinning. Тут анпиннинг обходится 1 кликом. Возможно, я что-то не знаю по поводу этого и так делать не надо.
            +1
            Вы правы, модуль «SSLUnpinning» делает примерно тоже самое, что и соответствующая команда у Objection.

            Но по личным ощущениям Objection как-то уверенее байпасит пининнг, обновляется чаще и кажется больше библиотек умеет «хукать».

            А уж если человек готов накатать скриптик для Фриды, то ему вообще море по колено будет х)

            Еще встречали случаи, когда программы детектили установленный XPosed и плохо себя вели из-за этого.

          Only users with full accounts can post comments. Log in, please.