D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
Тук тук! А вас там сколько?
Недавно столкнулся с интересным кейсом SSRF в котором пришлось фаззить. Фаззинг привёл меня к РЦЕшке. В этой статье я как раз написал о шагах которые мне пришлось выполнять, с примером функции в которой она может возникнуть. Всё максимально кратко, без воды, но с кофеином (Африкано).Спойлер: Ссылки на предыдущие части дневника
- Паутина
- Дневник белой шляпы [Часть 1]: не DDoS
- Дневник белой шляпы [Часть 2]: Интервью [GraphQL]
- Дневник белой шляпы [Часть 3]: Cтажировкa [File Inclusion (Remote / Local)]
- Дневник белой шляпы [Часть 5]: Удачная догадка [RCE - Проверка простейших CVE, найденных в PHP-приложениях]
- Дневник белой шляпы [Часть 6]: Сообщение [Websockets + Tool]
- Дневник белой шляпы [Часть 7]: Ничего [JWT]
- Дневник белой шляпы [Часть 9]: Сертификат [eWPT]
- Дневник белой шляпы [Часть 10]: Когда уязвимостей нет / История с крестиком
- ОС
- OSINT
- 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
Слепой 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
SuiteCRM
SuiteCRM — это CRM-система с открытым исходным кодом, предназначенная для предоставления организациям гибкой и настраиваемой платформы для управления взаимодействием с клиентами, продажами и другими бизнес-процессами.Функция getimagesize
getimagesize — это функция PHP, которая используется для получения размеров изображения. Эта функция отправляет запрос на указанный URL, чтобы проверить размеры изображения, что критично в контексте уязвимостей SSRF.Уязвимость в SuiteCRM
В SuiteCRM существует поток активности, который функционирует как блокнот или чат, где пользователи могут вводить заметки, отвечать и удалять их. Также у пользователей есть три опции: добавлять ссылки, изображения или видео с YouTube. Функции, используемые для добавления этих элементов, схожи.Изображение [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('<','>','"','''), (string) $link_url);
$feed->link_url = $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])));
}
Функция для добавления видео с 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];
}
}
Анализ уязвимости 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 секунд).
Изображение [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=
Изображение [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=