• XSS.stack #1 – первый литературный журнал от юзеров форума

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

grozdniyandy

White-Hat
Premium
Регистрация
11.08.2023
Сообщения
522
Реакции
677
Гарант сделки
2

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

Недавно столкнулся с интересным кейсом SSRF в котором пришлось фаззить. Фаззинг привёл меня к РЦЕшке. В этой статье я как раз написал о шагах которые мне пришлось выполнять, с примером функции в которой она может возникнуть. Всё максимально кратко, без воды, но с кофеином (Африкано).
  1. Паутина
    • Дневник белой шляпы [Часть 1]: не DDoS
    • Дневник белой шляпы [Часть 2]: Интервью [GraphQL]
    • Дневник белой шляпы [Часть 3]: Cтажировкa [File Inclusion (Remote / Local)]
    • Дневник белой шляпы [Часть 5]: Удачная догадка [RCE - Проверка простейших CVE, найденных в PHP-приложениях]
    • Дневник белой шляпы [Часть 6]: Сообщение [Websockets + Tool]
    • Дневник белой шляпы [Часть 7]: Ничего [JWT]
    • Дневник белой шляпы [Часть 9]: Сертификат [eWPT]
    • Дневник белой шляпы [Часть 10]: Когда уязвимостей нет / История с крестиком
  2. ОС
    • Дневник белой шляпы [Часть 4]: Знания [PrivEsc - Linux Capabilities] [Повышение привилегий - Возможности Linux]
  3. OSINT
    • Дневник белой шляпы [Часть 8]: Презентации [OSINT или Разведка ?]
  4. Exploit / AppSec
    • Дневник белой шляпы [Часть 11]: Пишем приват эксплоит CVE-2024-1512

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.pro/​

 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх