Skip to content

Commit cf55b39

Browse files
committed
Sphinx doc + GitHub pages deployment
1 parent 27cdd34 commit cf55b39

18 files changed

+418
-3
lines changed

.travis.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ python:
1313
- '3.8'
1414
- 'pypy3'
1515

16-
script: python -m unittest tests/tests.py
16+
script:
17+
- python -m unittest tests/tests.py
18+
- make -C docs html
1719

1820
deploy:
1921
- provider: releases
@@ -27,6 +29,14 @@ deploy:
2729
skip_cleanup: true
2830
api_key:
2931
secure: IcX91IbJikIWp5p9AgJWKVpVIhpBZdpstQmz7hES9BnGdh1o/cLcIHcJGhpJXqSQ+kEspxw5DHMhKYFcKShWmj1TyG4TI1eCNycJ/F8f2d4TRBvucZxNfiPZF7GmxZrWEze6iFJ4p3KPBzwQ2zfggxYwbyEL5d73vfLcVc3nQDpoanRvF94EDobMuAeKk5P01OGRU2IK4pMi1ESOolUZr2XKiNaTgNqol5np/XI6Gte+Mlx8bo+AcVKCC+mSSVotrTsPsRErma9sVF9OYf8OH0jySwAt2tqvWRAC66R+inJMbH1qJdJ1EsO2hyF3N7pe9oIGJZkRqxd7Z20MTDg8zYCydbNQB/bsLZeA1fLmt5uQ3+AmIGnia27v7h5tGd5oeceMUbmXtYbX5midfvDXnpZcpqUE/8aUiN/Lq0Lr6qGGiSjvlynEYBWfMY5W4yLhpsKryTn/oaeBMAoMg2IY4BFkSZ+Evtu1RQe5EloYzwT/QjJ2LVO6Rb0ORZpmXUZcuFJOLoISFDqjaI5OpamDuxwKzvR6OGwq+sFYTR42rLN4YZ9NVbUb5AqkKdwqvo8qRiEtivkokbcNwRtMSgEnvD1TSLArYHQdY9gvLNP8CTyW6qO+0Wt1/DianqjYhsk3fBBHijfRbBBRqfyYNmipLm0cPZ1VW4OeBRF+A1OumRc=
32+
- provider: pages
33+
skip_cleanup: true
34+
local_dir: docs/_build/html/
35+
on:
36+
repo: ShellCode33/CredSLayer
37+
tags: true
38+
github_token:
39+
secure: IcX91IbJikIWp5p9AgJWKVpVIhpBZdpstQmz7hES9BnGdh1o/cLcIHcJGhpJXqSQ+kEspxw5DHMhKYFcKShWmj1TyG4TI1eCNycJ/F8f2d4TRBvucZxNfiPZF7GmxZrWEze6iFJ4p3KPBzwQ2zfggxYwbyEL5d73vfLcVc3nQDpoanRvF94EDobMuAeKk5P01OGRU2IK4pMi1ESOolUZr2XKiNaTgNqol5np/XI6Gte+Mlx8bo+AcVKCC+mSSVotrTsPsRErma9sVF9OYf8OH0jySwAt2tqvWRAC66R+inJMbH1qJdJ1EsO2hyF3N7pe9oIGJZkRqxd7Z20MTDg8zYCydbNQB/bsLZeA1fLmt5uQ3+AmIGnia27v7h5tGd5oeceMUbmXtYbX5midfvDXnpZcpqUE/8aUiN/Lq0Lr6qGGiSjvlynEYBWfMY5W4yLhpsKryTn/oaeBMAoMg2IY4BFkSZ+Evtu1RQe5EloYzwT/QjJ2LVO6Rb0ORZpmXUZcuFJOLoISFDqjaI5OpamDuxwKzvR6OGwq+sFYTR42rLN4YZ9NVbUb5AqkKdwqvo8qRiEtivkokbcNwRtMSgEnvD1TSLArYHQdY9gvLNP8CTyW6qO+0Wt1/DianqjYhsk3fBBHijfRbBBRqfyYNmipLm0cPZ1VW4OeBRF+A1OumRc=
3040
- provider: pypi
3141
distributions: sdist bdist_wheel
3242
skip_existing: true
@@ -35,4 +45,4 @@ deploy:
3545
skip_cleanup: true
3646
user: __token__
3747
password:
38-
secure: nbDYdgllAoXpNV0tXLYAp8g1gGEboJ6fhvbC+H2XW66CciMfX5NfhM2mM3RUHIjJOLVsffuj7bg92QhwC72zK6dB/tNXOxw2U4Cs4/+h0hITzKfD2VkCgfVGF3XGR5xlB1hV1ZJAo+74qcNRd3KoaVhLRVpt174iGlXcQaHR0TdKGCExPedbviu5nNZD7Gde1cSvKnXfPk8ZVHzYU0O5X6HVJdOutFV7oAW1uqmEL3/AGc5Gomgfdl0O8AL8Al7SlFGX8Kts5zPE2h11SmGfIJuvkLbJRZwQ8UlHreT3rKpQuGCukXXFQbx3tRmWIb9zM2Np93QZsQ9qFQbyIekJvY9kqp9Lx8sq6sYQcbvXb9fp1+18+m4J5EfJ8D1Z1AgrjOaD2hlqxFwD91yZnWA0AY4yaKGU/GU18t1HTgT3I27AHMCj7OqR/CcRt9h/AYdrPiCzLGWqzvjOX2ayVsquVrkP39z5HFi2pJOp0fuuwMGYrVQ0GRYqMmZbiGiRayJFQXoZ9jY67RaffdDIzapw6pAuKd5bjNe0P6MpAyE7qk5Kz1XnCwNjhLzAFfglI3J5hVkoDzf8S6FFWyhYvWDWtxQ6wJqAzNIAiXJ2hI/5nxEkmKyLMk6dvcJdC9tjMFyqsLrQEbTAu04yJlYHWaAJ0F/HTEVo8Aw4cQdDpNdarfc=
48+
secure: nbDYdgllAoXpNV0tXLYAp8g1gGEboJ6fhvbC+H2XW66CciMfX5NfhM2mM3RUHIjJOLVsffuj7bg92QhwC72zK6dB/tNXOxw2U4Cs4/+h0hITzKfD2VkCgfVGF3XGR5xlB1hV1ZJAo+74qcNRd3KoaVhLRVpt174iGlXcQaHR0TdKGCExPedbviu5nNZD7Gde1cSvKnXfPk8ZVHzYU0O5X6HVJdOutFV7oAW1uqmEL3/AGc5Gomgfdl0O8AL8Al7SlFGX8Kts5zPE2h11SmGfIJuvkLbJRZwQ8UlHreT3rKpQuGCukXXFQbx3tRmWIb9zM2Np93QZsQ9qFQbyIekJvY9kqp9Lx8sq6sYQcbvXb9fp1+18+m4J5EfJ8D1Z1AgrjOaD2hlqxFwD91yZnWA0AY4yaKGU/GU18t1HTgT3I27AHMCj7OqR/CcRt9h/AYdrPiCzLGWqzvjOX2ayVsquVrkP39z5HFi2pJOp0fuuwMGYrVQ0GRYqMmZbiGiRayJFQXoZ9jY67RaffdDIzapw6pAuKd5bjNe0P6MpAyE7qk5Kz1XnCwNjhLzAFfglI3J5hVkoDzf8S6FFWyhYvWDWtxQ6wJqAzNIAiXJ2hI/5nxEkmKyLMk6dvcJdC9tjMFyqsLrQEbTAu04yJlYHWaAJ0F/HTEVo8Aw4cQdDpNdarfc=

docs/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Minimal makefile for Sphinx documentation
2+
#
3+
4+
# You can set these variables from the command line, and also
5+
# from the environment for the first two.
6+
SPHINXOPTS ?=
7+
SPHINXBUILD ?= sphinx-build
8+
SOURCEDIR = .
9+
BUILDDIR = _build
10+
11+
# Put it first so that "make" without argument is like "make help".
12+
help:
13+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14+
15+
.PHONY: help Makefile
16+
17+
# Catch-all target: route all unknown targets to Sphinx using the new
18+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19+
%: Makefile
20+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

docs/_static/css/custom.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import 'theme.css';
2+
3+
.wy-side-nav-search {
4+
background-color: darkred;
5+
}

docs/conf.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Configuration file for the Sphinx documentation builder.
2+
#
3+
# This file only contains a selection of the most common options. For a full
4+
# list see the documentation:
5+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
6+
7+
# -- Path setup --------------------------------------------------------------
8+
9+
# If extensions (or modules to document with autodoc) are in another directory,
10+
# add these directories to sys.path here. If the directory is relative to the
11+
# documentation root, use os.path.abspath to make it absolute, like shown here.
12+
#
13+
14+
import sphinx_rtd_theme
15+
16+
import os
17+
import sys
18+
sys.path.insert(0, os.path.abspath('..'))
19+
20+
21+
# -- Project information -----------------------------------------------------
22+
23+
project = 'CredSLayer'
24+
copyright = '2020, ShellCode'
25+
author = 'ShellCode'
26+
27+
# The full version, including alpha/beta/rc tags
28+
release = '1.0'
29+
30+
31+
# -- General configuration ---------------------------------------------------
32+
33+
# Add any Sphinx extension module names here, as strings. They can be
34+
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
35+
# ones.
36+
extensions = [
37+
'sphinx.ext.autodoc',
38+
'sphinx.ext.napoleon',
39+
'sphinx_rtd_theme',
40+
'sphinxarg.ext',
41+
'sphinx.ext.autosectionlabel'
42+
]
43+
44+
# Add any paths that contain templates here, relative to this directory.
45+
templates_path = ['_templates']
46+
47+
# List of patterns, relative to source directory, that match files and
48+
# directories to ignore when looking for source files.
49+
# This pattern also affects html_static_path and html_extra_path.
50+
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
51+
52+
53+
# -- Options for HTML output -------------------------------------------------
54+
55+
# The theme to use for HTML and HTML Help pages. See the documentation for
56+
# a list of builtin themes.
57+
#
58+
html_theme = 'sphinx_rtd_theme'
59+
60+
html_theme_options = {
61+
'style_nav_header_background': 'darkred',
62+
'collapse_navigation': True
63+
}
64+
65+
# Add any paths that contain custom static files (such as style sheets) here,
66+
# relative to this directory. They are copied after the builtin static files,
67+
# so a file named "default.css" will overwrite the builtin "default.css".
68+
html_static_path = ['_static']
69+
70+
add_module_names = False
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Code explanations
2+
=================
3+
4+
You will find here concepts you must be aware of to get involved.
5+
You do not need to be a Python expert to contribute,
6+
CredSLayer has been made in a way that is fairly easy to extend.
7+
8+
.. toctree::
9+
:maxdepth: 4
10+
11+
code/sessions
12+
code/parsers

docs/contribute/code/parsers.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Parsers
2+
========
3+
4+
.. automodule:: credslayer.parsers

docs/contribute/code/sessions.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Sessions
2+
========
3+
4+
CredSLayer's sessions is probably the most important concept, it helps you create a context between loads of packets you "receive".
5+
It will hold credentials you find and enables parsers to keep variables across per-packet analysis.
6+
7+
For example in telnet, data are transmitted line by line, and sometimes character by character.
8+
So the parser gathers those pieces of information and store them in a session variable that will be available to further packets belonging to the same session :
9+
10+
.. code-block:: python
11+
12+
session["data_being_built"] += data
13+
14+
The lines that follow are directly taken from the code's documentation and explain more in depth how sessions work.
15+
16+
.. automodule:: credslayer.core.session
17+
:members:

docs/contribute/create-parser.rst

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
Tutorial : new parser
2+
=====================
3+
4+
Create a new file in ``credslayer/parsers/`` named after the protocol you want to analyse. Usually you want to name your file the same as the `Protocol` column in wireshark.
5+
6+
.. image:: wireshark_protocol_column.png
7+
:width: 800
8+
:alt: Wireshark protocol column
9+
10+
But sometimes it won't work, so you might wanna check the name of the protocol by searching it using the following command line :
11+
12+
.. code-block:: none
13+
14+
$ tshark -G protocols | grep -i SEARCH_HERE | awk '{print $NF}'
15+
16+
17+
You now have to implement the following function that CredSLayer will automatically call for each incoming packet of your choosen protocol :
18+
19+
.. autofunction:: credslayer.parsers.ftp.analyse
20+
21+
Let's just take the ftp parser as an example, just read the comments :)
22+
23+
.. code-block:: python
24+
25+
# coding: utf-8
26+
27+
from pyshark.packet.layer import Layer
28+
29+
from credslayer.core import logger
30+
from credslayer.core.session import Session
31+
32+
33+
# Remember this function is called for every single packet that belong to the protocol
34+
def analyse(session: Session, layer: Layer):
35+
36+
# You can use the pretty_print method to show what's in the packet
37+
# layer.pretty_print()
38+
39+
# Just an alias of credentials_being_built
40+
current_creds = session.credentials_being_built
41+
42+
# We check (using pyshark's layer object) if the packet contains a "reponse_code" field.
43+
# This is the name tshark gave to the portion of the packet holding the response code.
44+
if hasattr(layer, "response_code"):
45+
code = int(layer.response_code)
46+
47+
# Code 230 means authentication has been successful
48+
if code == 230 and current_creds.username:
49+
# That's how you log credentials you've just found
50+
logger.found(session, "credentials found: {} -- {}".format(current_creds.username, current_creds.password))
51+
52+
# That's how you tell CredsLayer to remove the context and credentials currently being built.
53+
# You found everything you needed, you're done with everything you saved in the session.
54+
session.validate_credentials()
55+
56+
# Code 430 means credentials were wrong
57+
elif code == 430:
58+
# That's also how you tell CredsLayer to remove the context and credentials currently being built.
59+
# You just found out credentials were wrong, you're not interested in what you saved in the session.
60+
session.invalidate_credentials_and_clear_session()
61+
62+
# We check (using pyshark's layer object) if the packet contains a "request_command" field,
63+
# This is the name tshark gave to the portion of the packet holding the FTP command.
64+
elif hasattr(layer, "request_command"):
65+
command = layer.request_command
66+
67+
# The username is sent next to the "USER" command.
68+
# We store the username in `current_creds`, which is the alias for the credentials being built in the session.
69+
if command == "USER":
70+
current_creds.username = layer.request_arg
71+
72+
# Idem with the password
73+
elif command == "PASS":
74+
current_creds.password = layer.request_arg
75+
76+
I really encourage you to read about :ref:`Sessions` as this is what enables you to build a persistent context across each call to your *analyse* function.
77+
For example in FTP, the username is first sent in a packet, then the password in another one. Thanks to the :ref:`Sessions` object, you will be able to keep track
78+
of some valuable data. Then somehow (depending on the protocol you are analysing) you might receive an indicator of success or failure, in FTP codes 230 and 430 fulfill that purpose.
79+
When you find such an indicator, you must call ``session.invalidate_credentials_and_clear_session`` or ``session.validate_credentials`` to tell CredSLayer you're done with those credentials.

docs/contribute/setup.rst

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Environment setup
2+
=================
3+
4+
First you must `fork the repository <https://github.com/ShellCode33/CredSLayer/fork>`_.
5+
Then clone your personal repo and create a new branch based on develop :
6+
7+
.. code-block:: none
8+
9+
$ git clone https://github.com/[YourUsername]/CredSLayer
10+
$ cd CredSLayer/
11+
$ git checkout -b [Choose a name] develop
12+
13+
To prevent any dependencies conflicts, it's recommended to create a `virtualenv <https://docs.python.org/fr/3/library/venv.html>`_.
14+
CredSLayer supports Python 3.5 and above, so in order to make sure your code is compatible, I suggest you install this version of Python and create a virtualenv with it :
15+
16+
.. code-block:: none
17+
18+
$ python3.5 -m venv venv
19+
$ source venv/bin/activate
20+
21+
Then install the project in "dev mode" :
22+
23+
.. code-block:: none
24+
25+
$ pip install -e .
26+
27+
At this point, ``credslayer`` should be available from the command line (only when you're inside the virtualenv). The command will automatically use the latest changes you make to the code.
28+
29+
Once you're done with your modifications, make sure your code didn't break anything by running the unit tests:
30+
31+
.. code-block:: none
32+
33+
$ python -m unittest tests/tests.py
34+
35+
If there's no failure, add, commit and push your code :
36+
37+
.. code-block:: none
38+
39+
$ git add path/to/updated/file
40+
$ git commit -m "short description of your changes"
41+
$ git push
42+
43+
Then go to GitHub and create a pull request. I will review it and decide whether or not it's worth integrating it.
83.4 KB
Loading

0 commit comments

Comments
 (0)