Приветствую на второй части статьи по OWASP ZAP. В данной статье мы рассмотрим запуск ZAP в DOCKER, а так же различные тонкие моменты его запуска, различные режимы работы и типы контейнеров.
С первой частью статью можно познакомиться тут: Автоматизация OWASP ZAP. Часть 1. Вводная часть
Почему Docker?
Тут все очевидно и просто. Докер образ нам позволяет изолировать среду, более быстро и оперативно решать проблемы, либо не решать их совсем, а просто откатываться к предыдущим версиям образов, или обнулять все конфигурации например. К тому же докер нам позволяет переносить все зависимости и всю среду AS IS(как есть) практически на любую операционную систему, а также позволяет постоянно обновляться и проводить тестирование на самых новых версиях OWASP ZAP.
Также докеризация приложений является современным мэйнстримом и некоторые CI/СD системы предпочитают работать именно с такими сервисами и приложениями. (например GitLAB c его билдером, в котором собираются приложения докер образы и доставляются на целевые хосты, а также проводятся различные тесты. Каждая система тестов должна быть запущена в своем Docker контейнере).
В общем закончим лирическое отступление, и перейдем ближе к теме. Про докер очень много везде материала, и советую с ним все таки познакомиться поближе, если вы этого еще не сделали.
У Docker есть только один пожалуй недостаток(оно так же является и преимуществом), он не сохраняет данные которые сам в себе сохраняет. Но с этой проблемой мы будем бороться ниже.
Docker образы OWASP ZAP
Тут пожалуй позволю себе переписать немного документации разработчиков. Ссылочку оставляю тут:
Итак, OWASP ZAP имеет 4 докер образа. Обо всех по порядку:
Заметка: В дальнейшем zap лучше еще установить на локальной машине, для большего быстродействия и быстрой отладки. Docker нужен на целевой хост машине, с целью исключения неприятных сюрпризов. В "идеале" настраиваться и писать скрипты сразу на хост системе, которая будет прокси сервером для браузеров с регрессионными тестами (см. мою статью часть 1), но честно признаюсь, не очень хватает нервов для этого. Поэтому лучше сделать следующее:
Замечание: здесь я предполагаю, что у пользователя установлены все пакеты docker и это все работоспособно. Для начала, как говорит нам документация, надо на хостовую систему скачать нужный нам image:
Проверить, что image скачался и есть в локальном хранилище можно так:
Замечание: Если у вас активно используется докер, смотрите за количестом образов хранимых на хосте. Может внезапно кончиться место. Для того, чтобы запускалась каждый раз новая версия образа, необходимо периодически удалять хранимый на хосте образ zap либо проверять обновления через команду docker pull указанную выше.
Удалять же образы можно следующим способом:
Кратко пробежимся по команде:
--rm - говорит о том, что контейнер будет удален, после его остановки.
-u zap -p 8080:8080 -p 8090:8090 - в контейнере будет сервис запускаться под пользователем zap, у контейнера необходимо "выбросить" порты 8080 и 8090 на хостовую систему.
--name owasp-zap -даем контейнеру имя, чтобы потом с ним было проще управляться и обращаться через присвоенное нами имя, а не через его ID или случайное имя.
-d owasp/zap2docker-stable zap-webswing.sh - запускаемся в тихом режиме (-d) указываем образ который запустить, и ENTRIPOINT. Т.е. какую команду выполнить.
В данном случае, мы запускаем ZAP в режиме webswing. Ну а теперь поподробнее разберем режимы ZAP.
ВАЖНОЕ ЗАМЕЧАНИЕ: все свои конфиги, сохраненные сессии и скрипты zap хранит в домашней дирректории, т.е.
WEBSWING
Тут мы будем работать максимально. Это самый идеальный режим для отладки. По сути это режим в котором можно управлять OWASP ZAP через полноценный GUI WEB интерфейс и в реальности смотреть, что на нем сейчас работатает, состояние сканирований и т.п.
Раз уж мы в нем запустились, давайте сразу настроимся для дальнейшей удобной работы.
Допустим, что контейнер у меня работает на серевере с IP 1.1.1.1.
Чтобы запустить ZAP и попасть в GUI надо перейти по ссылке:
Обратите внимание, что /zap обязательно, иначе вы попадете не куда надо, а на страницу логина:
После открытия, запуститься сессия ZAP.
Обратите внимание: прокси zap будет доступно по порту 8090 только после того, как вы запустите сессию, т.е. перейдете по ссылке указанной выше. Там же будет и сессия.
Итак, мы запустили сессию. Теперь давайте настроим некоторые параметры, чтобы достучаться до API ZAP. Изначально, приложение достаточно закрыто. Это надо исправить.
Идем: Tools -> Options. Выбираем раздел API. Настраиваем как на картинке.
Стоит понимать, что данные настройки только для тестовой среды. Желательно ограничить IP адресацию для которой доступна API. Я это делаю на iptables, поэтому тут разрешил все. Также можете указать свой АПИ ключ, либо выключить его, поставив галку внизу.
Также можете тут-же доставить различные Add-ons. Как это сделать, описано в документации, не буду акцентировать внимание:
А теперь, чтобы при каждом запуске, не изменять конфигурации давайте сохраним их на хосте. И далее сделаем так, чтобы все, что ZAP создал в ходе своей работы, мы с легкостью могли взять с хостовой системы, не боясь, что что-то удалится при очередном перезапуске контейнера. Для этого:
СОВЕТ: На начальном этапе, когда данные чистые, советую указанные папки сохранить в GIT. (в игнор можно поставить пару папок, а именно: sessions, reports). Сессии достаточно объемны (могут достигать нескольких Гб) и их сохранять не очень желательно в гите. Ну отчетам в гите тоже не место. В идеале эти папки мапить вообще не надо, а сразу запускать с нужными параметрами zap. В режиме zap.sh мы это сможем сделать. В webswing есть одно предположение как это сделать (будет озвучено ниже), но пока не пробывал. Так же вопрос возникает с добавлением Add-ons при запуске.
webswing.config
Ссылка на документацию настроек webswing оставлю здесь:
Итак. При тесте я словил баг. Что сессия у меня не хотела выходить, но при этом она не сбрасывалась и в общем в GUI я не мог попасть. Начал поиск решения проблемы. Решение заключается в данном файлике webswing.config. По факту после копирования данного файла из контейнера, советую поменять параметр:
Так же отмечу интересный параметр:
Подозреваю, что это как раз и есть обходной путь из совета раздела WEBSWING. Т.е. тут в параметре args необходимо дописать с какими флагами будет запускаться zap.sh. По факту надо скопировать и вставить флаги и их данные из раздела ниже, но повторюсь, мною не тестировалось, при желании можете протестировать и отписаться в теме.
ZAP.sh режим
На самом деле это основной режим, в котором планируется постоянная эксплуатация OWASP ZAP. Т.е. режим в котором работает OWASP ZAP как прокси и доступно API. В большинстве случаев этого достаточно. Здесь не буду много расписывать. Приведу только команду запуска, как это выглядит у меня:
Обратите внимание, тут я не маплю папки из раздела webswing. Предполагаем, что в пайплайне это лишнее. Если мапить папки, как в разделе WEBSWING, то команда чуть измениться на и оборвется на указании порта. Если не мапить, остается открытым вопрос, по поводу сохранения установленных Add-ons. Как их доставлять и устанавливать в случае необходимости.
Справка о параметрах команды:
Теперь нам надо бы проверить, а запустился ли zap, и все корректно и через него можно запускать регрессионные тесты. Так сказать, надо создать некий HOOK для запуска тестов. Приведу тут команду, которой это все можно проверить в bash через утилиту zap-cli. (в будущем будет модифицироваться в Python):
Тут все просто, пока Waiting то запускаться нельзя. Тут команда больше для справки, чтобы было видно, как можно проверить готовность ZAP к работе.
Примечание: при тестировании данного режима у меня возник вопрос, а создаются ли дефолтно сессии при запуске zap.sh? И надо ли их создавать через запросы к API? Ответ был найден. Сессии создаются. И ни что не препятствует не создавать сессию, а сразу создавать контекст (при необходимости). Об этом поговорим в дальнейших частях.
API и организация к нему доступа
Предположим что мы запустились в одном из указанном режиме выше. Будем предполагать, что это режим Webswing.
Мы перешли по ссылке:
Отлично. Теперь проверим работу прокси сервера:
Поставим в нашем любимом браузере proxy на 1.1.1.1 port 8090 (ведь именно там работает прокси в данном режиме судя по команде запуска докера).
и попробуем открыть различные нами любимые сайты. Необходимо убедиться в том, что в
Теперь нам надо попасть к API и получить его описание. Попробуем открыть:
Failed to read
Вот тут я потерял много времени. (т.к. эта ошибка может и не выводиться в принципе, а просто не открываться страница).
РЕШЕНИЕ: необходимо обращаться к api только по hostname . Т.е. по адресу
После этого у вас все должно заработать.
Также если вы развернули zap в docker на локальном компе, полезная команда, для получения IP zap контейнера выглядит так:
Далее необходимо прописать в /etc/hosts полученный адрес по схеме выше.
Для локальной установки ZAP все работает предсказуемо, и можно зайти через
ОСТАНОВКА и удаление контейнера. Иные полезные команды
После того как попользовались, чтобы не оставлять контейнер работающим, его можно остановить командой
Также посмотреть все запущенные и работающие контейнеры можно через
Посмотреть совсем все контейнеры( в т.ч. нештатно работающие или остановленные) можно через
Удаление контейнера:
Послесловие
При написании статьи я уже не все перепроверял писал по заметкам, поэтому может что-то не так заработать, не исключаю этого. Прошу простить так-же за опечатки. очень долгая получилась по написанию статья. Возможно даже не все еще описал и задел и где-то что-то упустил.
В следующей части поговорим об основных понятиях ZAP. Возможно уже рассмотрим скрипты API на питоне. Все будет зависеть от объема данных которые будут попадать в статью.
С первой частью статью можно познакомиться тут: Автоматизация OWASP ZAP. Часть 1. Вводная часть
Почему Docker?
Тут все очевидно и просто. Докер образ нам позволяет изолировать среду, более быстро и оперативно решать проблемы, либо не решать их совсем, а просто откатываться к предыдущим версиям образов, или обнулять все конфигурации например. К тому же докер нам позволяет переносить все зависимости и всю среду AS IS(как есть) практически на любую операционную систему, а также позволяет постоянно обновляться и проводить тестирование на самых новых версиях OWASP ZAP.
Также докеризация приложений является современным мэйнстримом и некоторые CI/СD системы предпочитают работать именно с такими сервисами и приложениями. (например GitLAB c его билдером, в котором собираются приложения докер образы и доставляются на целевые хосты, а также проводятся различные тесты. Каждая система тестов должна быть запущена в своем Docker контейнере).
В общем закончим лирическое отступление, и перейдем ближе к теме. Про докер очень много везде материала, и советую с ним все таки познакомиться поближе, если вы этого еще не сделали.
У Docker есть только один пожалуй недостаток(оно так же является и преимуществом), он не сохраняет данные которые сам в себе сохраняет. Но с этой проблемой мы будем бороться ниже.
Docker образы OWASP ZAP
Тут пожалуй позволю себе переписать немного документации разработчиков. Ссылочку оставляю тут:
Ссылка скрыта от гостей
Итак, OWASP ZAP имеет 4 докер образа. Обо всех по порядку:
- owasp/zap2docker-stable полный стабильный образ со всеми возможными пакетами (curl, nano и т.п.) и скриптами запуска ZAP. Примерный размер 1.4 GB
- owasp/zap2docker-weekly то же самое что и в п.1 только обычно правила более свежие + различные недельные доработки. Не столь стабилен как п.1. Может что-то вылезти в процессе эксплуатации.
- owasp/zap2docker-live ну это в принципе еше менее стабильный релиз. Что накодили разрабы, то и зарелизили сюда.
- owasp/zap2docker-bare это максимально обрезанный Docker image который как раз и предназначен для встраивания в CI/CD пайплайны, для быстрого разворачивания, переносимости и скачивания. В идеале надо пользоваться только им. Размер примерно 350 мб.
- нам нужна будет отладка (curl очень нужен будет например, которого нет в обрезанной версии из п.4).
- нам нужен будет один из режимов запуска zap, для удобной отладки и конфигурирования на первых шагах, а также просмотра того, что мы собственно наконфигурировали в скриптах и что происходит при сканировании. Да и происходит ли оно?
Заметка: В дальнейшем zap лучше еще установить на локальной машине, для большего быстродействия и быстрой отладки. Docker нужен на целевой хост машине, с целью исключения неприятных сюрпризов. В "идеале" настраиваться и писать скрипты сразу на хост системе, которая будет прокси сервером для браузеров с регрессионными тестами (см. мою статью часть 1), но честно признаюсь, не очень хватает нервов для этого. Поэтому лучше сделать следующее:
- Развернуть целевую систему и проверить её работоспособность. Опишу в данной статье.
- Установить OWASP ZAP локально, для тестирования скриптов. (можно и без этого пункта, решать вам, и устанавливать тоже).
Замечание: здесь я предполагаю, что у пользователя установлены все пакеты docker и это все работоспособно. Для начала, как говорит нам документация, надо на хостовую систему скачать нужный нам image:
Bash:
docker pull owasp/zap2docker-stable
Bash:
root@cs30975:~# docker images | grep zap
owasp/zap2docker-stable latest a05b3e5e1979 6 weeks ago 1.38GB
Удалять же образы можно следующим способом:
- Ищем нужный образ:
Bash:root@cs30975:~# docker images | grep zap owasp/zap2docker-stable latest a05b3e5e1979 6 weeks ago 1.38GB
- Удаляем образ по его уникальному номеру:
Bash:root@cs30975:~# docker rmi a05b3e5e1979
Bash:
docker run --rm -u zap -p 8080:8080 -p 8090:8090 --name owasp-zap -d owasp/zap2docker-stable zap-webswing.sh
--rm - говорит о том, что контейнер будет удален, после его остановки.
-u zap -p 8080:8080 -p 8090:8090 - в контейнере будет сервис запускаться под пользователем zap, у контейнера необходимо "выбросить" порты 8080 и 8090 на хостовую систему.
--name owasp-zap -даем контейнеру имя, чтобы потом с ним было проще управляться и обращаться через присвоенное нами имя, а не через его ID или случайное имя.
-d owasp/zap2docker-stable zap-webswing.sh - запускаемся в тихом режиме (-d) указываем образ который запустить, и ENTRIPOINT. Т.е. какую команду выполнить.
В данном случае, мы запускаем ZAP в режиме webswing. Ну а теперь поподробнее разберем режимы ZAP.
ВАЖНОЕ ЗАМЕЧАНИЕ: все свои конфиги, сохраненные сессии и скрипты zap хранит в домашней дирректории, т.е.
/home/zap/.ZAP/
WEBSWING
Тут мы будем работать максимально. Это самый идеальный режим для отладки. По сути это режим в котором можно управлять OWASP ZAP через полноценный GUI WEB интерфейс и в реальности смотреть, что на нем сейчас работатает, состояние сканирований и т.п.
Раз уж мы в нем запустились, давайте сразу настроимся для дальнейшей удобной работы.
Допустим, что контейнер у меня работает на серевере с IP 1.1.1.1.
Чтобы запустить ZAP и попасть в GUI надо перейти по ссылке:
Ссылка скрыта от гостей
- тут порт, который мы ранее выкидывали в запуске докер контейнера.Обратите внимание, что /zap обязательно, иначе вы попадете не куда надо, а на страницу логина:
После открытия, запуститься сессия ZAP.
Обратите внимание: прокси zap будет доступно по порту 8090 только после того, как вы запустите сессию, т.е. перейдете по ссылке указанной выше. Там же будет и сессия.
Итак, мы запустили сессию. Теперь давайте настроим некоторые параметры, чтобы достучаться до API ZAP. Изначально, приложение достаточно закрыто. Это надо исправить.
Идем: Tools -> Options. Выбираем раздел API. Настраиваем как на картинке.
Стоит понимать, что данные настройки только для тестовой среды. Желательно ограничить IP адресацию для которой доступна API. Я это делаю на iptables, поэтому тут разрешил все. Также можете указать свой АПИ ключ, либо выключить его, поставив галку внизу.
Также можете тут-же доставить различные Add-ons. Как это сделать, описано в документации, не буду акцентировать внимание:
Ссылка скрыта от гостей
А теперь, чтобы при каждом запуске, не изменять конфигурации давайте сохраним их на хосте. И далее сделаем так, чтобы все, что ZAP создал в ходе своей работы, мы с легкостью могли взять с хостовой системы, не боясь, что что-то удалится при очередном перезапуске контейнера. Для этого:
- копируем домашнюю папку и webswing.config с контейнера на хост. Допустим у меня все будет находиться в папке
/www/owasp_zap/
Bash:cd /www/owasp_zap/ docker cp owasp-zap:/zap/webswing/webswing.config ./webswing/webswing.configdocker cp owasp-zap:/home/zap/ ./zap/
- Далее мы увидим, что все файлы у нас буду под root. Для того, чтобы все заработало и пользователь в докере смог зацепить данные файлы. На полученные папки и файлы нам надо изменить владельца. Следующими командами, узнаем uid и guid необходимые и меняем владельца.
Bash:root@cs30975:/www/owasp_zap# docker exec owasp-zap id uid=1000(zap) gid=1000(zap) groups=1000(zap) root@cs30975:/www/owasp_zap# chown -R 1000:1000 ./zap && chown -R 1000:1000 ./webswing
- теперь мы можем грохнуть контейнер
docker stop owasp-zap
- И запустить его с сохраненными ранее данными.
Код:docker run --rm -v $(pwd)/zap:/home/zap -v $(pwd)/webswing/webswing.config:/zap/webswing/webswing.config -u zap -p 8080:8080 -p 8090:8090 --name owasp-zap -d owasp/zap2docker-stable zap-webswing.sh
СОВЕТ: На начальном этапе, когда данные чистые, советую указанные папки сохранить в GIT. (в игнор можно поставить пару папок, а именно: sessions, reports). Сессии достаточно объемны (могут достигать нескольких Гб) и их сохранять не очень желательно в гите. Ну отчетам в гите тоже не место. В идеале эти папки мапить вообще не надо, а сразу запускать с нужными параметрами zap. В режиме zap.sh мы это сможем сделать. В webswing есть одно предположение как это сделать (будет озвучено ниже), но пока не пробывал. Так же вопрос возникает с добавлением Add-ons при запуске.
webswing.config
Ссылка на документацию настроек webswing оставлю здесь:
Ссылка скрыта от гостей
Итак. При тесте я словил баг. Что сессия у меня не хотела выходить, но при этом она не сбрасывалась и в общем в GUI я не мог попасть. Начал поиск решения проблемы. Решение заключается в данном файлике webswing.config. По факту после копирования данного файла из контейнера, советую поменять параметр:
"maxClients" : 5
(по умолчанию, значение равно 1).Так же отмечу интересный параметр:
JSON:
"launcherConfig" : {
"args" : "-host 0.0.0.0 -port 8090",
ZAP.sh режим
На самом деле это основной режим, в котором планируется постоянная эксплуатация OWASP ZAP. Т.е. режим в котором работает OWASP ZAP как прокси и доступно API. В большинстве случаев этого достаточно. Здесь не буду много расписывать. Приведу только команду запуска, как это выглядит у меня:
Bash:
docker run --rm -u zap -p 8090:8090 --env ZAP_PORT=8090 --name owasp-zap -d owasp/zap2docker-stable zap.sh -daemon -host 0.0.0.0 -port 8090 -config api.key=123456789 -config api.addrs.addr.name=.* -config api.addrs.addr.regex=true
Справка о параметрах команды:
--env ZAP_PORT=8090
-(переписываю дефолтный порт, на котором запуститься прокси и АПИ, по дефолту это 8080)zap.sh -daemon -host 0.0.0.0 -port 8090 -config api.key=123456789 -config api.addrs.addr.name=.* -config api.addrs.addr.regex=true
- это команда запуска демона zap.sh с определенными параметрами.Теперь нам надо бы проверить, а запустился ли zap, и все корректно и через него можно запускать регрессионные тесты. Так сказать, надо создать некий HOOK для запуска тестов. Приведу тут команду, которой это все можно проверить в bash через утилиту zap-cli. (в будущем будет модифицироваться в Python):
Bash:
while docker exec owasp-zap zap-cli status | grep -q "ZAP is not running"; do sleep 1; echo "Waiting.."; done
Примечание: при тестировании данного режима у меня возник вопрос, а создаются ли дефолтно сессии при запуске zap.sh? И надо ли их создавать через запросы к API? Ответ был найден. Сессии создаются. И ни что не препятствует не создавать сессию, а сразу создавать контекст (при необходимости). Об этом поговорим в дальнейших частях.
API и организация к нему доступа
Предположим что мы запустились в одном из указанном режиме выше. Будем предполагать, что это режим Webswing.
Мы перешли по ссылке:
Ссылка скрыта от гостей
и запустили сессию.Отлично. Теперь проверим работу прокси сервера:
Поставим в нашем любимом браузере proxy на 1.1.1.1 port 8090 (ведь именно там работает прокси в данном режиме судя по команде запуска докера).
и попробуем открыть различные нами любимые сайты. Необходимо убедиться в том, что в
Ссылка скрыта от гостей
видно перехваченные запросы и ответы (левое окошко). По крайней мере должно так быть, после игнорирования ошибки сертификата.Теперь нам надо попасть к API и получить его описание. Попробуем открыть:
Ссылка скрыта от гостей
и увидим печальную надпись после долгого ожидания:Failed to read
Ссылка скрыта от гостей
within 20 seconds, check to see if the site is available and if so consider adjusting ZAP's read time out in the Connection options panel.Вот тут я потерял много времени. (т.к. эта ошибка может и не выводиться в принципе, а просто не открываться страница).
РЕШЕНИЕ: необходимо обращаться к api только по hostname . Т.е. по адресу
Ссылка скрыта от гостей
. Поэтому для машины, с которой будете осуществлять доступ к АПИ необходимо в /etc/hosts
прописать следующее:
Код:
1.1.1.1 zap
Также если вы развернули zap в docker на локальном компе, полезная команда, для получения IP zap контейнера выглядит так:
Bash:
docker inspect owasp-zap | grep IPAddr
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.4",
"IPAddress": "172.17.0.4",
Для локальной установки ZAP все работает предсказуемо, и можно зайти через
Ссылка скрыта от гостей
ОСТАНОВКА и удаление контейнера. Иные полезные команды
После того как попользовались, чтобы не оставлять контейнер работающим, его можно остановить командой
docker stop owasp-zap
. Т.к. мы указывали ранее флаг --rm то данный контейнер удалиться после остановки.Также посмотреть все запущенные и работающие контейнеры можно через
docker ps
Посмотреть совсем все контейнеры( в т.ч. нештатно работающие или остановленные) можно через
docker ps -a
Удаление контейнера:
docker rm owasp-zap
Послесловие
При написании статьи я уже не все перепроверял писал по заметкам, поэтому может что-то не так заработать, не исключаю этого. Прошу простить так-же за опечатки. очень долгая получилась по написанию статья. Возможно даже не все еще описал и задел и где-то что-то упустил.
В следующей части поговорим об основных понятиях ZAP. Возможно уже рассмотрим скрипты API на питоне. Все будет зависеть от объема данных которые будут попадать в статью.