add initial sphinx rst framework

this change adds a structure for creating improved sphinx/restructured
text documentation. the initial commit only brings over the information
from the readme with some minor adjustments for titles and separating
content into sections.

Change-Id: If1a4cf7d046e784d84571a7a52480daab7d2be5c
This commit is contained in:
Michael McCune 2016-03-24 15:56:12 -04:00
parent 3a2df44a38
commit afd4cca2fd
10 changed files with 449 additions and 2 deletions

77
doc/source/conf.py Normal file
View File

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
# -- General configuration ----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
'sphinx.ext.autodoc',
# 'sphinx.ext.intersphinx',
'oslosphinx'
]
# autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles.
# execute "export SPHINX_DEBUG=1" in your terminal to disable
# The suffix of source filenames.
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Syntribos'
copyright = u'2015, OpenStack Foundation'
# If true, '()' will be appended to :func: etc. cross-reference text.
add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
add_module_names = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# -- Options for HTML output --------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
# html_theme_path = ["."]
# html_theme = '_theme'
# html_static_path = ['static']
html_theme_options = {}
# Output file base name for HTML help builder.
htmlhelp_basename = '%sdoc' % project
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
('index',
'%s.tex' % project,
u'%s Documentation' % project,
u'OpenStack Foundation', 'manual'),
]
# Example configuration for intersphinx: refer to the Python standard library.
# intersphinx_mapping = {'http://docs.python.org/': None}

View File

@ -0,0 +1,92 @@
Configuration
=============
Copy the data files from Syntribos data directory to .opencafe/data directory created during "cafe-config init". This directory contains the fuzz string files. Copy the example configuration file to .opencafe/configs directory created during "cafe-config init".
::
$ cp data/* .opencafe/data/
$ cp examples/configs/keystone.config .opencafe/configs/.
Modify the configuration files to update your keystone URL, API endpoint
and user credentials.
::
$ vi .opencafe/configs/keystone.config
Example configuration file:
::
[syntribos]
endpoint=<yourapiendpoint>
[user]
username=<yourusername>
password=<yourpassword>
user_id=<youruserid>
[auth]
endpoint=<yourkeystoneurl>
Your can create a directory to store the payloads for the resources
being tested. The payloads under examples directory can give you quick
start.
::
$ mkdir payloads
$ mkdir payloads/keystone
$ cp examples/payloads/keystone/* payloads/keystone/.
Here are some examples for payload files
::
$ vi payloads/keystone/domains_post.txt
::
POST /v3/domains HTTP/1.1
Accept: application/json
X-Auth-Token: CALL_EXTERNAL|syntribos.extensions.identity.client:get_token_v3:["user"]|
Content-type: application/json
{
"domain": {
"description": "Domain description",
"enabled": true,
"name": "CALL_EXTERNAL|syntribos.extensions.random_data.client:get_uuid:[]|"
}
}
::
$ vi payloads/keystone/domains_patch.txt
::
PATCH /v3/domains/c45412aa3cb74824a222c2f051bd62ac HTTP/1.1
Accept: application/json
X-Auth-Token: CALL_EXTERNAL|syntribos.extensions.identity.client:get_token_v3:["user"]|
Content-type: application/json
{
"domain": {
"description": "Domain description",
"enabled": true,
"name": "test name"
}
}
::
$ vi payloads/keystone/domains_get.txt
::
GET /v3/domains/{c45412aa3cb74824a222c2f051bd62ac} HTTP/1.1
Accept: application/json
X-Auth-Token: CALL_EXTERNAL|syntribos.extensions.identity.client:get_token_v3:["user"]|

44
doc/source/index.rst Normal file
View File

@ -0,0 +1,44 @@
Syntribos
=========
Syntribos is an Automated API Security Testing Tool utilizing the `Open
CAFE Framework <https://github.com/stackforge/opencafe>`__.
Given a simple configuration file and an example HTTP request, Syntribos
can replace any API URL, URL parameter, HTTP header and request body
field with a given set of strings. This is similar to Burp Proxy's
Intruder sniper attack, but Syntribos iterates through each position
automatically. Syntribos aims to automatically detect common security
defects such as SQL injection, LDAP injection, buffer overflow, etc. In
addition, Syntribos can be used to help identifying new security defects
by fuzzing.
Syntribos has the capability to test any API, but is designed with
`OpenStack <http://http://www.openstack.org/>`__ applications in mind.
Index
-----
.. toctree::
:maxdepth: 1
installation
configuration
running
logging
test.anatomy
unittests
Project information
-------------------
* Free software: `Apache license`_
* `Launchpad project`_
* `Blueprints`_
* `Bugs`_
.. _Apache license: https://github.com/openstack/syntribos/blob/master/LICENSE
.. _Launchpad project: https://launchpad.net/syntribos
.. _Blueprints: https://blueprints.launchpad.net/syntribos
.. _Bugs: https://bugs.launchpad.net/syntribos

View File

@ -0,0 +1,31 @@
Installation
============
Syntribos can be `installed with
pip <https://pypi.python.org/pypi/pip>`__ from the git repository.
- Clone the repository and install it using pip
::
$ git clone https://github.com/openstack/syntribos.git
$ cd syntribos
$ pip install . --upgrade
- To enable autocomplete for Syntribos, run the command.
::
$ . scripts/syntribos-completion
- Create a directory named .opencafe in the user's home directory, or in the case of a python virtualenv, in the virtualenv root folder.
::
$ cafe-config init
- Install the http library that gives you the minimum plugins required to use Syntribos.
::
$ cafe-config plugins install http

92
doc/source/logging.rst Normal file
View File

@ -0,0 +1,92 @@
Syntribos logging
=================
Syntribos takes advantage of the OpenCafe logging facility. Logs are
found in ``.opencafe/logs/`` Logs are then arranged in directories based
on each Syntribos configuration file, and then by date and time. Each
log filename has an easy to follow naming convention.
::
$ ls .opencafe/logs/keystone.config/2015-08-18_14_44_04.333088/
cafe.master.log
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str1_model1.log
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str1_model2.log
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str1_model3.log
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str2_model1.log
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str2_model2.log
syntribos.tests.fuzz.integer_overflow.(domains_post.txt)_(INT_OVERFLOW_BODY)_(integer-overflow.txt)_str2_model3.log
Each log file includes the request details:
::
------------
REQUEST SENT
------------
request method..: POST
request url.....: https://yourapiendpoint/v3/domains
request params..:
request headers.: {'Content-Length': '46', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', 'Accept': 'application/json', 'User-Agent': 'python-requests/2.7.0 CPython/2.7.9 Darwin/11.4.2', 'Host': 'yourapiendpoint', 'X-Auth-Token': u'9b1ed3d1cc69491ab914dcb6ced00440', 'Content-type': 'application/json'}
request body....: {"domain": {"description": "Domain description","enabled": "-1","name": u'ce9871c4-a0a1-4fbe-88db-f0729b43172c'}}
2015-08-18 14:44:12,464: DEBUG: cafe.engine.http.client:
and the response:
::
-----------------
RESPONSE RECEIVED
-----------------
response status..: <Response [406]>
response time....: 1.32309699059
response headers.: {'content-length': '112', 'server': 'nginx', 'connection': 'keep-alive', 'date': 'Tue, 18 Aug 2015 19:44:11 GMT', 'content-type': 'application/json; charset=UTF-8'}
response body....: {"message": "The server could not comply with the request since it is either malformed or otherwise incorrect."}
-------------------------------------------------------------------------------
2015-08-18 14:44:12,465: INFO: root: ========================================================
2015-08-18 14:44:12,465: INFO: root: Test Case....: test_case
2015-08-18 14:44:12,465: INFO: root: Created At...: 2015-08-18 14:44:11.139070
2015-08-18 14:44:12,465: INFO: root: No Test description.
2015-08-18 14:44:12,465: INFO: root: ========================================================
2015-08-18 14:44:12,465: WARNING: cafe.engine.models.data_interfaces.ConfigParserDataSource: No section: 'fuzz'. Using default value '200.0' instead
2015-08-18 14:44:12,465: DEBUG: root: Validate Length:
Initial request length: 52
Initial response length: 112
Request length: 46
Response length: 112
Request difference: -6
Response difference: 0
Precent difference: 0.0
Config percent: 200.0
Note the "Validate Length" section at the end. This is used to help
determine whether the test passed or failed. If the *Percent difference*
exceeds the *Config percent* the test has failed. The *Config percent*
is set in ``syntribos/syntribos/tests/fuzz/config.py``. The *Percent
difference* is calculated in
``syntribos/syntribos/tests/fuzz/base_fuzz.py``. Additional validations,
such as looking for SQL strings or stack traces, can be added to
individual tests.
The Logs also contain a summary of data related to the test results
above:
::
2015-08-18 14:44:12,466: INFO: root: ========================================================
2015-08-18 14:44:12,466: INFO: root: Test Case......: test_case
2015-08-18 14:44:12,466: INFO: root: Result.........: Passed
2015-08-18 14:44:12,466: INFO: root: Start Time.....: 2015-08-18 14:44:12.464843
2015-08-18 14:44:12,466: INFO: root: Elapsed Time...: 0:00:00.001203
2015-08-18 14:44:12,466: INFO: root: ========================================================
2015-08-18 14:44:12,467: INFO: root: ========================================================
2015-08-18 14:44:12,467: INFO: root: Fixture........: syntribos.tests.fuzz.all_attacks.(agent_patch.txt)_(ALL_ATTACKS_BODY)_(all-attacks.txt)_str1_model1
2015-08-18 14:44:12,467: INFO: root: Result.........: Passed
2015-08-18 14:44:12,467: INFO: root: Start Time.....: 2015-08-18 14:44:11.139070
2015-08-18 14:44:12,467: INFO: root: Elapsed Time...: 0:00:01.328030
2015-08-18 14:44:12,468: INFO: root: Total Tests....: 1
2015-08-18 14:44:12,468: INFO: root: Total Passed...: 1
2015-08-18 14:44:12,468: INFO: root: Total Failed...: 0
2015-08-18 14:44:12,468: INFO: root: Total Errored..: 0
2015-08-18 14:44:12,468: INFO: root: ========================================================

16
doc/source/running.rst Normal file
View File

@ -0,0 +1,16 @@
Running syntribos
=================
To execute a Syntribos test, run ``syntribos`` specifying the configuration
file and payload file(s) you want to use.
::
$ syntribos keystone.config payloads/keystone/domains_post.txt
To run ``syntribos`` against all payload files, just specify the payload
directory:
::
$ syntribos keystone.config payloads/keystone/

View File

@ -0,0 +1,74 @@
Basic syntribos test anatomy
============================
**Test Types**
The tests included at release time include LDAP injection, SQL
injection, integer overflow and the generic all\_attacks.
In order to run a specific test, simply use the ``-t, --test-types``
option and provide `syntribos` with a keyword or keywords to match from
the test files located in ``syntribos/tests/fuzz/``.
For SQL injection tests, use:
::
$ syntribos keystone.config payloads/keystone/domains_post.txt -t SQL
For SQL injection tests against the payload body only, use:
::
$ syntribos keystone.config payloads/keystone/domains_post.txt -t SQL_INJECTION_BODY
For all tests against HTTP headers only, use:
::
$ syntribos keystone.config payloads/keystone/domains_post.txt -t HEADERS
**Call External**
Syntribos payload files can be supplemented with variable data, or data
retrieved from external sources. This is handled using 'extensions.'
Extensions are found in ``syntribos/syntribos/extensions/`` .
One example packaged with Syntribos enables the tester to obtain an auth
token from keystone/identity. The code is located in
``identity/client.py``
To make use of this extension, add the following to the header of your
payload file:
::
X-Auth-Token: CALL_EXTERNAL|syntribos.extensions.identity.client:get_token_v3:["user"]|
The "user" string indicates the data from the configuration file we
added in ``opencafe/configs/keystone.config``
Another example is found in ``random_data/client.py`` . This returns a
UUID when random but unique data is needed. This can be used in place of
usernames when fuzzing a create user call.
::
"username": "CALL_EXTERNAL|syntribos.extensions.random_data.client:get_uuid:[]|",
The extension function can return one value or be used as a generator if
you want it to change for each test.
**Action Field**
While Syntribos is designed to test all fields in a request, it can also
ignore specific fields through the use of Action Fields. If you want to
fuzz against a static object ID, use the Action Field indicator as
follows:
::
"ACTION_FIELD:id": "1a16f348-c8d5-42ec-a474-b1cdf78cf40f",
The ID provided will remain static for every test.

8
doc/source/unittests.rst Normal file
View File

@ -0,0 +1,8 @@
Executing unittests
===================
Navigate to the ``syntribos`` root directory
::
$ python -m unittest discover syntribos/ -p ut_*.py

View File

@ -19,3 +19,8 @@ classifier =
[entry_points]
console_scripts =
syntribos = syntribos.runner:entry_point
[build_sphinx]
all_files = 1
build-dir = doc/build
source-dir = doc/source

12
tox.ini
View File

@ -4,16 +4,24 @@ skipsdist = True
[testenv]
usedevelop = True
install_command = pip install -U {opts} {packages}
install_command = pip install -U {opts} {packages}
setenv=VIRTUAL_ENV={envdir}
deps=-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands = cafe-config plugins install http
commands = cafe-config plugins install http
python setup.py testr --coverage --slowest --testr-args='{posargs}'
coverage combine
coverage report -m
coverage erase
[testenv:docs]
commands =
rm -rf doc/html doc/build
rm -rf doc/source/apidoc doc/source/api
python setup.py build_sphinx
whitelist_externals =
rm
[testenv:pep8]
commands=flake8 {posargs} syntribos