Сегодня мы пройдем виртуальную машину CTF с Hack The Box. В контексте этой статьи аббревиатура CTF будет расшифровываться как Compressed Token Format, а не Capture the Flag, а сама машина похвастается уязвимым к разному типу LDAP-инъекций веб-приложением, использованием генератора одноразовых паролей stoken в качестве механизма аутентификации на сервере, а также небрежно написанным скриптом на Bash, с помощью которого мы обманем архиватор 7z и получим root.
HTB — CTF
HTB — CTF

CTF — просто идеальная машина для составления райтапа: ее решение прямолинейно, нет множества развилок на пути, которые ведут в никуда и мешают следить за повествованием. Так что мне не придется выкручиваться и придумывать, какими словами лучше описать свой ход мысли при ее прохождении, чтобы сохранялась интрига. В то же время эта виртуалка весьма сложна (уровень Insane — 7,9 балла из 10), что делает ее особенно привлекательной для взлома тестирования на проникновение.

На пути к победному флагу нам предстоит:

  • поиграть со stoken — программой для Linux, которая генерирует одноразовые пароли (токены RSA SecurID);
  • разобраться с разными типами инъекций LDAP (Blind, Second Order);
  • написать несколько скриптов на Python для брута каталога LDAP;
  • злоупотребить функциями архиватора 7z, в частности его опцией @listfiles, для чтения файлов с правами суперпользователя.
 

Разведка

 

Nmap

Новая машина — новое сканирование портов. «Ни дня без Nmap!» — вполне годится на девиз пентестера.

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

root@kali:~# nmap -n -v -Pn -oA nmap/initial 10.10.10.122
root@kali:~# cat nmap/initial.nmap
# Nmap 7.70 scan initiated Sun Jul 28 15:02:31 2019 as: nmap -n -v -Pn -oA nmap/initial 10.10.10.122
Nmap scan report for 10.10.10.122
Host is up (0.077s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http

Read data files from: /usr/bin/../share/nmap
# Nmap done at Sun Jul 28 15:02:41 2019 -- 1 IP address (1 host up) scanned in 10.17 seconds

К слову, опция -n даст Nmap понять, что мы не хотим, чтобы он пытался резолвить имя хоста в IP-адрес (так как мы уже указываем хост через его IP, а не через доменное имя), опция -v немного расширит получаемый от сканера фидбэк (степень детализации фидбэка можно наращивать, добавляя флаги -v вплоть до -vvv), а опция -Pn убедит Nmap в том, что нет необходимости проверять (с помощью ICMP-запроса), что хост «жив», перед началом самого сканирования, так как мы наверняка знаем, что машина сейчас в онлайне.

Также не забудь указать путь для сохранения отчетов сканирования во всех форматах через -oA на случай, если придется писать отчет об успешно проведенном тестировании на проникновение, ведь ты же на стороне благородных вайтхетов, я надеюсь?

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

root@kali:~# nmap -n -v -Pn -sV -sC -oA nmap/version 10.10.10.122 -p22,80
root@kali:~# cat nmap/version.nmap
# Nmap 7.70 scan initiated Sun Jul 28 15:34:37 2019 as: nmap -n -v -Pn -sV -sC -oA nmap/version -p22,80 10.10.10.122
Nmap scan report for 10.10.10.122
Host is up (0.073s latency).

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 fd:ad:f7:cb:dc:42:1e:43:7d:b3:d5:8b:ce:63:b9:0e (RSA)
| 256 3d:ef:34:5c:e5:17:5e:06:d7:a4:c8:86:ca:e2:df:fb (ECDSA)
|_ 256 4c:46:e2:16:8a:14:f6:f0:aa:39:6c:97:46:db:b4:40 (ED25519)
80/tcp open http Apache httpd 2.4.6 ((CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16)
| http-methods:
| Supported Methods: POST OPTIONS GET HEAD TRACE
|_ Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16
|_http-title: CTF

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jul 28 15:34:46 2019 -- 1 IP address (1 host up) scanned in 9.27 seconds

Итак, что же нам доступно.

  1. Демон веб-сервера Apache без зазрения совести «сливает» нам дистрибутив ОС — мы имеем дело с CentOS. При слове CentOS в голове сразу выстраивается ряд мыслей: это свободный дистрибутив Linux на основе Red Hat; платные версии программных продуктов документируются гораздо лучше, чем бесплатные; раз CentOS — это бесплатная версия RHEL, следовательно, зная версию платного дистра (которую мы найдем быстрее благодаря подробной документации), мы также будем знать и версию CentOS, с которой работаем в данный момент. С первой ссылки поисковика по запросу httpd versions red hat видим, что httpd 2.4.6 встроена в RHEL 7. Вот и ответ: перед нами CentOS 7.
  2. Открыто всего два порта: 22-й — SSH и 80-й — веб-сервер Apache. Очевидно, что начинать исследование будем с веба.
Узнаем версию ОС по баннеру Apache
Узнаем версию ОС по баннеру Apache
 

Веб — порт 80

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

 

Браузер

Перейдя по адресу http://10.10.10.122:80, ты увидишь объявление следующего характера.

Главная страница веб-сервера
Главная страница веб-сервера

Вот мой вольный перевод этого текста.

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

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

Данный сервер защищен от некоторых видов атак, например от атаки методом «грубой силы». Поэтому если ты попытаешься забрутфорсить некоторые из доступных сервисов, ты можешь быть забанен на пять минут.

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

Список забаненных IP-адресов можно найти [здесь]. У тебя может не получиться загрузить этот список, пока ты находишься в бане.

На http://10.10.10.122:80/login.php тебя как раз ожидает та форма авторизации, которую нельзя брутить, если верить объявлению с главной.

Форма авторизации login.php
Форма авторизации login.php

В исходниках этой страницы есть интересный комментарий, который немного проливает свет на детали используемой технологии аутентификации.

Фрагмент исходного кода login.php
Фрагмент исходного кода login.php
<!-- we'll change the schema in the next phase of the project (if and only if we will pass the VA/PT) -->
<!-- at the moment we have choosen an already existing attribute in order to store the token string (81 digits) -->

Во-первых, речь идет о каком-то «атрибуте», который содержит токен (об этом чуть позже). Во-вторых, тот самый токен, как заверяет нас комментарий в сорцах, представляет собой строку длиной 81 символ (цифры). Вопросив поисковик о том, какой бывает софт для генерации одноразовых паролей в Linux, я нашел stoken.

 

stoken

Итак, stoken генерирует одноразовые пароли, совместимые с маркерами RSA SecurID 128 бит (AES). Маркеры SecurID обычно используются для аутентификации конечных пользователей на защищенных сетевых ресурсах и VPN, поскольку OTP обеспечивают большую устойчивость ко многим атакам, связанным со статическими паролями.

Я поискал слово ctf в readme, и, когда оно нашлось, я понял, что точно на верном пути.

Фрагмент README.md к stoken
Фрагмент README.md к stoken

Следующим шагом я решил найти упоминание о той строке из 81 цифры, речь о которой идет в HTML-коде страницы с авторизацией. Это упоминание было найдено и на первой странице из результатов поиска по запросу stoken 81 digits. И страница эта оказалась мануалом к stoken.

Фрагмент man page для stoken
Фрагмент man page для stoken

Здесь плюс ко всему прочему мы впервые узнаем, что скрывается за аббревиатурой CTF: Compressed Token Format, а не Capture The Flag, как я и обещал.

 

Веб-форма авторизации

Вернувшись к форме логина и попробовав авторизоваться как admin:0000, я увидел такое сообщение об ошибке.

Пользователя не существует
Пользователя не существует

Следом я попробовал элементарную SQL-инъекцию, использовав в качестве имени пользователя строку ' or 1=1 -- -... и не получил вообще никакой реакции от веб-сайта. Это навело меня на мысль, что на бэкенде с высокой долей вероятности существует некий черный список, содержащий определенные символы, которые форма не желает видеть в принципе. Скорее всего, это некий список управляющих символов, которые используются в выражениях, возвращающих выборку из БД по пользовательскому запросу.

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

Продолжение доступно только участникам

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

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

Аватар

snovvcrash

Безопасник, временами питонщик, местами криптоана(рхист)литик, по необходимости системный администратор.

Check Also

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

Британские правоохранители сообщили об аресте 19-летнего подозреваемого, который якобы пох…

4 комментария

  1. Аватар

    howtoseek

    21.08.2019 at 15:09

    Хардкорный квест. Офигенная статья, все очень подробно и понятно, пиши еще что-то подобное.

    П.С. тут наверно идет речь про «скобки», а не «кавычки».

    Теперь нам предстоит определить количество кавычек, необходимое для того, чтобы измененный LDAP-запрос оказался «правильным». Начнем с одной и будем в конце добавлять нулевой символ для отбрасывания оставшейся части оригинального запроса. Потом попробуем две, затем — три.

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

  2. Аватар

    xakep.sub

    21.08.2019 at 16:36

    Эт прям взрыв мозга. Спасибо!

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