Содержание статьи

Се­год­ня раз­берем важ­ную веб‑уяз­вимость — server-side request forgery (SSRF). Она поз­воля­ет зло­умыш­ленни­ку зас­тавить сер­вер жер­твы обра­тить­ся к внут­ренне­му ресур­су, который недос­тупен сна­ружи. В резуль­тате хакер может получить кон­фиден­циаль­ные дан­ные или вов­се зах­ватить всю кор­поратив­ную сеть.

Я пос­тара­юсь объ­яснить все аспекты, которые обыч­но меша­ют успешно экс­плу­ати­ровать SSRF. Прой­дем от самых азов до прод­винутых тех­ник.

warning

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

 

Азы SSRF

Для прак­тики соберем прос­тое веб‑при­ложе­ние со скры­той админкой. Соз­дай тек­сто­вый файл docker-composer.yml с таким содер­жимым:

version: "3.9"
services:
public-web:
build: ./public-web
ports:
- "8090:80"
networks:
- ssrfnet
internal-admin:
build: ./internal-admin
networks:
- ssrfnet
expose:
- "80"
networks:
ssrfnet:
driver: bridge

Ма­шина public-web будет играть роль уяз­вимого веб‑при­ложе­ния. Машина internal-admin дос­тупна исклю­читель­но внут­ри сети Docker, то есть с хост‑машины или отку­да‑то еще невоз­можно до нее дос­тучать­ся.

Ря­дом с docker-composer.yml соз­дай пап­ки public-web и internal-admin. В internal-admin положи admin.html. Это скры­тая стра­ница, ими­тиру­ющая админку:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Ты нашел админку</h1>
<p>Это скрытый внутренний ресурс</p>
</body>
</html>

До­бавь Dockerfile:

FROM nginx:1.25-alpine
COPY admin.html /usr/share/nginx/html/admin.html

В пап­ке public-web добавь еще один Dockerfile, который под­нимет сер­вис на базе PHP:

FROM php:8.2-apache
COPY index.php /var/www/html/

Код уяз­вимого веб‑при­ложе­ния:

<?php
if (isset($_GET['download']) && isset($_GET['api_url'])) {
$url = $_GET['api_url'];
$data = @file_get_contents($url);
if ($data === false) {
http_response_code(500);
echo "Не удалось скачать данные: " . htmlspecialchars($url);
exit;
}
$filename = basename(parse_url($url, PHP_URL_PATH));
if (!$filename) {
$filename = "currencies.zml";
}
$tmpDir = sys_get_temp_dir();
$filePath = $tmpDir . "/" . $filename;
$zipPath = $tmpDir . "/export.zip";
file_put_contents($filePath, $data);
$zip = new ZipArchive();
$zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$zip->addFile($filePath, $filename);
$zip->close();
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename="export.zip"");
header("Content-Length: " . filesize($zipPath));
readfile($zipPath);
exit;
}
if (isset($_GET['api_url']) && !isset($_GET['download'])) {
$url = $_GET['api_url'];
$resp = @file_get_contents($url);
echo "<h3>Результат запроса:</h3><pre>" . htmlspecialchars($resp) . "</pre>";
echo "<hr><a href='/'>Назад</a>";
exit;
}
$ru = "https://www.cbr.ru/scripts/XML_daily.asp";
$en = "https://www.cbr-xml-daily.ru/daily_eng.xml";
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Демо SSRF</title>
</head>
<body>
<h2>Проверка курсов валют</h2>
<form method="GET">
<select name="api_url">
<option value="<?= $ru ?>">Русский (ЦБ РФ)</option>
<option value="<?= $en ?>">English API</option>
</select>
<button type="submit">Узнать курсы валют</button>
<button type="submit" name="download" value="1">Скачать курсы (ZIP)</button>
</form>
</body>
</html>
Нормальная работа уязвимого приложения
Нор­маль­ная работа уяз­вимого при­ложе­ния

При­ложе­ние получа­ет кур­сы валют с сай­та ЦБ. Оно уяз­вимо не толь­ко к SSRF, но и к LFI и RFI. Но мы скон­цен­три­руем­ся на SSRF. Ког­да поль­зователь выберет язык и наж­мет «Узнать кур­сы валют», выпол­нится GET-зап­рос. В парамет­рах api_url, который сооб­щает при­ложе­нию адрес, по которо­му мож­но получить дан­ные. Выпол­ни тес­товый зап­рос, что­бы убе­дить­ся, что дан­ные при­ходят.

info

О том, как работа­ет тех­ника LFI, читай в статье «File Inclusion и Path Traversal. Раз­бира­ем две базовые веб‑уяз­вимос­ти».

Ты видишь исходни­ки все­го про­екта. Но пред­ставь, что прос­то прос­матри­ваешь зап­росы к веб‑при­ложе­нию. На что ты обра­тишь вни­мание? Думаю, что на ука­зание URL в одной из перемен­ных. Это и есть прос­той спо­соб пред­положить, что сер­вер уяз­вим к SSRF.

Эксплуатация SSRF
Экс­плу­ата­ция SSRF

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии