ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   Веб-уязвимости (https://forum.antichat.xyz/forumdisplay.php?f=114)
-   -   Автоматизация безопасности API с OWASP ZAP: эффективный практический гайд (https://forum.antichat.xyz/showthread.php?t=574972)

zakrush 09.09.2020 14:41

Приветствую снова всех. Извиняюсь за долгое отсутствие, некоторые данную часть ждали больше всего. К сожалению не смог выпустить все оперативно в силу различных причин (в т.ч. и лени )
Итак, для тех, кто не знаком, советую ознакомиться с предыдущими вводными частями:
Автоматизация OWASP ZAP. Часть 1. Вводная часть
Автоматизация OWASP ZAP. Часть 2. Запуск в Docker, доступ к API

Итак в данной части постараюсь кратко пробежать по основным понятиям, структуре кода автоматизации, ну и по нескольким своим скриптам, на примере которых вы уже можете создавать что-то свое.

Определения

Сессия - это сессия в рамках которой происходит работа ZAP. Сессии можно создавать, загружать, сохранять. Сессия стартует по факту вместе с ZAP. Ей можно дать имя, и она будет сохраняться. Если открыть новую сессию с таким же именем как и предыдущая, то сессия пересоздастся.
Контекст - по факту выборка того, на что надо обратить внимание. Т.е. набор URL, того, что надо исключить, набор технологий (базы данных, языки программирования и т.д.). Тут же настройка аутентификации, авторизации, отслеживания сессий(для сканирования под Login пользователем) (это вообще отдельная статья может быть по премудростям аутентификации, если будет интересно, смогу в будущем описать или ответить в личке).
Паук и ajax-паук - ну тут стандартно, первый смотрит в ответах урлы и ходит по ним, с обозначенной глубиной. Второй предназначен для JavaScript, т.е. он запускает браузер и через браузер пытается выдернуть динамически формируемые урлы. (Для пауков как раз и важна авторизация и управление сессиями про которые я описал в контексте).
Активное сканирование - это как раз и есть нужный нам модуль. Тут ZAP береn накопленное все добро из прокси и пауков (из статей выше я писал, что я натравливаю end-to-end регрессионные тесты) и делает сканирование (т.е. вставляет пейлоады в различные параметры, в зависимости от настроек активного сканирования).

Код автоматизации и его структура

Итак с определениями закончили, если что, будем разбираться прямо по ходу описания скриптов.
Вот тут мой репозиторий, которым вы можете также пользоваться. Там же описаны какие версии питона неоходимы и какие имеются зависимости. Так же там есть докер файл, и описание, как все тесты запускать из докера.

Давайте рассмотрим структуру репки:

Код:


Код:

├── Dockerfile
├── Jenkinsfile

Тут в корне, как я писал ранее, находится Dockerfile(чтобы запускать скрипт из докера). И Jenkinsfile. Последний у нас используется дженкинсом, и описывает джобу которую он выполняет после прохождения end-to-end тестов. Т.е. по факту там написано, что надо скачать уже сбилженный докер из registry(развернут у нас же) и запустить его. Образ оказывается в registry в через Gitlab CI/CD и строится каждый раз когда изменения мержатся в мастер, но это уже лирическое отступление.

Далее перейдем к папке scripts где все и находится.

Код:


Код:

.
├── api_scan.py
├── configs
├── defectdojo
├── regression_scan.py
├── scan_core
└── slack

Здесь есть два файла. Это и есть основные скрипты описывающие действия ЗАП и других модулей. Их будем рассматривать выше.
slack- здесь описан класс для интеграции со слэк. Делает базовые вещи (шлет сообщения, отчеты, и может удалять отчеты и файлы) через модуль requests.
defectdojo - тут просто один файл который я взял вот отсюда (репозиторий defectDojo). В файле __init__ создал наследованный класс и определил для него нужные мне методы.
configs - тут хранятся различные переменные/настройки которые используются в скриптах.

scan_core тут основные функции обращений к API ZAP и описаны. Кратко пройдемся по папкам:

Код:


Код:

├── api_conf.py
├── colors.py
├── __init__.py
├── jobs
│  ├── __init__.py
│  ├── reports.py
│  ├── scans.py
│  └── spiders.py
├── setup
│  ├── auth.py
│  ├── init_context.py
│  ├── __init__.py
│  ├── init_spider.py
│  ├── policy.py
│  ├── proxy.py
│  └── session.py
└── shared_core.py

api_conf.py - тут конфиги различных АПИ. необходимо открыть и отредактировать своими значениями.
shared_core.py какие то общие функции.
Папка setup- тут находятся различные функции предназначенные для настройки ZAP.
job - тут функции которые выполняют различную работу (запускают пауков, активное сканирование, и строит отчеты и отправляет их. Тут же в reports описана интеграция с redmine).

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

Как упоминалось ранее, в папке scripts находятся 2 файла:

Код:


Код:

.
├── api_scan.py
└── regression_scan.py

api_scan.pyпредназначен для сканирования АПИ приложения. Т.е. он подгружает спецификацию и сканирует её. Тут есть недостаток у ЗАП, что он заполняет данные своими данными, поэтому для лучшего тестирования лучше взять у тестировщиков валидные данные и создать отдельный файл, а также запускать сканирование через zap-api-scan.py (который поставляется с ZAP в докере). Кому интересно, объясню позже, расписывать очень долго. Но для пробы пера, сойдет. Так же как доп. материал, советую ознакомиться со статьей авторов: OWASP ZAP
Обратите внимание, тут должны быть установлены доп. модули: Replacer и OpenAPI (В докере последнее имеется).

Краткие действия в файле:
1. Выключаются все ранее созданные реплэйсеры (они автоматически вставляют данные в запросы отправляемые ZAP, в моем случае это хедер с токеном авторизации или иные данные которые помешают получить токен авторизации). Создаем контекст и задаем ему настройки.
2.

Python:


Код:

token
=
requests
.
post
(
config
.
site
+
"auth"
,
json
=
config
.
log_pass
)
.
json
(
)
[
config
.
token_data
]
[
/
INDENT
]
# Load API from url
print
(
f'Remove replace rule{config.replacer_name}==>{zap.replacer.remove_rule(config.replacer_name)}'
)
print
(
f'Add replacer rule{config.replacer_name}==> '
+
zap
.
replacer
.
add_rule
(
description
=
config
.
replacer_name
,
enabled
=
True
,
matchtype
=
"REQ_HEADER"
,
matchstring
=
"Access-Token"
,
matchregex
=
False
,
replacement
=
token
)
)


Делаю Запрос и получаю токен. Удаляю реплэйсер (если был), и создаю новый с полученным токеном. В моем случае это Header вида Token: dsadasdasdsadsadsa4321dsa

3.

Python:


Код:

zap
.
openapi
.
import_url
(
url
=
config
.
site
+
config
.
spec_path
,
hostoverride
=
config
.
site
)

Импортируем описание АПИ. После этого в ZAP должно создастся дерево запросов.
4.Ниже настраиваем параметры активного сканирования (количество потоков, исключаемые из сканирования параметры и urls).
5. Старт сканирования. С обработкой ошибок и отправлением уведомлений в SLACK
6. Последними двумя строками, в случае если сканирование завершилось, создаем html отчет и отправляем его в слак.

regression_scan.py
Настройки сканирования в данном файле можно задавать флагами. Описание флагов можно получить через опцию --help.
По умолчанию скрипт делает активное сканирование (без паука) и и отсылает результаты в Slack и DefectDojo (менеджер уязвимостей).

Давайте быстренько пробежимся по скрипту:

Python:


Код:

if
args
.
new_session
:
[
/
INDENT
]
[
INDENT
=
2
]
set_session
.
new_session
(
)

Создает новую сессию. Это надо перед тем, как стартовать end-to-end тесты. Данный флаг не надо использовать с другими флагами. У нас это запускается Jenkins в prejob (на самом деле создаем новую сессию через curl).


Python:


Код:

context_id
=
context_init
.
set_contex_properties
(
contextname
=
conf
.
contextName
,
include_url
=
conf
.
contextIncludeURL
,
exclude_url
=
conf
.
contextExcludeURL
,
technology
=
conf
.
contextTechnology
)
# Remove "Default context" for exclude all scans not in scope.
context_init
.
remove_default_context
(
)
policy_name
=
import_scan_policy
(
policy_name
=
conf
.
ImportedPolicyName
)
print
(
f"{policy_name}was applied for ascan"
)


Создаем контекст с определенным листом технологий, и исключающими УРЛс. Удаляем дефолтный контекст (чтобы не интересующие нас сайты случайно не залетели в отчет).
Т.к. у меня тонкая настройка политики, то я ранее создал её в интерфейсе ZAP и положил в папку, которой делаю volume в Docker с ZAP. Тут я её подгружаю. Так же имеются методы, которые позволяют создать политику с собственным именем и выставить для всех пейлоадов определенные одинаковые параметры. (Все значения параметров определяются в конфигах в папке configs).

Далее не буду копировать код, но если указано, что надо запустить паука, то запускается паук и после его отработки аналогично скрипту и его описанию выше, настраиваются параметры активного сканирования.


Python:


Код:

# Start Ascan
try
:
print
(
f"Start ASCAN with Context{conf.contextName}and policy{policy_name}"
)
scans
.
start_ascan
(
context_name
=
conf
.
contextName
,
scan_policy
=
policy_name
)
except
ValueError
:
print
(
"Scan_id does not exist. Proxy is empty."
)
slack
.
post_message_to_slack
(
"ERROR! Proxy is empty!"
)
sys
.
exit
(
)
except
Exception
as
e
:
print
(
"Error:"
,
e
)
slack
.
post_message_to_slack
(
"Error: "
+
str
(
e
)
)
sys
.
exit
(
)

Тут стартует активное сканирование, и обрабатываются ошибки с их отправкой в Slack.

В следующем модуле генерируются и отправляются отчеты:

Python:


Код:

slack
.
upload_file
(
file
=
html_report
)

отправляем файл с отчетом в Slack.

Python:


Код:

add_redmine_issue_notes
(
type_of_scan
=
'Regression'
)

отправляем отчет в редмайн (предварительно создал отдельный проект)

Python:


Код:

xml_report
=
report_gen
(
type_file
=
'xml'
)
dd
=
DefectDojoTB
(
product_name
=
r_conf
.
dd_name_of_product
,
engagement_name
=
r_conf
.
dd_name_of_engagement
)
print
(
'Upload report to DefectDojo:'
,
dd
.
import_tb_scan
(
scan_type
=
r_conf
.
dd_scan_type
,
file
=
xml_report
,
scan_date
=
datetime
.
datetime
.
now
(
)
.
strftime
(
'%Y-%m-%d'
)
,
tags
=
r_conf
.
dd_scan_tag
)
)


Создаем объект класса DefectDojo и далее загружаем xml отчет в заранее созданный product и engagement.

Заключительное слово
Благодарю всех, кто осилил. По хорошему все это добро надо разбивать на несколько частей. + У ЗАП много еще потайных мест и вещей которые не сразу понятны. К сожалению, я не имею возможности/времени ими поделиться, если будет много вопросов возможно и составлю по ним описания. Зависит от активности и интереса комьюнити.
Так же возможно не все работает, т.к. мною не все функции были протестированы, особенно темное пятно в Пауке(т.к. у меня нет в нем необходимости на настоящий момент). А также не до конца понятен алгоритм Аякс паука. Точнее какой url ему скармливать, в моих приложениях он не очень активно что-то находит.

Так же у ЗАП есть механизмы внутреннего скриптования. Про них можно много рассказывать тоже, и некоторые вещи без скриптов в самом ZAP в современных приложениях к сожалению не реализуемы. Данной области я касался лишь слегка, но большинство вещей все-таки можно выполнить стандартными возможностями OWASP ZAP.


Время: 01:51