From 4fe6feb1a1501853f3fa3448fd61b1884e08ed88 Mon Sep 17 00:00:00 2001 From: William Petit Date: Tue, 24 Dec 2019 12:54:32 +0100 Subject: [PATCH] Ajout d'un pipeline Lighthouse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + améliorations/corrections sur le pipeline d'audit W3AF --- .gitignore | 1 + Makefile | 47 +++++++- resources/com/cadoles/lighthouse/Dockerfile | 54 +++++++++ .../com/cadoles/lighthouse/config.js.tmpl | 4 + resources/com/cadoles/lighthouse/run-audit.sh | 17 +++ resources/com/cadoles/w3af/Dockerfile | 8 ++ resources/com/cadoles/w3af/audit.w3af.tmpl | 22 ++-- resources/com/cadoles/w3af/run-audit.sh | 6 + vars/audit.groovy | 3 +- vars/lighthouse.groovy | 113 ++++++++++++++++++ 10 files changed, 265 insertions(+), 10 deletions(-) create mode 100644 .gitignore create mode 100644 resources/com/cadoles/lighthouse/Dockerfile create mode 100644 resources/com/cadoles/lighthouse/config.js.tmpl create mode 100644 resources/com/cadoles/lighthouse/run-audit.sh create mode 100644 resources/com/cadoles/w3af/run-audit.sh create mode 100644 vars/lighthouse.groovy diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..249cda9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/data \ No newline at end of file diff --git a/Makefile b/Makefile index 9ec9013..db89b4f 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,7 @@ +DOCKER_ARGS ?= +W3AF_COMMAND ?= +LIGHTHOUSE_COMMAND ?= +LIGHTHOUSE_URL ?= image-w3af: docker build \ @@ -9,11 +13,50 @@ image-w3af: ./resources/com/cadoles/w3af interactive-w3af: + $(MAKE) W3AF_COMMAND="/bin/sh" w3af + +audit-w3af: + $(MAKE) W3AF_COMMAND="/usr/local/bin/run-audit" w3af + +w3af: docker run \ -it --rm \ --net host \ -v "$(PWD)/resources/com/cadoles/w3af/audit.w3af.tmpl:/home/w3af/w3af/audit.w3af.tmpl:ro" \ + $(DOCKER_ARGS) \ jenkins-w3af:latest \ - /bin/sh + $(W3AF_COMMAND) -.PHONY: image-w3af \ No newline at end of file +image-lighthouse: + docker build \ + --build-arg=HTTP_PROXY=$(HTTP_PROXY) \ + --build-arg=HTTPS_PROXY=$(HTTPS_PROXY) \ + --build-arg=http_proxy=$(http_proxy) \ + --build-arg=https_proxy=$(https_proxy) \ + -t jenkins-lighthouse \ + ./resources/com/cadoles/lighthouse + +interactive-lighthouse: + $(MAKE) LIGHTHOUSE_COMMAND="/bin/sh" lighthouse + +audit-lighthouse: + $(MAKE) LIGHTHOUSE_COMMAND="/usr/local/bin/run-audit" lighthouse + +lighthouse: + mkdir -p "$(PWD)/data/lighthouse/reports" + docker run \ + -it --rm \ + --net host \ + --cap-add=SYS_ADMIN \ + -e HTTP_PROXY=$(HTTP_PROXY) \ + -e HTTPS_PROXY=$(HTTPS_PROXY) \ + -e http_proxy=$(http_proxy) \ + -e https_proxy=$(https_proxy) \ + -e LIGHTHOUSE_URL=$(LIGHTHOUSE_URL) \ + -u $(shell id -u $(USER)):$(shell id -g $(USER)) \ + -v "$(PWD)/data/lighthouse/reports:/home/lighthouse/reports" \ + $(DOCKER_ARGS) \ + jenkins-lighthouse:latest \ + $(LIGHTHOUSE_COMMAND) + +.PHONY: image-w3af image-lighthouse \ No newline at end of file diff --git a/resources/com/cadoles/lighthouse/Dockerfile b/resources/com/cadoles/lighthouse/Dockerfile new file mode 100644 index 0000000..88202e0 --- /dev/null +++ b/resources/com/cadoles/lighthouse/Dockerfile @@ -0,0 +1,54 @@ +FROM golang:1.11.4 as envtpl + +ARG HTTP_PROXY= +ARG HTTPS_PROXY= +ARG http_proxy= +ARG https_proxy= + +RUN apt-get update -y && apt-get install -y git + +RUN git clone https://github.com/subfuzion/envtpl /src \ + && cd /src \ + && git checkout v1.0.0 \ + && CGO_ENABLED=0 GOOS=linux go build \ + -ldflags "-X main.AppVersionMetadata=$(date -u +%s)" \ + -a -installsuffix cgo -o ./bin/envtpl ./cmd/envtpl/. + +FROM alpine:3.10 + +ARG HTTP_PROXY= +ARG HTTPS_PROXY= +ARG http_proxy= +ARG https_proxy= + +COPY --from=envtpl /src/bin/envtpl /usr/local/bin/envtpl + +RUN apk add --no-cache \ + nss \ + freetype \ + freetype-dev \ + harfbuzz \ + ca-certificates \ + ttf-freefont \ + nodejs \ + npm \ + chromium + +RUN npm install -g lighthouse + +RUN adduser -D lighthouse + +COPY run-audit.sh /usr/local/bin/run-audit +RUN chmod +x /usr/local/bin/run-audit + +COPY config.js.tmpl /home/lighthouse/config.js.tmpl + +WORKDIR /home/lighthouse + +RUN mkdir /home/lighthouse/reports + +RUN chown -R lighthouse: /home/lighthouse + +USER lighthouse + +CMD /usr/local/bin/run-audit \ No newline at end of file diff --git a/resources/com/cadoles/lighthouse/config.js.tmpl b/resources/com/cadoles/lighthouse/config.js.tmpl new file mode 100644 index 0000000..5e49c41 --- /dev/null +++ b/resources/com/cadoles/lighthouse/config.js.tmpl @@ -0,0 +1,4 @@ +module.exports = { + extends: 'lighthouse:default', + settings: {}, +}; \ No newline at end of file diff --git a/resources/com/cadoles/lighthouse/run-audit.sh b/resources/com/cadoles/lighthouse/run-audit.sh new file mode 100644 index 0000000..e0526fd --- /dev/null +++ b/resources/com/cadoles/lighthouse/run-audit.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +envtpl -o config.js /home/lighthouse/config.js.tmpl + +mkdir -p reports +rm -f reports/* + +cd reports + +lighthouse \ + --no-enable-error-reporting \ + --chrome-flags="--headless --disable-dev-shm-usage --no-sandbox --disable-gpu" \ + --config=../config.js \ + --output json --output html \ + --output-path=lighthouse \ + -- \ + "$LIGHTHOUSE_URL" \ No newline at end of file diff --git a/resources/com/cadoles/w3af/Dockerfile b/resources/com/cadoles/w3af/Dockerfile index 134f1a0..798c8a1 100644 --- a/resources/com/cadoles/w3af/Dockerfile +++ b/resources/com/cadoles/w3af/Dockerfile @@ -94,9 +94,17 @@ RUN git clone --depth=1 \ && rm -rf /home/w3af/w3af/.git \ && chown -R w3af /home/w3af/w3af +COPY run-audit.sh /usr/local/bin/run-audit +RUN chmod +x /usr/local/bin/run-audit + USER w3af WORKDIR /home/w3af/w3af COPY audit.w3af.tmpl /home/w3af/w3af/audit.w3af.tmpl +ENV HTTP_PROXY= +ENV HTTPS_PROXY= +ENV http_proxy= +ENV https_proxy= + CMD ["./w3af_console"] \ No newline at end of file diff --git a/resources/com/cadoles/w3af/audit.w3af.tmpl b/resources/com/cadoles/w3af/audit.w3af.tmpl index 3fda4b2..40af5e1 100644 --- a/resources/com/cadoles/w3af/audit.w3af.tmpl +++ b/resources/com/cadoles/w3af/audit.w3af.tmpl @@ -4,7 +4,7 @@ # Configure HTTP settings http-settings -set timeout {{ default 10 .W3AF_TIMEOUT }} +set timeout {{ default 60 .W3AF_TIMEOUT }} {{ if .W3AF_BASIC_AUTH_USERNAME }} set basic_auth_user {{ .W3AF_BASIC_AUTH_USERNAME }} set basic_auth_passwd {{ .W3AF_BASIC_AUTH_PASSWORD }} @@ -41,15 +41,23 @@ back # Configure target authentication auth detailed auth config detailed -set username {{ .W3AF_AUTH_FORM_USERNAME }} -set password {{ .W3AF_AUTH_FORM_PASSWORD }} +set username '{{ .W3AF_AUTH_FORM_USERNAME }}' +set password '{{ .W3AF_AUTH_FORM_PASSWORD }}' set method POST set auth_url {{ .W3AF_AUTH_FORM_URL }} -set username_field {{ default "username" .W3AF_AUTH_FORM_USERNAME_FIELD }} -set password_field {{ default "password" .W3AF_AUTH_FORM_PASSWORD_FIELD }} -set data_format {{ default "username=%U&password=%P" .W3AF_AUTH_FORM_DATA_FORMAT }} +set username_field '{{ default "username" .W3AF_AUTH_FORM_USERNAME_FIELD }}' +set password_field '{{ default "password" .W3AF_AUTH_FORM_PASSWORD_FIELD }}' +set data_format '{{ default "%u=%U&%p=%P" .W3AF_AUTH_FORM_DATA_FORMAT }}' set check_url {{ .W3AF_AUTH_FORM_CHECK_URL }} -set check_string '{{- default "connected" .W3AF_AUTH_FORM_CHECK_STRING -}}' +set check_string '{{ default "connected" .W3AF_AUTH_FORM_CHECK_STRING }}' +set follow_redirects True +back +{{end}} + +{{ if .W3AF_AUTH_LOGOUT_URL_REGEX }} +crawl web_spider +crawl config web_spider +set ignore_regex {{ .W3AF_AUTH_LOGOUT_URL_REGEX }} back {{end}} diff --git a/resources/com/cadoles/w3af/run-audit.sh b/resources/com/cadoles/w3af/run-audit.sh new file mode 100644 index 0000000..f6ef56e --- /dev/null +++ b/resources/com/cadoles/w3af/run-audit.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +mkdir -p reports +rm -f reports/* +envtpl -o audit.w3af /home/w3af/w3af/audit.w3af.tmpl +/home/w3af/w3af/w3af_console -y -n -s audit.w3af \ No newline at end of file diff --git a/vars/audit.groovy b/vars/audit.groovy index 9af78b9..c1049e9 100644 --- a/vars/audit.groovy +++ b/vars/audit.groovy @@ -8,7 +8,7 @@ def call() { parameters { string( - name: 'targetUrl', + name: 'url', description: 'URL cible pour l\'audit' ) string( @@ -97,6 +97,7 @@ def call() { -e W3AF_AUTH_FORM_URL='${params.authFormUrl}' -e W3AF_AUTH_FORM_USERNAME='${params.authFormUsername}' -e W3AF_AUTH_FORM_PASSWORD='${params.authFormPassword}' + -e W3AF_AUTH_FORM_DATA_FORMAT='${params.authFormDataFormat}' -e W3AF_AUTH_FORM_CHECK_URL='${params.authFormCheckUrl}' -e W3AF_AUTH_FORM_CHECK_STRING='${params.authFormCheckString}' -e W3AF_AUTH_FORM_USERNAME_FIELD='${params.authFormUsernameField}' diff --git a/vars/lighthouse.groovy b/vars/lighthouse.groovy new file mode 100644 index 0000000..3f45020 --- /dev/null +++ b/vars/lighthouse.groovy @@ -0,0 +1,113 @@ +// Pipeline d'exécution d'un audit Lighthouse +def call() { + pipeline { + + agent { + label 'docker' + } + + parameters { + string( + name: 'url', + description: 'URL cible pour l\'audit' + ) + string( + name: 'auditTimeout', + description: "Délai maximum pour la réalisation de l'audit (en minutes)", + defaultValue: '60' + ) + } + + stages { + + stage("Check parameters") { + steps { + script { + if (!params.url?.trim()) { + error("L'URL cible n'est pas définie !") + } + } + } + } + + stage("Run Lighthouse audit") { + steps { + script { + def lighthouseImage = buildDockerImage() + def dockerArgs = """ + -e LIGHTHOUSE_URL='${params.url}' + """ + timeout(params.auditTimeout.toInteger()) { + lighthouseImage.inside(dockerArgs) { + sh 'run-audit' + } + } + } + } + } + } + + post { + always { + publishHTML target: [ + allowMissing: true, + alwaysLinkToLastBuild: false, + keepAll: true, + reportDir: 'reports', + reportFiles: 'lighthouse.report.html', + reportName: "Rapport Lighthouse" + ] + cleanWs() + } + success { + wrap([$class: 'BuildUser']) { + rocketSend ( + avatar: 'https://jenkins.cadol.es/static/b5f67753/images/headshot.png', + message: """ + L'audit Lighthouse pour `${params.url}` est terminé. + + [Voir le rapport](${env.BUILD_URL}Rapport_20Lighthouse/) + + @${env.BUILD_USER_ID ? env.BUILD_USER_ID : 'here'} + """.stripIndent(), + rawMessage: true + ) + } + } + failure { + rocketSend ( + avatar: 'https://jenkins.cadol.es/static/b5f67753/images/headshot.png', + message: """ + L'audit Lighthouse pour `${params.url}` a échoué: + + [Voir le job](${env.RUN_DISPLAY_URL}) + + @${env.BUILD_USER_ID ? env.BUILD_USER_ID : 'here'} + """.stripIndent(), + rawMessage: true + ) + } + } + + } +} + +def buildDockerImage() { + dir ('.lighthouse') { + def resourceFiles = [ + 'com/cadoles/lighthouse/Dockerfile', + 'com/cadoles/lighthouse/config.js.tmpl', + 'com/cadoles/lighthouse/run-audit.sh' + ]; + + for (res in resourceFiles) { + def fileContent = libraryResource res + def fileName = res.substring(res.lastIndexOf("/")+1) + writeFile file:fileName, text:fileContent + } + + def safeJobName = URLDecoder.decode(env.JOB_NAME).toLowerCase().replace('/', '-').replace(' ', '-') + def imageTag = "${safeJobName}-${env.BUILD_ID}" + return docker.build("lighthouse:${imageTag}", ".") + } +} \ No newline at end of file