Дневник белой шляпы [Часть 12]: Тук тук! Анализ CVE-2024-5932 (SSRF)

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0

Тук тук! А вас там сколько?​

Недавно столкнулся с интересным кейсом SSRF в котором пришлось фаззить. Фаззинг привёл меня к РЦЕшке. В этой статье я как раз написал о шагах которые мне пришлось выполнять, с примером функции в которой она может возникнуть. Всё максимально кратко, без воды, но с кофеином (Африкано).
Спойлер: Ссылки на предыдущие части дневника
  1. Паутина
  2. ОС
  3. OSINT
  4. Exploit / AppSec

SSRF (Server-Side Request Forgery)​

SSRF (подделка серверных запросов) — это уязвимость веб-безопасности, которая позволяет хацкеру заставить серверное приложение отправлять запросы на несанкционированные ресурсы. SSRF можно разделить на два типа: обычный SSRF и слепой SSRF.

Обычный SSRF​

В обычном SSRF хацкер может видеть ответ сервера после выполнения подделанного запроса. Это позволяет ему напрямую получать обратную связь от своих действий, например, видеть содержимое внутренних веб-страниц или данные из внутренней сети.
Пример:
Предположим, веб-приложение позволяет пользователям вводить URL, чтобы извлечь и отобразить его содержимое. Сервер извлекает содержимое по указанному URL и возвращает его пользователю. Если приложение не проверяет URL, хацкер может ввести URL, указывающий на внутренний сервер (например, http://localhost/admin), чтобы получить доступ к конфиденциальной внутренней информации.
Код: Скопировать в буфер обмена
Код:
GET /fetch?url=http://localhost/admin HTTP/1.1
Host: example.com
Сервер извлекает содержимое с http://localhost/admin и отправляет его хацкеру, раскрывая конфиденциальные данные.

Слепой SSRF​

В слепом SSRF хацкер не видит ответа сервера после выполнения запроса. Сервер все равно выполняет запрос, но злоумышленник должен полагаться на косвенные методы наблюдения за эффектами своих действий, такие как различия во времени или побочные эффекты на других системах.
Пример:
Предположим, веб-приложение позволяет пользователям отправлять URL-адреса для обработки сервером, но результат не отображается пользователю. Злоумышленник может отправить запрос на внутренний IP-адрес и измерить время, за которое сервер ответит. Если запрос к существующему внутреннему сервису обрабатывается быстрее, чем к несуществующему, злоумышленник может сделать вывод о наличии определенных сервисов или открытых портов.
Код: Скопировать в буфер обмена
Код:
POST /submit-url HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

url=http://127.0.0.1:80
Хотя хацкер не видит содержимого ответа, он может заметить, что сервер отвечает быстрее, если порт 80 открыт, что указывает на наличие веб-сервера на 127.0.0.1.

SuiteCRM​

SuiteCRM — это CRM-система с открытым исходным кодом, предназначенная для предоставления организациям гибкой и настраиваемой платформы для управления взаимодействием с клиентами, продажами и другими бизнес-процессами.

Функция getimagesize​

getimagesize — это функция PHP, которая используется для получения размеров изображения. Эта функция отправляет запрос на указанный URL, чтобы проверить размеры изображения, что критично в контексте уязвимостей SSRF.

Уязвимость в SuiteCRM​

В SuiteCRM существует поток активности, который функционирует как блокнот или чат, где пользователи могут вводить заметки, отвечать и удалять их. Также у пользователей есть три опции: добавлять ссылки, изображения или видео с YouTube. Функции, используемые для добавления этих элементов, схожи.

1724184827788.png


Изображение [1]
Функция для добавления ссылок
Код: Скопировать в буфер обмена
Код:
public function getDisplay(&$data)
{
    return '<div style="padding-left:10px"><a href="' . $data['LINK_URL'] . '" target="_blank">' .$data['LINK_URL'] .'</a></div>';
}
public function handleInput($feed, $link_type, $link_url)
{
    $feed->link_type = $link_type;
    // Автоматически добавляет http:// перед link_url, если его нет
    if ($link_url[0] != '.' && $link_url[0] != '/') {
        if (strncmp($link_url, 'http://', 7) != 0 && strncmp($link_url, 'https://', 8) != 0) {
            $link_url = 'http://'.$link_url;
        }
    }
    // Предотвращение XSS-атак путем экранирования специальных символов
    $link_url = str_replace(array('<','>','"',"'"), array('&lt;','&gt;','&quot;','&apos;'), (string) $link_url);
    $feed->link_url = $link_url;
}
Эта функция обрабатывает введенный URL и присваивает его объекту $feed. Она обеспечивает наличие протокола (http:// или https://) в URL. Если URL не начинается с точки (.) или слэша (/), и не содержит протокола, перед ним добавляется http://. Затем она экранирует специальные символы (<, >, ", '), чтобы предотвратить возможные XSS-атаки, заменяя их на соответствующие HTML-entity. В конце функция сохраняет очищенный и, возможно, модифицированный URL в атрибуте $feed->link_url.
Функция для добавления изображений
Код: Скопировать в буфер обмена
Код:
public function handleInput($feed, $link_type, $link_url)
{
    parent::handleInput($feed, $link_type, $link_url);
    // Класс FeedLinkHandlerLink помогает обработать этот URL
    $link_url = $feed->link_url;
    $imageData = @getimagesize($link_url);
    if (!isset($imageData)) {
        // Изображение не было загружено, возможно, это ссылка и allow_url_fopen отключен
        $imageData[0] = 0;
        $imageData[1] = 0;
    } else {
        if (max($imageData[0], $imageData[1]) > 425) {
            // Если изображение большое, масштабируем его до 425 пикселей
            $scale = 425 / max($imageData[0], $imageData[1]);
            $imageData[0] = floor($imageData[0] * $scale);
            $imageData[1] = floor($imageData[1] * $scale);
        }
    }
    $feed->link_url = base64_encode(serialize(array('url' => $link_url, 'width' => $imageData[0], 'height' => $imageData[1])));
}
Эта функция расширяет базовый метод handleInput, вызывая parent::handleInput для наследования функциональности обработки URL. Затем она получает размеры изображения с помощью getimagesize(), что и является уязвимостью. Если изображение больше 425 пикселей в ширину или высоту, его размеры пропорционально уменьшаются. В конце функция кодирует и сериализует URL вместе с шириной и высотой изображения в строку base64 и сохраняет её в $feed->link_url.
Функция для добавления видео с YouTube
Код: Скопировать в буфер обмена
Код:
public function handleInput($feed, $link_type, $link_url)
{
    $match = array();
    preg_match('/v=([^\&]+)/', (string) $link_url, $match);
   
    if (!empty($match[1])) {
        $feed->link_type = $link_type;
        $feed->link_url = $match[1];
    }
}
Эта функция извлекает идентификатор видео из URL YouTube с помощью регулярного выражения (preg_match). Она ищет шаблон v=, который является общим для URL YouTube. Если URL содержит этот шаблон, функция сохраняет извлеченный идентификатор видео в $feed->link_url.
Анализ уязвимости SSRF
Уязвимость возникает только при добавлении изображений, так как в этом процессе отправляется запрос для получения размеров изображения с помощью getimagesize(). В некоторых случаях уязвимости SSRF могут быть использованы для выполнения удаленного кода (RCE), но в данном случае это похоже на слепой SSRF.

Прежде чем понять, до каких пределов мы можем эксплуатировать эту уязвимость, сначала нужно понять общие возможности, предоставляемые SSRF:
1. Сканирование портов: Обнаружение открытых портов во внутренних сетях.
2. Сканирование шлюзов: Определение шлюзов и маршрутизаторов. Запрос к закрытому порту на существующем хосте обычно возвращается быстрее, чем запрос к недоступному хосту.
- Диапазоны частных IP-адресов: 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8
3. Сканирование IP-адресов шлюзов: Если первые 10 IP-адресов активны, а следующие 10-20 не активны, скорее всего, только первые 10 — это активные устройства.
4. Сканирование портов на найденных IP-адресах: Определение, какие порты открыты на обнаруженных IP-адресах.
5. Сканирование каталогов: Особенно полезно для неизвестных портов. Если вы нашли конечную точку с неизвестными параметрами, попробуйте угадать параметры и использовать их.
6. Запросы к вашему серверу: Вы можете заставить целевой сервер отправлять запросы обратно на ваш сервер и анализировать заголовки, которые могут раскрыть информацию о используемом ПО.
7. Эксплуатация уязвимостей в программном обеспечении: Например, если сервер использует headless Chrome, вы можете создать веб-страницу с JavaScript-кодом, который заставляет сервер отправлять запросы на любую веб-страницу (например, fetch -> response.text -> data) и затем украсть данные (например, fetch -> "/callback?" + data).

В данном случае при отправке запроса на 127.0.0.1 время отклика составляет 1,2 секунды, что меньше типичного таймаута (10-60 секунд).

1724184528244.png


Изображение [2]​

Код: Скопировать в буфер обмена
Код:
POST /index.php HTTP/1.1

text=aaaaaaa&link_type=Image&link_url=http://127.0.0.1&to_pdf=1&module=Home&action=CallMethodDashlet&method=pushUserFeed&id=
Но если мы отправляем запрос на 192.168.0.1 (которого не существует в моем случае), то время отклика превышает одну минуту, что является типичным значением таймаута для многих серверов.

1724184557278.png


Изображение [3]​

Код: Скопировать в буфер обмена
Код:
POST /index.php HTTP/1.1

text=aaaaaaa&link_type=Image&link_url=http://192.168.0.1&to_pdf=1&module=Home&action=CallMethodDashlet&method=pushUserFeed&id=
Эти различия во времени ответа можно использовать для сканирования внутренних сетей и выявления активных узлов или служб. Например, если отправка запроса на внутренний IP-адрес занимает значительно меньше времени, чем ожидалось, это может свидетельствовать о наличии активного узла по данному адресу.

Conclusion​

Слепой SSR всего лишь одна из атак связанные с временем, советую почитать интересный ресёрч на эту тему: https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work

Автор grozdniyandy

Источник https://xss.is/

 
Сверху Снизу