Merge branch 'master' of https://github.com/radicallyopensecurity/pentext into development
# Conflicts: # .gitignore # xml/dtd/invoice.xsd # xml/source/quickscope.xml # xml/xslt/generate_invoice.xsl
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,4 +1,9 @@
|
||||
|
||||
xml/PenText.xpr
|
||||
# (Emacs) (temporary) files
|
||||
.#*
|
||||
\#*#
|
||||
.projectile
|
||||
# Compiled Python stuff
|
||||
*.pyc
|
||||
|
||||
.DS_Store
|
||||
|
||||
51
README.md
51
README.md
@@ -1,2 +1,49 @@
|
||||
# pentext
|
||||
PenText system
|
||||
# Pentext
|
||||
|
||||
The PenText XML documentation project is a collection of XML templates, XML schemas and XSLT code, which combined provide an easy way to generate IT security documents including test reports (for penetration tests, load tests, code audits, etc), offers (to companies requesting these tests) and invoices.
|
||||
|
||||
### How it Works
|
||||
The OWASP PenText project is based on XML. A PenText Report, Quote, Invoice or Generic Document is in fact a (modular) XML document, conforming to an XML Schema. The XML Schema ensures that the documents are structured correctly, so that they can then be transformed into other formats using XSLT and the SAXON XSLT processor. Currently there is only one target format: PDF. To produce the PDF document, the report, offer, invoice or generic document XML is first transformed into XSL-FO (XSL Formatting Objects), which is then converted to PDF using Apache FOP.
|
||||
|
||||
### The Structure
|
||||
The directories are used as follows:
|
||||
- chatops: contains bash and Python scripts that can be used with Hubot (chatOps), handy for automation while getting started or for checking document validity or spellchecking.
|
||||
- xml:
|
||||
- contains the PenText XML system and templates in directories *dtd*, *source* and *xslt*
|
||||
- your report or quote will go into *source*
|
||||
- contains a *graphics* map for your company logo
|
||||
- the *findings* and *non-findings* directories are for findings and non-findings
|
||||
|
||||
## Getting Started
|
||||
|
||||
What do you need ?
|
||||
|
||||
1. Clone this repository
|
||||
|
||||
2. Install the toolchain
|
||||
|
||||
3. Edit the content
|
||||
|
||||
Listo! That's all you need. Now you can build PDF reports using the content.
|
||||
|
||||
|
||||
### Toolchain
|
||||
To convert the XML content into PDF files the tools the *Apache FOP* library and the *Java* library *Saxon* will be used
|
||||
It is easiest to install the toolchain using Ansible: check out the role PeterMosmans.docbuilder (https://galaxy.ansible.com/PeterMosmans/docbuilder/)
|
||||
|
||||
To edit (and view) the content you'll need a XML editor - which could be any text editor like *JEdit*, to a full IDE- for editing of course ;). Preferably something that can check XML file validity. To view the resulting PDF files a PDF viewer is necessary.
|
||||
|
||||
### Building PDF's
|
||||
Manually compiling a quotation, report or other document can be done using `java -jar path-to-Saxon-jar -s:name-of-xml-file -xsl:name-of-xsl-file-in-xsl-directory -o:name-for-pdf-output`
|
||||
But why do it manually when the [ChatOps](https://github.com/radicallyopensecurity/pentext/tree/master/chatops) directory contains so much nice scripts to do just that ?
|
||||
|
||||
See for more detailed information the [tools manual](https://github.com/radicallyopensecurity/pentext/blob/master/xml/doc/Tools%20manual.md)
|
||||
|
||||
## Adding and Modifying Content
|
||||
### Guidelines
|
||||
- There is a guide for [report writing](xml/doc/report/Report%20Writing%20-%20Procedure.md)
|
||||
- There is also a guide for [quotation writing](xml/doc/offerte/Offerte%20Writing%20Procedure.md)
|
||||
|
||||
### Example documents
|
||||
Besides the reports and quotations, generic documents can also be created.
|
||||
Those can be found [here](xml/doc/examples)
|
||||
|
||||
123
chatops/README.md
Normal file
123
chatops/README.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# Introduction
|
||||
This directory contains the ChatOps scripts, based on Hubot. It uses RocketChat and gitlab as the underlying framework (but can be modified to fit any other framework).
|
||||
|
||||
This document describes the goal of the scripts, as well as installation instructions and their basic usage.
|
||||
|
||||
|
||||
## Workflow
|
||||
Scripts are ordered by workflow, not alphabetically.
|
||||
The workflow consists of
|
||||
1. setting up a repository for a quote with the PenText framework
|
||||
2. (optional: converting quickscope input to a quote)
|
||||
3. building a PDF quote
|
||||
4. setting up a repository for a pentest with the PenText framework, based on a quote
|
||||
5. (optional: converting gitlab issues to XML findings and non-findings)
|
||||
6. (optional: validating a PenText report)
|
||||
7. building a PDF report
|
||||
8. building a PDF invoice
|
||||
|
||||
## Naming
|
||||
The scripts either take the **project name** as input, or the **repository name** (and optional namespace and branch). The project name is leading, repository names are derived from the project names: the quotation repository has `off-` as prefix, and the pentest repository will have `pen-` as prefix.
|
||||
As a rule of thumb, the handlers that are prefixed with `start` (startquote, startpentest) will take the **project name** as input. All other handlers take the **repository name** as input.
|
||||
|
||||
Example: when the project's name is ros, then the corresponding quote repository and RocketChat channel's name will be `off-ros`.
|
||||
If this quote will result in a pentest project, then the corresponding repository and RocketChat channel will be named `pen-ros`.
|
||||
|
||||
Note that git repository names are _lowercase_.
|
||||
|
||||
|
||||
# Scripts
|
||||
|
||||
The scripts use multiple environment variables, that can be set by the user under which rosbot is running. These are
|
||||
+ `GITLABCLI` :: the location of the python-gitlab command line interface (defaults to `gitlab`)
|
||||
+ `GITSERVER` :: the name of the gitlab server (defaults to `gitlab.local`)
|
||||
+ `GITWEB` :: the URL of the gitlab webinterface (defaults to `https://$GITSERVER`)
|
||||
+ `NAMESPACE` :: the namespace of the user which is used to set up gitlab repositories (defaults to `ros`)
|
||||
+ `PENTEXTREPO` :: the location of the PenText repository (defaults to `https://github.com/radicallyopensecurity/pentext`)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The Bash scripts use the python-gitlab command-line interface to talk to the gitlab instance. This interface can be installed using `sudo pip install git+https://github.com/gpocentek/python-gitlab`. Obviously, Python needs to be installed as well.
|
||||
This command line interface expects a configuration file `.python-gitlab.cfg` for the user under which rosbot is running, which it uses to connect to gitlab. Make sure it contains the correct details so that you can connect to gitlab.
|
||||
|
||||
If you want to convert and build documents, the pentext toolchain is necessary. Use the ansible playbook https://galaxy.ansible.com/PeterMosmans/docbuilder/ or install the tools (Java, Saxon and Apache FOP) by hand, see https://github.com/radicallyopensecurity/pentext/blob/master/xml/doc/Tools%20manual.md for more information.
|
||||
|
||||
## Test the configuration
|
||||
Test out whether the configuration is successful by manually executing the Bash script [bash/test_pentext](bash/test_pentext) - this should return an OK.
|
||||
|
||||
|
||||
## CoffeeScript
|
||||
|
||||
### rosbot.coffee
|
||||
|
||||
[scripts/rosbot.coffee](scripts/rosbot.coffee) - contains the various keywords and redirects to the proper handlers. All RocketChat-specific actions (e.g. the creation of rooms) is being handled by this script.
|
||||
|
||||
The scripts contains an array of users that will be added to the newly created rooms by default.
|
||||
|
||||
Example:
|
||||
`admins = ['admin']`
|
||||
|
||||
## Bash
|
||||
|
||||
### startquote
|
||||
Start the quotation process by setting up a repository with the PenText framework, and creating a RocketChat channel.
|
||||
|
||||
Handled by [bash/handler_quote](bash/handler_quote)
|
||||
|
||||
Sets up a pentest RocketChat channel named `off-PROJECT_NAME`, a gitlab repo named `off-PROJECT_NAME`, and installs the latest version of the Pentext framework. Note that this uses the `PROJECT_NAME` as input, so it will automatically append the `off-` prefix.
|
||||
|
||||
Usage: `startquote PROJECT_NAME`
|
||||
|
||||
|
||||
### quickscope
|
||||
Converts a quickscope (`source/quickscope.xml`) into a full-blown XML quote.
|
||||
|
||||
Handled by [bash/handler_quickscope](bash/handler_quickscope)
|
||||
|
||||
|
||||
Usage: `quickscope REPO_NAME [NAMESPACE [BRANCH]]]`
|
||||
|
||||
|
||||
### build
|
||||
Builds PDF files from XML quotes and reports.
|
||||
|
||||
Handled by [bash/handler_build](bash/handler_build)
|
||||
|
||||
Usage: `build quote|report REPO_NAME [NAMESPACE [[BRANCH]] [-PARAMETERS]`
|
||||
|
||||
|
||||
### startpentest
|
||||
Start the pentesting process by setting up a repository with the PenText framework, adding standard gitlab labels and issues, and creating a RocketChat channel.
|
||||
|
||||
Handled by [bash/handler_pentest](bash/handler_pentest)
|
||||
|
||||
Sets up a pentest RocketChat channel named `pen-PROJECT_NAME`, and a gitlab repo named `pen-PROJECT_NAME`. Will use the quotation found in the corresponding `off-PROJECT_NAME` as base. Note that the prefix `pen-` is set by the `rosbot.coffee` script.
|
||||
|
||||
Usage: `startpentest PROJECT_NAME`
|
||||
|
||||
|
||||
### convert
|
||||
Converts gitlab issues labeled with `finding` and `non-finding` into XML files, and adds those to the repository
|
||||
Handled by [bash/handler_convert](bash/hander_convert)
|
||||
|
||||
Converts gitlab items to XML findings
|
||||
|
||||
Usage: `convert REPO_NAME`
|
||||
|
||||
|
||||
### validate
|
||||
Validates quotes and reports.
|
||||
Handled by [bash/handler_validate](bash/handler_validate)
|
||||
|
||||
Validates quotes and reports using the `validate_report.py` script (proper casing, spell checking, long lines, cross-checks)
|
||||
|
||||
Usage: `validate [OPTIONAL PARAMETERS]`
|
||||
|
||||
|
||||
### invoice
|
||||
Builds PDF invoices from quotes.
|
||||
|
||||
Handled by [bash/handler_invoice](bash/handler_invoice)
|
||||
|
||||
|
||||
Usage: `invoice REPO_NAME INVOICE_NO [NAMESPACE [[BRANCH]] [-PARAMETERS]`
|
||||
126
chatops/bash/handler_build
Normal file
126
chatops/bash/handler_build
Normal file
@@ -0,0 +1,126 @@
|
||||
#!/bin/bash
|
||||
|
||||
# handler_build - builds PDF quotes and reports from XML files
|
||||
#
|
||||
# This script is part of the PenText framework
|
||||
# https://pentext.org
|
||||
#
|
||||
# Copyright (C) 2016 Radically Open Security
|
||||
# https://www.radicallyopensecurity.com
|
||||
#
|
||||
# Author(s): Peter Mosmans
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
VERSION=0.11
|
||||
DOCBUILDER=/usr/local/bin/docbuilder.py
|
||||
TEMPLOC=$(mktemp -d)
|
||||
|
||||
# These variables should be set environment-specific
|
||||
[ -z $GITSERVER ] && GITSERVER=gitlab.local
|
||||
[ -z $GITWEB ] && GITWEB=https://${GITSERVER}
|
||||
[ -z $NAMESPACE ] && NAMESPACE=ros
|
||||
BRANCH=master
|
||||
|
||||
# Read standard 'command line' variables
|
||||
[[ ! -z $1 ]] && TARGET=$1
|
||||
[[ ! -z $2 ]] && REPO=$2
|
||||
|
||||
# Reading positional parms is a bit ugly, shifting parms or getopt would be nicer
|
||||
if [[ ! -z $3 ]]; then
|
||||
if [[ ! $3 == -* ]]; then
|
||||
NAMESPACE=$3
|
||||
else
|
||||
PARMS=$3
|
||||
fi
|
||||
fi
|
||||
if [[ ! -z $4 ]]; then
|
||||
if [[ ! $3 == -* ]]; then
|
||||
BRANCH=$4
|
||||
else
|
||||
PARMS="$PARMS $4"
|
||||
fi
|
||||
fi
|
||||
if [[ $# -ge 5 ]]; then
|
||||
shift 4
|
||||
PARMS="$PARMS $@"
|
||||
fi
|
||||
|
||||
trap cleanup EXIT QUIT
|
||||
|
||||
# Make sure that the temporary files are always removed
|
||||
cleanup() {
|
||||
trap '' EXIT INT QUIT
|
||||
[ -d $TEMPLOC ] && rm -rf $TEMPLOC &>/dev/null
|
||||
exit
|
||||
}
|
||||
|
||||
# As quote used to be called offer or even offer,
|
||||
# this function retains backward compatibility - v0.1
|
||||
backwards_compatible() {
|
||||
if [[ $TARGET == "quote" ]] && [ ! -f $TARGET.xml ]; then
|
||||
TARGET="offerte"
|
||||
fi
|
||||
}
|
||||
|
||||
# Clones repo using global (!) variables - v0.2
|
||||
clone_repo() {
|
||||
pushd $TEMPLOC 1>/dev/null
|
||||
git clone -b $BRANCH --depth=1 -q ssh://git@${GITSERVER}/${NAMESPACE}/${REPO}.git &>/dev/null
|
||||
if [ ! -d $TEMPLOC/$REPO ]; then
|
||||
echo "[-] could not clone repo ${NAMESPACE}/${REPO}"
|
||||
exit 1
|
||||
else
|
||||
cd $REPO
|
||||
fi
|
||||
}
|
||||
|
||||
# Preflight checks using global (!) variables - v0.2
|
||||
preflight_checks() {
|
||||
if ([[ $TARGET != "quote" ]] && [[ $TARGET != "report" ]]) || [ -z $REPO ]; then
|
||||
echo "Usage: build quote|report REPOSITORY [NAMESPACE [BRANCH] [-v]"
|
||||
exit
|
||||
fi
|
||||
if [ ! -f $DOCBUILDER ]; then
|
||||
echo "[-] this script needs docbuilder.py ($DOCBUILDER)"
|
||||
fi
|
||||
}
|
||||
|
||||
build() {
|
||||
if [ ! -d source ]; then
|
||||
echo "[-] missing necessary pentext framework files"
|
||||
exit 1
|
||||
fi
|
||||
pushd source &>/dev/null
|
||||
backwards_compatible
|
||||
targetpdf=target/$TARGET-latest.pdf
|
||||
$DOCBUILDER -c -i $TARGET.xml -o ../$targetpdf -x ../xslt/generate_$TARGET.xsl $PARMS
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "[-] Sorry, failed to parse $TARGET. Use \`builder $TARGET $REPO $NAMESPACE $BRANCH -v\` for more information."
|
||||
exit 1
|
||||
fi
|
||||
popd &>/dev/null
|
||||
if [ ! -f $targetpdf ]; then
|
||||
echo "[-] hmmm... failed to build PDF file (could not find $targetpdf)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
add_to_repo() {
|
||||
git add target/$TARGET-latest.pdf
|
||||
git add target/waiver_?*.pdf &>/dev/null
|
||||
git commit -q -m "$targetpdf proudly manufactured using ChatOps" &>/dev/null
|
||||
git push -q >/dev/null
|
||||
}
|
||||
|
||||
preflight_checks
|
||||
echo "builder v$VERSION - Rocking your world, one build at a time..."
|
||||
clone_repo
|
||||
build
|
||||
add_to_repo
|
||||
echo "[+] listo! Check out $GITWEB/$NAMESPACE/$REPO/raw/$BRANCH/$targetpdf"
|
||||
exit 0
|
||||
131
chatops/bash/handler_convert
Normal file
131
chatops/bash/handler_convert
Normal file
@@ -0,0 +1,131 @@
|
||||
#!/bin/bash
|
||||
|
||||
# handler_convert - converts gitlab issues into XML files
|
||||
#
|
||||
# This script is part of the PenText framework
|
||||
# https://pentext.org
|
||||
#
|
||||
# Copyright (C) 2016 Radically Open Security
|
||||
# https://www.radicallyopensecurity.com
|
||||
#
|
||||
# Author(s): Peter Mosmans
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
VERSION=0.2
|
||||
CONVERTER=/usr/local/bin/gitlab-to-pentext.py
|
||||
TEMPLOC=$(mktemp -d)
|
||||
|
||||
# These variables should be set environment-specific
|
||||
[ -z $GITLABCLI ] && GITLABCLI=gitlab
|
||||
[ -z $GITSERVER ] && GITSERVER=gitlab.local
|
||||
[ -z $NAMESPACE ] && NAMESPACE=ros
|
||||
BRANCH=master
|
||||
|
||||
# Read standard 'command line' variables
|
||||
[[ ! -z $1 ]] && REPO=$1
|
||||
# Reading parms is a bit ugly, shifting parms or actually using getopt would be nicer
|
||||
if [[ ! -z $2 ]]; then
|
||||
if [[ ! $2 == -* ]]; then
|
||||
NAMESPACE=$2
|
||||
else
|
||||
PARMS=$2
|
||||
fi
|
||||
fi
|
||||
if [[ ! -z $3 ]]; then
|
||||
if [[ ! $3 == -* ]]; then
|
||||
BRANCH=$3
|
||||
else
|
||||
PARMS="$PARMS $3"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $# -ge 4 ]]; then
|
||||
shift 3
|
||||
PARMS="$PARMS $@"
|
||||
fi
|
||||
|
||||
trap cleanup EXIT QUIT
|
||||
|
||||
# Make sure that the temporary files are always removed
|
||||
cleanup() {
|
||||
trap '' EXIT INT QUIT
|
||||
[ -d $TEMPLOC ] && rm -rf $TEMPLOC &>/dev/null
|
||||
exit
|
||||
}
|
||||
|
||||
# As quote used to be called offerte or offer,
|
||||
# this function retains backward compatibility - v0.2
|
||||
backwards_compatible() {
|
||||
if [[ $TARGET == "quote" ]] && [ ! -f $TARGET.xml ]; then
|
||||
TARGET="offerte"
|
||||
fi
|
||||
}
|
||||
|
||||
# Clones repo using global (!) variables - v0.2
|
||||
clone_repo() {
|
||||
pushd $TEMPLOC 1>/dev/null
|
||||
git clone -b $BRANCH --depth=1 -q ssh://git@${GITSERVER}/${NAMESPACE}/${REPO}.git &>/dev/null
|
||||
if [ ! -d $TEMPLOC/$REPO ]; then
|
||||
echo "[-] could not clone repo ${NAMESPACE}/${REPO}"
|
||||
exit 1
|
||||
else
|
||||
cd $REPO
|
||||
fi
|
||||
}
|
||||
|
||||
# Preflight checks using global (!) variables - v0.2
|
||||
preflight_checks() {
|
||||
if [ -z $REPO ]; then
|
||||
echo "[-] repository name needed"
|
||||
exit
|
||||
fi
|
||||
if [ ! -f $CONVERTER ]; then
|
||||
echo "[-] this script needs gitlab-to-pentext.py ($CONVERTER)"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
get_id() {
|
||||
project_id=$($GITLABCLI project search --query $REPO|awk '/id:/{print $2}')
|
||||
if [ -z $project_id ]; then
|
||||
echo "[-] could not find $REPO in gitlab"
|
||||
exit
|
||||
fi
|
||||
return $project_id
|
||||
}
|
||||
|
||||
convert() {
|
||||
$CONVERTER --issues $project_id -y
|
||||
}
|
||||
|
||||
add_to_repo() {
|
||||
git add * &>/dev/null
|
||||
git commit -q -m "Converted gitlab (non) findings to XML using ChatOps" &>/dev/null
|
||||
git push -q >/dev/null
|
||||
}
|
||||
|
||||
validate() {
|
||||
if [ ! -d source ]; then
|
||||
echo "[-] missing necessary pentext framework files"
|
||||
exit 1
|
||||
fi
|
||||
$VALIDATOR $PARMS
|
||||
if [[ -f project-vocabulary.pws ]]; then
|
||||
git add project-vocabulary.pws
|
||||
git commit -q -m 'Added spellcheck vocabulary using ChatOps' >/dev/null
|
||||
git push -q >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
preflight_checks
|
||||
echo "convert v$VERSION - Convert all the things!"
|
||||
get_id
|
||||
clone_repo
|
||||
convert
|
||||
add_to_repo
|
||||
echo "[+] Listo!"
|
||||
126
chatops/bash/handler_invoice
Normal file
126
chatops/bash/handler_invoice
Normal file
@@ -0,0 +1,126 @@
|
||||
#!/bin/bash
|
||||
|
||||
# handler_invoice - builds PDF invoices from quotes
|
||||
#
|
||||
# This script is part of the PenText framework
|
||||
# https://pentext.org
|
||||
#
|
||||
# Copyright (C) 2016 Radically Open Security
|
||||
# https://www.radicallyopensecurity.com
|
||||
#
|
||||
# Author(s): Peter Mosmans
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
VERSION=0.5
|
||||
DOCBUILDER=/usr/local/bin/docbuilder.py
|
||||
TEMPLOC=$(mktemp -d)
|
||||
DATESTAMP=$(date +"%Y-%m-%d")
|
||||
INVOICE="00/000"
|
||||
|
||||
# These variables should be set environment-specific
|
||||
[ -z $GITSERVER ] && GITSERVER=gitlab.local
|
||||
[ -z $GITWEB ] && GITWEB=https://${GITSERVER}
|
||||
[ -z $NAMESPACE ] && NAMESPACE=ros
|
||||
BRANCH=master
|
||||
TARGET=quote
|
||||
|
||||
# Read standard 'command line' variables
|
||||
[[ ! -z $1 ]] && REPO=$1
|
||||
[[ ! -z $2 ]] && INVOICE=$2
|
||||
|
||||
# Reading positional parms is a bit ugly, shifting parms or getopt would be nicer
|
||||
if [[ ! -z $3 ]]; then
|
||||
if [[ ! $3 == -* ]]; then
|
||||
NAMESPACE=$3
|
||||
else
|
||||
PARMS=$3
|
||||
fi
|
||||
fi
|
||||
if [[ ! -z $4 ]]; then
|
||||
if [[ ! $3 == -* ]]; then
|
||||
BRANCH=$4
|
||||
else
|
||||
PARMS="$PARMS $4"
|
||||
fi
|
||||
fi
|
||||
if [[ $# -ge 5 ]]; then
|
||||
shift 4
|
||||
PARMS="$PARMS $@"
|
||||
fi
|
||||
trap cleanup EXIT QUIT
|
||||
|
||||
# Make sure that the temporary files are always removed
|
||||
cleanup() {
|
||||
trap '' EXIT INT QUIT
|
||||
[ -d $TEMPLOC ] && rm -rf $TEMPLOC &>/dev/null
|
||||
exit
|
||||
}
|
||||
|
||||
# As quote used to be called offerte or offer,
|
||||
# this function retains backward compatibility - v0.2
|
||||
backwards_compatible() {
|
||||
if [[ $TARGET == "quote" ]] && [ ! -f $TARGET.xml ]; then
|
||||
TARGET="offerte"
|
||||
fi
|
||||
}
|
||||
|
||||
# Clones repo using global (!) variables - v0.2
|
||||
clone_repo() {
|
||||
pushd $TEMPLOC 1>/dev/null
|
||||
git clone -b $BRANCH --depth=1 -q ssh://git@${GITSERVER}/${NAMESPACE}/${REPO}.git &>/dev/null
|
||||
if [ ! -d $TEMPLOC/$REPO ]; then
|
||||
echo "[-] could not clone repo ${NAMESPACE}/${REPO}"
|
||||
exit 1
|
||||
else
|
||||
cd $REPO
|
||||
fi
|
||||
}
|
||||
|
||||
# Preflight checks using global (!) variables - v0.2
|
||||
preflight_checks() {
|
||||
if [ -z $REPO ]; then
|
||||
echo "Usage: invoice REPOSITORY [INVOICE_NUMBER [NAMESPACE [BRANCH]]] [-v]"
|
||||
exit
|
||||
fi
|
||||
if [ ! -f $DOCBUILDER ]; then
|
||||
echo "[-] this script needs docbuilder.py ($DOCBUILDER)"
|
||||
fi
|
||||
}
|
||||
|
||||
build() {
|
||||
if [ ! -d source ]; then
|
||||
echo "[-] missing necessary pentext framework files"
|
||||
exit 1
|
||||
fi
|
||||
pushd source &>/dev/null
|
||||
backwards_compatible
|
||||
targetpdf=target/invoice-latest.pdf
|
||||
$DOCBUILDER -c -i $TARGET.xml -o ../$targetpdf -x ../xslt/generate_invoice.xsl -invoice "$INVOICE" -date $DATESTAMP --fop ../target/invoice.fo $PARMS
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "[-] Sorry, failed to generate $targetpdf"
|
||||
exit 1
|
||||
fi
|
||||
popd &>/dev/null
|
||||
if [ ! -f target/invoice-latest.pdf ]; then
|
||||
echo "[-] hmmm... failed to build PDF file (could not find $targetpdf)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
add_to_repo() {
|
||||
git add target/invoice-latest.pdf
|
||||
git commit -q -m "Invoice $INVOICE automatically generated using ChatOps" &>/dev/null
|
||||
git push -q >/dev/null
|
||||
}
|
||||
|
||||
preflight_checks
|
||||
echo "invoice v$VERSION - Congrats, another project from conception to ka-CHING"
|
||||
clone_repo
|
||||
build
|
||||
add_to_repo
|
||||
echo "[+] listo! Check out $GITWEB/$NAMESPACE/$REPO/raw/$BRANCH/$targetpdf"
|
||||
163
chatops/bash/handler_pentest
Normal file
163
chatops/bash/handler_pentest
Normal file
@@ -0,0 +1,163 @@
|
||||
#!/bin/bash
|
||||
|
||||
# handler_pentest - sets up a pentest repo with PenText based on a quote repo
|
||||
#
|
||||
# This script is part of the PenText framework
|
||||
# https://pentext.org
|
||||
#
|
||||
# Copyright (C) 2016 Radically Open Security
|
||||
# https://www.radicallyopensecurity.com
|
||||
#
|
||||
# Author(s): Peter Mosmans
|
||||
# John Sinteur
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
VERSION=0.9
|
||||
SAXON=/usr/local/bin/saxon/saxon9he.jar
|
||||
TEMPLATEREPO=ssh://git@gitlab.local/peter/templates
|
||||
|
||||
# These variables should be set environment-specific
|
||||
[ -z $GITLABCLI ] && GITLABCLI=gitlab
|
||||
[ -z $GITSERVER ] && GITSERVER=gitlab.local
|
||||
[ -z $NAMESPACE ] && NAMESPACE=ros
|
||||
[ -z $NAMESPACEID ] && NAMESPACEID=1
|
||||
[ -z $PENTEXTREPO ] && PENTEXTREPO=https://github.com/radicallyopensecurity/pentext
|
||||
|
||||
TEMPLOC=$(mktemp -d)
|
||||
pentext=$(echo $PENTEXTREPO|awk -F '/' '{print $5}')
|
||||
# Read standard 'command line' variables
|
||||
[[ ! -z $1 ]] && REPO=$1
|
||||
[[ ! -z $2 ]] && NAMESPACE=$2
|
||||
[[ ! -z $3 ]] && PREVIOUS=$3
|
||||
BRANCH=master
|
||||
TARGET=quote
|
||||
|
||||
trap cleanup EXIT QUIT
|
||||
|
||||
# Make sure that the temporary files are always removed
|
||||
cleanup() {
|
||||
trap '' EXIT INT QUIT
|
||||
# remove repo if not finished successfully
|
||||
if [ -z $finished ] && [ ! -z $project_id ]; then
|
||||
$GITLABCLI project delete --id $project_id
|
||||
echo "[-] deleted project $project_id"
|
||||
fi
|
||||
[ -d $TEMPLOC ] && rm -rf $TEMPLOC &>/dev/null
|
||||
exit
|
||||
}
|
||||
|
||||
# As quote used to be called offerte or offer,
|
||||
# this function retains backward compatibility - v0.2
|
||||
backwards_compatible() {
|
||||
if [[ $TARGET == "quote" ]] && [ ! -f $TARGET.xml ]; then
|
||||
TARGET="offerte"
|
||||
fi
|
||||
}
|
||||
|
||||
# Clones repo using global (!) variables - v0.3
|
||||
clone_repo() {
|
||||
pushd $TEMPLOC 1>/dev/null
|
||||
git clone --depth=1 -q ssh://git@${GITSERVER}/${NAMESPACE}/${REPO}.git &>/dev/null
|
||||
if [ ! -d $TEMPLOC/$REPO ]; then
|
||||
echo "[-] could not clone repo ${NAMESPACE}/${REPO}"
|
||||
exit 1
|
||||
else
|
||||
cd $REPO
|
||||
fi
|
||||
}
|
||||
|
||||
# Preflight checks using global (!) variables
|
||||
preflight_checks() {
|
||||
if [ -z $REPO ]; then
|
||||
echo "[-] repository name needed (without leading pen- or off-)"
|
||||
exit
|
||||
fi
|
||||
if [ ! -f $SAXON ]; then
|
||||
echo "[-] this script needs saxon ($SAXON)"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_repo() {
|
||||
project_id=$($GITLABCLI project create --name $REPO --namespace $NAMESPACEID --issues-enabled true --wiki-enabled true --snippets-enabled true --wall-enabled true --merge-requests-enabled true 2>/dev/null| awk '/id:/{print $2}')
|
||||
if [ ! -z $project_id ]; then
|
||||
echo "[+] successfully created gitlab project $REPO with id ${project_id}"
|
||||
$GITLABCLI project-label create --project-id ${project_id} --name documentation --color "#0000FF" &>/dev/null
|
||||
$GITLABCLI project-label create --project-id ${project_id} --name finding --color "#00c800" &>/dev/null
|
||||
$GITLABCLI project-label create --project-id ${project_id} --name lead --color "#e4d700" &>/dev/null
|
||||
$GITLABCLI project-label create --project-id ${project_id} --name non-finding --color "#c80000" &>/dev/null
|
||||
$GITLABCLI project-label create --project-id ${project_id} --name future-work --color "#f8b7b2" &>/dev/null
|
||||
$GITLABCLI project-issue create --project-id ${project_id} --description "Please drop all your positive/negative comments here, so that we can keep on improving our processes. It is important that we learn from <b>what</b>. No need for namecalling, <b>who</b> is unimportant <br /> <h2>Thumbs up</h2> <h2>Improvement</h2><h2>Not project related</h2><h2>Project related</h2>" --title "Retrospective: add your feedback HERE" &> /dev/null
|
||||
else
|
||||
echo "[-] could not create repo $NAMESPACE/$REPO"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Add standard templates using global (!) variables - v0.2
|
||||
add_templates() {
|
||||
[ -d $TEMPLOC/$pentext ] && rm -rf $TEMPLOC/$pentext &>/dev/null
|
||||
pushd $TEMPLOC 1>/dev/null && git clone --depth=1 $PENTEXTREPO &>/dev/null && popd 1>/dev/null
|
||||
|
||||
if [ ! -d $TEMPLOC/$pentext ]; then
|
||||
echo "[-] could not clone (and therefore add) pentext repo $TEMPLATEREPO"
|
||||
exit 1
|
||||
else
|
||||
clone_repo
|
||||
# copy the framework
|
||||
cp -r $TEMPLOC/$pentext/xml/* .
|
||||
# remove the docs
|
||||
rm -r doc &>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
grab_offer() {
|
||||
pushd source &>/dev/null
|
||||
backwards_compatible
|
||||
if [ ! -f $TARGET.xml ]; then
|
||||
echo "[-] could not find $TARGET.xml"
|
||||
exit
|
||||
fi
|
||||
cp client_info.xml $TEMPLOC/client_info.xml &> /dev/null
|
||||
cp $TARGET.xml $TEMPLOC/quote.xml &> /dev/null
|
||||
}
|
||||
|
||||
convert_report() {
|
||||
cp $TEMPLOC/quote.xml source/quote.xml &> /dev/null
|
||||
cp $TEMPLOC/client_info.xml source/client_info.xml &> /dev/null
|
||||
pushd source &>/dev/null
|
||||
java -jar $SAXON -s:quote.xml -xsl:../xslt/off2rep.xsl -o:report.xml
|
||||
if [ ! -f report.xml ]; then
|
||||
echo "[-] hmmm... failed to convert quote into report.xml"
|
||||
exit 1
|
||||
fi
|
||||
popd &>/dev/null
|
||||
mkdir -p findings/ &>/dev/null
|
||||
mkdir -p non-findings/ &>/dev/null
|
||||
}
|
||||
|
||||
add_to_repo() {
|
||||
git add * &>/dev/null
|
||||
git commit -q -m "Initialized pentest repository with PenText using ChatOps" &> /dev/null
|
||||
git push -q > /dev/null
|
||||
}
|
||||
|
||||
preflight_checks
|
||||
echo "startpentest v${VERSION} - Ready for some ACTION?"
|
||||
ORIGREPO=$REPO
|
||||
REPO=off-$ORIGREPO
|
||||
[[ ! -z $PREVIOUS ]] && $REPO=$PREVIOUS
|
||||
clone_repo
|
||||
grab_offer
|
||||
REPO=pen-${ORIGREPO}
|
||||
setup_repo
|
||||
add_templates
|
||||
convert_report
|
||||
add_to_repo
|
||||
|
||||
echo "[+] listo!"
|
||||
finished=true
|
||||
90
chatops/bash/handler_quickscope
Normal file
90
chatops/bash/handler_quickscope
Normal file
@@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
|
||||
# handler_quickscope - converts a quickscope into a quotation
|
||||
#
|
||||
# This script is part of the PenText framework
|
||||
# https://pentext.org
|
||||
#
|
||||
# Copyright (C) 2016 Radically Open Security
|
||||
# https://www.radicallyopensecurity.com
|
||||
#
|
||||
# Author(s): Peter Mosmans
|
||||
# John Sinteur
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
VERSION=0.3
|
||||
SAXON=/usr/local/bin/saxon/saxon9he.jar
|
||||
TEMPLOC=$(mktemp -d)
|
||||
|
||||
|
||||
# These variables should be set environment-specific
|
||||
[ -z $GITSERVER ] && GITSERVER=gitlab.local
|
||||
[ -z $NAMESPACE ] && NAMESPACE=ros
|
||||
|
||||
# Read standard 'command line' variables
|
||||
[[ ! -z $1 ]] && REPO=$1
|
||||
[[ ! -z $2 ]] && NAMESPACE=$2
|
||||
[[ ! -z $3 ]] && BRANCH=$3 || BRANCH=master
|
||||
|
||||
trap cleanup EXIT QUIT
|
||||
|
||||
# Make sure that the temporary files are always removed
|
||||
cleanup() {
|
||||
trap '' EXIT INT QUIT
|
||||
[ -d $TEMPLOC ] && rm -rf $TEMPLOC &>/dev/null
|
||||
exit
|
||||
}
|
||||
|
||||
# Clones repo using global (!) variables - v0.2
|
||||
clone_repo() {
|
||||
pushd $TEMPLOC 1>/dev/null
|
||||
git clone --depth=1 -q ssh://git@${GITSERVER}/${NAMESPACE}/${REPO}.git &>/dev/null
|
||||
if [ ! -d $TEMPLOC/$REPO ]; then
|
||||
echo "[-] could not clone repo ${NAMESPACE}/${REPO}"
|
||||
exit 1
|
||||
else
|
||||
cd $REPO
|
||||
fi
|
||||
}
|
||||
|
||||
# Preflight checks using global (!) variables
|
||||
preflight_checks() {
|
||||
if [ -z $REPO ]; then
|
||||
echo "Usage: quickscope REPOSITORY [NAMESPACE]"
|
||||
exit
|
||||
fi
|
||||
if [ ! -f $SAXON ]; then
|
||||
echo "[-] this script needs saxon ($SAXON)"
|
||||
fi
|
||||
}
|
||||
|
||||
convert_quickscope() {
|
||||
if [ ! -f $TEMPLOC/$REPO/source/quickscope.xml ] || [ ! -f $TEMPLOC/$REPO/xslt/qs2offerte.xsl ]; then
|
||||
echo "[-] missing necessary pentext framework files"
|
||||
exit 1
|
||||
fi
|
||||
java -jar $SAXON -s:$TEMPLOC/$REPO/source/quickscope.xml -xsl:$TEMPLOC/$REPO/xslt/qs2offerte.xsl -o:$TEMPLOC/$REPO/source/offerte.xml
|
||||
if [ ! -f $TEMPLOC/$REPO/source/offerte.xml ]; then
|
||||
echo "[-] failed to parse quote"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
add_to_repo() {
|
||||
git add source/offerte.xml &>/dev/null
|
||||
git commit -q -m "Created quickscope using ChatOps" &>/dev/null
|
||||
git push -q >/dev/null
|
||||
}
|
||||
|
||||
preflight_checks
|
||||
echo "quickscope v${VERSION} - Rockin' and scoping'..."
|
||||
clone_repo
|
||||
convert_quickscope
|
||||
add_to_repo
|
||||
echo "[+] listo!"
|
||||
exit 0
|
||||
113
chatops/bash/handler_quote
Normal file
113
chatops/bash/handler_quote
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/bin/bash
|
||||
|
||||
# handler_quote - sets up a quote gitlab repository using PenText
|
||||
#
|
||||
# This script is part of the PenText framework
|
||||
# https://pentext.org
|
||||
#
|
||||
# Copyright (C) 2016 Radically Open Security
|
||||
# https://www.radicallyopensecurity.com
|
||||
#
|
||||
# Author(s): Peter Mosmans
|
||||
# John Sinteur
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
VERSION=0.7
|
||||
|
||||
# These variables should be set environment-specific
|
||||
[ -z $GITLABCLI ] && GITLABCLI=gitlab
|
||||
[ -z $GITSERVER ] && GITSERVER=gitlab.local
|
||||
[ -z $NAMESPACE ] && NAMESPACE=ros
|
||||
[ -z $NAMESPACEID ] && NAMESPACEID=1
|
||||
[ -z $PENTEXTREPO ] && PENTEXTREPO=https://github.com/radicallyopensecurity/pentext
|
||||
PREFIX="off-"
|
||||
pentext=$(echo $PENTEXTREPO|awk -F '/' '{print $5}')
|
||||
TEMPLOC=$(mktemp -d)
|
||||
|
||||
# Read standard 'command line' variables
|
||||
[[ ! -z $1 ]] && REPO=$PREFIX$1
|
||||
REPO=${REPO,,} # follow git specs: lowercase
|
||||
[[ ! -z $2 ]] && NAMESPACE=$2
|
||||
|
||||
trap cleanup EXIT QUIT
|
||||
|
||||
# Make sure that the temporary files are always removed
|
||||
cleanup() {
|
||||
trap '' EXIT INT QUIT
|
||||
# remove repo if not finished successfully
|
||||
if [ -z $finished ] && [ ! -z $project_id ]; then
|
||||
$GITLABCLI project delete --id $project_id
|
||||
echo "[-] deleted project $project_id"
|
||||
fi
|
||||
[ -d $TEMPLOC ] && rm -rf $TEMPLOC &>/dev/null
|
||||
exit
|
||||
}
|
||||
|
||||
# Clones repo using global (!) variables - v0.3
|
||||
clone_repo() {
|
||||
pushd $TEMPLOC 1>/dev/null
|
||||
git clone --depth=1 -q ssh://git@${GITSERVER}/${NAMESPACE}/${REPO}.git &>/dev/null
|
||||
if [ ! -d $TEMPLOC/$REPO ]; then
|
||||
echo "[-] could not clone repo ${NAMESPACE}/${REPO}"
|
||||
exit 1
|
||||
else
|
||||
cd $REPO
|
||||
fi
|
||||
}
|
||||
|
||||
# Preflight checks using global (!) variables
|
||||
preflight_checks() {
|
||||
if [ -z $REPO ]; then
|
||||
echo "Usage: startquote PROJECT_NAME"
|
||||
exit
|
||||
fi
|
||||
if ! which $GITLABCLI &>/dev/null; then
|
||||
echo "[-] this script needs the gitlab command line interface (python-gitlab)"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_repo() {
|
||||
project_id=$($GITLABCLI project create --name $REPO --namespace $NAMESPACEID --issues-enabled true --wiki-enabled true --snippets-enabled true --wall-enabled true --merge-requests-enabled true 2>/dev/null| awk '/id:/{print $2}')
|
||||
if [ ! -z $project_id ]; then
|
||||
echo "[+] successfully created gitlab project $REPO with id ${project_id}"
|
||||
else
|
||||
echo "[-] could not create repo $NAMESPACE/$REPO"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Add standard templates using global (!) variables - v0.2
|
||||
add_templates() {
|
||||
[ -d $TEMPLOC/$pentext ] && rm -rf $TEMPLOC/$pentext &>/dev/null
|
||||
pushd $TEMPLOC 1>/dev/null && git clone --depth=1 $PENTEXTREPO &>/dev/null && popd 1>/dev/null
|
||||
|
||||
if [ ! -d $TEMPLOC/$pentext ]; then
|
||||
echo "[-] could not clone (and therefore add) pentext repo $TEMPLATEREPO"
|
||||
exit 1
|
||||
else
|
||||
clone_repo
|
||||
# copy the framework
|
||||
cp -r $TEMPLOC/$pentext/xml/* .
|
||||
# remove the docs
|
||||
rm -r doc &>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
add_to_repo() {
|
||||
git add * &>/dev/null
|
||||
git commit -q -m "Initialized quote repository with PenText using ChatOps" &>/dev/null
|
||||
git push -q > /dev/null
|
||||
}
|
||||
|
||||
preflight_checks
|
||||
echo "startquote v${VERSION} - Humbly setting up your quote framework..."
|
||||
setup_repo
|
||||
add_templates
|
||||
add_to_repo
|
||||
echo "[+] listo!"
|
||||
finished=true
|
||||
113
chatops/bash/handler_validate
Normal file
113
chatops/bash/handler_validate
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/bin/bash
|
||||
|
||||
# handler_validate - validates quotes and reports
|
||||
#
|
||||
# This script is part of the PenText framework
|
||||
# https://pentext.org
|
||||
#
|
||||
# Copyright (C) 2016 Radically Open Security
|
||||
# https://www.radicallyopensecurity.com
|
||||
#
|
||||
# Author(s): Peter Mosmans
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
VERSION=0.3
|
||||
VALIDATOR=/usr/local/bin/validate_report.py
|
||||
TEMPLOC=$(mktemp -d)
|
||||
|
||||
|
||||
# These variables should be set environment-specific
|
||||
[ -z $GITSERVER ] && GITSERVER=gitlab.local
|
||||
[ -z $NAMESPACE ] && NAMESPACE=ros
|
||||
BRANCH=master
|
||||
|
||||
# Read standard 'command line' variables
|
||||
[[ ! -z $1 ]] && REPO=$1
|
||||
# Reading parms is a bit ugly, shifting parms or actually using getopt would be nicer
|
||||
if [[ ! -z $2 ]]; then
|
||||
if [[ ! $2 == -* ]]; then
|
||||
NAMESPACE=$2
|
||||
else
|
||||
PARMS=$2
|
||||
fi
|
||||
fi
|
||||
if [[ ! -z $3 ]]; then
|
||||
if [[ ! $3 == -* ]]; then
|
||||
BRANCH=$3
|
||||
else
|
||||
PARMS="$PARMS $3"
|
||||
fi
|
||||
fi
|
||||
if [[ $# -ge 4 ]]; then
|
||||
shift 3
|
||||
PARMS="$PARMS $@"
|
||||
fi
|
||||
|
||||
trap cleanup EXIT QUIT
|
||||
|
||||
# Make sure that the temporary files are always removed
|
||||
cleanup() {
|
||||
trap '' EXIT INT QUIT
|
||||
[ -d $TEMPLOC ] && rm -rf $TEMPLOC &>/dev/null
|
||||
exit
|
||||
}
|
||||
|
||||
# As quote used to be called offerte or offer,
|
||||
# this function retains backward compatibility - v0.2
|
||||
backwards_compatible() {
|
||||
if [[ $TARGET == "quote" ]] && [ ! -f $TARGET.xml ]; then
|
||||
TARGET="offerte"
|
||||
fi
|
||||
}
|
||||
|
||||
# Clones repo using global (!) variables - v0.3
|
||||
clone_repo() {
|
||||
pushd $TEMPLOC 1>/dev/null
|
||||
git clone --depth=1 -q ssh://git@${GITSERVER}/${NAMESPACE}/${REPO}.git &>/dev/null
|
||||
if [ ! -d $TEMPLOC/$REPO ]; then
|
||||
echo "[-] could not clone repo ${NAMESPACE}/${REPO}"
|
||||
exit 1
|
||||
else
|
||||
cd $REPO
|
||||
fi
|
||||
}
|
||||
|
||||
# Preflight checks using global (!) variables - v0.2
|
||||
preflight_checks() {
|
||||
if [ -z $REPO ]; then
|
||||
echo "[-] repository name needed"
|
||||
exit
|
||||
fi
|
||||
if [ ! -f $VALIDATOR ]; then
|
||||
echo "[-] this script needs validate_report.py ($VALIDATOR)"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
validate() {
|
||||
if [ ! -d source ]; then
|
||||
echo "[-] missing necessary pentext framework files"
|
||||
exit 1
|
||||
fi
|
||||
$VALIDATOR $PARMS
|
||||
}
|
||||
|
||||
# Add changed files to the repository
|
||||
add_to_repo() {
|
||||
git add * &>/dev/null
|
||||
git commit -q -m "validate fixed some files using ChatOps" &>/dev/null
|
||||
git push -q > /dev/null
|
||||
}
|
||||
|
||||
|
||||
preflight_checks
|
||||
echo "validate v$VERSION - Validating all of your needs..."
|
||||
clone_repo
|
||||
validate
|
||||
add_to_repo
|
||||
# Don't Listo! here, as the validate script tells the user that
|
||||
50
chatops/bash/releaser.sh
Normal file
50
chatops/bash/releaser.sh
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# releaser - renames (and encrypts) pentest reports for release
|
||||
#
|
||||
# This script is part of the PenText framework
|
||||
# https://pentext.org
|
||||
#
|
||||
# Copyright (C) 2016 Radically Open Security
|
||||
# https://www.radicallyopensecurity.com
|
||||
#
|
||||
# Author(s): Peter Mosmans
|
||||
# Marcus Bointon
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
source=target/report-latest.pdf
|
||||
name=$1
|
||||
targetdir=target
|
||||
type=REP
|
||||
version=1.0
|
||||
|
||||
if [ -z ${name} ]; then
|
||||
echo "Usage: releaser NAME [version [TYPE]]"
|
||||
echo "Names files TYPE-YYYYMMDD-vVERSION-NAME"
|
||||
echo "Expects source to be ${source}, and the target directory is ${targetdir}"
|
||||
echo "defaults are version=1.0 and TYPE=REP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ ! -z $2 ] && version=$2
|
||||
[ ! -z $3 ] && type=$3
|
||||
|
||||
fullname="${targetdir}/${type}-$(date +'%Y%m%d')-v${version}-${name}.pdf"
|
||||
if [ -f ${source} ]; then
|
||||
if [ -f ${fullname} ]; then
|
||||
echo "${fullname} already exists. Exiting..."
|
||||
exit 1
|
||||
else
|
||||
cp -v ${source} ${fullname}
|
||||
PASS=$(head -c 25 /dev/random | base64 | head -c 25)
|
||||
zip --password ${PASS} "${fullname}.zip" ${fullname} 2>/dev/null && echo "Zip file encrypted with password '${PASS}'"
|
||||
fi
|
||||
else
|
||||
echo "Could not find source ${source}"
|
||||
exit 1
|
||||
fi
|
||||
169
chatops/bash/test_pentext
Normal file
169
chatops/bash/test_pentext
Normal file
@@ -0,0 +1,169 @@
|
||||
#!/bin/bash
|
||||
|
||||
# test_pentext - tests the PenText toolchain
|
||||
#
|
||||
# This script is part of the PenText framework
|
||||
# https://pentext.org
|
||||
#
|
||||
# Copyright (C) 2016 Radically Open Security
|
||||
# https://www.radicallyopensecurity.com
|
||||
#
|
||||
# Author(s): Peter Mosmans
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
VERSION=0.6
|
||||
DOCBUILDER=/usr/local/bin/docbuilder.py
|
||||
VALIDATOR=/usr/local/bin/validate_report.py
|
||||
SAXON=/usr/local/bin/saxon/saxon9he.jar
|
||||
|
||||
# These variables should be set environment-specific
|
||||
[ -z $GITLABCLI ] && GITLABCLI=gitlab
|
||||
[ -z $GITSERVER ] && GITSERVER=gitlab.local
|
||||
[ -z $GITWEB ] && GITWEB=https://$GITSERVER
|
||||
[ -z $NAMESPACE ] && NAMESPACE=ros
|
||||
[ -z $NAMESPACEID ] && NAMESPACEID=1
|
||||
[ -z $PENTEXTREPO ] && PENTEXTREPO=https://github.com/radicallyopensecurity/pentext
|
||||
|
||||
TEMPLOC=$(mktemp -d)
|
||||
BRANCH=master
|
||||
reponame=test-pentext-$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1)
|
||||
pentext=$(echo $PENTEXTREPO|awk -F '/' '{print $5}')
|
||||
# Read standard 'command line' variables
|
||||
[[ ! -z $1 ]] && REPO=$1
|
||||
# Reading parms is a bit ugly, shifting parms or actually using getopt would be nicer
|
||||
if [[ ! -z $2 ]]; then
|
||||
if [[ ! $2 == -* ]]; then
|
||||
NAMESPACE=$2
|
||||
else
|
||||
PARMS=$2
|
||||
fi
|
||||
fi
|
||||
if [[ ! -z $3 ]]; then
|
||||
if [[ ! $3 == -* ]]; then
|
||||
BRANCH=$3
|
||||
else
|
||||
PARMS="$PARMS $3"
|
||||
fi
|
||||
fi
|
||||
if [[ $# -ge 4 ]]; then
|
||||
shift 3
|
||||
PARMS="$PARMS $@"
|
||||
fi
|
||||
|
||||
trap cleanup EXIT QUIT
|
||||
|
||||
# Make sure that the temporary files are always removed
|
||||
cleanup() {
|
||||
trap '' EXIT INT QUIT
|
||||
[ -d $TEMPLOC ] && rm -rf $TEMPLOC &>/dev/null
|
||||
|
||||
exit
|
||||
}
|
||||
|
||||
# As quote used to be called offerte or offer,
|
||||
# this function retains backward compatibility - v0.2
|
||||
backwards_compatible() {
|
||||
if [[ $TARGET == "quote" ]] && [ ! -f $TARGET.xml ]; then
|
||||
TARGET="offerte"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_repo() {
|
||||
echo "[*] testing gitlab command line interface..."
|
||||
REPO=${reponame,,} # lowercase, but of course
|
||||
project_id=$($GITLABCLI project create --name $REPO --namespace $NAMESPACEID --issues-enabled true --wiki-enabled true --snippets-enabled true --wall-enabled true --merge-requests-enabled true| awk '/id:/{print $2}')
|
||||
if [ ! -z $project_id ]; then
|
||||
echo "[+] successfully created test gitlab project with id ${project_id}"
|
||||
else
|
||||
echo "[-] could not create repo $reponame - is the .python-gitlab.cfg configuration corrent ?"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Clones repo using global (!) variables - v0.3
|
||||
clone_repo() {
|
||||
echo "[*] testing gitlab SSH access using ssh://git@${GITSERVER}/${NAMESPACE}..."
|
||||
pushd $TEMPLOC 1>/dev/null
|
||||
git clone --depth=1 -q ssh://git@${GITSERVER}/${NAMESPACE}/$REPO.git &>/dev/null
|
||||
if [ ! -d $TEMPLOC/$REPO ]; then
|
||||
echo "[-] could not clone repo ${NAMESPACE}/$reponame - is the namespace correct ?"
|
||||
exit 1
|
||||
else
|
||||
echo "[+] successfully cloned repo using namespace ${NAMESPACE}"
|
||||
fi
|
||||
cd $TEMPLOC/$REPO
|
||||
}
|
||||
|
||||
# Preflight checks
|
||||
preflight_checks() {
|
||||
echo "The following variables will be used: "
|
||||
echo "DOCBUILDER=$DOCBUILDER (location of docbuilder.py)"
|
||||
echo "GITLABCLI=$GITLABCLI (command line gitlab interface)"
|
||||
echo "GITSERVER=$GITSERVER (git server)"
|
||||
echo "GITWEB=$GITWEB (webinterface of git server)"
|
||||
echo "NAMESPACE=$NAMESPACE (namespace of repositories)"
|
||||
echo "NAMESPACEID=$NAMESPACEID (namespace ID of repositories)"
|
||||
echo "PENTEXTREPO=$PENTEXTREPO (location of pentext repo)"
|
||||
echo "SAXON=$SAXON (saxon binary)"
|
||||
echo "VALIDATOR=$VALIDATOR (location of validate_report.py)"
|
||||
echo "[*] testing binaries..."
|
||||
[ ! -f $VALIDATOR ] && echo "[-] validate_report.py ($VALIDATOR) is missing (necessary for validate)"
|
||||
[ ! -f $DOCBUILDER ] && echo "[-] docbuilder.py ($DOCBUILDER) is missing (necessary for build)"
|
||||
[ ! -f $SAXON ] && echo "[-] saxon ($SAXON) is missing (necessary for invoice)"
|
||||
which java &> /dev/null || echo "[-] java is missing (necessary for saxon)"
|
||||
if ! which $GITLABCLI &>/dev/null && [ ! -f $GITLABCLI ]; then
|
||||
echo "[-] gitlab ($GITLABCLI) is missing, required for startquote and startpentest"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
add_to_repo() {
|
||||
echo "[*] testing add to repo"
|
||||
echo "commit test" > testcommit
|
||||
git add testcommit
|
||||
git commit -q -m "test_pentext testcommit"
|
||||
git push -q
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "[-] failed adding stuff to repo"
|
||||
fi
|
||||
}
|
||||
|
||||
delete_repo() {
|
||||
if [ ! -z $project_id ]; then
|
||||
$GITLABCLI project delete --id $project_id &>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "[+] successfully deleted testproject $project_id"
|
||||
else
|
||||
echo "[-] hmmm... failed deleting testproject $project_id"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
clone_pentext() {
|
||||
echo "[*] testing access to PenText repo $PENTEXTREPO..."
|
||||
pushd $TEMPLOC 1>/dev/null
|
||||
git clone --depth=1 $PENTEXTREPO &>/dev/null
|
||||
popd 1>/dev/null
|
||||
|
||||
if [ ! -d $TEMPLOC/$pentext ]; then
|
||||
echo "[-] could not clone repo $TEMPLATEREPO..."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# preflight_checks
|
||||
echo "test_pentext v$VERSION - Testing the PenText toolchain"
|
||||
preflight_checks
|
||||
setup_repo
|
||||
clone_repo
|
||||
add_to_repo
|
||||
delete_repo
|
||||
clone_pentext
|
||||
echo "[+] all tests successful. Good to go!"
|
||||
234
chatops/python/docbuilder.py
Normal file
234
chatops/python/docbuilder.py
Normal file
@@ -0,0 +1,234 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Builds PDF files from (intermediate fo and) XML files.
|
||||
|
||||
This script is part of the PenText framework
|
||||
https://pentext.org
|
||||
|
||||
Copyright (C) 2015-2016 Radically Open Security
|
||||
https://www.radicallyopensecurity.com
|
||||
|
||||
Author(s): Peter Mosmans
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
from subprocess import PIPE
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
|
||||
GITREV = 'GITREV' # Magic tag which gets replaced by the git short commit hash
|
||||
OFFERTE = 'generate_offerte.xsl' # XSL for generating waivers
|
||||
WAIVER = 'waiver_' # prefix for waivers
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
"""
|
||||
Parses command line arguments.
|
||||
"""
|
||||
global verboseprint
|
||||
global verboseerror
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description=textwrap.dedent('''\
|
||||
Builds PDF files from (intermediate fo and) XML files.
|
||||
|
||||
Copyright (C) 2015-2016 Radically Open Security (Peter Mosmans)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.'''))
|
||||
parser.add_argument('-c', '--clobber', action='store_true',
|
||||
help='overwrite output file if it already exists')
|
||||
parser.add_argument('-date', action='store',
|
||||
help='the invoice date')
|
||||
parser.add_argument('--fop-config', action='store',
|
||||
default='/etc/docbuilder/rosfop.xconf',
|
||||
help="""fop configuration file (default
|
||||
/etc/docbuilder/rosfop.xconf""")
|
||||
parser.add_argument('-f', '--fop', action='store',
|
||||
default='../target/report.fo',
|
||||
help="""intermediate fop output file (default:
|
||||
../target/report.fo)""")
|
||||
parser.add_argument('--fop-binary', action='store',
|
||||
default='/usr/local/bin/fop',
|
||||
help='fop binary (default /usr/local/bin/fop')
|
||||
parser.add_argument('-i', '--input', action='store',
|
||||
default='report.xml',
|
||||
help="""input file (default: report.xml)""")
|
||||
parser.add_argument('-invoice', action='store',
|
||||
help="""invoice number""")
|
||||
parser.add_argument('--saxon', action='store',
|
||||
default='/usr/local/bin/saxon/saxon9he.jar',
|
||||
help="""saxon JAR file (default
|
||||
/usr/local/bin/saxon/saxon9he.jar)""")
|
||||
parser.add_argument('-x', '--xslt', action='store',
|
||||
default='../xslt/generate_report.xsl',
|
||||
help='input file (default: ../xslt/generate_report.xsl)')
|
||||
parser.add_argument('-o', '--output', action='store',
|
||||
default='../target/report-latest.pdf',
|
||||
help="""output file name (default:
|
||||
../target/report-latest.pdf""")
|
||||
parser.add_argument('-v', '--verbose', action='store_true',
|
||||
help='increase output verbosity')
|
||||
parser.add_argument('-w', '--warnings', action='store_true',
|
||||
help='show warnings')
|
||||
args = parser.parse_args()
|
||||
if args.verbose:
|
||||
def verboseprint(*args): # pylint: disable=missing-docstring
|
||||
for arg in args:
|
||||
print(arg, end="")
|
||||
print()
|
||||
|
||||
def verboseerror(*args): # pylint: disable=missing-docstring
|
||||
for arg in args:
|
||||
print(arg, end="", file=sys.stderr)
|
||||
print(file=sys.stderr)
|
||||
else:
|
||||
verboseprint = lambda *a: None
|
||||
verboseerror = lambda *a: None
|
||||
return vars(parser.parse_args())
|
||||
|
||||
|
||||
def print_output(stdout, stderr):
|
||||
"""
|
||||
Prints out standard out and standard err using the verboseprint function.
|
||||
"""
|
||||
if stdout:
|
||||
verboseprint('[+] stdout: {0}'.format(stdout))
|
||||
if stderr:
|
||||
verboseerror('[-] stderr: {0}'.format(stderr))
|
||||
|
||||
|
||||
def change_tag(fop):
|
||||
"""
|
||||
Replaces GITREV in document by git commit shorttag.
|
||||
"""
|
||||
cmd = ['git', 'log', '--pretty=format:%h', '-n', '1']
|
||||
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||
shorttag, _stderr = process.communicate()
|
||||
if not process.returncode:
|
||||
fop_file = open(fop).read()
|
||||
if GITREV in fop_file:
|
||||
fop_file = fop_file.replace(GITREV, shorttag)
|
||||
with open(fop, 'w') as new_file:
|
||||
new_file.write(fop_file)
|
||||
print('[+] Embedding git version information into document')
|
||||
|
||||
|
||||
def to_fo(options):
|
||||
"""
|
||||
Creates a fo output file based on a XML file.
|
||||
Returns True if successful
|
||||
"""
|
||||
cmd = ['java', '-jar', options['saxon'],
|
||||
'-s:' + options['input'], '-xsl:' + options['xslt'],
|
||||
'-o:' + options['fop'], '-xi']
|
||||
if options['invoice']:
|
||||
cmd.append('INVOICE_NO=' + options['invoice'])
|
||||
if options['date']:
|
||||
cmd.append('DATE=' + options['date'])
|
||||
process = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
|
||||
stdout, stderr = process.communicate()
|
||||
print_output(stdout, stderr)
|
||||
if process.returncode:
|
||||
print_exit('[-] Error creating fo file from XML input',
|
||||
process.returncode)
|
||||
else:
|
||||
change_tag(options['fop'])
|
||||
return True
|
||||
|
||||
|
||||
def to_pdf(options):
|
||||
"""
|
||||
Creates a PDF file based on a fo file.
|
||||
Returns True if successful
|
||||
"""
|
||||
cmd = [options['fop_binary'], '-c', options['fop_config'], options['fop'],
|
||||
options['output']]
|
||||
try:
|
||||
verboseprint('Converting {0} to {1}'.format(options['fop'],
|
||||
options['output']))
|
||||
process = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
|
||||
stdout, stderr = process.communicate()
|
||||
result = process.returncode
|
||||
print_output(stdout, stderr)
|
||||
if result == 0:
|
||||
print('[+] Succesfully built ' + options['output'])
|
||||
except OSError as exception:
|
||||
print_exit('[-] ERR: {0}'.format(exception.strerror), exception.errno)
|
||||
return result == 0
|
||||
|
||||
|
||||
def print_exit(text, result):
|
||||
"""
|
||||
Prints error message and exits with result code.
|
||||
"""
|
||||
print(text, file=sys.stderr)
|
||||
sys.exit(result)
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
The main program.
|
||||
"""
|
||||
global verboseerror
|
||||
global verboseprint
|
||||
result = False
|
||||
options = parse_arguments()
|
||||
if not os.path.isfile(options['input']):
|
||||
print_exit('[-] Cannot find input file {0}'.
|
||||
format(options['input']), result)
|
||||
try:
|
||||
if os.path.isfile(options['output']):
|
||||
if not options['clobber']:
|
||||
print_exit('[-] Output file {0} already exists. '.
|
||||
format(options['output']) +
|
||||
'Use -c (clobber) to overwrite',
|
||||
result)
|
||||
os.remove(options['output'])
|
||||
except OSError as exception:
|
||||
print_exit('[-] Could not remove/overwrite file {0} ({1})'.
|
||||
format(options['output'], exception.strerror), result)
|
||||
result = to_fo(options)
|
||||
if result:
|
||||
if OFFERTE in options['xslt']: # an offerte can generate multiple fo's
|
||||
report_output = options['output']
|
||||
verboseprint('generating separate waivers detected')
|
||||
output_dir = os.path.dirname(options['output'])
|
||||
fop_dir = os.path.dirname(options['fop'])
|
||||
try:
|
||||
for fop in [os.path.splitext(x)[0] for x in
|
||||
os.listdir(fop_dir) if x.endswith('fo')]:
|
||||
if WAIVER in fop:
|
||||
options['output'] = output_dir + os.sep + fop + '.pdf'
|
||||
else:
|
||||
options['output'] = report_output
|
||||
options['fop'] = fop_dir + os.sep + fop + '.fo'
|
||||
result = to_pdf(options) and result
|
||||
except OSError as exception:
|
||||
print_exit('[-] ERR: {0}'.format(exception.strerror),
|
||||
exception.errno)
|
||||
else:
|
||||
result = to_pdf(options)
|
||||
|
||||
else:
|
||||
print_exit('[-] Unsuccessful (error {0})'.format(result), result)
|
||||
sys.exit(not result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
275
chatops/python/gitlab-to-pentext.py
Normal file
275
chatops/python/gitlab-to-pentext.py
Normal file
@@ -0,0 +1,275 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Gitlab bridge for PenText: imports and updates gitlab issues into PenText
|
||||
(XML) format
|
||||
|
||||
This script is part of the PenText framework
|
||||
https://pentext.org
|
||||
|
||||
Copyright (C) 2016 Radically Open Security
|
||||
https://www.radicallyopensecurity.com
|
||||
|
||||
Author(s): Peter Mosmans
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import argparse
|
||||
import collections
|
||||
import os
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
try:
|
||||
import gitlab
|
||||
import jxmlease
|
||||
# Path of this script. The validate_report module is on the same path.
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
import validate_report
|
||||
except ImportError as exception:
|
||||
print('[-] This script needs python-gitlab, jxmlease and validate_report library',
|
||||
file=sys.stderr)
|
||||
print("validate_report is part of the pentext framework", file=sys.stderr)
|
||||
print("Install python-gitlab with: sudo pip install python-gitlab", file=sys.stderr)
|
||||
print("Install jxmlease with: sudo pip install jxmlease", file=sys.stderr)
|
||||
print("", file=sys.stderr)
|
||||
print("Currently missing: " + exception.message, file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def add_finding(issue, options):
|
||||
"""
|
||||
Writes issue as XML finding to file.
|
||||
"""
|
||||
title = validate_report.capitalize(issue.title.strip())
|
||||
print_status('{0} - {1} - {2}'.format(issue.state, issue.labels,
|
||||
title), options)
|
||||
threat_level = 'Moderate'
|
||||
finding_type = 'TODO'
|
||||
finding_id = '{0}-{1}'.format(issue.iid, valid_filename(title))
|
||||
filename = 'findings/{0}.xml'.format(finding_id)
|
||||
finding = collections.OrderedDict()
|
||||
finding['title'] = title
|
||||
finding['description'] = unicode.replace(issue.description,
|
||||
'\r\n', '\n')
|
||||
finding['technicaldescription'] = ''
|
||||
for note in [x for x in issue.notes.list() if not x.system]:
|
||||
finding['technicaldescription'] += unicode.replace(note.body,
|
||||
'\r\n', '\n')
|
||||
finding['impact'] = {}
|
||||
finding['impact']['p'] = 'TODO'
|
||||
finding['recommendation'] = {}
|
||||
finding['recommendation']['ul'] = {}
|
||||
finding['recommendation']['ul']['li'] = 'TODO'
|
||||
finding_xml = jxmlease.XMLDictNode(finding, tag='finding',
|
||||
xml_attrs={'id': finding_id,
|
||||
'threatLevel': threat_level,
|
||||
'type': finding_type})
|
||||
if options['dry_run']:
|
||||
print_line('[+] {0}'.format(filename))
|
||||
print(finding_xml.emit_xml())
|
||||
else:
|
||||
if os.path.isfile(filename) and not options['overwrite']:
|
||||
print_line('Finding {0} already exists (use --overwrite to overwrite)'.
|
||||
format(filename))
|
||||
else:
|
||||
if options['y'] or ask_permission('Create file ' + filename):
|
||||
with open(filename, 'w') as xmlfile:
|
||||
xmlfile.write(finding_xml.emit_xml().encode('utf-8'))
|
||||
print_line('[+] Created {0}'.format(filename))
|
||||
|
||||
|
||||
def add_non_finding(issue, options):
|
||||
"""
|
||||
Adds a non-finding.
|
||||
"""
|
||||
title = validate_report.capitalize(issue.title.strip())
|
||||
print_status('{0} - {1} - {2}'.format(issue.state, issue.labels,
|
||||
title), options)
|
||||
non_finding_id = '{0}-{1}'.format(issue.iid, valid_filename(title))
|
||||
filename = 'non-findings/{0}.xml'.format(non_finding_id)
|
||||
non_finding = collections.OrderedDict()
|
||||
non_finding['title'] = title
|
||||
non_finding['p'] = unicode.replace(issue.description,
|
||||
'\r\n', '\n')
|
||||
for note in [x for x in issue.notes.list() if not x.system]:
|
||||
non_finding['p'] += unicode.replace(note.body,
|
||||
'\r\n', '\n')
|
||||
non_finding_xml = jxmlease.XMLDictNode(non_finding, tag='non-finding',
|
||||
xml_attrs={'id': non_finding_id})
|
||||
if options['dry_run']:
|
||||
print_line('[+] {0}'.format(filename))
|
||||
print(non_finding_xml.emit_xml())
|
||||
else:
|
||||
if os.path.isfile(filename) and not options['overwrite']:
|
||||
print_line('Non-finding {0} already exists (use --overwrite to overwrite)'.
|
||||
format(filename))
|
||||
else:
|
||||
if options['y'] or ask_permission('Create file ' + filename):
|
||||
with open(filename, 'w') as xmlfile:
|
||||
xmlfile.write(non_finding_xml.emit_xml().encode('utf-8'))
|
||||
print_line('[+] Created {0}'.format(filename))
|
||||
|
||||
|
||||
def ask_permission(question):
|
||||
"""
|
||||
Ask question and return True if user answered with y.
|
||||
"""
|
||||
print_line('{0} ? [y/N]'.format(question))
|
||||
return raw_input().lower() == 'y'
|
||||
|
||||
|
||||
def convert_markdown(text):
|
||||
"""
|
||||
Replace markdown monospace with monospace tags
|
||||
"""
|
||||
result = text
|
||||
return result
|
||||
# print('EXAMINING ' + text + ' END')
|
||||
# monospace = re.findall("\`\`\`(.*?)\`\`\`", text, re.DOTALL)
|
||||
# if len(monospace):
|
||||
# result = {}
|
||||
# result['monospace'] = ''.join(monospace)
|
||||
|
||||
|
||||
def list_issues(gitserver, options):
|
||||
"""
|
||||
Lists all issues for options['issues']
|
||||
"""
|
||||
try:
|
||||
for issue in gitserver.project_issues.list(project_id=options['issues']):
|
||||
if issue.state == 'closed' and not options['closed']:
|
||||
continue
|
||||
if 'finding' in issue.labels:
|
||||
add_finding(issue, options)
|
||||
if 'non-finding' in issue.labels:
|
||||
add_non_finding(issue, options)
|
||||
except Exception as exception:
|
||||
print_error('could not find any issues ({0})'.format(exception), -1)
|
||||
|
||||
|
||||
def list_projects(gitserver):
|
||||
"""
|
||||
Lists all available projects.
|
||||
"""
|
||||
for project in gitserver.projects.list(all=True):
|
||||
print_line('{0} - {1}'.format(project.as_dict()['id'],
|
||||
project.as_dict()['path']))
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
"""
|
||||
Parses command line arguments.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description=textwrap.dedent('''\
|
||||
gitlab-to-pentext - imports and updates gitlab issues into PenText (XML) format
|
||||
|
||||
Copyright (C) 2015-2016 Radically Open Security (Peter Mosmans)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.'''))
|
||||
parser.add_argument('--closed', action='store',
|
||||
help='take closed issues into account')
|
||||
parser.add_argument('--dry-run', action='store_true',
|
||||
help='do not write anything, only output on screen')
|
||||
parser.add_argument('--issues', action='store',
|
||||
help='list issues for a given project')
|
||||
parser.add_argument('--overwrite', action='store_true',
|
||||
help='overwrite existing issues')
|
||||
parser.add_argument('--projects', action='store_true',
|
||||
help='list gitlab projects')
|
||||
parser.add_argument('-v', '--verbose', action='store_true',
|
||||
help='increase output verbosity')
|
||||
parser.add_argument('-y', action='store_true',
|
||||
help='assume yes on all questions, write findings')
|
||||
if len(sys.argv) == 1:
|
||||
parser.print_help()
|
||||
return vars(parser.parse_args())
|
||||
|
||||
|
||||
def preflight_checks():
|
||||
"""
|
||||
Checks if all tools are there.
|
||||
Exits with 0 if everything went okilydokily.
|
||||
"""
|
||||
try:
|
||||
gitserver = gitlab.Gitlab.from_config('remote')
|
||||
gitserver.auth()
|
||||
except gitlab.config.GitlabDataError as exception:
|
||||
print_error('could not connect {0}'.format(exception), -1)
|
||||
return gitserver
|
||||
|
||||
|
||||
def print_error(text, result=False):
|
||||
"""
|
||||
Prints error message.
|
||||
When @result, exits with result.
|
||||
"""
|
||||
if len(text):
|
||||
print_line('[-] ' + text, True)
|
||||
if result:
|
||||
sys.exit(result)
|
||||
|
||||
|
||||
def print_line(text, error=False):
|
||||
"""
|
||||
Prints text, and flushes stdout and stdin.
|
||||
When @error, prints text to stderr instead of stdout.
|
||||
"""
|
||||
if not error:
|
||||
print(text)
|
||||
else:
|
||||
print(text, file=sys.stderr)
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
|
||||
def print_status(text, options=False):
|
||||
"""
|
||||
Prints status message if options array is given and contains 'verbose'.
|
||||
"""
|
||||
if options and options['verbose']:
|
||||
print_line('[*] ' + str(text))
|
||||
|
||||
|
||||
def valid_filename(filename):
|
||||
"""
|
||||
Return a valid filename.
|
||||
"""
|
||||
result = ''
|
||||
for char in filename.strip():
|
||||
if char in [':', '/', '.', '\\', ' ', '[', ']', '(', ')', '\'']:
|
||||
if len(char) and not result.endswith('-'):
|
||||
result += '-'
|
||||
else:
|
||||
result += char
|
||||
return result.lower()
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
The main program.
|
||||
"""
|
||||
options = parse_arguments()
|
||||
gitserver = preflight_checks()
|
||||
if options['projects']:
|
||||
list_projects(gitserver)
|
||||
if options['issues']:
|
||||
list_issues(gitserver, options)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
551
chatops/python/validate_report.py
Normal file
551
chatops/python/validate_report.py
Normal file
@@ -0,0 +1,551 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Cross-checks findings, validates XML files, offerte and report files.
|
||||
|
||||
This script is part of the PenText framework
|
||||
https://pentext.org
|
||||
|
||||
Copyright (C) 2015-2016 Radically Open Security
|
||||
https://www.radicallyopensecurity.com
|
||||
|
||||
Author(s): Peter Mosmans
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import argparse
|
||||
import mmap
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
import xml.sax
|
||||
|
||||
try:
|
||||
from lxml import etree as ElementTree
|
||||
except ImportError as exception:
|
||||
print('[-] This script needs lxml',
|
||||
file=sys.stderr)
|
||||
print("Install lxml with: sudo pip install lxml", file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
# When set to True, the report will be validated using docbuilder
|
||||
DOCBUILDER = False
|
||||
VOCABULARY = 'project-vocabulary.pws'
|
||||
# Snippets may contain XML fragments without the proper entities
|
||||
EXAMPLEDIR = 'examples/'
|
||||
NOT_CAPITALIZED = ['a', 'an', 'and', 'as', 'at', 'but', 'by', 'for', 'in',
|
||||
'nor', 'of', 'on', 'or', 'the', 'to', 'up']
|
||||
SNIPPETDIR = 'snippets/'
|
||||
TEMPLATEDIR = 'templates/'
|
||||
OFFERTE = '/offerte.xml'
|
||||
REPORT = '/report.xml'
|
||||
WARN_LINE = 80 # There should be a separation character after x characters...
|
||||
MAX_LINE = 86 # ... and before y
|
||||
|
||||
|
||||
if DOCBUILDER:
|
||||
import docbuilder_proxy
|
||||
import proxy_vagrant
|
||||
try:
|
||||
import aspell
|
||||
except:
|
||||
print('[-] aspell not installed: spelling not available')
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
"""
|
||||
Parses command line arguments.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description=textwrap.dedent('''\
|
||||
validate_report - validates offer letters and reports
|
||||
|
||||
Copyright (C) 2015-2016 Radically Open Security (Peter Mosmans)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.'''))
|
||||
parser.add_argument('-a', '--all', action='store_true',
|
||||
help='Perform all checks')
|
||||
parser.add_argument('--auto-fix', action='store_true',
|
||||
help='Try to automatically correct issues')
|
||||
parser.add_argument('-c', '--capitalization', action='store_true',
|
||||
help='Check capitalization')
|
||||
parser.add_argument('--debug', action='store_true',
|
||||
help='Show debug information')
|
||||
parser.add_argument('--edit', action='store_true',
|
||||
help='Open files with issues using an editor')
|
||||
parser.add_argument('--learn', action='store_true',
|
||||
help='Store all unknown words in dictionary file')
|
||||
parser.add_argument('--long', action='store_true',
|
||||
help='Check for long lines')
|
||||
parser.add_argument('--offer', action='store_true',
|
||||
help='Validate offer master file')
|
||||
parser.add_argument('--spelling', action='store_true',
|
||||
help='Check spelling')
|
||||
parser.add_argument('-v', '--verbose', action='store_true',
|
||||
help='increase output verbosity')
|
||||
parser.add_argument('--no-report', action='store_true',
|
||||
help='Do not validate report master file')
|
||||
parser.add_argument('--quiet', action='store_true',
|
||||
help='Don\'t output status messages')
|
||||
return vars(parser.parse_args())
|
||||
|
||||
|
||||
def validate_spelling(tree, filename, options):
|
||||
"""
|
||||
Checks spelling of text within tags.
|
||||
If options['learn'], then unknown words will be added to the dictionary.
|
||||
"""
|
||||
result = True
|
||||
try:
|
||||
speller = aspell.Speller(('lang', 'en'),
|
||||
('personal-dir', '.'),
|
||||
('personal', VOCABULARY))
|
||||
except: # some versions of aspell use a different path
|
||||
speller = aspell.Speller(('lang', 'en'),
|
||||
('personal-path', './' + VOCABULARY))
|
||||
if options['debug']:
|
||||
[print(i[0] + ' ' + str(i[2]) + '\n') for i in speller.ConfigKeys()]
|
||||
try:
|
||||
root = tree.getroot()
|
||||
for section in root.iter():
|
||||
if section.text and isinstance(section.tag, basestring) and \
|
||||
section.tag not in ('a', 'code', 'monospace', 'pre'):
|
||||
for word in re.findall('([a-zA-Z]+\'?[a-zA-Z]+)', section.text):
|
||||
if not speller.check(word):
|
||||
if options['learn']:
|
||||
speller.addtoPersonal(word)
|
||||
else:
|
||||
result = False
|
||||
print('[-] Misspelled (unknown) word {0} in {1}'.
|
||||
format(word.encode('utf-8'), filename))
|
||||
if options['learn']:
|
||||
speller.saveAllwords()
|
||||
except aspell.AspellSpellerError as exception:
|
||||
print('[-] Spelling disabled ({0})'.format(exception))
|
||||
return result
|
||||
|
||||
|
||||
def all_files():
|
||||
"""
|
||||
Returns a list of all files contained in the git repository.
|
||||
"""
|
||||
cmd = ['git', 'ls-files']
|
||||
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
return process.stdout.read().splitlines()
|
||||
|
||||
|
||||
def open_editor(filename):
|
||||
if sys.platform in ('linux', 'linux2'):
|
||||
editor = os.getenv('EDITOR')
|
||||
if editor:
|
||||
print('{0} {1}'.format(editor, filename))
|
||||
sys.stdout.flush()
|
||||
subprocess.call([editor, '"{0}"'.format(filename)], shell=True)
|
||||
else:
|
||||
subprocess.call('xdg-open', filename)
|
||||
elif sys.platform == "darwin":
|
||||
subprocess.call(['open', filename])
|
||||
elif sys.platform == "win32":
|
||||
os.system('"{0}"'.format(filename.replace('/', os.path.sep)))
|
||||
|
||||
|
||||
def validate_files(filenames, options):
|
||||
"""
|
||||
Checks file extensions and calls appropriate validator function.
|
||||
Returns True if all files validated succesfully.
|
||||
"""
|
||||
result = True
|
||||
masters = []
|
||||
findings = []
|
||||
non_findings = []
|
||||
scans = []
|
||||
for filename in filenames:
|
||||
if (filename.lower().endswith('.xml') or
|
||||
filename.lower().endswith('xml"')):
|
||||
if SNIPPETDIR not in filename and TEMPLATEDIR not in filename:
|
||||
if (OFFERTE in filename and options['offer']) or \
|
||||
(REPORT in filename and not options['no_report']):
|
||||
masters.append(filename)
|
||||
# try:
|
||||
type_result, xml_type = validate_xml(filename, options)
|
||||
result = result and type_result
|
||||
if 'non-finding' in xml_type:
|
||||
non_findings.append(filename)
|
||||
else:
|
||||
if 'finding' in xml_type:
|
||||
findings.append(filename)
|
||||
else:
|
||||
if 'scans' in xml_type:
|
||||
scans.append(filename)
|
||||
if len(masters):
|
||||
for master in masters:
|
||||
result = validate_master(master, findings, non_findings, scans, options) and result
|
||||
return result
|
||||
|
||||
|
||||
def print_output(options, stdout, stderr=None):
|
||||
"""
|
||||
Prints out standard out and standard err using the verboseprint function.
|
||||
"""
|
||||
if stdout and options['verbose']:
|
||||
print('[+] {0}'.format(stdout))
|
||||
if stderr and options['verbose']:
|
||||
print('[-] {0}'.format(stderr))
|
||||
|
||||
|
||||
def validate_report():
|
||||
"""
|
||||
Validates XML report file by trying to build it.
|
||||
Returns True if the report was built successful.
|
||||
"""
|
||||
host, command = docbuilder_proxy.read_config(docbuilder_proxy.CONFIG_FILE)
|
||||
command = command + ' -c'
|
||||
return proxy_vagrant.execute_command(host, command)
|
||||
|
||||
|
||||
def validate_xml(filename, options):
|
||||
"""
|
||||
Validates XML file by trying to parse it.
|
||||
Returns True if the file validated successfully.
|
||||
"""
|
||||
result = True
|
||||
xml_type = ''
|
||||
# crude check whether the file is outside the pentext framework
|
||||
if 'notes' in filename:
|
||||
return result, xml_type
|
||||
print_output(options, 'Validating XML file: {0}'.format(filename))
|
||||
try:
|
||||
with open(filename, 'rb') as xml_file:
|
||||
xml.sax.parse(xml_file, xml.sax.ContentHandler())
|
||||
tree = ElementTree.parse(filename, ElementTree.XMLParser(strip_cdata=False))
|
||||
type_result, xml_type = validate_type(tree, filename, options)
|
||||
result = validate_long_lines(tree, filename, options) and result and type_result
|
||||
if options['edit'] and not result:
|
||||
open_editor(filename)
|
||||
except (xml.sax.SAXException, ElementTree.ParseError) as exception:
|
||||
print('[-] validating {0} failed ({1})'.format(filename, exception))
|
||||
result = False
|
||||
except IOError as exception:
|
||||
print('[-] validating {0} failed ({1})'.format(filename, exception))
|
||||
result = False
|
||||
return result, xml_type
|
||||
|
||||
|
||||
def get_all_text(node):
|
||||
"""
|
||||
Retrieves all text within tags.
|
||||
"""
|
||||
text_string = node.text or ''
|
||||
for element in node:
|
||||
text_string += get_all_text(element)
|
||||
if node.tail:
|
||||
text_string += node.tail
|
||||
return text_string.strip()
|
||||
|
||||
|
||||
def is_capitalized(line):
|
||||
"""
|
||||
Checks whether all words in @line start with a capital.
|
||||
|
||||
Returns True if that's the case.
|
||||
"""
|
||||
return not line or line.strip() == capitalize(line)
|
||||
|
||||
|
||||
def capitalize(line):
|
||||
"""
|
||||
Returns a capitalized version of @line, where the first word and all other
|
||||
words not in NOT_CAPITALIZED are capitalized.
|
||||
"""
|
||||
capitalized = ''
|
||||
for word in line.strip().split():
|
||||
if word not in NOT_CAPITALIZED or not len(capitalized):
|
||||
word = word[0].upper() + word[1:]
|
||||
capitalized += word + ' '
|
||||
return capitalized.strip()
|
||||
|
||||
|
||||
def validate_type(tree, filename, options):
|
||||
"""
|
||||
Performs specific checks based on type.
|
||||
Currently only finding and non-finding are supported.
|
||||
"""
|
||||
result = True
|
||||
fix = False
|
||||
root = tree.getroot()
|
||||
xml_type = root.tag
|
||||
attributes = []
|
||||
tags = []
|
||||
if options['spelling']:
|
||||
result = validate_spelling(tree, filename, options)
|
||||
if xml_type == 'pentest_report':
|
||||
attributes = ['findingCode']
|
||||
if xml_type == 'finding':
|
||||
attributes = ['threatLevel', 'type', 'id']
|
||||
tags = ['title', 'description', 'technicaldescription', 'impact',
|
||||
'recommendation']
|
||||
if xml_type == 'non-finding':
|
||||
attributes = ['id']
|
||||
tags = ['title']
|
||||
if not len(attributes):
|
||||
return result, xml_type
|
||||
|
||||
for attribute in attributes:
|
||||
if attribute not in root.attrib:
|
||||
print('[A] Missing obligatory attribute in {0}: {1}'.
|
||||
format(filename, attribute))
|
||||
if attribute == 'id':
|
||||
root.set(attribute, filename)
|
||||
fix = True
|
||||
else:
|
||||
result = False
|
||||
else:
|
||||
if attribute == 'threatLevel' and root.attrib[attribute] not in \
|
||||
('Low', 'Moderate', 'Elevated', 'High', 'Extreme'):
|
||||
print('[-] threatLevel is not Low, Moderate, High, Elevated or Extreme: {0}'.
|
||||
format(root.attrib[attribute]))
|
||||
result = False
|
||||
if attribute == 'type' and (options['capitalization'] and not \
|
||||
is_capitalized(root.attrib[attribute])):
|
||||
print('[A] Type missing capitalization (expected {0}, read {1})'.
|
||||
format(capitalize(root.attrib[attribute]),
|
||||
root.attrib[attribute]))
|
||||
root.attrib[attribute] = capitalize(root.attrib[attribute])
|
||||
fix = True
|
||||
for tag in tags:
|
||||
if root.find(tag) is None:
|
||||
print('[-] Missing tag in {0}: {1}'.format(filename, tag))
|
||||
result = False
|
||||
continue
|
||||
if not get_all_text(root.find(tag)):
|
||||
print('[-] Empty tag in {0}: {1}'.format(filename, tag))
|
||||
result = False
|
||||
continue
|
||||
if tag == 'title' and (options['capitalization'] and \
|
||||
not is_capitalized(root.find(tag).text)):
|
||||
print('[A] Title missing capitalization in {0} (expected {1}, read {2})'.
|
||||
format(filename, capitalize(root.find(tag).text),
|
||||
root.find(tag).text))
|
||||
root.find(tag).text = capitalize(root.find(tag).text)
|
||||
fix = True
|
||||
all_text = get_all_text(root.find(tag))
|
||||
if tag == 'description' and all_text.strip()[-1] != '.':
|
||||
print('[A] Description missing final dot in {0}: {1}'.format(filename, all_text))
|
||||
root.find(tag).text = all_text.strip() + '.'
|
||||
fix = True
|
||||
if fix:
|
||||
if options['auto_fix']:
|
||||
print('[+] Automatically fixed {0}'.format(filename))
|
||||
tree.write(filename)
|
||||
else:
|
||||
print('[+] NOTE: Items with [A] can be fixed automatically, use --auto-fix')
|
||||
return (result and not fix), xml_type
|
||||
|
||||
|
||||
def validate_long_lines(tree, filename, options):
|
||||
"""
|
||||
Checks whether pre or code section contains lines longer than MAX_LINE characters
|
||||
Returns True if the file validated successfully.
|
||||
"""
|
||||
if not options['long']:
|
||||
return True
|
||||
result = True
|
||||
fix = False
|
||||
root = tree.getroot()
|
||||
for pre_section in [j for section in ('pre', 'code') for j in root.iter(section)]:
|
||||
if pre_section.text:
|
||||
fixed_text = ''
|
||||
for line in pre_section.text.splitlines():
|
||||
while len(line) > MAX_LINE:
|
||||
result = False
|
||||
print('[-] {0} Line inside {1} too long: {2}'.
|
||||
format(filename, section, line.encode('utf-8')[MAX_LINE:]))
|
||||
cutpoint = MAX_LINE
|
||||
for split in [' ', '"', '\'', '=', '-', ';']:
|
||||
if split in line.encode('utf-8')[WARN_LINE:MAX_LINE]:
|
||||
cutpoint = line.find(split, WARN_LINE, MAX_LINE)
|
||||
fix = True
|
||||
fixed_line = line[:cutpoint] + '\n'
|
||||
print('cutted line {0}'.format(line))
|
||||
line = line[cutpoint:]
|
||||
fixed_text += fixed_line.encode('utf-8')
|
||||
print('[A] can be fixed (breaking at {0}): {1}'.format(cutpoint, fixed_line))
|
||||
fixed_text += line + '\n'
|
||||
if fix and options['auto_fix']:
|
||||
print('[+] Automatically fixed {0}'.format(filename))
|
||||
pre_section.text = fixed_text
|
||||
print(fixed_text)
|
||||
tree.write(filename)
|
||||
close_file(filename)
|
||||
return result
|
||||
|
||||
|
||||
def validate_master(filename, findings, non_findings, scans, options):
|
||||
"""
|
||||
Validates master file.
|
||||
"""
|
||||
result = True
|
||||
include_findings = []
|
||||
include_nonfindings = []
|
||||
print_output(options, 'Validating master file {0}'.format(filename))
|
||||
try:
|
||||
xmltree = ElementTree.parse(filename,
|
||||
ElementTree.XMLParser(strip_cdata=False))
|
||||
if not find_keyword(xmltree, 'TODO', filename):
|
||||
print('[-] Keyword checks failed for {0}'.format(filename))
|
||||
result = False
|
||||
print_output(options, 'Performing cross check on findings, non-findings and scans...')
|
||||
for finding in findings:
|
||||
if not cross_check_file(filename, finding):
|
||||
print('[A] Cross check failed for finding {0}'.
|
||||
format(finding))
|
||||
include_findings.append(finding)
|
||||
result = False
|
||||
for non_finding in non_findings:
|
||||
if not cross_check_file(filename, non_finding):
|
||||
print('[A] Cross check failed for non-finding {0}'.
|
||||
format(non_finding))
|
||||
include_nonfindings.append(non_finding)
|
||||
result = False
|
||||
if result:
|
||||
print_output(options, 'Cross checks successful')
|
||||
except (ElementTree.ParseError, IOError) as exception:
|
||||
print('[-] validating {0} failed ({1})'.format(filename, exception))
|
||||
result = False
|
||||
if not result:
|
||||
if options['auto_fix']:
|
||||
add_include(filename, 'findings', include_findings)
|
||||
add_include(filename, 'nonFindings', include_nonfindings)
|
||||
close_file(filename)
|
||||
print('[+] Automatically fixed {0}'.format(filename))
|
||||
else:
|
||||
print('[+] NOTE: Items with [A] can be fixed automatically, use --auto-fix')
|
||||
return result
|
||||
|
||||
|
||||
def report_string(report_file):
|
||||
"""
|
||||
Return the report_file into a big memory mapped string.
|
||||
"""
|
||||
try:
|
||||
report = open(report_file)
|
||||
return mmap.mmap(report.fileno(), 0, access=mmap.ACCESS_READ)
|
||||
except IOError as exception:
|
||||
print('[-] Could not open {0} ({1})'.format(report_file, exception))
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def cross_check_file(filename, external):
|
||||
"""
|
||||
Checks whether filename contains a cross-check to the file external.
|
||||
"""
|
||||
result = True
|
||||
report_text = report_string(filename)
|
||||
if report_text.find(external) == -1:
|
||||
print('[-] could not find a reference in {0} to {1}'.format(filename, external))
|
||||
result = False
|
||||
return result
|
||||
|
||||
|
||||
def add_include(filename, identifier, findings):
|
||||
"""
|
||||
Adds XML include based on the identifier ('findings' or 'nonFindings').
|
||||
"""
|
||||
tree = ElementTree.parse(filename, ElementTree.XMLParser(strip_cdata=False))
|
||||
root = tree.getroot()
|
||||
for section in tree.iter('section'):
|
||||
if section.attrib['id'] == identifier:
|
||||
finding_section = section
|
||||
if finding_section is not None:
|
||||
for finding in findings:
|
||||
new_finding = ElementTree.XML('<placeholderinclude href="../{0}"/>'.format(finding))
|
||||
finding_section.append(new_finding)
|
||||
tree.write(filename, encoding="utf-8", xml_declaration=True, pretty_print=True)
|
||||
|
||||
|
||||
def close_file(filename):
|
||||
"""
|
||||
Replace placeholder with proper XML include.
|
||||
"""
|
||||
f = open(filename, 'r')
|
||||
filedata = f.read()
|
||||
f.close()
|
||||
newdata = filedata.replace("placeholderinclude", "xi:include")
|
||||
fileout = filename
|
||||
f = open(fileout, 'w')
|
||||
f.write(newdata)
|
||||
f.close()
|
||||
tree = ElementTree.parse(filename, ElementTree.XMLParser(strip_cdata=False))
|
||||
tree.write(filename, encoding="utf-8", xml_declaration=True, pretty_print=True)
|
||||
|
||||
def find_keyword(xmltree, keyword, filename):
|
||||
"""
|
||||
Finds keywords in an XML tree.
|
||||
This function needs lots of TLC.
|
||||
"""
|
||||
result = True
|
||||
section = ''
|
||||
for tag in xmltree.iter():
|
||||
if tag.tag == 'section' and' id' in tag.attrib:
|
||||
section = 'in {0}'.format(tag.attrib['id'])
|
||||
if tag.text:
|
||||
if keyword in tag.text:
|
||||
print('[-] {0} found in {1} {2}'.format(keyword, filename, section))
|
||||
result = False
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
The main program. Cross-checks, validates XML files and report.
|
||||
Returns True if the checks were successful.
|
||||
"""
|
||||
# we want to print pretty Unicode characters
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
options = parse_arguments()
|
||||
if options['all']:
|
||||
options['capitalization'] = True
|
||||
options['long'] = True
|
||||
if options['learn']:
|
||||
print_output(options, 'Adding unknown words to {0}'.format(VOCABULARY))
|
||||
# if options['spelling']:
|
||||
# if not os.path.exists(VOCABULARY):
|
||||
# print_output(options, 'Creating project-specific vocabulary file {0}'.
|
||||
# format(VOCABULARY))
|
||||
# options['learn'] = True
|
||||
print_output(options, 'Validating all XML files...')
|
||||
result = validate_files(all_files(), options)
|
||||
if result:
|
||||
print_output(options, 'Validation checks successful')
|
||||
if DOCBUILDER:
|
||||
print_output(options, 'Validating report build...')
|
||||
result = validate_report() and result
|
||||
if result:
|
||||
print('[+] Succesfully validated everything. Good to go')
|
||||
else:
|
||||
print('[-] Errors occurred')
|
||||
if options['spelling'] and options['learn']:
|
||||
print('[*] Don\'t forget to check the vocabulary file {0}'.
|
||||
format(VOCABULARY))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
271
chatops/scripts/rosbot.coffee
Normal file
271
chatops/scripts/rosbot.coffee
Normal file
@@ -0,0 +1,271 @@
|
||||
# Description:
|
||||
# Allows hubot to execute PenText framework commands
|
||||
#
|
||||
# Dependencies:
|
||||
# The PenText framework
|
||||
#
|
||||
# Configuration:
|
||||
# See the various handlers in bash/
|
||||
#
|
||||
# Usage:
|
||||
# build
|
||||
# Builds a .pdf document of <type> based on files in <repository>. The file is stored in target/ of the specified repository.
|
||||
# Usage: build <type> <repository> [namespace=ros] [branch=master] [-v]
|
||||
# <type> Can be either report or quote
|
||||
# <repository> Specifies the name of the gitlab repository where the files needed to do the job are located.
|
||||
# [namespace] This optional parameter refers to the gitlab user or group this repository is part of. Defaults to ros
|
||||
# [branch] This optional parameter specifies which branch to use. Defaults to master.
|
||||
# [-v] Specifying this flag will yield verbose output.
|
||||
#
|
||||
# convert
|
||||
# Converts gitlab issues in <respository> to xml files. The issues must be open and need to be labelled with either finding or non-finding.
|
||||
# Depending on the label, the xml files will be put in either the finding/ or non-finding/ directory in the repository.
|
||||
# Usage: convert <repository> [--closed] [--dry-run] [--issues] [--projects] [-v|--verbose] [-y]
|
||||
# <repository> Specifies the name of the gitlab repository where the files needed to do the job are located.
|
||||
# [--closed] If specified, will include closed issues
|
||||
# [--dry-run] If specified, will not write xml files, but only displays output on screen
|
||||
# [--issues] If specified, will list issues in given <repository>
|
||||
# [--projects] If specified, will list gitlab repositories
|
||||
# [-v|--verbose] If specified, will yield verbose output
|
||||
# [-y] Assumes yes on all questions
|
||||
#
|
||||
# validate
|
||||
# Validates the XML structure of a reports or quote to be able to generate a .pdf file. (See build command)
|
||||
# Usage: validate <repository> [-a|-all] [--autofix] [-c|--capitalization] [--debug] [--edit] [--learn] [--long] [--offer] [--spelling] [-v|--verbose] [--no-report] [--quiet]
|
||||
# <repository> Specifies the name of the gitlab repository where the files needed to do the job are located.
|
||||
# [-a|-all] Perform all checks
|
||||
# [--autofix] Try to automatically correct issues
|
||||
# [-c|--capitalization] Check capitalization
|
||||
# [--debug] Show debug information
|
||||
# [--edit] Open files with issues using an editor
|
||||
# [--learn] Store all unknown words in dictionary file
|
||||
# [--long] Check for long lines
|
||||
# [--offer] Validate offer master file
|
||||
# [--spelling] Check spelling
|
||||
# [-v|--verbose] If specified, will yield verbose output
|
||||
# [--no-report] Do not validate report master file
|
||||
# [--quiet] Don't output status messages
|
||||
#
|
||||
#
|
||||
# Commands:
|
||||
# hubot build <type> <repo> <target> - Builds a .pdf file from <target> in <repo>
|
||||
# hubot convert <repo> <target> - Builds a .xml file from <target> in <repo>
|
||||
# hubot invoice <repo> <target> - Builds pdf invoice from quote
|
||||
# hubot quickscope <repo> <namespace> [branch=MASTER] - Converts quickscope into quotation
|
||||
# hubot startpentest <name> - Bootstraps a pentest
|
||||
# hubot startquote <name> - Bootstraps a quotation
|
||||
# hubot validate <parms..> - Validates a report/quotation
|
||||
# hubot usage [command] - Displays usage information for command. If no command is specified, supported commands are displayed.
|
||||
#
|
||||
|
||||
# Author:
|
||||
# Peter Mosmans
|
||||
# John Sinteur
|
||||
# Daniel Attevelt
|
||||
#
|
||||
# This is part of the PenText framework
|
||||
#
|
||||
|
||||
USAGE_LABEL = '# Usage:'
|
||||
|
||||
Fs = require 'fs'
|
||||
Path = require 'path'
|
||||
|
||||
admins = ['peter']
|
||||
|
||||
###
|
||||
This will initialise the usage information for the chatops command used in the pentext framework
|
||||
It will parse the file comment sections in search of usage information. See above for an example
|
||||
|
||||
! This section should always be above the commands section and should always be terminated by two consecutive #s !
|
||||
! Only single word commands are supported !
|
||||
|
||||
robot gets a new property .usages which can be used later on
|
||||
###
|
||||
init_usage = (robot) ->
|
||||
robot.usages = []
|
||||
|
||||
load_scripts(robot)
|
||||
|
||||
###
|
||||
This will load all the scripts in the same folder as this one. It will then proceed
|
||||
to parsing those scripts in order to extract the rosbot command usage information
|
||||
###
|
||||
load_scripts = (robot) ->
|
||||
if Fs.existsSync(__dirname)
|
||||
for file in Fs.readdirSync(__dirname).sort()
|
||||
fullPath = Path.join __dirname, file
|
||||
robot.logger.info "File: " + fullPath
|
||||
|
||||
body = Fs.readFileSync fullPath, 'utf-8'
|
||||
parse_scripts(robot, body)
|
||||
|
||||
###
|
||||
This function will parse the script for usage information.
|
||||
It will do so by looping through every comment line until it hits the # Usage: label
|
||||
Then it will start to look for a command tag that is identified by:
|
||||
# (3 spaces) <command>. The will let the function know it's dealing with a command identifiers.
|
||||
# (5 spaces) <infoline> lets the function know it's dealing with info line that should go together with the previously encountered command.
|
||||
|
||||
The sequence is broken by two sequential empty comment lines. e.g.:
|
||||
#
|
||||
#
|
||||
|
||||
###
|
||||
parse_scripts = (robot, body) ->
|
||||
parsing_usage = false
|
||||
current_command = null
|
||||
|
||||
# https://regex101.com
|
||||
cmd_regex = /^#[ ]{3}[\S]+/i
|
||||
info_regex = /^#[ ]{5}[\S]+/i
|
||||
|
||||
# Loop through each comment line until there is none.
|
||||
for line in body.split "\n"
|
||||
break unless line[0] is '#' or line.substr(0, 2) is '//'
|
||||
|
||||
# Determine if we've reached the Usage: tag
|
||||
if line.indexOf(USAGE_LABEL) != -1
|
||||
parsing_usage = true
|
||||
|
||||
if parsing_usage
|
||||
# Pre-cleaning ...
|
||||
cleanedLine = line.replace(/^(#|\/\/)\s?/, "").trim()
|
||||
|
||||
# Are we dealing with a command?
|
||||
if line.match cmd_regex
|
||||
current_command = cleanedLine
|
||||
robot.usages[current_command] = []
|
||||
|
||||
# Are we dealing with an info line ?
|
||||
if line.match info_regex
|
||||
if not robot.usages[current_command]
|
||||
robot.logger.debug "Error parsing chatpos usage info: found info line, but no command line"
|
||||
else
|
||||
robot.usages[current_command].push cleanedLine
|
||||
|
||||
# Detects two sequential #'s and quits parsing usage when it does
|
||||
if cleanedLine.length == 0
|
||||
if current_command == null
|
||||
parsing_usage = false
|
||||
else
|
||||
current_command = null
|
||||
|
||||
# Sanity check
|
||||
robot.logger.info "--- Following usage information parsed ----"
|
||||
for command, lines of robot.usages
|
||||
for index, line of lines
|
||||
robot.logger.info "* #{command} : #{line}"
|
||||
|
||||
module.exports = (robot) ->
|
||||
run_cmd = (cmd, args, cb ) ->
|
||||
spawn = require("child_process").spawn
|
||||
child = spawn(cmd, args)
|
||||
child.stdout.on "data", (buffer) -> cb buffer.toString()
|
||||
child.stderr.on "data", (buffer) -> cb buffer.toString()
|
||||
|
||||
init_usage(robot)
|
||||
|
||||
|
||||
# ***************************************************************************
|
||||
# ChatOps command handlers
|
||||
# ***************************************************************************
|
||||
|
||||
robot.respond /build (.*)/i, id:'chatops.build', (msg) ->
|
||||
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
|
||||
msg.match.shift();
|
||||
args = msg.match[0].split(" ");
|
||||
cmd = "bash/handler_build";
|
||||
run_cmd cmd, args, (text) -> msg.send text.replace("\n","");
|
||||
|
||||
robot.respond /convert (.*)/i, id:'chatops.convert', (msg) ->
|
||||
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
|
||||
msg.match.shift();
|
||||
args = msg.match[0].split(" ");
|
||||
cmd = "bash/handler_convert";
|
||||
run_cmd cmd, args, (text) -> msg.send text.replace("\n","");
|
||||
|
||||
robot.respond /invoice (.*)/i, id:'chatops.invoice', (msg) ->
|
||||
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
|
||||
msg.match.shift();
|
||||
args = msg.match[0].split(" ");
|
||||
cmd = "bash/handler_invoice";
|
||||
run_cmd cmd, args, (text) -> msg.send text.replace("\n","");
|
||||
|
||||
robot.respond /quickscope (.*)/i, id:'chatops.quickscope', (msg) ->
|
||||
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
|
||||
msg.match.shift();
|
||||
args = msg.match[0].split(" ");
|
||||
cmd = "bash/handler_quickscope";
|
||||
run_cmd cmd, args, (text) -> msg.send text.replace("\n","");
|
||||
|
||||
robot.respond /startpentest (.*)/i, id:'chatops.startpentest', (msg) ->
|
||||
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
|
||||
msg.match.shift();
|
||||
args = msg.match[0].split(" ");
|
||||
if args[0].substring(0, 4) == "off-"
|
||||
msg.send "[-] Please do not start pen names with off-";
|
||||
return;
|
||||
if args[0].substring(0, 4) == "pen-"
|
||||
msg.send "[-] Please do not start pen names with pen-";
|
||||
return;
|
||||
roomName = "pen-" + args[0];
|
||||
newroom = robot.adapter.callMethod('createPrivateGroup', roomName, admins)
|
||||
msg.send "[+] new channel created - Added " + admins + " to the new room " + roomName
|
||||
newroom.then (roomId) =>
|
||||
robot.messageRoom roomId.rid, "@all hello!"
|
||||
args[1] = roomId.rid
|
||||
cmd = "bash/handler_pentest";
|
||||
run_cmd cmd, args, (text) -> msg.send text.replace("\n","");
|
||||
|
||||
robot.respond /startquote (.*)/i, id:'chatops.startquote',(msg) ->
|
||||
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
|
||||
msg.match.shift();
|
||||
args = msg.match[0].split(" ");
|
||||
if args[0].substring(0, 4) == "pen-"
|
||||
msg.send "[-] Please do not start quote names with pen-";
|
||||
return;
|
||||
if args[0].substring(0, 4) == "off-"
|
||||
msg.send "[-] Please do not start quote names with off-";
|
||||
return;
|
||||
roomName = "off-" + args[0]
|
||||
newroom = robot.adapter.callMethod('createPrivateGroup', roomName, admins)
|
||||
msg.send "[+] new channel created - Added " + admins + " to the new room " + roomName
|
||||
newroom.then (roomId) =>
|
||||
robot.messageRoom roomId.rid, "@all hello!"
|
||||
cmd = "bash/handler_quote";
|
||||
run_cmd cmd, args, (text) -> msg.send text.replace("\n","");
|
||||
|
||||
robot.respond /validate (.*)/i, id:'chatops.validate', (msg) ->
|
||||
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
|
||||
msg.match.shift();
|
||||
args = msg.match[0].split(" ");
|
||||
cmd = "bash/handler_validate";
|
||||
run_cmd cmd, args, (text) -> msg.send text.replace("\n","");
|
||||
|
||||
|
||||
# Handler for the usage command.
|
||||
# Note that the regex option group (.*) also captures the space after the command
|
||||
# This allows for the case when there is no command specified, supported commands can be displayed
|
||||
robot.respond /usage(.*)/i, id:'chatops.usage', (msg) ->
|
||||
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
|
||||
msg.match.shift();
|
||||
args = msg.match[0].trim().split(" ");
|
||||
command = args[0]
|
||||
|
||||
# If not command is provided, return information on which commands can be handled
|
||||
if command.trim().length == 0
|
||||
msg.send "I can provide usage information for the following commands:"
|
||||
for command of robot.usages
|
||||
msg.send command
|
||||
msg.send "Issue the command: usage <command> for usage information for this command"
|
||||
return
|
||||
|
||||
# This deals when unsupported commands
|
||||
if not robot.usages[command]
|
||||
msg.send "I have no usage information for: " + command
|
||||
return
|
||||
|
||||
# All odd case have been dealt with, let's get down to business
|
||||
for index, line of robot.usages[command]
|
||||
msg.send line
|
||||
56
pull_upstream_changes.sh
Normal file
56
pull_upstream_changes.sh
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# pull_upstream_changes - Updates repo and applies upstream changes
|
||||
#
|
||||
# Copyright (C) 2016 Peter Mosmans [Radically Open Security]
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
# File which has to exist in the target directory to qualify as target
|
||||
FINGERPRINT="dtd"
|
||||
# List of files and directories that need to be updated
|
||||
SOURCEFILES="dtd xslt"
|
||||
# Root directory within source repo
|
||||
SOURCEROOT="xml"
|
||||
|
||||
|
||||
## Don't change anything below this line
|
||||
VERSION=0.6
|
||||
|
||||
source=$(dirname $(readlink -f $0))
|
||||
target=$1
|
||||
|
||||
if [ -z "$target" ]; then
|
||||
target=$(readlink -f .)
|
||||
if [ "${target}" == "${source}" ]; then
|
||||
echo "Usage: pull_upstream_changes [TARGET]"
|
||||
echo " or run from within target directory"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if the target actually contains the repository
|
||||
if [ ! -z ${FINGERPRINT} ] && [ ! -d $target/dtd ]; then
|
||||
echo "[-] ${target} does not contain the correct repository"
|
||||
exit
|
||||
fi
|
||||
|
||||
# Update repository
|
||||
echo "[*] Updating source repository (${source})..."
|
||||
pushd "$source" >/dev/null && git pull && popd >/dev/null
|
||||
|
||||
# Only update newer files
|
||||
echo "[*] Applying changes (if any)..."
|
||||
for sourcefile in ${SOURCEFILES}; do
|
||||
if [ -d "${source}/${SOURCEROOT}/${sourcefile}" ]; then
|
||||
cp -prv ${source}/${SOURCEROOT}/${sourcefile} $target/
|
||||
else
|
||||
cp -pv ${source}/${SOURCEROOT}/${sourcefile} $target/${sourcefile}
|
||||
fi
|
||||
done
|
||||
echo "[+] Done"
|
||||
|
||||
@@ -28,7 +28,7 @@ Download Saxon Home Edition (HE) 9.6 **for Java** at: http://saxon.sourceforge.n
|
||||
|
||||
### FOP
|
||||
|
||||
Download Apache FOP 1.1 at https://xmlgraphics.apache.org/fop/download.html and unzip.
|
||||
Download Apache FOP 2.1 at https://xmlgraphics.apache.org/fop/download.html and unzip.
|
||||
|
||||
### Fonts
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<quickscope xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:xml="http://www.w3.org/XML/1998/namespace">
|
||||
<!-- Today's date -->
|
||||
<version date="2015-01-01"/>
|
||||
<!-- YYYY-MM-DD -->
|
||||
xmlns:xml="http://www.w3.org/XML/1998/namespace"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../dtd/quickscope.xsd">
|
||||
|
||||
<!-- COMPANY INFO -->
|
||||
<xi:include href="client_info.xml"/>
|
||||
|
||||
@@ -20,26 +20,26 @@
|
||||
<!-- Which targets will need to be tested?
|
||||
(one <target> element for each piece of software/service/server address/location...), delete/add as necessary -->
|
||||
<targets>
|
||||
<target>target1.sittingduck.com</target>
|
||||
<target>target2.sittingduck.com</target>
|
||||
<target>FishInABarral App</target>
|
||||
<target>target1.target.com</target>
|
||||
<target>target2.target.com</target>
|
||||
</targets>
|
||||
</meta>
|
||||
<!-- Some information about any third parties involved with the software/service to be tested, if applicable.
|
||||
If not applicable, delete the whole <third_party> element. If more parties are needed, add <third_party> elements -->
|
||||
<!-- Do we need permission from third parties? Insert as many <third_party> elements as needed under this comment -->
|
||||
<third_party>
|
||||
<full_name>HotshotDevs Inc.</full_name>
|
||||
<short_name>HotshotDevs</short_name>
|
||||
<full_name>Third Party BV</full_name>
|
||||
<short_name>Third Party</short_name>
|
||||
<!-- Name of the person who will need to sign the waiver for this vendor -->
|
||||
<waiver_rep>Hotshot Dev Lawyer</waiver_rep>
|
||||
<address>Silicon Valley St. 50</address>
|
||||
<city>San Francisco</city>
|
||||
<country>US</country>
|
||||
<waiver_rep>TP Waiver Rep</waiver_rep>
|
||||
<address>TP Street 123</address>
|
||||
<city>TP City</city>
|
||||
<country>TP Country</country>
|
||||
</third_party>
|
||||
|
||||
<pentest_info>
|
||||
<!-- How long would you like the test to be? (in days) -->
|
||||
<days>10</days>
|
||||
<days>6</days>
|
||||
<!-- How many mandays (if you don't know, try days * number of assigned pentesters) -->
|
||||
<mandays>12</mandays>
|
||||
<!-- Service execution (Use one of the following values: time-boxed, subscription) -->
|
||||
<nature>time-boxed</nature>
|
||||
<!-- Testing type (Use one of the following values: crystal-box, black-box, grey-box) -->
|
||||
@@ -52,10 +52,11 @@
|
||||
<delivery>TBD</delivery>
|
||||
<!-- Do you need/want a code audit? (possible values: yes/no), only for pentest -->
|
||||
<codeaudit perform="yes"/>
|
||||
<!-- Is there an application that needs to be tested? Type its name below. If not, please DELETE <application_name> element -->
|
||||
<application_name>FishInABarrel</application_name>
|
||||
<!-- Is there an application that needs to be tested? Add an <application_name> element below. -->
|
||||
<application_name>AppToTest</application_name>
|
||||
|
||||
<!-- rate (to be filled in by ROS ;) -->
|
||||
<rate>1000000</rate>
|
||||
<rate>40000</rate>
|
||||
|
||||
</pentest_info>
|
||||
</quickscope>
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
<xs:element name="invoice_mail" type="emailAddress"/>
|
||||
|
||||
<xs:element name="duration" type="xs:nonNegativeInteger"/>
|
||||
<xs:element name="mandays" type="xs:nonNegativeInteger"/>
|
||||
<xs:element name="test_planning" type="xs:string"/>
|
||||
<xs:element name="report_due" type="xs:string"/>
|
||||
<xs:element name="nature" type="xs:string"/>
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
|
||||
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd" />
|
||||
<xs:import namespace="http://www.w3.org/2001/XInclude" schemaLocation="http://www.w3.org/2001/XInclude/XInclude.xsd"/>
|
||||
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
||||
<xs:import namespace="http://www.w3.org/2001/XInclude"
|
||||
schemaLocation="http://www.w3.org/2001/XInclude/XInclude.xsd"/>
|
||||
<xs:include schemaLocation="common.xsd"/>
|
||||
|
||||
|
||||
<xs:element name="generic_document">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="meta"/>
|
||||
<xs:element ref="generate_index"/>
|
||||
<xs:element ref="section" maxOccurs="unbounded"/>
|
||||
<xs:element ref="appendix" maxOccurs="unbounded"/>
|
||||
<xs:element ref="appendix" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
||||
<xs:element name="meta">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@@ -27,9 +29,9 @@
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
||||
<xs:element name="subtitle" type="xs:string"/>
|
||||
|
||||
|
||||
<xs:element name="collaborators">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@@ -38,7 +40,7 @@
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
||||
<xs:element name="reviewers">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@@ -46,9 +48,9 @@
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
||||
<xs:element name="reviewer" type="xs:string"/>
|
||||
|
||||
|
||||
<xs:element name="approver">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@@ -57,10 +59,10 @@
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
||||
<xs:element name="bio" type="xs:string"/>
|
||||
<xs:element name="classification" type="xs:NCName"/>
|
||||
|
||||
|
||||
<xs:element name="section">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@@ -84,7 +86,7 @@
|
||||
<xs:attribute ref="xml:base"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
||||
<xs:element name="appendix">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
@@ -105,10 +107,18 @@
|
||||
<xs:attribute ref="visibility" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
|
||||
<!-- Placeholders -->
|
||||
|
||||
<xs:complexType name="block" mixed="true">
|
||||
<xs:choice maxOccurs="unbounded">
|
||||
<xs:group ref="inline-all"/>
|
||||
<xs:group ref="placeholders"/>
|
||||
</xs:choice>
|
||||
<xs:attribute ref="xml:base"/>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Placeholders -->
|
||||
|
||||
<xs:group name="placeholders">
|
||||
<xs:choice></xs:choice>
|
||||
<xs:choice/>
|
||||
</xs:group>
|
||||
</xs:schema>
|
||||
|
||||
@@ -14,15 +14,16 @@
|
||||
<xs:element ref="servicesdelivered" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element ref="additionalcosts" minOccurs="0" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute ref="xml:lang"/>
|
||||
<xs:attribute name="invoice_no" type="xs:string"/>
|
||||
<xs:attribute name="date" type="xs:date" use="optional"/>
|
||||
<xs:attribute name="denomination" use="required">
|
||||
<xs:attribute name="denomination" use="optional" default="eur">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="eur"/>
|
||||
<xs:enumeration value="gbp"/>
|
||||
<xs:enumeration value="usd"/>
|
||||
</xs:restriction>
|
||||
<xs:enumeration value="eur"/>
|
||||
<xs:enumeration value="usd"/>
|
||||
<xs:enumeration value="gbp"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="duration"/>
|
||||
<xs:element ref="mandays"/>
|
||||
<xs:element ref="test_planning"/>
|
||||
<xs:element ref="report_due"/>
|
||||
<xs:element ref="nature"/>
|
||||
|
||||
78
xml/dtd/quickscope.xsd
Normal file
78
xml/dtd/quickscope.xsd
Normal file
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd" />
|
||||
<xs:import namespace="http://www.w3.org/2001/XInclude" schemaLocation="http://www.w3.org/2001/XInclude/XInclude.xsd"/>
|
||||
<xs:include schemaLocation="common.xsd"/>
|
||||
<xs:element name="quickscope">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="client"/>
|
||||
<xs:element ref="meta"/>
|
||||
<xs:element ref="third_party" minOccurs="0"/>
|
||||
<xs:element ref="pentest_info"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="meta">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="offer_language"/>
|
||||
<xs:element ref="offer_type"/>
|
||||
<xs:element ref="requested_service"/>
|
||||
<xs:element ref="targets"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="offer_language" type="xs:NCName"/>
|
||||
<xs:element name="offer_type" type="xs:NCName"/>
|
||||
<xs:element name="requested_service" type="xs:string"/>
|
||||
<xs:element name="third_party">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="full_name" minOccurs="1"/>
|
||||
<xs:element ref="short_name"/>
|
||||
<xs:element ref="waiver_rep"/>
|
||||
<xs:element ref="address"/>
|
||||
<xs:element ref="city"/>
|
||||
<xs:element ref="country"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="pentest_info">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="days"/>
|
||||
<xs:element ref="mandays"/>
|
||||
<xs:element ref="nature"/>
|
||||
<xs:element ref="type"/>
|
||||
<xs:element ref="planning"/>
|
||||
<xs:element ref="delivery"/>
|
||||
<xs:element ref="codeaudit"/>
|
||||
<xs:element ref="application_name" minOccurs="0"/>
|
||||
<xs:element ref="rate"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="days" type="xs:integer"/>
|
||||
<xs:element name="mandays" type="xs:integer"/>
|
||||
<xs:element name="planning" type="xs:NCName"/>
|
||||
<xs:element name="delivery" type="xs:NCName"/>
|
||||
<xs:element name="codeaudit">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="perform" use="required" type="xs:NCName"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="application_name" type="xs:NCName"/>
|
||||
<xs:element name="rate" type="xs:integer"/>
|
||||
|
||||
<xs:complexType name="block" mixed="true">
|
||||
<xs:choice maxOccurs="unbounded">
|
||||
<xs:group ref="inline-all"/>
|
||||
<xs:group ref="placeholders"/>
|
||||
</xs:choice>
|
||||
<xs:attribute ref="xml:base"/>
|
||||
</xs:complexType>
|
||||
<xs:group name="placeholders">
|
||||
<xs:choice/>
|
||||
</xs:group>
|
||||
</xs:schema>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<xs:import schemaLocation="pentestreport.xsd"/>
|
||||
<xs:import namespace="http://www.w3.org/2001/XInclude" schemaLocation="xi.xsd"/>
|
||||
<xs:attribute name="noNamespaceSchemaLocation"/>
|
||||
</xs:schema>
|
||||
@@ -79,7 +79,7 @@ the location of this file.
|
||||
<!--
|
||||
<directory recursive="true">/Library/Fonts/</directory>
|
||||
-->
|
||||
<font kerning="yes" embed-url="LiberationSansNarrow-Regular-webfont.ttf">
|
||||
<font kerning="yes" embed-url="LiberationSansNarrow-Regular.ttf">
|
||||
<font-triplet name="LiberationSansNarrow" style="normal" weight="normal"/>
|
||||
</font>
|
||||
<font kerning="yes" embed-url="LiberationSansNarrow-Bold.ttf">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<quickscope xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:xml="http://www.w3.org/XML/1998/namespace">
|
||||
<!-- Today's date -->
|
||||
<version date="2015-01-01"/>
|
||||
<!-- YYYY-MM-DD -->
|
||||
<!-- CLIENT INFO -->
|
||||
xmlns:xml="http://www.w3.org/XML/1998/namespace"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../dtd/quickscope.xsd">
|
||||
|
||||
<!-- COMPANY INFO -->
|
||||
<xi:include href="client_info.xml"/>
|
||||
|
||||
<!-- SERVICE INFO -->
|
||||
@@ -16,29 +16,23 @@
|
||||
<offer_type>pentest</offer_type>
|
||||
<!-- Required service -->
|
||||
<!-- Note: is only used when type is 'other', if offer_type is a specific type, service name will be taken from the localisation strings -->
|
||||
<requested_service></requested_service>
|
||||
<!-- Which targets will need to be tested?
|
||||
(one <target> element for each piece of software/service/server address/location...), delete/add as necessary -->
|
||||
<requested_service>penetration testing services</requested_service>
|
||||
<!-- Which targets will need to be tested?
|
||||
(one <target> element for each piece of software/service/server address/location...), delete/add as necessary -->
|
||||
<targets>
|
||||
<target></target>
|
||||
<target></target>
|
||||
</targets>
|
||||
</meta>
|
||||
<!-- Some information about any third parties involved with the software/service to be tested, if applicable.
|
||||
If not applicable, delete the whole <third_party> element. If more parties are needed, add <third_party> elements -->
|
||||
<third_party>
|
||||
<full_name></full_name>
|
||||
<short_name></short_name>
|
||||
<!-- Name of the person who will need to sign the waiver for this vendor -->
|
||||
<waiver_rep></waiver_rep>
|
||||
<address></address>
|
||||
<city></city>
|
||||
<country></country>
|
||||
</third_party>
|
||||
|
||||
<!-- Do we need permission from third parties? Insert as many <third_party> elements as needed under this comment -->
|
||||
<!-- INSERT OPTIONAL THIRD PARTIES HERE -->
|
||||
|
||||
<!-- ___________________________________ -->
|
||||
<pentest_info>
|
||||
<!-- How long would you like the test to be? (in days) -->
|
||||
<days></days>
|
||||
<days>0</days>
|
||||
<!-- How many mandays (if you don't know, try days * number of assigned pentesters) -->
|
||||
<mandays>0</mandays>
|
||||
<!-- Service execution (Use one of the following values: time-boxed, subscription) -->
|
||||
<nature>time-boxed</nature>
|
||||
<!-- Testing type (Use one of the following values: crystal-box, black-box, grey-box) -->
|
||||
@@ -51,8 +45,11 @@
|
||||
<delivery>TBD</delivery>
|
||||
<!-- Do you need/want a code audit? (possible values: yes/no), only for pentest -->
|
||||
<codeaudit perform="yes"/>
|
||||
<!-- Is there an application that needs to be tested? Type its name below. If not, please DELETE <application_name> element -->
|
||||
<application_name></application_name>
|
||||
<!-- Is there an application that needs to be tested? Add an <application_name> element below. -->
|
||||
<!-- INSERT OPTIONAL APPLICATION NAME HERE -->
|
||||
|
||||
<!-- ___________________________________ -->
|
||||
|
||||
<!-- rate (to be filled in by ROS ;) -->
|
||||
<rate>0</rate>
|
||||
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<pentest_report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xsi:noNamespaceSchemaLocation="../dtd/pentestreport.xsd"
|
||||
xml:lang="en"
|
||||
findingCode="XXX">
|
||||
<meta>
|
||||
<title>Penetration Test Report</title>
|
||||
<xi:include href="client_info.xml"/>
|
||||
<targets><!--one target element per target-->
|
||||
<target>dsfsd</target>
|
||||
<target>adfsd</target>
|
||||
</targets>
|
||||
<collaborators>
|
||||
<reviewers>
|
||||
<reviewer>FirstName LastName</reviewer>
|
||||
</reviewers>
|
||||
<approver>
|
||||
<name>Melanie Rieback</name>
|
||||
<bio>Melanie Rieback is a former Asst. Prof. of Computer Science from the
|
||||
VU, who is also the co-founder/CEO of Radically Open Security.</bio>
|
||||
</approver>
|
||||
<pentesters>
|
||||
<pentester>
|
||||
<name>FirstName LastName</name>
|
||||
<bio>Info</bio>
|
||||
</pentester>
|
||||
</pentesters>
|
||||
</collaborators>
|
||||
<classification>Confidential</classification>
|
||||
<version_history><!--needed for date on frontpage and in signature boxes; it is possible to add a new <version> after each review; in that case, make sure to update the date/time-->
|
||||
<version number="auto" date="2016-08-25T10:00:00"><!--actual date-time here; you can leave the number attribute alone-->
|
||||
<v_author>ROS Writer</v_author>
|
||||
<!--name of the author here; for internal use only-->
|
||||
<v_description>Initial draft</v_description>
|
||||
<!--for internal use only-->
|
||||
</version>
|
||||
</version_history>
|
||||
<xi:include href="snippets/company_info.xml"/>
|
||||
</meta>
|
||||
<generate_index/>
|
||||
<section id="executiveSummary">
|
||||
<title>Executive Summary</title>
|
||||
<section id="introduction">
|
||||
<title>Introduction</title>
|
||||
<p>...</p>
|
||||
<p>This report contains our findings as well as detailed explanations of exactly
|
||||
how ROS performed the penetration test.</p>
|
||||
</section>
|
||||
<section id="scope">
|
||||
<title>Scope of work</title>
|
||||
<p>The scope of the penetration test was limited to the following target:</p>
|
||||
<generate_targets/>
|
||||
</section>
|
||||
<section id="objectives">
|
||||
<title>Project objectives</title>
|
||||
<p>...</p>
|
||||
</section>
|
||||
<section id="timeline">
|
||||
<title>Timeline</title>
|
||||
<p>The Security Audit took place between X and Y, 2016.</p>
|
||||
</section>
|
||||
<xi:include href="resultsinanutshell.xml"/>
|
||||
<section id="findingSummary">
|
||||
<title>Summary of Findings</title>
|
||||
<generate_findings/>
|
||||
<!-- generated from Findings section -->
|
||||
</section>
|
||||
<section id="recommendationSummary">
|
||||
<title>Summary of Recommendations</title>
|
||||
<generate_recommendations/>
|
||||
<!-- generated from Findings section -->
|
||||
</section>
|
||||
</section>
|
||||
<xi:include href="snippets/report/methodology.xml"/>
|
||||
<section id="recon">
|
||||
<title>Reconnaissance and Fingerprinting</title>
|
||||
<p>Through automated scans we were able to gain the following information about the
|
||||
software and infrastructure. Detailed scan output can be found in the sections
|
||||
below.</p>
|
||||
<section id="scans">
|
||||
<title>Automated Scans</title>
|
||||
<p>As part of our active reconnaissance we used the following automated
|
||||
scans:</p>
|
||||
<ul><!--analyze_hosts - https://github.com/PeterMosmans/security-scripts-->
|
||||
<li>nmap – <a href="http://nmap.org">http://nmap.org</a>
|
||||
</li>
|
||||
<!--OWASP Zed Attack Proxy - https://github.com/zaproxy/zaproxy Skipfish – https://code.google.com/p/skipfish/ sqlmap – https://github.com/sqlmapproject/sqlmap testssl.sh –
|
||||
https://github.com/drwetter/testssl.sh-->
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="techSummary">
|
||||
<title>Pentest Technical Summary</title>
|
||||
<section id="findings">
|
||||
<title>Findings</title>
|
||||
<p>We have identified the following issues:</p>
|
||||
<!-- Listing of Findings (written by pentesters) -->
|
||||
<!-- Extreme -->
|
||||
<!-- High -->
|
||||
<!-- Moderate -->
|
||||
<!-- Elevated -->
|
||||
<!-- Low -->
|
||||
</section>
|
||||
<section id="nonFindings">
|
||||
<title>Non-Findings</title>
|
||||
<p>In this section we list some of the things that were tried but turned out to
|
||||
be dead ends.</p>
|
||||
</section>
|
||||
<!-- Listing of Non-Findings (written by pentesters) -->
|
||||
</section>
|
||||
<xi:include href="futurework.xml"/>
|
||||
<xi:include href="conclusion.xml"/>
|
||||
<appendix id="testteam">
|
||||
<title>Testing team</title>
|
||||
<generate_testteam/>
|
||||
</appendix>
|
||||
</pentest_report>
|
||||
@@ -55,6 +55,72 @@
|
||||
<translation xml:lang="nl">VOOR</translation>
|
||||
<translation xml:lang="en">FOR</translation>
|
||||
</string>
|
||||
<string id="page_kvk">
|
||||
<translation xml:lang="nl">Kamer van Koophandel</translation>
|
||||
<translation xml:lang="en">Chamber of Commerce</translation>
|
||||
</string>
|
||||
<string id="invoice_no">
|
||||
<translation xml:lang="nl">Factuur nr.</translation>
|
||||
<translation xml:lang="en">Invoice no.</translation>
|
||||
</string>
|
||||
<string id="invoice_fao">
|
||||
<translation xml:lang="nl">T.a.v.</translation>
|
||||
<translation xml:lang="en">F.a.o.</translation>
|
||||
</string>
|
||||
<string id="invoice_svcdeliv">
|
||||
<translation xml:lang="nl">Geleverde diensten</translation>
|
||||
<translation xml:lang="en">Services delivered</translation>
|
||||
</string>
|
||||
<string id="invoice_days">
|
||||
<translation xml:lang="nl">daagse</translation>
|
||||
<translation xml:lang="en">day</translation>
|
||||
</string>
|
||||
<string id="invoice_vat">
|
||||
<translation xml:lang="nl">BTW</translation>
|
||||
<translation xml:lang="en">VAT</translation>
|
||||
</string>
|
||||
<string id="invoice_vatno">
|
||||
<translation xml:lang="nl">BTW-nummer</translation>
|
||||
<translation xml:lang="en">VAT number</translation>
|
||||
</string>
|
||||
<string id="invoice_additional">
|
||||
<translation xml:lang="nl">Extra gemaakte kosten</translation>
|
||||
<translation xml:lang="en">Additional expenses</translation>
|
||||
</string>
|
||||
<string id="invoice_total">
|
||||
<translation xml:lang="nl">Totaal te betalen</translation>
|
||||
<translation xml:lang="en">Total amount to be paid</translation>
|
||||
</string>
|
||||
<string id="invoice_donation">
|
||||
<translation xml:lang="nl">doneert > 90% van haar totale winst aan goede doelen.</translation>
|
||||
<translation xml:lang="en">donates > 90% of its entire profits to
|
||||
charity.</translation>
|
||||
</string>
|
||||
<string id="invoice_pleasepay">
|
||||
<translation xml:lang="nl">Maak binnen 30 dagen het totale bedrag over op de volgende rekening:</translation>
|
||||
<translation xml:lang="en">Please be so kind to pay within 30 days
|
||||
by money transfer, to the following account:</translation>
|
||||
</string>
|
||||
<string id="invoice_iban">
|
||||
<translation xml:lang="nl">IBAN</translation>
|
||||
<translation xml:lang="en">IBAN</translation>
|
||||
</string>
|
||||
<string id="invoice_ref">
|
||||
<translation xml:lang="nl">Referentie</translation>
|
||||
<translation xml:lang="en">Reference</translation>
|
||||
</string>
|
||||
<string id="invoice_regards">
|
||||
<translation xml:lang="nl">Met vriendelijke groet</translation>
|
||||
<translation xml:lang="en">Kind regards</translation>
|
||||
</string>
|
||||
<string id="invoice_team">
|
||||
<translation xml:lang="nl">uw team bij</translation>
|
||||
<translation xml:lang="en">your dedicated team at</translation>
|
||||
</string>
|
||||
<string id="invoice_yaygreen">
|
||||
<translation xml:lang="nl">Spaar papier — niet afdrukken tenzij absoluut noodzakelijk. Lees onze (unieke) voorwaarden op: https://radicallyopensecurity.com/TermsandConditions.pdf</translation>
|
||||
<translation xml:lang="en">Please keep digital unless absolutely required. Read the (unique) terms and conditions of Radically Open Security at: https://radicallyopensecurity.com/TermsandConditions.pdf</translation>
|
||||
</string>
|
||||
<string id="qs2off_about">
|
||||
<translation xml:lang="nl">Over <client_short/></translation>
|
||||
<translation xml:lang="en">About <client_short/></translation>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<!-- snippet --><p><company_short/> will test for the presence of the
|
||||
most common vulnerabilities, using both publicly available vulnerability
|
||||
scanning tools and manual testing. <company_short/> shall perform a
|
||||
<p_duration/>-day, <p_boxtype/>, intrusive test via the internet.</p>
|
||||
<p_duration/>-day (<p_mandays/>-manday), <p_boxtype/>, intrusive test via the internet.</p>
|
||||
|
||||
<!-- snippet --> <!--Not Needed if Disclaimer is Included; Duplicate Text-->
|
||||
<!--p>It is possible that in the course of the penetration
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
<li><client_poc1/> (<client_short/>)</li>
|
||||
</ul>
|
||||
<!-- remove this for non pentesting offers-->
|
||||
<p>Our penetration tests are run a bit like a Capture The Flag
|
||||
(CTF) competition:
|
||||
<p>The workflow of our penetration testing team is modeled on that of a Capture The Flag (CTF) team:
|
||||
<!-- remove this for non pentesting offers-->
|
||||
|
||||
<company_long/> has a geographically distributed team
|
||||
|
||||
@@ -74,7 +74,5 @@
|
||||
evidence it has which relates to this investigation or these
|
||||
proceedings.</p>
|
||||
|
||||
<generate_waiver_signature_box/>
|
||||
|
||||
</standard_waiver>
|
||||
</waivers>
|
||||
|
||||
@@ -1,38 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<section>
|
||||
<title>Over ons <company_long/></title>
|
||||
<p><company_long/> is 's werelds eerste non-profit computer security consultancy bedrijf.
|
||||
Wij zijn een <i>Fiscaal Fondswervende Instelling</i> en in die hoedanigheid kunnen we 90 procent van onze winst
|
||||
<p><company_long/> is het eerste non-profit computer security consultancy bedrijf ter wereld.
|
||||
We zijn een <i>Fiscaal Fondswervende Instelling</i> en kunnen daardoor 90 procent van onze winst
|
||||
belastingvrij aan non-profit stichting NLnet doneren. Stichting NLnet ondersteunt al bijna twintig jaar
|
||||
open-source, digitale rechten en internet onderzoek.</p>
|
||||
open-source, digitale rechten en internetonderzoek.</p>
|
||||
|
||||
<p>Onze winst worden dus niet uitgekeerd aan aandeelhouders, investeerders of eigenaren.
|
||||
Met de winst dienen we de maatschappij. Omdat wij geen winstoogmerk hebben kunnen we de beste ethische
|
||||
veiligheidsexperts rekruteren. Met onze kernwaarden trekken we gelijkgestemde klanten aan. Wij stellen onze klanten
|
||||
in staat om met IT veiligheidsbudgetten sociaal verantwoord ondernemen te ondersteunen.
|
||||
Het hoge tempo waarmee wij groeien weerspiegelt de positieve respons van de markt op onze idealistische
|
||||
filosofie en ons innovatieve business model.</p>
|
||||
<p>Onze winst wordt dus niet uitgekeerd aan aandeelhouders, investeerders of eigenaren, maar ingezet om de maatschappij te dienen. Omdat we geen winstoogmerk hebben, kunnen we de beste ethische
|
||||
veiligheidsexperts rekruteren. Met onze kernwaarden trekken we gelijkgestemde klanten aan, die we
|
||||
in staat stellen om met hun IT-veiligheidsbudget het sociaal verantwoord ondernemen te ondersteunen.
|
||||
Ons hoge groeitempo weerspiegelt de positieve respons van de markt op onze idealistische
|
||||
filosofie en ons innovatieve businessmodel.</p>
|
||||
|
||||
<p><company_long/> heeft een aantal waarden die wij beschrijven als onze
|
||||
"Kernwaarden." Deze zijn:</p>
|
||||
<p>De waarden die <company_long/> als haar kernwaarden zou willen omschrijven zijn:</p>
|
||||
<ul>
|
||||
<li><b>Openheid van zaken</b><br/>
|
||||
Wij bouwen geen toezichtssystemen, we helpen geen hacking activisten, we verkopen geen <i>exploits</i>
|
||||
aan geheime diensten of iets in die richting. Als een opdracht ons moreel verwerpelijk lijkt, nemen
|
||||
Wij bouwen geen toezichtssystemen, hacken geen activisten en verkopen geen <i>exploits</i>
|
||||
aan geheime diensten. Als een opdracht ons moreel verwerpelijk lijkt, nemen
|
||||
we die niet aan. </li>
|
||||
<li><b>Open-Source</b><br/>
|
||||
Wij geven ALLE tools en frameworks, die wij open-source bouwen, vrij op onze website.</li>
|
||||
<li><b>Leren vissen</b><br/>
|
||||
Tijdens de samenwerken delen wij niet alleen de resultaten met onze opdrachtgevers, maar
|
||||
geven wij ook een stapsgewijze beschrijving waarmee klanten in de toekomst zelf de
|
||||
veiligheid van hun systemen kunnen testen. Wij willen graag inzichtelijk maken wat we doen. Het is geen
|
||||
Wij geven de broncode van <b>alle</b> tools en frameworks die we bouwen vrij op onze website.</li>
|
||||
<li><b>Het "<i>teach to fish</i>"-principe</b><br/>
|
||||
Tijdens het samenwerken delen we niet alleen onze bevindingen met onze opdrachtgevers, maar
|
||||
beschrijven we ook stap voor stap hoe de opdrachtgever in de toekomst zelf de
|
||||
veiligheid van zijn of haar systemen kan testen. Wij willen graag inzichtelijk maken wat we doen. Het is geen
|
||||
hogere wiskunde. We helpen klanten om hun kennis en houding ten aanzien van veiligheid te verbeteren.</li>
|
||||
<li><b>Gratis IoCs</b><br/>
|
||||
Wij geven ALLE verzamelde bedreigingen (<i>Indicators of Compromise</i>) vrij in
|
||||
een open-source <i>database</i> die iederen gratis kan gebruiken (Opgeschoond in
|
||||
overeenstemming met klanten).</li>
|
||||
<li><b>Zero days</b><br/>
|
||||
Wij verkopen geen <i>'Zero days' exploits</i> (nuldagenaanval) - wij brengen ze op verantwoorde wijze aan het licht!</li>
|
||||
<li><b>Gratis <i>IoC</i>s</b><br/>
|
||||
Wij geven <b>alle</b> verzamelde gevarenindicatoren (<i>Indicators of Compromise</i>) vrij in
|
||||
een open-source <i>database</i> die iederen gratis kan gebruiken (uiteraard gebeurt dit in overleg met de klant en worden de gegevens opgeschoond voor ze openbaar worden gemaakt).</li>
|
||||
<li><b><i>Zero days</i></b><br/>
|
||||
Wij verkopen geen <i>'Zero day' exploits</i> (pas bekend geworden kwetsbaarheden) - wij brengen ze op verantwoorde wijze aan het licht!</li>
|
||||
</ul>
|
||||
<p>Voor meer informatie over <company_long/> verwijzen wij u naar onze website:
|
||||
<a href="http://www.radicallyopensecurity.com">www.radicallyopensecurity.com</a>.</p>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<p>
|
||||
<!--snippet -->Crystal-Box vs. Black-Box pentesting verwijst naar de hoeveelheid
|
||||
informatie over het doelwit; de omgeving, architectuur, en/of applicaties die de klant
|
||||
<div>
|
||||
<p>
|
||||
Crystal-Box vs. Black-Box pentesting verwijst naar de hoeveelheid
|
||||
informatie over de doelwit omgeving, architectuur, en/of applicaties die de klant
|
||||
in eerste instantie deelt met de pentesters. Bij Black-Box testing ontvangen de
|
||||
pentesters helemaal geen informatie over het doelwit. Bij Crystal-Box tests
|
||||
pentester helemaal geen informatie over het doelwit. Bij Crystal-Box tests
|
||||
ontvangen de pentesters alle informatie die opgevraagd wordt betreffende het doelwit,
|
||||
inclusief broncode (wanneer dit relevant is), toegang tot ontwikkelaars of systeembeheer, etc...
|
||||
|
||||
<br />
|
||||
In dit geval zal <company_short/> een Black-Box test uitvoeren.
|
||||
inclusief source code (wanneer dit relevant is), toegang tot developers of systeembeheer, etc...
|
||||
</p>
|
||||
<p>
|
||||
In dit geval zal <company_short/> een Black-box test uitvoeren.
|
||||
</p></div>
|
||||
<!-- end of template -->
|
||||
@@ -1,39 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<section>
|
||||
<title>Broncode Audit</title>
|
||||
<p><company_short/> zal een broncode audit uitvoeren ter ondersteuning van pentesting.
|
||||
Gedurende een code audit onderzoeken wij handmatig de broncode van een applicatie
|
||||
<title>Broncode-audit</title>
|
||||
<p><company_short/> zal een broncode-audit uitvoeren ter ondersteuning van pentesting.
|
||||
Gedurende de code-audit onderzoeken wij handmatig de broncode van een applicatie
|
||||
om te verzekeren dat er geen kwetsbaarheden in de beveiliging zitten en gebruiken wij
|
||||
ons begrip van de code om het pentesten te leiden. Als er kwetsbaarheden gevonden worden
|
||||
documenteren wij deze en komen met suggesties om deze op te lossen. Dit wordt gedaan
|
||||
door goed-getrainde penetratie testers die zowel raw code kunnen herzien,
|
||||
als het interpreteren van de bevindingen van de geautomatiseerde scans, wat het in context brengt.</p>
|
||||
<p>Tijdens het code audit gedeelte van penetratie tests nemen wij de volgende criteria mee:</p>
|
||||
documenteren wij deze en komen met suggesties om deze op te lossen. De audit wordt uitgevoerd
|
||||
door goed getrainde penetratietesters die zowel raw code kunnen herzien
|
||||
als de bevindingen van geautomatiseerde scans interpreteren en in context brengen.</p>
|
||||
<p>Tijdens het code-audit-gedeelte van penetratietests nemen wij de volgende criteria mee:</p>
|
||||
<ol>
|
||||
<li>Risico Beoordeling en "Dreiging Modellering"<br/>
|
||||
In deze stap analyseren wij de risico's van een bepaalde applicatie of systeem.
|
||||
Dreiging Modellering is een specifieke, gestructureerde aanpak voor risico
|
||||
analyse dat ons in staat stelt om beveiligingsrisico's te identificeren,
|
||||
kwalificeren en te addresseren. Dit is de reden voor de vervlechting met
|
||||
het proces van Code Herziening. Bijvoorbeeld: Gebruiksgegevens zijn heilig.
|
||||
Wij focussen op versleutelde opslag, ontdekken of <client_short/> werknemers
|
||||
een "backdoor" in hun data hebben en snijden gestolen toestellen af
|
||||
<li>Risicobeoordeling en "Threat Modeling"<br/>
|
||||
In deze stap analyseren wij de risico's van een bepaalde toepassing of een bepaald systeem.
|
||||
"Threat modeling" is een specifieke, gestructureerde aanpak voor risico-analyse die wordt ingezet tijdens het codeherzieningsproces en die ons in staat stelt beveiligingsrisico's te identificeren, te
|
||||
kwalificeren en te addresseren. Bijvoorbeeld: Gebruiksgegevens zijn heilig.
|
||||
We controleren op versleutelde gegevensopslag, onderzoeken of <client_short/> werknemers
|
||||
een "backdoor" in hun data hebben of ontkoppelen (indien van toepassing) gestolen toestellen
|
||||
door deze op afstand te wissen en accounts in te trekken.</li>
|
||||
<li>Doel en Context<br/>
|
||||
Hier focussen wij op de risico's, voornamelijk in het snel en gemakkelijk
|
||||
delen van interne documenten en routebeschrijvingen. Accountgegevens
|
||||
zijn niet zo geheim als wij weten wie in een vergadering zit, maar
|
||||
wat besproken wordt geheim is.</li>
|
||||
Hier richten we ons vooral op de risico's, bijvoorbeeld wanneer (te) snel en gemakkelijk
|
||||
interne documenten en agenda's worden gedeeld. Accountgegevens
|
||||
zijn niet zo geheim als wij weten wie bij vergaderingen aanwezig is - zelfs als het besprokene wél geheim blijft.
|
||||
</li>
|
||||
<li>Complexiteit<br/>
|
||||
De complexiteit van het systeem zit hem in de frameworks die de
|
||||
webapplicatie ondersteunen. Wij zouden deze negeren en ons alleen richten
|
||||
op de "custom" en backend code, waarvan wij weten dat het gebaseerd is
|
||||
op .NET/ C#. We zouden ons ook focussen op implementatiefouten en bekende
|
||||
fouten in de systemen. Bijvoorbeeld: We zouden bevestigen of u de laatste
|
||||
versie van de software gebruikt, maar we zouden niet delven in het framework zelf.
|
||||
Omdat wij aannemen dat de code is geschreven door een team zal dit waarschijnlijk duidelijk
|
||||
geschreven code zijn. Als u meerdere full-release versies heeft, zullen er
|
||||
ongetwijfeld meerdere code revisies en audits op deze code zijn.</li>
|
||||
(web)applicatie ondersteunen. Wij richten ons voornamelijk
|
||||
op de "custom" en back-end code, en dan in het bijzonder op implementatiefouten en bekende
|
||||
fouten in de systemen. Bijvoorbeeld: We controleren of u de laatste
|
||||
versie van de ondersteunende software gebruikt, maar duiken niet in het eigenlijke framework.
|
||||
We nemen aan dat de code is geschreven door een team en dus waarschijnlijk duidelijk
|
||||
geschreven is. Als u meerdere full-release versies heeft, zullen er
|
||||
ongetwijfeld meerdere coderevisies en -audits zijn.</li>
|
||||
</ol>
|
||||
<p>Voor meer informatie verwijzen wij u naar de volgende link:
|
||||
<a href="https://www.owasp.org/index.php/OWASP_Code_Review_V2_Table_of_Contents">https://www.owasp.org/index.php/OWASP_Code_Review_V2_Table_of_Contents</a></p>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<title>Algemene voorwaarden</title>
|
||||
<!-- snippet --><p><company_short/> zal alleen de <company_svc_short/>
|
||||
uitvoeren als het de toestemming heeft gekregen van <generate_permission_parties/>
|
||||
zoals uiteengezet in de penetration test verklaring, bijgevoegd als <b>Annex 2</b>,
|
||||
of verschafd als los document.</p>
|
||||
zoals uiteengezet in de penetratietestvrijwaring, bijgevoegd als <b>Annex 2</b>
|
||||
of verschaft als los document.</p>
|
||||
|
||||
<p><company_short/> voert deze opdracht uit op basis van de algemene voorwaarden,
|
||||
die bijgevoegd zijn als Annex 1.
|
||||
<company_short/> weigert alle algemene voorwaarden die gebruikt worden door
|
||||
<company_short/> verwerpt alle algemene voorwaarden die gebruikt worden door
|
||||
<client_short/>.</p>
|
||||
<p>Om akkoord te gaan met dit aanbod, tekent u deze brief in tweevoud en retourneert
|
||||
deze naar:</p>
|
||||
<p>Om akkoord te gaan met dit aanbod dient u deze brief in tweevoud te tekenen en te
|
||||
retourneren naar:</p>
|
||||
<contact>
|
||||
<name><company_legal_rep/></name>
|
||||
<address><company_long/><br/>Overdiemerweg 28<br/>1111 PP Diemen</address>
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--snippet -->
|
||||
<p>
|
||||
<div><p>
|
||||
Crystal-Box vs. Black-Box pentesting verwijst naar de hoeveelheid
|
||||
informatie over de doelwit omgeving, architectuur, en/of applicaties die de klant
|
||||
in eerste instantie deelt met de pentesters. Bij Black-Box testing ontvangen de
|
||||
pentester helemaal geen informatie over het doelwit. Bij Crystal-Box tests
|
||||
ontvangen de pentesters alle informatie die opgevraagd wordt betreffende het doelwit,
|
||||
inclusief source code (wanneer dit relevant is), toegang tot developers of systeembeheer, etc...
|
||||
<br />
|
||||
<br />
|
||||
<company_short/> zal een Crystal-Box pentest uitvoeren, wat de voorkeursmethode is.
|
||||
In tegenstelling tot "real world" aanvallers, die alle tijd van de wereld hebben,
|
||||
vinden pentests plaats in een beperkt tijdsbestek. Crystal-Box pentesting biedt ons
|
||||
de mogelijkheid om zo efficiënt mogelijk onze tijd te benutten, wat zorgt voor
|
||||
een maximalisatie van het aantal kwetsbaarheden die kunnen worden gevonden.
|
||||
Daarnaast sluit de Crystal-Box pentest het beste aan bij de "Meekijken over de Schouder"
|
||||
optie die <company_short/> aanbiedt aan <client_short/>.
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> zal een Crystal-box pentest uitvoeren - de methode die onze voorkeur heeft.
|
||||
In tegenstelling tot "echte" hackers, die alle tijd van de wereld hebben,
|
||||
vinden pentests plaats in een beperkt tijdsbestek. Crystal-box pentesting biedt ons
|
||||
de mogelijkheid om onze tijd zo efficiënt mogelijk te gebruiken, waardoor het maximale aantal kwetsbaarheden kan worden gevonden.
|
||||
Daarnaast sluit de Crystal-box pentest het beste aan bij de "meekijk"-optie die <company_short/> <client_short/> biedt.
|
||||
</p></div>
|
||||
<!-- end of template -->
|
||||
|
||||
@@ -2,23 +2,22 @@
|
||||
<section>
|
||||
<title>Vrijwaring</title>
|
||||
|
||||
<p>Het is mogelijk dat in de loop van het penetratie testen <company_short/>
|
||||
de operaties van het doelwit hindert of hier schade aan toebrengt.
|
||||
<p>Het is mogelijk dat <company_short/> in de loop van het testen
|
||||
bedrijfsvoering bij het doelwit hindert of bedrijfsschade aanricht.
|
||||
<client_short/> geeft hier toestemming voor, onder voorbehoud dat <company_short/>
|
||||
hier niet nalatig of roekeloos mee omgaat. <client_short/> waarborgt dit ook en heeft de bevoegdheid om
|
||||
hier toestemming voor te geven.</p>
|
||||
niet nalatig of roekeloos handelt. <client_short/> garandeert bovendien dat ze bevoegd is om
|
||||
deze toestemming te verlenen.</p>
|
||||
|
||||
<p>Het is van belang om de limitaties van de diensten van <company_short/> te begrijpen.
|
||||
<company_short/> geeft geen (en kan geen) garanties geven dat iets veilig is.
|
||||
<company_short/>, heeft in plaats daarvan, een wettelijke inspanningsverplichting
|
||||
voor de uit te voeren diensten.</p>
|
||||
<p>Laat duidelijk zijn dat er grenzen zijn aan wat <company_short/> kan leveren.
|
||||
<company_short/> kan geen garantie geven dat een systeem 100% veilig is, en doet dat dan ook niet.
|
||||
<company_short/> heeft wel een wettelijke inspanningsverplichting.</p>
|
||||
|
||||
<p><company_short/> en <client_short/> komen hierbij overeen dat redelijke maatregelen
|
||||
worden getroffen om, de vertrouwelijkheid van informatie en persoonlijke
|
||||
gegevens van de doelwitten waar zij toegang tot krijgen
|
||||
in de loop van het uitvoeren van de penetratie test, in stand wordt gehouden.
|
||||
<p><company_short/> en <client_short/> komen hierbij overeen dat er redelijke maatregelen
|
||||
worden getroffen om de informatie en persoonlijke
|
||||
gegevens waar <company_short/> in de loop van de penetratietest toegang toe krijgt
|
||||
zullen worden beschermd en vertrouwelijk zullen worden behandeld.
|
||||
Beide partijen zullen de informatie en data die zij ontvangen of waar zij toegang tot krijgen
|
||||
alleen gebruiken ten behoeve van de doelen die beschreven zijn in deze overeenkomst.
|
||||
<company_short/> garandeert dat alle kern-leden, externe freelancers en vrijwilligers
|
||||
die betrokken zijn bij het uitvoeren van de penetratie test een geheimhoudingsverklaring (NDA) hebben getekend.</p>
|
||||
<company_short/> garandeert dat alle kernleden, externe freelancers en vrijwilligers
|
||||
die bij het uitvoeren van de penetratietest betrokken zijn een geheimhoudingsverklaring (NDA) hebben getekend.</p>
|
||||
</section>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- snippet --><p>Gebaseerd op de verstrekte informatie, verwachten wij dat het dienstverband <p_duration/> dagen duurt.
|
||||
De planning van dit dienstverband is als volgt:</p>
|
||||
<!-- snippet --><p>Op basis van de verstrekte informatie verwachten wij dat het uitvoeren van de opdracht <p_duration/> dagen zal duren.
|
||||
De planning van de opdracht is als volgt:</p>
|
||||
@@ -1,197 +1,295 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<annex>
|
||||
<title>Annex 1<br/>General Terms and Conditions</title>
|
||||
|
||||
<p><b>What is this document?</b></p>
|
||||
<p>These are the general terms and conditions (in Dutch: “<i>algemene voorwaarden</i>”)
|
||||
of <company_long/> (<company_short/>). This version of the general terms and conditions
|
||||
is dated 15 July 2014.</p>
|
||||
<p>In the spirit of <company_short/>'s philosophy, <company_short/> wants these
|
||||
general terms and conditions to be as understandable as possible. If you have any
|
||||
questions, feel free to ask for clarification.</p>
|
||||
<p><b>What is <company_long/>?</b></p>
|
||||
<p><company_short/> is a private limited liability company under Dutch law located
|
||||
in Amsterdam, The Netherlands. It is registered at the Dutch Chamber of Commerce
|
||||
under no. 60628081.</p>
|
||||
<p><b>To what do these terms and conditions apply?</b></p>
|
||||
<p>These general terms and conditions apply to all agreements between <company_short/>
|
||||
and the customer. <company_short/> rejects any terms and conditions used by the
|
||||
customer. The parties can only deviate from these general terms and conditions
|
||||
in writing. These general terms and conditions are also intended to benefit any
|
||||
person employed or engaged by <company_short/> during the performance of an assignment.</p>
|
||||
<p><b>How does <company_short/> agree on an assignment?</b></p>
|
||||
<p><company_short/> wants both parties to have a clear picture of an assignment
|
||||
before it starts. This means there only is an agreement between <company_short/>
|
||||
and the customer after <company_short/> sends a written offer containing the key
|
||||
terms of the agreement and the customer subsequently accepts the offer.
|
||||
Communications other than the written offer do not form part of the agreement.
|
||||
<company_short/> can rescind an offer until it is accepted by the customer.</p>
|
||||
<p><b>What can the customer expect from <company_short/>?</b></p>
|
||||
<p>It is important to understand the limits of <company_short/>'s services.
|
||||
<company_short/> does not (and cannot) give guarantees that something is secure.
|
||||
<company_short/> instead has an obligation to make reasonable efforts
|
||||
(in Dutch: “<i>inspanningsverplichting</i>”) to perform the agreed services.</p>
|
||||
<p><company_short/> will make reasonable efforts to perform the assignment in
|
||||
accordance with the plan set out in the offer (if any). If <company_short/>
|
||||
expects it will not fulfill the plan as documented, it will let the customer
|
||||
know without delay. <company_short/> is not automatically deemed to be in default
|
||||
if it doesn't meet the plan.</p>
|
||||
<p><company_short/> will make reasonable efforts to avoid disruption of the
|
||||
customer's operations and damage to its owned or operated systems, but it
|
||||
cannot guarantee that this will be avoided. The customer agrees
|
||||
to this. <company_short/> is not obliged to restore the systems or recover any
|
||||
data deleted or amended in the course of the assignment.</p>
|
||||
<p><b>What can <company_short/> expect from the customer?</b></p>
|
||||
<p>The customer will provide <company_short/> with all means necessary to allow
|
||||
<company_short/> to perform the agreed services. If <company_short/> needs explicit
|
||||
permission from the customer to perform its services (for example, when doing
|
||||
penetration tests) the customer gives this permission. The customer also warrants
|
||||
that it has the legal authority to give this permission.</p>
|
||||
<p><b>How do the parties handle confidential information?</b></p>
|
||||
<p><company_short/> and the customer will not disclose to others confidential
|
||||
information and personal data they receive from each other or gain access to in
|
||||
the course of an assignment. <company_short/> has the right to disclose this
|
||||
information and data to persons engaged by <company_short/>, but only if these
|
||||
persons have a similar confidentiality obligation vis-á-vis <company_short/>.
|
||||
Any person will only use the information and data it receives or gains access
|
||||
to for the purposes following from the agreement. Both parties will take reasonable
|
||||
measures to maintain the confidentiality of the information and data they received
|
||||
or gained access to, and will ensure that persons engaged by them do the same.</p>
|
||||
<p><b>What does <company_short/> do with vulnerabilities it finds in the course
|
||||
of an assignment?</b></p>
|
||||
<p>If <company_short/> in the course of an assignment finds a vulnerability which
|
||||
might affect the customer, it will report this to the customer. If a vulnerability
|
||||
might affect third parties as well, <company_short/> retains the right to disclose
|
||||
this vulnerability also to others than the customer. It will only do so after
|
||||
having given the customer a reasonable period to take measures minimising the
|
||||
impact of the vulnerability, in line with responsible disclosure best practices.</p>
|
||||
<p><b>What does <company_short/> do with indicators of compromise it finds?</b></p>
|
||||
<p>If <company_short/> in the course of an assignment finds indicators of
|
||||
compromise, such as malware signatures and IP-addresses, it will report this to
|
||||
the customer. <company_short/> retains the right to also publish this information
|
||||
in a publicly accessible database. It will only do so after it has given the
|
||||
customer the opportunity to object to the publication of data which would
|
||||
negatively impact the customer.</p>
|
||||
<p><b>Who owns the products developed in the course of the assignment?</b></p>
|
||||
<p><company_short/> retains any intellectual property rights in products developed
|
||||
for an assignment, such as software and reports. <company_short/>, however, wants
|
||||
to teach as many customers as possible 'how to fish'.</p>
|
||||
<p>For software it developed, this means that <company_short/> gives the customer
|
||||
a permanent, non-exclusive, transferable, sub-licensable, worldwide license to
|
||||
distribute and use the software in source and binary forms, with or without
|
||||
modification (very similar to the BSD-license). If <company_short/>'s software
|
||||
is based on other software which is provided under a license which restricts
|
||||
<company_short/>'s ability to license its own software (such as the GPLv3 license),
|
||||
the more restrictive license will apply.</p>
|
||||
<p>For other products it developed, such as reports and analyses, <company_short/>
|
||||
gives the customer the same license, but this license is exclusive to the customer
|
||||
and does not contain the right to modification. The latter condition is intended
|
||||
to ensure that the customer will not change <company_short/>'s products, such as
|
||||
reports and analyses. <company_short/> retains the right to reuse these products,
|
||||
for example for training and marketing purposes. <company_short/> will remove any
|
||||
confidential information from these products before publication.</p>
|
||||
<p><company_short/> retains title to any property transferred to the customer
|
||||
until all outstanding payments by the customer have been done in full (in Dutch:
|
||||
“<i>eigendomsvoorbehoud</i>”). <company_short/> also only gives a license after
|
||||
all outstanding payments have been done in full.</p>
|
||||
<p><b>Who will perform the assignment?</b></p>
|
||||
<p><company_short/> has the right to appoint the persons who will perform the
|
||||
assignment. It has the right to replace a person with someone with at least the
|
||||
same expertise, but only after having consulted with the customer. This means
|
||||
that section 7:404 Dutch Civil Code (in Dutch: “<i>Burgerlijk Wetboek</i>”) is
|
||||
excluded.</p>
|
||||
<p>Due to the nature of <company_short/>'s business, <company_short/> regularly
|
||||
works with freelancers for the performance of its assignments. <company_short/>
|
||||
has the right to engage third parties, including freelancers, in the course of
|
||||
the performance of an assignment.</p>
|
||||
<p><company_short/> wants to be able to use the expertise of its entire team to
|
||||
help with an assignment. This means that in the course of an assignment, it is
|
||||
possible that the persons performing the assignment will consult with and be
|
||||
advised by others in <company_short/>'s team. These others will of course be
|
||||
bound by the same confidentiality obligations as the persons performing the assignment.</p>
|
||||
<p><b>What happens when the scope of the assignment is bigger than agreed?</b></p>
|
||||
<p><company_short/> and the customer will attempt to precisely define the scope
|
||||
of the assignment before <company_short/> starts. If during the course of the
|
||||
assignment, the scope turns out to be bigger than expected, <company_short/>
|
||||
will report this to the customer and make a written offer for the additional work.</p>
|
||||
<p><b>How is payment arranged?</b></p>
|
||||
<p>All amounts in <company_short/>'s offers are in Euros, excluding VAT and
|
||||
other applicable taxes, unless agreed otherwise.</p>
|
||||
<p>For assignments where the parties agreed to an hourly fee, <company_short/>
|
||||
will send an invoice after each month. For other assignments, <company_short/>
|
||||
will send an invoice after completion of the assignment, and at moments set out
|
||||
in the offer (if any). The customer must pay an invoice within 30 days of the
|
||||
invoice date.</p>
|
||||
<p><company_short/> may, prior to an assignment, agree on the payment of a
|
||||
deposit by the customer. <company_short/> will settle deposits with interim
|
||||
payments or the final invoice for the assignment.</p>
|
||||
<p>If the payment is not received before the agreed term, the client will be
|
||||
deemed to be in default without prior notice. <company_short/> will then have
|
||||
the right to charge the statutory interest (in Dutch: “<i>wettelijke rente</i>”)
|
||||
and any judicial and extrajudicial (collection) costs (in Dutch:
|
||||
“<i>gerechtelijke- en buitengerechtelijke (incasso)kosten</i>”).</p>
|
||||
<p>If the customer cancels or delays the assignment two weeks before it starts,
|
||||
<company_short/> is entitled to charge the customer 50% of the agreed price.
|
||||
If the customer cancels or delays the assignment after it already started,
|
||||
<company_short/> is entitled to charge the customer 100% of the agreed price.
|
||||
<company_short/> is entitled to charge a pro rata percentage in the case of
|
||||
cancellation or delay shorter than two weeks before the start of the assignment
|
||||
(i.e. a cancellation one week before the assignment would entitle <company_short/>
|
||||
to charge 75% of the agreed price).</p>
|
||||
<p><b>For what can <company_short/> be held liable?</b></p>
|
||||
<p>Any liability of <company_short/> resulting from or related to the performance
|
||||
of an assignment, shall be limited to the amount that is paid out in that
|
||||
specific case under an applicable indemnity insurance of <company_short/>,
|
||||
if any, increased by the amount of the applicable deductible (in Dutch:
|
||||
“<i>eigen risico</i>”) which under that insurance shall be borne by <company_short/>.
|
||||
If no amount is paid out under an insurance, these damages are limited to the
|
||||
amount already paid for the assignment, with a maximum of EUR 10.000.
|
||||
Each claim for damages shall expire after a period of one month from the day
|
||||
following the day on which the customer became aware or could reasonably
|
||||
be aware of the existence of the damages.</p>
|
||||
<p>To make things clear, <company_short/> is not liable if a person associated
|
||||
with <company_short/> acts contrary to any confidentiality or non-compete
|
||||
obligation vis-á-vis the customer or a third party, this person might have
|
||||
agreed to in another engagement.</p>
|
||||
<p>What happens when third parties lodge a claim or initiate criminal proceedings
|
||||
against <company_short/>?</p>
|
||||
<p>The customer shall indemnify <company_short/> and any person employed or
|
||||
engaged by <company_short/> for any claims of third parties which are in any
|
||||
way related to the activities of <company_short/> and any person employed or
|
||||
engaged by <company_short/> for the customer.</p>
|
||||
<p>Should a third party lodge a claim against <company_short/> or any of the
|
||||
consultants it engaged or employed as a result of the performance of the assignment
|
||||
for the customer, then the customer will co-operate fully with <company_short/>
|
||||
in defending against this claim, including by providing to <company_short/> any
|
||||
evidence it has which relates to this claim.
|
||||
Should the public prosecutor initiate an investigation or criminal proceedings
|
||||
against <company_short/> or any of the consultants it engaged or employed as a
|
||||
result of the performance of the assignment for the customer, then the customer
|
||||
will also co-operate fully with <company_short/> in defending against this
|
||||
investigation or proceedings, including by providing any evidence it has which
|
||||
relates to this investigation or these proceedings.</p>
|
||||
<p>The customer shall reimburse <company_short/> and any person employed or
|
||||
engaged by <company_short/> all costs of legal defence and all damages in
|
||||
relation to these claims, investigations or proceedings. This provision does
|
||||
not apply to the extent a claim, investigation, or proceeding is the result of
|
||||
the intent or recklessness (in Dutch: “<i>opzet of bewuste roekeloosheid</i>”)
|
||||
of <company_short/> or a person employed or engaged by <company_short/>.</p>
|
||||
<p><b>When is this agreement terminated and what happens then?</b></p>
|
||||
<p>Each of the parties may terminate the agreement wholly or partly without
|
||||
prior notice if the other party is declared bankrupt or is being wound up or if
|
||||
the other party's affairs are being administered by the court
|
||||
(in Dutch: “surséance van betaling”).</p>
|
||||
<p><b>When can <company_short/> not be expected to perform the assignment?</b></p>
|
||||
<p>In the case of force majeure (in Dutch: “<i>overmacht</i>”) as a result of
|
||||
which <company_short/> cannot reasonably be expected to perform the assignment,
|
||||
the performance will be suspended. Situations of force majeure include cases
|
||||
where means, such as soft- and hardware, which are prescribed by the customer
|
||||
do not function well. The agreement may be terminated by either party if a
|
||||
situation of force majeure has continued longer than 90 days. The customer will
|
||||
then have to pay the amount for the work already performed pro rata.</p>
|
||||
<p><b>Which law applies and which court is competent?</b></p>
|
||||
<p>Dutch law applies to the legal relationship between <company_short/> and its
|
||||
customers. Any dispute between <company_short/> and a customer will be resolved
|
||||
in the first instance exclusively by the District Court (in Dutch:
|
||||
“<i>rechtbank</i>”) of Amsterdam, the Netherlands.</p>
|
||||
</annex>
|
||||
<title>Annex 1<br/>Algemene Voorwaarden</title>
|
||||
|
||||
<p>
|
||||
<b>Wat houdt dit document in?</b>
|
||||
</p>
|
||||
<p>
|
||||
Dit zijn de algemene voorwaarden van <company_long/> (<company_short/>)
|
||||
Deze versie van de algemene voorwaarden dateert van 15 juli 2014.
|
||||
</p>
|
||||
<p>
|
||||
In lijn met de filosofie van <company_short/> wil <company_short/> dat deze algemene voorwaarden zo
|
||||
begrijpelijk mogelijk zijn. Vraag gerust om opheldering als u vragen heeft.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wat is Radically Open Security?</b>
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> is een besloten vennootschap met beperkte aansprakelijkheid volgens
|
||||
Nederlands recht en is gevestigd in Amsterdam, Nederland. Het bedrijf staat geregistreerd
|
||||
bij de Nederlandse Kamer van koophandel onder nr. 60628081.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Waarop zijn deze algemene voorwaarden van toepassing?</b>
|
||||
</p>
|
||||
<p>
|
||||
Deze algemene voorwaarden zijn van toepassing op alle overeenkomsten tussen
|
||||
<company_short/> en de klant. <company_short/> wijst algemene voorwaarden die gebruikt worden door de
|
||||
klant van de hand. Partijen kunnen alleen schriftelijk van deze algemene
|
||||
voorwaarden afwijken. Deze algemene voorwaarden zijn ook bedoeld ten gunste
|
||||
van een persoon die tijdens het uitvoeren van een opdracht in dienst is van
|
||||
of ingeschakeld is door <company_short/>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Hoe stemt <company_short/> in met een opdracht?</b>
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> wil dat beide partijen een duidelijk beeld hebben van een opdracht voordat
|
||||
die begint. Dit betekent dat er alleen een overeenkomst is tussen <company_short/> en de
|
||||
klant indien <company_short/> een schriftelijke offerte stuurt met daarin de belangrijkste
|
||||
bepalingen van de overeenkomst en de klant vervolgens de offerte accepteert.
|
||||
Mededelingen, anders dan de schriftelijke offerte, maken geen deel uit van de
|
||||
overeenkomst. <company_short/> kan een offerte intrekken totdat het door de klant is geaccepteerd.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wat kan de klant verwachten van <company_short/>?</b>
|
||||
</p>
|
||||
<p>
|
||||
Het is belangrijk om op de hoogte te zijn van de grenzen van de diensten van
|
||||
<company_short/>. <company_short/> garandeert niet (en kan niet garanderen) dat iets veilig is. In plaats
|
||||
daarvan heeft <company_short/> een inspanningsverplichting om de afgesproken diensten uit
|
||||
te voeren.
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> zal redelijke inspanningen leveren om de opdracht uit te voeren conform
|
||||
de planning die is vastgelegd in de offerte (indien van toepassing). Indien
|
||||
<company_short/> verwacht dat het de planning niet haalt, brengt <company_short/> de klant onverwijld
|
||||
op de hoogte. <company_short/> wordt niet automatisch in verzuim geacht te zijn indien
|
||||
<company_short/> de planning niet haalt.
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> zal redelijke inspanningen leveren om schade aan systemen die eigendom
|
||||
zijn van de klant of beheerd worden door de klant te voorkomen, maar kan niet
|
||||
garanderen dat dergelijke schade zal worden vermeden. <company_short/> is niet verplicht
|
||||
om data te herstellen die het tijdens de opdracht heeft verwijderd of gewijzigd.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wat kan <company_short/> van de klant verwachten?</b>
|
||||
</p>
|
||||
<p>
|
||||
De klant zal <company_short/> voorzien van alle nodige middelen om <company_short/> in staat te stellen
|
||||
om de afgesproken diensten uit te voeren. Indien <company_short/> nadrukkelijke toestemming
|
||||
nodig heeft van de klant om zijn diensten uit te voeren, bijvoorbeeld bij het
|
||||
uitvoeren van penetratietesten of een basis-securityscan, geeft de klant deze toestemming. De klant
|
||||
garandeert tevens dat het de wettelijke bevoegdheid heeft om deze toestemming te geven.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Hoe gaan de partijen om met vertrouwelijk informatie?</b>
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> en de klant onthullen aan anderen geen vertrouwelijke informatie en persoonlijke
|
||||
gegevens die zij van elkaar ontvangen of waar zij gedurende de opdracht toegang
|
||||
toe krijgen. <company_short/> heeft het recht om de informatie openbaar te maken aan personen
|
||||
die door <company_short/> zijn ingeschakeld, maar alleen indien deze personen een vergelijkbare
|
||||
geheimhoudingsplicht hebben ten aanzien van <company_short/>. Een ieder aan wie deze informatie
|
||||
of deze gegevens openbaar zijn gemaakt zal dit alleen gebruiken voor de doelen
|
||||
die voortkomen uit de overeenkomst. Beide partijen zullen redelijke maatregelen
|
||||
nemen om de vertrouwelijkheid van deze informatie en gegevens te handhaven,
|
||||
ook met betrekking tot personen die door de partijen zijn ingeschakeld.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wat doet <company_short/> met kwetsbaarheden die het tijdens de opdracht ontdekt?</b>
|
||||
</p>
|
||||
<p>
|
||||
Indien <company_short/> tijdens de opdracht een kwetsbaarheid vindt die de klant zou kunnen
|
||||
beïnvloeden, geeft <company_short/> dit door aan de klant. Indien een kwetsbaarheid derden
|
||||
ook zou kunnen beïnvloeden, behoudt <company_short/> het recht om deze kwetsbaarheid ook
|
||||
aan anderen dan te klant bekend te maken. <company_short/> zal dit alleen doen nadat <company_short/>
|
||||
de klant een redelijke periode heeft gegeven om maatregelen te nemen om het
|
||||
effect van de kwetsbaarheid te minimaliseren, overeenkomstig best practices
|
||||
voor ‘responsible disclosure’.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wat doet <company_short/> als het indicaties van compromittering tegenkomt? </b>
|
||||
</p>
|
||||
<p>
|
||||
Indien <company_short/> tijdens een opdracht indicaties van compromittering tegenkomt,
|
||||
zoals malware-handtekeningen en IP-adressen, geeft <company_short/> dit door aan de klant.
|
||||
<company_short/> behoudt het recht om deze informatie ook in een openbaar toegankelijke
|
||||
database te publiceren. <company_short/> zal dit alleen doen nadat het de klant de mogelijkheid
|
||||
heeft gegeven om bezwaar te maken tegen de publicatie van gegevens die een negatief
|
||||
effect zouden hebben op de klant.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wie is eigenaar van de producten die tijdens de opdracht worden ontwikkeld?</b>
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> behoudt intellectuele eigendomsrechten van producten die voor een opdracht
|
||||
zijn ontwikkeld, zoals software en rapporten. <company_short/> wil echter zoveel mogelijk
|
||||
klanten ‘leren vissen’.
|
||||
</p>
|
||||
<p>
|
||||
Voor software die <company_short/> heeft ontwikkeld betekent dit dat <company_short/> de klant een
|
||||
permanente, niet-exclusieve, overdraagbare, sub-licentieerbare, wereldwijde
|
||||
licentie geeft om de software in bronvorm of binaire vorm te verspreiden of
|
||||
te gebruiken, met of zonder wijziging (vrijwel gelijk aan de BSD-licentie).
|
||||
Indien de software van <company_short/> gebaseerd is op andere software die geleverd is
|
||||
onder een licentie die het vermogen beperkt van <company_short/> om een licentie te verbinden
|
||||
aan de eigen software (zoals de GPLv3-licentie), is de beperkendere licentie
|
||||
van toepassing.
|
||||
</p>
|
||||
<p>
|
||||
Voor overige producten die <company_short/> heeft ontwikkeld, zoals rapporten en analyses,
|
||||
geeft <company_short/> dezelfde licentie aan de klant, maar deze licentie geldt exclusief
|
||||
voor de klant en bevat geen recht op wijziging. De laatste voorwaarde is bedoeld
|
||||
om te garanderen dat de klant de producten van <company_short/> niet verandert, zoals rapporten
|
||||
en analyses. <company_short/> behoudt het recht om deze producten opnieuw te gebruiken,
|
||||
bijvoorbeeld voor trainings- en marketingdoeleinden. Voorafgaand aan publicatie
|
||||
verwijdert <company_short/> vertrouwelijke informatie van deze producten.
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> behoudt het eigendomsrecht van een goed dat is overgedragen aan de klant
|
||||
totdat alle uitstaande betalingen volledig door de klant zijn voldaan, i.e.
|
||||
eigendomsvoorbehoud. <company_short/> geeft tevens alleen een licentie nadat alle uitstaande
|
||||
betalingen volledig zijn voldaan.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wie zal de opdracht uitvoeren?</b>
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> heeft het recht om personen te benoemen die de opdracht zullen uitvoeren.
|
||||
<company_short/> heeft het recht om een persoon te vervangen door iemand met minstens
|
||||
dezelfde expertise, maar alleen na overleg met de klant. Dit betekent dat artikel
|
||||
7:404 van het Nederlands Burgerlijk Wetboek is uitgesloten.
|
||||
</p>
|
||||
<p>
|
||||
Vanwege de aard van de zaken van <company_short/> werkt <company_short/> regelmatig met freelancers
|
||||
voor het uitvoeren van de opdrachten. <company_short/> heeft het recht om derden in te schakelen,
|
||||
waaronder freelancers, tijdens het uitvoeren van een opdracht.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wat gebeurt er wanneer de omvang van de opdracht groter is dan afgesproken?</b>
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> en de klant zullen proberen om de omvang van de opdracht nauwkeurig te
|
||||
bepalen voordat <company_short/> begint. Indien tijdens de opdracht de omvang groter blijkt
|
||||
te zijn dan verwacht zal <company_short/> dit rapporteren aan de klant en een schriftelijke
|
||||
offerte opstellen voor het meerwerk.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Hoe is de betaling geregeld?</b>
|
||||
</p>
|
||||
<p>
|
||||
Alle bedragen in de offertes van <company_short/> zijn in euro’s en exclusief BTW en
|
||||
overige van toepassing zijnde belastingen, tenzij anders overeengekomen.
|
||||
</p>
|
||||
<p>
|
||||
Voor opdrachten waarbij de partijen een uurtarief hebben afgesproken stuurt
|
||||
<company_short/> aan het einde van iedere maand een factuur. Voor overige opdrachten zal
|
||||
<company_short/> een factuur sturen na voltooiing van de opdracht en op momenten zoals
|
||||
vastgelegd in de offerte (indien van toepassing). De klant moet een factuur
|
||||
binnen 30 dagen na factuurdatum betalen.
|
||||
</p>
|
||||
<p>
|
||||
<company_short/> kan, voorafgaand aan een opdracht, instemmen met een aanbetaling door de klant.
|
||||
<company_short/> zal aanbetalingen verrekenen met tussentijdse betalingen of met de laatste
|
||||
factuur voor de opdracht.
|
||||
</p>
|
||||
<p>
|
||||
Indien de betaling niet voor de afgesproken termijn is ontvangen wordt de
|
||||
klant zonder voorafgaande kennisgeving geacht in verzuim te zijn. <company_short/> heeft
|
||||
dan het recht om de wettelijke rente en eventuele gerechtelijke en buitengerechtelijke
|
||||
(incasso)kosten in rekening te brengen.
|
||||
</p>
|
||||
<p>
|
||||
Indien de klant de opdracht binnen twee weken voor de start annuleert of
|
||||
uitstelt heeft <company_short/> het recht om de klant 50% van de afgesproken prijs in
|
||||
rekening te brengen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Waarvoor kan <company_short/> aansprakelijk worden gesteld?</b>
|
||||
</p>
|
||||
<p>
|
||||
Een aansprakelijkheid van <company_short/> ten gevolge van of in verband met de uitvoering
|
||||
van een opdracht is beperkt tot het bedrag dat in dat specifieke geval krachtens
|
||||
een van toepassing zijnde aansprakelijkheidsverzekering van <company_short/> is uitbetaald,
|
||||
indien van toepassing, verhoogd met het bedrag van het eigen risico, dat volgens
|
||||
de verzekering wordt gedragen door <company_short/>. Indien geen bedrag wordt uitbetaald
|
||||
krachtens een verzekering, is deze schadevergoeding beperkt tot het bedrag
|
||||
dat al is betaald voor de opdracht, met een maximum van 10.000 euro.
|
||||
</p>
|
||||
<p>
|
||||
Elke vordering tot schadevergoeding verloopt na een periode van een maand
|
||||
vanaf de dag volgend op de dag waarop de klant kennis had gekregen van of
|
||||
redelijkerwijs kennis zou kunnen krijgen van het bestaan van de schadevergoeding.
|
||||
</p>
|
||||
<p>
|
||||
Ter verduidelijking, <company_short/> is niet aansprakelijk wanneer een persoon die verbonden
|
||||
is met <company_short/> handelt in strijd met eventuele geheimhouding of niet-concurrentiebeding
|
||||
ten aanzien van de klant of derden, die deze persoon afgesproken zou kunnen
|
||||
hebben in een andere verbintenis.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wat gebeurt er wanneer derden een vordering indienen of een strafrechtelijke
|
||||
procedure instellen tegen <company_short/>?</b>
|
||||
</p>
|
||||
<p>
|
||||
De klant vrijwaart <company_short/> en een persoon in dienst van of ingeschakeld door <company_short/>
|
||||
van vorderingen van derden die op enige manier verband houden met de activiteiten
|
||||
van <company_short/> en een persoon in dienst van of ingeschakeld door <company_short/> voor de klant.
|
||||
De klant vergoed aan <company_short/> en een persoon in dienst van of ingeschakeld door <company_short/>
|
||||
alle kosten voor juridische bijstand en alle schade met betrekking tot deze
|
||||
vorderingen. Deze bepaling is niet van toepassing voor zover een vordering
|
||||
het gevolg is van opzet of bewuste roekeloosheid van <company_short/> of een persoon in
|
||||
dienst van of ingeschakeld door <company_short/>.
|
||||
</p>
|
||||
<p>
|
||||
Indien een derde partij een vordering indient tegen <company_short/> of een van de adviseurs
|
||||
die <company_short/> heeft ingeschakeld of in dienst heeft, als gevolg van het uitvoeren
|
||||
van de opdracht voor de klant, zal de klant volledig meewerken met <company_short/> in de
|
||||
verdediging tegen deze vordering, inclusief het leveren aan <company_short/> van enig
|
||||
bewijs dat betrekking heeft op deze vordering. Indien de officier van justitie
|
||||
een onderzoek instelt of een strafrechtelijke procedure instelt tegen <company_short/> of
|
||||
een van de adviseurs die <company_short/> heeft ingeschakeld of in dienst heeft, als gevolg
|
||||
van het uitvoeren van de opdracht voor de klant, zal de klant ook volledig
|
||||
meewerken met <company_short/> in de verdediging tegen dit onderzoek of procedure, inclusief
|
||||
het leveren van enig bewijs dat betrekking heeft op dit onderzoek of deze procedure.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wanneer wordt deze overeenkomst beëindigd en wat gebeurt er dan?</b>
|
||||
</p>
|
||||
<p>
|
||||
Elk van de partijen kan de overeenkomst zonder voorafgaande kennisgeving
|
||||
geheel of gedeeltelijk beëindigen indien de andere partij failliet is verklaard
|
||||
of is ontbonden of indien de andere partij in surseance van betaling verkeert.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Wanneer kan er niet van <company_short/> worden verwacht dat het de opdracht uitvoert?</b>
|
||||
</p>
|
||||
<p>
|
||||
In het geval van overmacht als gevolg waarvan van <company_short/> redelijkerwijs niet verwacht
|
||||
kan worden dat het de opdracht uitvoert, zal de uitvoering worden uitgesteld.
|
||||
Situaties van overmacht zijn onder andere gevallen waarbij middelen zoals
|
||||
software en hardware die zijn voorgeschreven door de klant niet goed functioneren.
|
||||
Indien een situatie van overmacht langer dan 90 dagen heeft geduurd, kan de
|
||||
overeenkomst door een van beide partijen worden beëindigd. De klant zal dan
|
||||
naar rato het bedrag moeten betalen voor het werk dat al is uitgevoerd.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Welk recht is van toepassing en welke rechtbank is bevoegd?</b>
|
||||
</p>
|
||||
<p>
|
||||
Op de rechtsverhouding tussen <company_short/> en zijn klanten is het Nederlands recht
|
||||
van toepassing. Een geschil tussen <company_short/> en een klant wordt in eerste instantie
|
||||
uitsluitend beslecht door de Arrondissementsrechtbank te Amsterdam, Nederland.
|
||||
</p>
|
||||
</annex>
|
||||
@@ -1,58 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<section>
|
||||
<title>Pentest Methodologie</title>
|
||||
<p>Tijdens het uitvoeren van de penetratie tests volgt <company_long/> in grote lijnen de volgende stappen:</p>
|
||||
<title>Pentestmethodologie</title>
|
||||
<p>Tijdens het uitvoeren van de penetratietests volgt <company_long/> in grote lijnen de volgende stappen:</p>
|
||||
|
||||
<ol>
|
||||
<li>Benodigdheden Verzamelen en Scoping; </li>
|
||||
<li>Ontdekking;</li>
|
||||
<li>Vaststellen voorwaarden/vereisten en Scoping;</li>
|
||||
<li>Onderzoek;</li>
|
||||
<li>Validatie;</li>
|
||||
<li>Informatieverzameling;</li>
|
||||
<li>Analyse van Bedreigingen en Kwetsbaarheden;</li>
|
||||
<li>Verzamelen gegevens;</li>
|
||||
<li>Analyse van Risico's en Kwetsbaarheden;</li>
|
||||
<li>Exploitatie;</li>
|
||||
<li>Rapportage;</li>
|
||||
<li>Rapportage.</li>
|
||||
</ol>
|
||||
|
||||
|
||||
<p><b>Step 1: Benodigdheden Verzamelen en Scoping</b> <br/>
|
||||
<p><b>Stap 1: Vaststellen voorwaarden/vereisten en Scoping</b> <br/>
|
||||
De verwachtingen van beide partijen worden besproken en overeenkomsten worden gemaakt
|
||||
betreffende het uitvoeren van de test(s). Bijvoorbeeld, contactgegevens en de
|
||||
scope van de pentest worden vastgelegd.</p>
|
||||
betreffende het uitvoeren van de test(s). Tijdens deze stap worden bijvoorbeeld alle contactgegevens verzameld en vastgesteld wat de
|
||||
scope van de pentest is.</p>
|
||||
|
||||
<p><b>Step 2: Ontdekking</b><br/>
|
||||
Zo veel mogelijk informatie betreffende de "target" organisatie en de "target" objecten
|
||||
wordt verzameld. Deze informatie wordt passief verzameld, voornamelijk uit publieke bronnen.</p>
|
||||
<p><b>Stap 2: Onderzoek</b><br/>
|
||||
Er word zo veel mogelijk informatie betreffende de te testen organisatie en doelwitten verzameld. Deze informatie wordt passief verzameld, voornamelijk uit publieke bronnen.</p>
|
||||
|
||||
<p><b>Step 3: Validatie</b><br/>
|
||||
Alle door de klant gespecificeerde systemen worden kruisverwezen met de bevindingen
|
||||
van de Ontdekking stap. Wij doen dit om te garanderen dat de ontdekte systemen
|
||||
<p><b>Stap 3: Validatie</b><br/>
|
||||
Alle door de klant gespecificeerde systemen worden nagelopen aan de hand van wat tijdens de Onderzoeksstap is ontdekt. We doen dit om te garanderen dat de ontdekte systemen
|
||||
wettelijk eigendom van de klant zijn en om de scope met de klant te verifiëren.</p>
|
||||
|
||||
<p><b>Step 4: Informatieverzameling</b><br/>
|
||||
<p><b>Stap 4: Verzamelen gegevens</b><br/>
|
||||
Informatie uit Stap 2 wordt hier gebruikt om actief informatie betreffende de
|
||||
systemen te verzamelen. Activiteiten gedurende deze fase kunnen het volgende inhouden:
|
||||
Vaststellen welke onderdelen van de verscheidene componenten zullen worden onderzocht;
|
||||
Testen op de aanwezigheid van bekende kwetsbaarheden, gebruikmakend van automatische tests;
|
||||
De aangeboden diensten identificeren en de voor hen gebruikte software te "fingerprinten."</p>
|
||||
systemen te verzamelen. Mogelijke activiteiten gedurende deze fase zijn:
|
||||
Vaststellen welke onderdelen van de verscheidene componenten zullen worden getest;
|
||||
met behulp van geautomatiseerde tests controleren op de aanwezigheid van bekende kwetsbaarheden;
|
||||
identificeren welke diensten op de onderzochte systemen worden aangeboden en de gebruikte software te "fingerprinten".</p>
|
||||
|
||||
<p><b>Step 5: Analyse van Bedreigingen en Kwetsbaarheden</b><br/>
|
||||
Potentiële bedrijgingen en kwetsbaarheden worden geïndexeerd, gebaseerd op de verzamelde informatie.</p>
|
||||
<p><b>Stap 5: Analyse van Risico's en Kwetsbaarheden</b><br/>
|
||||
Potentiële risico's en kwetsbaarheden worden geïndexeerd op basis van de verzamelde informatie.</p>
|
||||
|
||||
<p><b>Step 6: Exploitatie</b><br/>
|
||||
Hier wordt gepoogd om kwetsbaarheden van de verscheidene componenten te gebruiken.
|
||||
De diverse applicaties en componenten van de klants infrastructuur worden
|
||||
meedogenloos gesondeerd voor frequent voorkomende design-, configuratie- en programmeerfouten.</p>
|
||||
<p><b>Stap 6: Exploitatie</b><br/>
|
||||
Hier wordt gepoogd om kwetsbaarheden in de verscheidene componenten uit te buiten.
|
||||
De diverse applicaties en componenten van de infrastructuur van de klant worden
|
||||
grondig gecontroleerd op vaak voorkomende ontwerp-, configuratie- en programmeerfouten.</p>
|
||||
|
||||
<p>Notitie: <company_long/> gebruikt als basis open-source scanning tools, maar
|
||||
voert in het algemeen de meeste exploitatie handmatig uit.</p>
|
||||
<p>Opmerking: <company_long/> gebruikt open-source scanning tools als basis, maar
|
||||
voert in de regel de meeste exploitatiepogingen handmatig uit.</p>
|
||||
|
||||
<p><b>Step 7: Rapportage</b><br/>
|
||||
Na het afronden van de verificatie zal een rapport worden geleverd met een stapsgewijze benadering,
|
||||
waarbij resultaten en ontdekte kwetsbaarheden worden beschreven. Het rapport en de resultaten
|
||||
zullen worden gepresenteerd aan de verantwoordelijke projectleider of -manager in het kantoor van de klant.</p>
|
||||
<p><b>Stap 7: Rapportage</b><br/>
|
||||
Na het afronden van de test zal een rapport worden geleverd waarin de resultaten en ontdekte kwetsbaarheden stap voor stap worden beschreven. Het rapport en de resultaten worden eventueel gepresenteerd aan de verantwoordelijke projectleider of -manager in het kantoor van de klant.</p>
|
||||
|
||||
<p>Stappen 4-6 kunnen meerdere malen herhaald worden per test. Voorbeeld: Toegang kan worden
|
||||
verkregen in een extern systeem dat fungeert als een opstapje tot het interne netwerk.
|
||||
<p>Stappen 4-6 kunnen meerdere malen herhaald worden per test. Zo kan er bijvoorbeeld door exploitatie van kwetsbaarheden toegang worden
|
||||
verkregen tot een extern systeem dat fungeert als een opstapje tot het interne netwerk.
|
||||
Het interne netwerk zal vervolgens worden verkend in Stappen 4 en 5, om vervolgens te worden geëxploiteerd in Stap 6.</p>
|
||||
</section>
|
||||
@@ -1,20 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<section>
|
||||
<title>Planning en Betaling</title>
|
||||
<p><company_short/> houdt het volgende schema aan voor haar werkzaamheden:</p>
|
||||
<p><company_short/> houdt de volgende planning aan voor haar werkzaamheden:</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li><p_testingduration/>: <company_short/> voert <company_svc_short/> uit op het doelwit</li>
|
||||
<li><p_reportwritingduration/>: <company_short/> maakt een concept rapport over de tests</li>
|
||||
<li><p_reportdue/>: <company_short/> levert het definitieve rapport.</li>
|
||||
<li><company_short/> voert <company_svc_short/> uit op het doelwit: <p_testingduration/>.</li>
|
||||
<li><company_short/> levert het definitieve rapport: <p_reportdue/>.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<!-- snippet --><p>Ons vaste tarief voor de bovenstaand beschreven
|
||||
<p>Ons vaste tarief voor de bovenstaand beschreven
|
||||
<company_svc_short/> is <p_fee/>,- excl. BTW en bijkomende kosten.
|
||||
<company_short/> zal een factuur sturen na afronding van deze opdracht.
|
||||
<client_short/> zal het afgesproken bedrag binnen 30 dagen na de factureringsdatum overmaken.</p>
|
||||
<!-- snippet --><p>Eventuele extra werkzaamheden zullen apart worden verrekend.
|
||||
<p>Eventuele extra werkzaamheden zullen apart worden verrekend.
|
||||
Een uurtarief zal hieraan voorafgaand worden besproken.</p>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<p>Om de diensten naar behoren uit te kunnen voeren heeft <company_short/> toegang nodig tot:</p>
|
||||
<!--Example of most common scenario, change if necessary!! :-->
|
||||
<ul>
|
||||
<li>test accounts</li>
|
||||
<li>testaccounts</li>
|
||||
<li>een testomgeving</li>
|
||||
<li>contactgegevens van de systeemadministrators, voor noodgevallen</li>
|
||||
|
||||
|
||||
@@ -1,21 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<section>
|
||||
<section todo="no">
|
||||
<title>Projectoverzicht</title><!-- section with an overview of ROS activities -->
|
||||
<!-- snippet --><p><company_short/> zal <company_svc_long/> uitvoeren voor <client_short/>
|
||||
op de onderstaand beschreven systemen. De diensten zijn bedoelt om inzicht te bieden
|
||||
op de hieronder beschreven systemen. De diensten zijn bedoeld om inzicht te bieden
|
||||
in de veiligheid van deze systemen. Om dit te kunnen bewerkstelligen zal <company_short/>
|
||||
toegang krijgen tot deze systemen, proberen kwetsbaarheden op te sporen en trachten
|
||||
verdere toegang te krijgen door de gevonden kwetsbaarheden uit te buiten.</p>
|
||||
|
||||
<!-- snippet --><p><company_short/> zal de volgende objectieven testen
|
||||
(de “<b>objectieven</b>”):</p>
|
||||
<!-- snippet --><p><company_short/> zal de volgende doelwitten testen
|
||||
(de “<b>Doelwitten</b>”):</p>
|
||||
|
||||
<generate_targets/>
|
||||
|
||||
<!-- snippet --><p><company_short/> zal testen op de aanwezigheid van de
|
||||
meest voorkomende kwetsbaarheden, gebruik makend van zowel publiek beschikbare
|
||||
scanning tools, als door handmatig testen. <company_short/> zal een
|
||||
<p_duration/>-daagse, <p_boxtype/>, grondige test uitvoeren, via internet.</p>
|
||||
scanning tools, als door handmatig testen. <company_short/> zal een grondige
|
||||
<p_duration/>-daagse (<p_mandays/> mandagen), <p_boxtype/> test uitvoeren via internet.</p>
|
||||
|
||||
<section todo="yes">
|
||||
<title>Scope</title>
|
||||
<p><company_short/> schat de uitvoering van de penetratietest op ... dagen in totaal: </p>
|
||||
<ul>
|
||||
<li>... dagen voor het testen van ...;</li>
|
||||
<li>... dagen voor het testen van ...;</li>
|
||||
<li>... dagen voor de verificatie van potentiële risico's, opstellen van een Proof of Concept
|
||||
en het vastleggen van onze bevindingen en aanbevelingen in het rapport.</li>
|
||||
</ul>
|
||||
<br/>
|
||||
<b>Out of scope</b><br/>
|
||||
<p>De onderliggende netwerkinfrastructuur, ..., ... en eventuele loadbalancing-infrastructuur maken geen deel uit van de scope.
|
||||
Uitgesloten zijn ook:</p>
|
||||
<ul>
|
||||
<li>elke vorm van social engineering;</li>
|
||||
<li>(D)DoS aanvallen;</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
<!-- snippet --> <!--Not Needed if Disclaimer is Included; Duplicate Text-->
|
||||
<!--p>It is possible that in the course of the penetration
|
||||
|
||||
@@ -4,48 +4,56 @@
|
||||
|
||||
<section>
|
||||
<title>Team</title>
|
||||
<p><company_short/> mag de activiteiten uitvoeren met haar kern-teamleden,
|
||||
externe freelancers, en/of vrijwilligers.</p>
|
||||
<p>Het eerste contactpersoon voor deze opdracht zal zijn:</p>
|
||||
<ul>
|
||||
<li><company_poc1/> (<company_short/>)</li>
|
||||
<li><client_poc1/> (<client_short/>)</li>
|
||||
</ul>
|
||||
<p>Onze penetratie tests lijken een beetje op een "verover de vlag competitie":
|
||||
|
||||
<company_long/> heeft een geografisch gedistribueerd team
|
||||
en wij gebruiken online infrastructuur (RocketChat, GitLabs, etc.)
|
||||
om ons werk te coördineren. Dit geeft ons de mogelijkheid om
|
||||
om verscheidene technische mensen uit de organisatie van de klant
|
||||
uit te nodigen om op vrijwillige basis samen te werken met ons pentest team.
|
||||
Natuurlijk geldt deze uitnodiging ook voor <client_short/>.</p>
|
||||
|
||||
<p>In de loop van het project hebben wij de insteek om actief te
|
||||
brainstormen met <client_short/> over zowel de pentest, als het proces.
|
||||
Dit is een doorlopende leerervaring voor zowel u, als voor onszelf.
|
||||
Daarnaast hebben wij ervaren dat een directe lijn voor feedback naar de klant
|
||||
de kwaliteit en de focus van het dienstverband enorm verbeteren.</p>
|
||||
<p><company_short/> voert de activiteiten zoals genoemd in deze offerte uit
|
||||
met haar kernteamleden, externe freelancers, en/of vrijwilligers.<br />
|
||||
De eerste aanspreekpunt voor deze opdracht zijn:</p>
|
||||
<ul>
|
||||
<li><company_poc1/> (<company_short/>)</li>
|
||||
<li><client_poc1/> (<client_short/>)</li>
|
||||
</ul>
|
||||
<p>De werkwijze van onze penetratietest-teams is gemodelleerd die van een
|
||||
"<i>Capture The Flag</i>-team": <company_long/> heeft een
|
||||
geografisch gedistribueerd team; wij gebruiken online infrastructuur
|
||||
(RocketChat, GitLabs, etc.) om ons werk te coördineren. Dit geeft ons de
|
||||
mogelijkheid om verscheidene technische mensen uit de organisatie van de
|
||||
klant uit te nodigen om op vrijwillige basis samen te werken met ons
|
||||
pentestteam. Uiteraard geldt deze uitnodiging ook voor <client_short/>.</p>
|
||||
|
||||
<p> <company_short/> betrekt <client_short/> actief bij het project door tussentijds
|
||||
overleg te voeren over de voortgang van de <company_svc_short/> en over het proces.
|
||||
Door deze manier van werken wordt het project een doorlopende leerervaring voor
|
||||
zowel u als voor <company_short/>. <company_short/> heeft ervaren dat een
|
||||
rechtstreeks contact met de klant tijdens het project de kwaliteit en de focus
|
||||
van onze diensten aanzienlijk verbetert.</p>
|
||||
|
||||
</section>
|
||||
<section>
|
||||
<title>Rapportage</title>
|
||||
<p><company_short/> zal rapporteren aan <client_short/> betreffende de
|
||||
penetratie test. Dit rapport zal de genomen stappen bevatten die benodigd waren
|
||||
gedurende de test en daarnaast de bevonden kwetsbaarheden. Daarnaast zal het
|
||||
aanbevelingen bevatten, maar geen uitgebreide oplossingen om deze
|
||||
kwetsbaarheden op te lossen.</p>
|
||||
|
||||
<p>Een voorbeeld van een Pentest rapport kan hier gevonden worden</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/radicallyopensecurity/templates/blob/master/sample-report/REP_SittingDuck-
|
||||
pentestreport-v10.pdf">https://github.com/radicallyopensecurity/templates/blob/master/sample-report/REP_SittingDuck-
|
||||
pentestreport-v10.pdf</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Een van <company_short/> haar kernwaarden is het
|
||||
"Leer iemand Vissen" principe - ook bekend als het
|
||||
"Meekijken over de Schouder" principe. Wij streven ernaar om
|
||||
onze diensten te structureren, zodat zij kans kunnen bieden
|
||||
om deze te benutten voor educatieve- of trainingsdoeleinden voor onze klanten.</p>
|
||||
<p>
|
||||
<company_short/> zal voor <client_short/> de tijdens de <company_svc_short/>
|
||||
aangetroffen kwetsbaarheden onderzoeken en classificeren. Onze bevindingen verwerken we in een (Engelstalig)
|
||||
rapport. De belangrijkste bevindingen worden voorzien van een gedetailleerd advies
|
||||
voor het verbeteren van de onveilige situatie. De minder kritische bevindingen
|
||||
zullen door ons minder gedetailleerd worden behandeld. Voorafgaand aan de oplevering
|
||||
van het rapport krijgt <client_short/> inzage in de conceptversie, zodat er nog ruimte is voor
|
||||
vragen en suggesties. De bevindingen uit het rapport zullen telefonisch en/of per email door
|
||||
<client_short/> en <company_short/> worden besproken.
|
||||
</p>
|
||||
|
||||
<p>Een voorbeeld van een pentestrapport vindt u hier:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/radicallyopensecurity/templates/blob/master/sample-report/REP_SittingDuck-
|
||||
pentestreport-v10.pdf"
|
||||
>https://github.com/radicallyopensecurity/templates/blob/master/sample-report/REP_SittingDuck-
|
||||
pentestreport-v10.pdf</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>Een van de kernwaarden van <company_short/> is het "Teach To Fish"-principe - ook
|
||||
bekend als het "Peek over our Shoulder (PooS)"-principe. Wij streven ernaar
|
||||
om onze diensten en rapporten zodanig te structureren dat onze klanten ze
|
||||
mogelijk kunnen benutten voor educatieve of trainingsdoeleinden.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -5,29 +5,28 @@
|
||||
<section>
|
||||
<title>Team</title>
|
||||
<p><company_short/> voert de activiteiten zoals genoemd in deze offerte uit
|
||||
met haar kern-teamleden, externe freelancers, en/of vrijwilligers.<br />
|
||||
De eerste aanspreekpunt voor deze opdracht zijn:
|
||||
met haar kernteamleden, externe freelancers, en/of vrijwilligers.<br />
|
||||
De eerste aanspreekpunt voor deze opdracht zijn:</p>
|
||||
<ul>
|
||||
<li><company_poc1/> (<company_short/>)</li>
|
||||
<li><client_poc1/> (<client_short/>)</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<company_long/> werkt met een geografisch gespreid team. Onze teamleden bevinden
|
||||
zich in verschillende uithoeken van de wereld. <company_short/> maakt gebruik van een eigen
|
||||
online infrastructuur (RocketChat, GitLabs, et cetera) om het werk binnen het
|
||||
online infrastructuur (RocketChat, GitLabs, etcetera) om het werk binnen het
|
||||
team te coördineren. De online infrastructuur biedt ons de mogelijkheid
|
||||
om technische mensen uit de organisatie van <client_short/> uit te nodigen op
|
||||
vrijwillige basis met ons pentestteam samen te werken. Natuurlijk geldt deze
|
||||
vrijwillige basis met ons pentestteam samen te werken. Uiteraard geldt deze
|
||||
uitnodiging ook voor <generate_permission_parties/>.
|
||||
</p>
|
||||
|
||||
<p> <company_short/> betrekt <client_short/> actief bij het project door tussentijds
|
||||
overleg te voeren over de voortgang van de <company_svc_short/> en over het proces.
|
||||
Door deze manier van werken wordt het project een doorlopende leerervaring voor
|
||||
zowel u, als voor <company_short/>. <company_short/> heeft ervaren dat een
|
||||
rechtstreeks contact met de klant tijdens het project, de kwaliteit en de focus
|
||||
zowel u als voor <company_short/>. <company_short/> heeft ervaren dat een
|
||||
rechtstreeks contact met de klant tijdens het project de kwaliteit en de focus
|
||||
van onze diensten aanzienlijk verbetert.</p>
|
||||
|
||||
</section>
|
||||
@@ -35,18 +34,18 @@
|
||||
<title>Rapportage</title>
|
||||
<p>
|
||||
<company_short/> zal voor <client_short/> de tijdens de <company_svc_short/>
|
||||
aangetroffen kwetsbaarheden onderzoeken en classificeren. Onze bevindingen verwerken we in een Engelstalig
|
||||
aangetroffen kwetsbaarheden onderzoeken en classificeren. Onze bevindingen verwerken we in een (Engelstalig)
|
||||
rapport. De belangrijkste bevindingen worden voorzien van een gedetailleerd advies
|
||||
voor het verbeteren van de onveilige situatie. De minder kritische bevindingen
|
||||
zullen door ons minder gedetailleerd worden behandeld. Voorafgaand aan de oplevering
|
||||
van het rapport, krijgt <client_short/> inzage in de conceptversie zodat er nog ruimte is voor
|
||||
vragen en suggesties. De bevindinen uit het rapport zullen telefonisch en/of per email door
|
||||
van het rapport krijgt <client_short/> inzage in de conceptversie, zodat er nog ruimte is voor
|
||||
vragen en suggesties. De bevindingen uit het rapport zullen telefonisch en/of per email door
|
||||
<client_short/> en <company_short/> worden besproken.
|
||||
</p>
|
||||
<p>
|
||||
De managementsamenvatting wordt door <client_short/> zelf geschreven. Het rapport
|
||||
zal een omschrijving van de stappen en de gevonden kwetsbaarheden bevatten.
|
||||
Daarnaast zal het aanbevelingen bevatten (maar geen uitgebreide oplossingen) om
|
||||
De managementsamenvatting wordt door <client_short/> zelf geschreven. Het volledige rapport
|
||||
bevat een omschrijving van alle stappen en de gevonden kwetsbaarheden.
|
||||
Daarnaast bevat het aanbevelingen (maar geen uitgebreide oplossingen) om
|
||||
de kwetsbaarheden te verhelpen. Het rapport wordt voorzien van een bijlage (annex)
|
||||
met ruwe testgegevens.
|
||||
</p>
|
||||
|
||||
@@ -28,9 +28,7 @@ in de veiligheid van deze systemen. <company_short/> zal zich daartoe toegang ve
|
||||
deze systemen om op zoek te gaan naar kwetsbaarheden. Vervolgens zal worden getracht
|
||||
dergelijke kwetsbaarheden uit te buiten om verdere toegang en verhoogde privileges
|
||||
te bemachtigen. <company_short/> zal de volgende doelwitten testen (de “Doelwitten”):
|
||||
<ul>
|
||||
<li>Doelsysteem</li>
|
||||
</ul>
|
||||
<generate_targets/>
|
||||
</p>
|
||||
<p>2. <i><signee_short/></i> verklaart hierbij <company_short/> en de Consultants – op een datum die
|
||||
per email zal worden bevestigd – de meest uitvoerige toestemming te verlenen voor
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
<finding id="..." threatLevel="Moderate" type="Information Leak">
|
||||
<!-- Note: threatLevel can be Low, Moderate, Elevated, High or Extreme; type is free text -->
|
||||
|
||||
<!--
|
||||
id needs to be unique across the report, preferably identical to the filename
|
||||
(without extension).
|
||||
|
||||
threatLevel can be Low, Moderate, Elevated, High or Extreme.
|
||||
|
||||
type is the root cause, written in Title Case.
|
||||
|
||||
Examples: Easily Guessable Credentials
|
||||
Lack Of Application Hardening
|
||||
Lack Of Webserver Hardening
|
||||
Missing Patch
|
||||
Network Design Flaw
|
||||
-->
|
||||
|
||||
<title>Title Case</title>
|
||||
|
||||
|
||||
@@ -76,8 +76,6 @@
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
href="snippets/report/methodology.xml"/>
|
||||
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="code-audit-methodology.xml"/>
|
||||
|
||||
<section id="recon" break="before">
|
||||
<title>Reconnaissance and Fingerprinting</title>
|
||||
<p>Through automated scans we were able to gain the following information about the
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
<xsl:import href="waiver.xslt"/>-->
|
||||
|
||||
<xsl:include href="styles_inv.xslt"/>
|
||||
<xsl:include href="localisation.xslt"/>
|
||||
|
||||
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
|
||||
|
||||
<xsl:variable name="lang" select="/*/@xml:lang"/>
|
||||
|
||||
<!-- ****** AUTO_NUMBERING_FORMAT: value of the <xsl:number> element used for auto numbering -->
|
||||
<!--<xsl:param name="AUTO_NUMBERING_FORMAT" select="'1.1.1'"/>-->
|
||||
@@ -76,7 +78,8 @@
|
||||
<fo:table-body>
|
||||
<fo:table-row>
|
||||
<fo:table-cell xsl:use-attribute-sets="td">
|
||||
<fo:block><xsl:value-of select="/offerte/meta/pentestinfo/duration"/>-day <xsl:value-of select="/offerte/meta/offered_service_short"/> <xsl:value-of select="/offerte/meta/permission_parties/client/short_name"/></fo:block>
|
||||
<fo:block><xsl:value-of select="/offerte/meta/pentestinfo/duration"/>-
|
||||
<xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_days'"/></xsl:call-template> <xsl:value-of select="/offerte/meta/offered_service_short"/> <xsl:value-of select="/offerte/meta/permission_parties/client/short_name"/></fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell xsl:use-attribute-sets="td align-right">
|
||||
<fo:block xsl:use-attribute-sets="p"><xsl:value-of select="$denomination"/> <xsl:number value="$fee" grouping-separator="," grouping-size="3"/>.--</fo:block>
|
||||
@@ -84,7 +87,7 @@
|
||||
</fo:table-row>
|
||||
<fo:table-row>
|
||||
<fo:table-cell xsl:use-attribute-sets="td">
|
||||
<fo:block>VAT 21%</fo:block>
|
||||
<fo:block><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_vat'"/></xsl:call-template> 21%</fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell xsl:use-attribute-sets="td align-right">
|
||||
<fo:block xsl:use-attribute-sets="p"><xsl:value-of select="$denomination"/> <xsl:number value="$vat" grouping-separator="," grouping-size="3"/>.--</fo:block>
|
||||
@@ -92,7 +95,7 @@
|
||||
</fo:table-row>
|
||||
<fo:table-row xsl:use-attribute-sets="border-top bold">
|
||||
<fo:table-cell xsl:use-attribute-sets="td">
|
||||
<fo:block>Total amount to be paid</fo:block>
|
||||
<fo:block><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_total'"/></xsl:call-template></fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell xsl:use-attribute-sets="td align-right">
|
||||
<fo:block xsl:use-attribute-sets="p"><xsl:value-of select="$denomination"/> <xsl:number value="$vat + $fee" grouping-separator="," grouping-size="3"/>.--</fo:block>
|
||||
@@ -109,9 +112,9 @@
|
||||
<xsl:template name="custom_invoice">
|
||||
<xsl:variable name="denomination">
|
||||
<xsl:choose>
|
||||
<xsl:when test="/invoice/@denomination = 'usd'">$</xsl:when>
|
||||
<xsl:when test="/invoice/@denomination = 'eur'">€</xsl:when>
|
||||
<xsl:when test="/invoice/@denomination = 'gbp'">£</xsl:when>
|
||||
<xsl:when test="/invoice/@denomination = 'usd'">$</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<xsl:call-template name="invoiceStart">
|
||||
@@ -137,7 +140,7 @@
|
||||
<xsl:if test="additionalcosts">
|
||||
<fo:table-row>
|
||||
<fo:table-cell xsl:use-attribute-sets="td padding-top">
|
||||
<fo:block xsl:use-attribute-sets="bold">Additional Expenses</fo:block>
|
||||
<fo:block xsl:use-attribute-sets="bold"><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_additional'"/></xsl:call-template></fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell xsl:use-attribute-sets="td align-right padding-top">
|
||||
<fo:block xsl:use-attribute-sets="p"> </fo:block>
|
||||
@@ -165,7 +168,7 @@
|
||||
</xsl:variable>
|
||||
<fo:table-row>
|
||||
<fo:table-cell xsl:use-attribute-sets="td padding-top">
|
||||
<fo:block>VAT 21%</fo:block>
|
||||
<fo:block><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_vat'"/></xsl:call-template> 21%</fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell xsl:use-attribute-sets="td align-right padding-top">
|
||||
<fo:block xsl:use-attribute-sets="p"><xsl:value-of select="$denomination"/> <xsl:number value="$vat" grouping-separator="," grouping-size="3"/>.--</fo:block>
|
||||
@@ -173,7 +176,7 @@
|
||||
</fo:table-row>
|
||||
<fo:table-row xsl:use-attribute-sets="border-top bold">
|
||||
<fo:table-cell xsl:use-attribute-sets="td">
|
||||
<fo:block>Total amount to be paid</fo:block>
|
||||
<fo:block><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_total'"/></xsl:call-template></fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell xsl:use-attribute-sets="td align-right">
|
||||
<fo:block xsl:use-attribute-sets="p"><xsl:value-of select="$denomination"/> <xsl:number value="$total" grouping-separator="," grouping-size="3"/>.--</fo:block>
|
||||
@@ -190,14 +193,14 @@
|
||||
<xsl:template name="invoiceStart">
|
||||
<xsl:param name="INVOICE_NO"/>
|
||||
<xsl:param name="DATE"/>
|
||||
<fo:block xsl:use-attribute-sets="title-0">Invoice nr. <xsl:value-of select="$INVOICE_NO"
|
||||
<fo:block xsl:use-attribute-sets="title-0"><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_no'"/></xsl:call-template><xsl:text> </xsl:text><xsl:value-of select="$INVOICE_NO"
|
||||
/></fo:block>
|
||||
<fo:block>
|
||||
<fo:block>
|
||||
<xsl:value-of select="/*/meta//client/full_name"/>
|
||||
</fo:block>
|
||||
<fo:block>
|
||||
<xsl:if test="/*/meta//client/invoice_rep">T.a.v. <xsl:value-of
|
||||
<xsl:if test="/*/meta//client/invoice_rep"><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_fao'"/></xsl:call-template><xsl:text> </xsl:text><xsl:value-of
|
||||
select="/offerte/meta/permission_parties/client/invoice_rep"/></xsl:if>
|
||||
</fo:block>
|
||||
<fo:block>
|
||||
@@ -217,27 +220,26 @@
|
||||
<fo:block xsl:use-attribute-sets="p big-space-below" text-align="right">
|
||||
<xsl:value-of select="$DATE"/>
|
||||
</fo:block>
|
||||
<fo:block xsl:use-attribute-sets="title-2">Services Delivered</fo:block>
|
||||
<fo:block xsl:use-attribute-sets="title-2"><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_svcdeliv'"/></xsl:call-template></fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="invoiceEnd">
|
||||
<xsl:param name="INVOICE_NO"/>
|
||||
<fo:block xsl:use-attribute-sets="big-space-below"><xsl:value-of
|
||||
select="/*/meta/company/full_name"/> donates > 90% of its entire profits to
|
||||
charity.</fo:block>
|
||||
<fo:block xsl:use-attribute-sets="big-space-below">Please be so kind to pay within 30 days
|
||||
by money transfer, to the following account:</fo:block>
|
||||
select="/*/meta/company/full_name"/><xsl:text> </xsl:text><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_donation'"/></xsl:call-template></fo:block>
|
||||
<fo:block xsl:use-attribute-sets="big-space-below"><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_pleasepay'"/></xsl:call-template></fo:block>
|
||||
|
||||
<fo:block xsl:use-attribute-sets="big-space-below" margin-left="1.3cm">
|
||||
<fo:block>
|
||||
<xsl:value-of select="/*/meta/company/full_name"/>
|
||||
</fo:block>
|
||||
<fo:block>IBAN: <xsl:value-of select="/*/meta/company/iban"/></fo:block>
|
||||
<fo:block>Reference: <xsl:value-of select="$INVOICE_NO"/></fo:block>
|
||||
<fo:block>
|
||||
<xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_iban'"/></xsl:call-template>: <xsl:value-of select="/*/meta/company/iban"/></fo:block>
|
||||
<fo:block><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_ref'"/></xsl:call-template>: <xsl:value-of select="$INVOICE_NO"/></fo:block>
|
||||
</fo:block>
|
||||
|
||||
<fo:block>Kind regards,</fo:block>
|
||||
<fo:block>your dedicated team at</fo:block>
|
||||
<fo:block><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_regards'"/></xsl:call-template>,</fo:block>
|
||||
<fo:block><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_team'"/></xsl:call-template></fo:block>
|
||||
<fo:block font-style="italic">
|
||||
<xsl:value-of select="/*/meta/company/full_name"/>
|
||||
</fo:block>
|
||||
@@ -287,8 +289,8 @@
|
||||
<fo:block xsl:use-attribute-sets="TinyFont">
|
||||
<fo:block xsl:use-attribute-sets="bold orange-text"><xsl:value-of select="/*/meta/company/website"/></fo:block>
|
||||
<fo:block><xsl:value-of select="/*/meta/company/email"/></fo:block>
|
||||
<fo:block>Chamber of Commerce <xsl:value-of select="/*/meta/company/coc"/></fo:block>
|
||||
<fo:block>VAT number <xsl:value-of select="/*/meta/company/vat_no"/></fo:block>
|
||||
<fo:block><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'page_kvk'"/></xsl:call-template><xsl:text> </xsl:text><xsl:value-of select="/*/meta/company/coc"/></fo:block>
|
||||
<fo:block><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_vatno'"/></xsl:call-template><xsl:text> </xsl:text><xsl:value-of select="/*/meta/company/vat_no"/></fo:block>
|
||||
</fo:block>
|
||||
</fo:table-cell>
|
||||
</fo:table-row>
|
||||
@@ -304,12 +306,12 @@
|
||||
<xsl:template name="page_footer">
|
||||
<fo:static-content flow-name="region-after-cover" xsl:use-attribute-sets="FooterFont">
|
||||
<fo:block xsl:use-attribute-sets="footer">
|
||||
<fo:inline xsl:use-attribute-sets="TinyFont orange-text">Please keep digital unless absolutely required. Read the (unique) terms and conditions of Radically Open Security at: https://radicallyopensecurity.com/TermsandConditions.pdf</fo:inline>
|
||||
<fo:inline xsl:use-attribute-sets="TinyFont orange-text"><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_yaygreen'"/></xsl:call-template></fo:inline>
|
||||
</fo:block>
|
||||
</fo:static-content>
|
||||
<fo:static-content flow-name="region-after-content" xsl:use-attribute-sets="FooterFont">
|
||||
<fo:block xsl:use-attribute-sets="footer">
|
||||
<fo:inline xsl:use-attribute-sets="TinyFont orange-text">Please keep digital unless absolutely required. Read the (unique) terms and conditions of Radically Open Security at: https://radicallyopensecurity.com/TermsandConditions.pdf</fo:inline>
|
||||
<fo:inline xsl:use-attribute-sets="TinyFont orange-text"><xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_yaygreen'"/></xsl:call-template></fo:inline>
|
||||
</fo:block>
|
||||
</fo:static-content>
|
||||
</xsl:template>
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
<xsl:import href="graphics.xslt"/>
|
||||
<xsl:import href="generic.xslt"/>
|
||||
<xsl:import href="numbering.xslt"/>
|
||||
<xsl:import href="placeholders.xslt"/><!--
|
||||
<xsl:import href="snippets.xslt"/>-->
|
||||
<xsl:import href="placeholders.xslt"/>
|
||||
<xsl:import href="waiver.xslt"/>
|
||||
|
||||
<xsl:include href="localisation.xslt"/>
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="xs" version="2.0">
|
||||
|
||||
<xsl:include href="localisation.xslt"/>
|
||||
|
||||
<xsl:param name="INVOICE_NO">00/000</xsl:param>
|
||||
<xsl:param name="DATE">
|
||||
<xsl:value-of select="format-date(current-date(), '[Y]-[M,2]-[D1]', 'en', (), ())"/>
|
||||
<xsl:value-of select="format-date(current-date(), '[Y]-[M,2]-[D,2]', 'en', (), ())"/>
|
||||
</xsl:param>
|
||||
|
||||
<xsl:variable name="lang" select="/*/@xml:lang"/>
|
||||
|
||||
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
|
||||
|
||||
<!-- ROOT -->
|
||||
@@ -22,6 +26,9 @@
|
||||
<xsl:attribute name="invoice_no">
|
||||
<xsl:value-of select="$INVOICE_NO"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="$lang"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="denomination">
|
||||
<xsl:value-of select="/offerte/meta/pentestinfo/fee/@denomination"/>
|
||||
</xsl:attribute>
|
||||
@@ -34,18 +41,30 @@
|
||||
</xsl:element>
|
||||
</meta>
|
||||
<servicesdelivered>
|
||||
<xsl:comment>Add/delete <service> elements as needed</xsl:comment>
|
||||
<service>
|
||||
<description>
|
||||
<xsl:value-of select="/offerte/meta/pentestinfo/duration"
|
||||
/>-day <xsl:value-of select="/offerte/meta/offered_service_short"
|
||||
/>-<xsl:call-template name="getString"><xsl:with-param name="stringID" select="'invoice_days'"/></xsl:call-template> <xsl:value-of select="/offerte/meta/offered_service_short"
|
||||
/> <xsl:value-of
|
||||
select="/offerte/meta/permission_parties/client/short_name"/>
|
||||
</description>
|
||||
<fee>
|
||||
<fee vat="yes">
|
||||
<xsl:value-of select="/offerte/meta/pentestinfo/fee"/>
|
||||
</fee>
|
||||
</service>
|
||||
</servicesdelivered>
|
||||
<additionalcosts>
|
||||
<xsl:comment>Add/delete <cost> elements as needed</xsl:comment>
|
||||
<cost>
|
||||
<description>...</description>
|
||||
<fee vat="yes">0</fee>
|
||||
</cost>
|
||||
<cost>
|
||||
<description>...</description>
|
||||
<fee vat="yes">0</fee>
|
||||
</cost>
|
||||
</additionalcosts>
|
||||
</invoice>
|
||||
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<version_history>
|
||||
<xsl:comment>needed for date on frontpage and in signature boxes; it is possible to add a new <version> after each review; in that case, make sure to update the date/time</xsl:comment>
|
||||
<version number="auto">
|
||||
<xsl:attribute name="date"><xsl:value-of select="format-date(current-date(), '[Y]-[M,2]-[D1]', 'en', (), ())"/>T10:00:00</xsl:attribute>
|
||||
<xsl:attribute name="date"><xsl:value-of select="format-date(current-date(), '[Y]-[M,2]-[D,2]', 'en', (), ())"/>T10:00:00</xsl:attribute>
|
||||
<xsl:comment>actual date-time here; you can leave the number attribute alone</xsl:comment>
|
||||
<v_author>ROS Writer</v_author>
|
||||
<xsl:comment>name of the author here; for internal use only</xsl:comment>
|
||||
|
||||
@@ -68,7 +68,11 @@
|
||||
<fo:page-number/>/<fo:page-number-citation ref-id="EndOfDoc"/>
|
||||
<fo:leader leader-pattern="space"/>
|
||||
<fo:inline xsl:use-attribute-sets="TinyFont"><xsl:value-of
|
||||
select="*/meta/company/full_name"/> - Chamber of Commerce
|
||||
select="*/meta/company/full_name"/><xsl:text> - </xsl:text>
|
||||
<xsl:call-template name="getString">
|
||||
<xsl:with-param name="stringID" select="'page_kvk'"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="*/meta/company/coc"/></fo:inline>
|
||||
</fo:block>
|
||||
</fo:static-content>
|
||||
@@ -77,7 +81,11 @@
|
||||
<fo:page-number/>/<fo:page-number-citation ref-id="EndOfDoc"/>
|
||||
<fo:leader leader-pattern="space"/>
|
||||
<fo:inline xsl:use-attribute-sets="TinyFont"><xsl:value-of
|
||||
select="*/meta/company/full_name"/> - Chamber of Commerce
|
||||
select="*/meta/company/full_name"/><xsl:text> - </xsl:text>
|
||||
<xsl:call-template name="getString">
|
||||
<xsl:with-param name="stringID" select="'page_kvk'"/>
|
||||
</xsl:call-template>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="*/meta/company/coc"/></fo:inline>
|
||||
</fo:block>
|
||||
</fo:static-content>
|
||||
|
||||
@@ -147,6 +147,12 @@
|
||||
<xsl:with-param name="placeholderElement" select="$placeholderElement"/>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
<xsl:template match="p_mandays">
|
||||
<xsl:param name="placeholderElement" select="/*/meta/pentestinfo/mandays"/>
|
||||
<xsl:call-template name="checkPlaceholder">
|
||||
<xsl:with-param name="placeholderElement" select="$placeholderElement"/>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
<xsl:template match="p_boxtype">
|
||||
<xsl:param name="placeholderElement" select="/*/meta/pentestinfo/type"/>
|
||||
<xsl:call-template name="checkPlaceholder">
|
||||
|
||||
@@ -89,14 +89,18 @@
|
||||
<xsl:value-of select="/*/pentest_info/days"/>
|
||||
</duration>
|
||||
<xsl:comment>duration of pentest, in working days</xsl:comment>
|
||||
<mandays>
|
||||
<xsl:value-of select="/*/pentest_info/mandays"/>
|
||||
</mandays>
|
||||
<xsl:comment>duration of pentest, in mandays</xsl:comment>
|
||||
<test_planning>
|
||||
<xsl:value-of select="/*/pentest_info/planning"/>
|
||||
</test_planning>
|
||||
<xsl:comment>date or date range in text, e.g. May 18th until May 25th, 2015</xsl:comment>
|
||||
<xsl:comment>date or date range in text, e.g. May 18th until May 25th, 2016</xsl:comment>
|
||||
<report_due>
|
||||
<xsl:value-of select="/*/pentest_info/delivery"/>
|
||||
</report_due>
|
||||
<xsl:comment>date or date range in text, e.g. May 18th until May 25th, 2015</xsl:comment>
|
||||
<xsl:comment>date or date range in text, e.g. May 18th until May 25th, 2016</xsl:comment>
|
||||
<nature>
|
||||
<xsl:value-of select="/*/pentest_info/nature"/>
|
||||
</nature>
|
||||
|
||||
@@ -110,10 +110,16 @@
|
||||
</xsl:if>
|
||||
</fo:block>
|
||||
<xsl:apply-templates/>
|
||||
<xsl:call-template name="generate_waiver_signature_box"/>
|
||||
|
||||
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="generate_waiver_signature_box">
|
||||
<xsl:template name="generate_waiver_signature_box">
|
||||
<xsl:param name="signee_long" tunnel="yes"/>
|
||||
<xsl:param name="signee_waiver_rep" tunnel="yes"/>
|
||||
<xsl:param name="signee_city" tunnel="yes"/>
|
||||
<fo:block keep-together.within-page="always" xsl:use-attribute-sets="signaturebox">
|
||||
<fo:table width="100%" table-layout="fixed">
|
||||
<fo:table-column column-width="proportional-column-width(10)"/>
|
||||
@@ -138,20 +144,20 @@
|
||||
<fo:table-cell xsl:use-attribute-sets="td">
|
||||
<fo:block xsl:use-attribute-sets="p"><xsl:call-template name="getString">
|
||||
<xsl:with-param name="stringID" select="'waiver_signed_in'"/>
|
||||
</xsl:call-template>     <xsl:value-of select="city"
|
||||
</xsl:call-template>     <xsl:value-of select="$signee_city"
|
||||
/></fo:block>
|
||||
</fo:table-cell>
|
||||
</fo:table-row>
|
||||
<fo:table-row>
|
||||
<fo:table-cell xsl:use-attribute-sets="td">
|
||||
<xsl:choose>
|
||||
<xsl:when test="waiver_rep">
|
||||
<xsl:when test="$signee_waiver_rep">
|
||||
<fo:block xsl:use-attribute-sets="p"><xsl:call-template
|
||||
name="getString">
|
||||
<xsl:with-param name="stringID"
|
||||
select="'waiver_signed_by'"/>
|
||||
</xsl:call-template>    <xsl:value-of
|
||||
select="waiver_rep"/></fo:block>
|
||||
select="$signee_waiver_rep"/></fo:block>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<fo:block xsl:use-attribute-sets="p"><xsl:call-template
|
||||
@@ -169,7 +175,7 @@
|
||||
<fo:block xsl:use-attribute-sets="p"><xsl:call-template name="getString">
|
||||
<xsl:with-param name="stringID" select="'waiver_signed_for'"/>
|
||||
</xsl:call-template>    <xsl:value-of
|
||||
select="full_name"/></fo:block>
|
||||
select="$signee_long"/></fo:block>
|
||||
</fo:table-cell>
|
||||
</fo:table-row>
|
||||
</fo:table-body>
|
||||
@@ -177,6 +183,9 @@
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<!-- deprecated element; ignore if still there -->
|
||||
<xsl:template match="generate_waiver_signature_box"/>
|
||||
|
||||
<!-- special waiver placeholders -->
|
||||
<!-- (tunnel ftw ;) -->
|
||||
<xsl:template match="signee_long">
|
||||
|
||||
Reference in New Issue
Block a user