diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..cf7a39fb
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "pip" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "daily"
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 00000000..b97268c6
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,68 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+# ******** NOTE ********
+
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ master ]
+ schedule:
+ - cron: '20 19 * * 3'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'java', 'python' ]
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
+ # Learn more...
+ # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
+
+ # âšī¸ Command-line programs to run using the OS shell.
+ # đ https://git.io/JvXDl
+
+ # âī¸ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
new file mode 100644
index 00000000..f1abc2ff
--- /dev/null
+++ b/.github/workflows/python-package.yml
@@ -0,0 +1,39 @@
+# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: Python package
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: [3.5, 3.6, 3.7, 3.8]
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install flake8 pytest
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ - name: Lint with flake8
+ run: |
+ # stop the build if there are Python syntax errors or undefined names
+ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
+ # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
+ flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
+ - name: Test with pytest
+ run: |
+ pytest
diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml
new file mode 100644
index 00000000..76c166ec
--- /dev/null
+++ b/.github/workflows/ruby.yml
@@ -0,0 +1,33 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
+# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
+
+name: Ruby
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ test:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Ruby
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
+ # uses: ruby/setup-ruby@v1
+ uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
+ with:
+ ruby-version: 2.6
+ - name: Install dependencies
+ run: bundle install
+ - name: Run tests
+ run: bundle exec rake
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
index 1a610f7d..f934f49c
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,10 @@ apikeys.py
# Junk files
shodan
+pentest*
+kickoff*
+kick-off*
+knownbugs.txt
+.swp
+cpentest
+*sqlite
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..ca9cfdea
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "jok3r-pocs"]
+ path = jok3r-pocs
+ url = https://github.com/koutto/jok3r-pocs
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
old mode 100644
new mode 100755
index b6257d00..1c71d0fe
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,16 @@
=========
Changelog
=========
+**v3.0 BETA 3 Arkham Subversion** 2020-07-21
+ *Add RPC service and tool (disabled by default)
+ *Add initial scheme for F5 BIG IP vulnerability scanner and exploiter
+ *Add/fix/customize some bits here and there
+ *First pre-release v0.1
+
+**v3.0 BETA 3** 2020-07-18
+ * Add waf-checker and Pentest1 to attacks profiles
+ * Fix several minor bugs and customizations
+ * Kali GPG key updated
**v3.0 BETA 2** 2019-07-09
* Fix several bugs after testings
diff --git a/Dockerfile b/Dockerfile
old mode 100644
new mode 100755
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
diff --git a/README.rst b/README.rst
old mode 100644
new mode 100755
index 46c0a040..865be3b8
--- a/README.rst
+++ b/README.rst
@@ -2,12 +2,12 @@
-.. image:: ./pictures/logo.png
+.. image:: ./pictures/joker.png
.. raw:: html
- Jok3r v3 beta
+ Jok3r v3 beta Arkham SubVersion
.. image:: https://img.shields.io/badge/python-3.6-blue.svg
@@ -18,13 +18,6 @@
:target: https://jok3r.readthedocs.io/en/latest/
:alt: Documentation ReadTheDocs
-.. image:: https://img.shields.io/microbadger/image-size/koutto/jok3r.svg
- :target: https://hub.docker.com/r/koutto/jok3r/
- :alt: Docker Size
-
-.. image:: https://img.shields.io/docker/cloud/build/koutto/jok3r.svg
- :alt: Docker Build Status
-
.. raw:: html
@@ -37,7 +30,6 @@ and bugs might be present.**
**Many tests are going on: see https://github.com/koutto/jok3r/blob/master/tests/TESTS.rst.
Ideas, bug reports, contributions are welcome !**
-
.. contents::
:local:
:depth: 1
@@ -487,11 +479,12 @@ Supported Services & Security Checks
- `Oracle (default 1521/tcp)`_
- `PostgreSQL (default 5432/tcp)`_
- `RDP (default 3389/tcp)`_
+- `RPC (default 2049/udp)`_
- `SMB (default 445/tcp)`_
- `SMTP (default 25/tcp)`_
- `SNMP (default 161/udp)`_
- `SSH (default 22/tcp)`_
-- `Telnet (default 21/tcp)`_
+- `Telnet (default 23/tcp)`_
- `VNC (default 5900/tcp)`_
@@ -761,6 +754,19 @@ RDP (default 3389/tcp)
| ms12-020 | vulnscan | Check for MS12-020 RCE vulnerability (any Windows before 13 Mar 2012) | metasploit |
+---------+----------+-----------------------------------------------------------------------+------------+
+RPC (default 2049/udp)
+----------------------
+
+.. code-block:: console
+
+ +----------+----------+-----------------------------------------------------------------------+------------+
+ | Name | Category | Description | Tool used |
+ +----------+----------+-----------------------------------------------------------------------+------------+
+ | ls-rpc-srv | recon | Listing RPC services | rpcscan |
+ | ls-nfs-mountpoints | recon | Listing NFS mount points | rpcscan |
+ | ls-nfs-shares | recon | Listing NFS shares | rpcscan |
+ +----------+----------+-----------------------------------------------------------------------+------------+
+
SMB (default 445/tcp)
---------------------
@@ -869,4 +875,4 @@ Known Issues
=============
Changelog
=============
-See `Changelog `_
\ No newline at end of file
+See `Changelog `_
diff --git a/TODO.rst b/TODO.rst
old mode 100644
new mode 100755
index e69504c7..25259ef9
--- a/TODO.rst
+++ b/TODO.rst
@@ -12,6 +12,7 @@ BUGS
IMPROVEMENTS / NEW FEATURES
===============================================================================
* Run custom command
+* New command: kick-off
* Session / Restore
* Indicate checks that need a reverse connection (IP reachable from target)
* Products SMTP (eg Exim) https://en.wikipedia.org/wiki/List_of_mail_server_software
@@ -47,6 +48,58 @@ TOOLS/CHECKS TO ADD
* Wordpress RCE https://github.com/opsxcq/exploit-CVE-2016-10033
* https://github.com/peacand/winsharecrawler
* https://github.com/Bo0oM/fuzz.txt/blob/master/fuzz.txt
+* https://github.com/dwisiswant0/findom-xss
+* https://github.com/devanshbatham/ParamSpider
+* https://github.com/google/tsunami-security-scanner
+* https://github.com/OWASP/Amass
+* https://github.com/inc0d3/moodlescan
+* https://github.com/m4ll0k/WAScan
+* https://github.com/skavngr/rapidscan
+* https://github.com/projectdiscovery/nuclei
+* https://pypi.org/project/SpitzerSec/
+* https://github.com/OJ/gobuster
+* https://github.com/khalilbijjou/WAFNinja.git
+* https://github.com/jas502n/CVE-2020-5902
+* https://github.com/D4Vinci/CWFF
+* https://github.com/bhassani/EternalBlueC
+
+TOR MONITORING:
+* https://github.com/andreyglauzer/VigilantOnion
+* https://github.com/teal33t/poopak
+* https://github.com/CIRCL/AIL-framework
+* https://github.com/s-rah/onionscan
+* https://github.com/automatingosint/osint_public
+* https://github.com/trandoshan-io
+* https://github.com/itsmehacker/DarkScrape/blob/master/README.md
+* https://github.com/GoSecure/freshonions-torscraper
+* https://github.com/DedSecInside/TorBot
+* https://github.com/AshwinAmbal/DarkWeb-Crawling-Indexing/blob/master/README.md
+* https://github.com/k4m4/onioff
+* https://github.com/MikeMeliz/TorCrawl.py
+* https://github.com/bunseokbot/darklight
+* https://github.com/saidortiz/onion_osint
+* https://github.com/vlall/Darksearch
+* https://github.com/ntddk/onionstack
+* https://github.com/mrrva/illCrawler
+* https://github.com/scresh/Digamma
+* https://github.com/reidjs/onionup/blob/master/README.md
+* https://github.com/desyncr/onionuptime/blob/master/README.md
+
+CVE SELECTION TO ADD
+===============================================================================
+
+F5 BIG-IP vulnerabilities:
+
+* CVE-2020-5902
+* CVE-2020-5903
+* CVE-2020-5857
+* CVE-2020-5876
+* CVE-2020-5877
+* CVE-2020-5883
+* CVE-2020-5885
+* CVE-2020-5881
+* CVE-2020-5875
+
DOCUMENTATION
===============================================================================
@@ -58,8 +111,6 @@ SERVICES TO ADD
* NFS
* nfsshell (sudo apt-get install libreadline-dev ; make)
* MongoDB
-* RPC
- * https://github.com/hegusung/RPCScan.git
* DNS
* LDAP
* MDNS
@@ -70,6 +121,12 @@ SERVICES TO ADD
* RSH
* IMAP
+Dorking capabilities (Google, shodan, Bing, Censys...)
+#########################################################################################
+# DORKS
+#########################################################################################
+Tools:
+# darkd0rk3r, dorkme, fast-google-dorks-search,gdork,goodork3,google DB tool,googledorker,katana
diff --git a/apikeys.py b/apikeys.py
old mode 100644
new mode 100755
diff --git a/doc/Makefile b/doc/Makefile
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/command_attack.doctree b/doc/_build/doctrees/command_attack.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/command_db.doctree b/doc/_build/doctrees/command_db.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/command_info.doctree b/doc/_build/doctrees/command_info.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/command_toolbox.doctree b/doc/_build/doctrees/command_toolbox.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/environment.pickle b/doc/_build/doctrees/environment.pickle
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/index.doctree b/doc/_build/doctrees/index.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/info.doctree b/doc/_build/doctrees/info.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/installation.doctree b/doc/_build/doctrees/installation.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/settings.doctree b/doc/_build/doctrees/settings.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/smartmodules.doctree b/doc/_build/doctrees/smartmodules.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/what.doctree b/doc/_build/doctrees/what.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/why.doctree b/doc/_build/doctrees/why.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/doctrees/wordlists.doctree b/doc/_build/doctrees/wordlists.doctree
old mode 100644
new mode 100755
diff --git a/doc/_build/html/.buildinfo b/doc/_build/html/.buildinfo
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/command_attack.rst.txt b/doc/_build/html/_sources/command_attack.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/command_db.rst.txt b/doc/_build/html/_sources/command_db.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/command_info.rst.txt b/doc/_build/html/_sources/command_info.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/command_toolbox.rst.txt b/doc/_build/html/_sources/command_toolbox.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/index.rst.txt b/doc/_build/html/_sources/index.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/info.rst.txt b/doc/_build/html/_sources/info.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/installation.rst.txt b/doc/_build/html/_sources/installation.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/settings.rst.txt b/doc/_build/html/_sources/settings.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/smartmodules.rst.txt b/doc/_build/html/_sources/smartmodules.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/what.rst.txt b/doc/_build/html/_sources/what.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/why.rst.txt b/doc/_build/html/_sources/why.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_sources/wordlists.rst.txt b/doc/_build/html/_sources/wordlists.rst.txt
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/ajax-loader.gif b/doc/_build/html/_static/ajax-loader.gif
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/alabaster.css b/doc/_build/html/_static/alabaster.css
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/basic.css b/doc/_build/html/_static/basic.css
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/comment-bright.png b/doc/_build/html/_static/comment-bright.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/comment-close.png b/doc/_build/html/_static/comment-close.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/comment.png b/doc/_build/html/_static/comment.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/css/badge_only.css b/doc/_build/html/_static/css/badge_only.css
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/css/theme.css b/doc/_build/html/_static/css/theme.css
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/custom.css b/doc/_build/html/_static/custom.css
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/doctools.js b/doc/_build/html/_static/doctools.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/documentation_options.js b/doc/_build/html/_static/documentation_options.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/down-pressed.png b/doc/_build/html/_static/down-pressed.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/down.png b/doc/_build/html/_static/down.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/file.png b/doc/_build/html/_static/file.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-bold.eot b/doc/_build/html/_static/fonts/Lato/lato-bold.eot
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-bold.ttf b/doc/_build/html/_static/fonts/Lato/lato-bold.ttf
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-bold.woff b/doc/_build/html/_static/fonts/Lato/lato-bold.woff
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-bold.woff2 b/doc/_build/html/_static/fonts/Lato/lato-bold.woff2
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-bolditalic.eot b/doc/_build/html/_static/fonts/Lato/lato-bolditalic.eot
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-bolditalic.ttf b/doc/_build/html/_static/fonts/Lato/lato-bolditalic.ttf
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-bolditalic.woff b/doc/_build/html/_static/fonts/Lato/lato-bolditalic.woff
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-bolditalic.woff2 b/doc/_build/html/_static/fonts/Lato/lato-bolditalic.woff2
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-italic.eot b/doc/_build/html/_static/fonts/Lato/lato-italic.eot
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-italic.ttf b/doc/_build/html/_static/fonts/Lato/lato-italic.ttf
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-italic.woff b/doc/_build/html/_static/fonts/Lato/lato-italic.woff
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-italic.woff2 b/doc/_build/html/_static/fonts/Lato/lato-italic.woff2
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-regular.eot b/doc/_build/html/_static/fonts/Lato/lato-regular.eot
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-regular.ttf b/doc/_build/html/_static/fonts/Lato/lato-regular.ttf
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-regular.woff b/doc/_build/html/_static/fonts/Lato/lato-regular.woff
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/Lato/lato-regular.woff2 b/doc/_build/html/_static/fonts/Lato/lato-regular.woff2
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/doc/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/fontawesome-webfont.eot b/doc/_build/html/_static/fonts/fontawesome-webfont.eot
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/fontawesome-webfont.svg b/doc/_build/html/_static/fonts/fontawesome-webfont.svg
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/fontawesome-webfont.ttf b/doc/_build/html/_static/fonts/fontawesome-webfont.ttf
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/fontawesome-webfont.woff b/doc/_build/html/_static/fonts/fontawesome-webfont.woff
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/fonts/fontawesome-webfont.woff2 b/doc/_build/html/_static/fonts/fontawesome-webfont.woff2
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/jquery-3.1.0.js b/doc/_build/html/_static/jquery-3.1.0.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/jquery.js b/doc/_build/html/_static/jquery.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/js/modernizr.min.js b/doc/_build/html/_static/js/modernizr.min.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/js/theme.js b/doc/_build/html/_static/js/theme.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/minus.png b/doc/_build/html/_static/minus.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/plus.png b/doc/_build/html/_static/plus.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/pygments.css b/doc/_build/html/_static/pygments.css
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/searchtools.js b/doc/_build/html/_static/searchtools.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/underscore-1.3.1.js b/doc/_build/html/_static/underscore-1.3.1.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/underscore.js b/doc/_build/html/_static/underscore.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/up-pressed.png b/doc/_build/html/_static/up-pressed.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/up.png b/doc/_build/html/_static/up.png
old mode 100644
new mode 100755
diff --git a/doc/_build/html/_static/websupport.js b/doc/_build/html/_static/websupport.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/command_attack.html b/doc/_build/html/command_attack.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/command_db.html b/doc/_build/html/command_db.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/command_info.html b/doc/_build/html/command_info.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/command_toolbox.html b/doc/_build/html/command_toolbox.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/genindex.html b/doc/_build/html/genindex.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/index.html b/doc/_build/html/index.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/info.html b/doc/_build/html/info.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/installation.html b/doc/_build/html/installation.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/objects.inv b/doc/_build/html/objects.inv
old mode 100644
new mode 100755
diff --git a/doc/_build/html/search.html b/doc/_build/html/search.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/searchindex.js b/doc/_build/html/searchindex.js
old mode 100644
new mode 100755
diff --git a/doc/_build/html/settings.html b/doc/_build/html/settings.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/smartmodules.html b/doc/_build/html/smartmodules.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/what.html b/doc/_build/html/what.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/why.html b/doc/_build/html/why.html
old mode 100644
new mode 100755
diff --git a/doc/_build/html/wordlists.html b/doc/_build/html/wordlists.html
old mode 100644
new mode 100755
diff --git a/doc/command_attack.rst b/doc/command_attack.rst
old mode 100644
new mode 100755
index 288a66c4..1a99d84f
--- a/doc/command_attack.rst
+++ b/doc/command_attack.rst
@@ -54,7 +54,7 @@ The command `attack` is where security checks against targets are started.
There are 2 modes of attacks:
* Single target
-* Multiple targets from a mission sccope in database
+* Multiple targets from a mission scope in database
Single Target Mode
@@ -99,7 +99,7 @@ Multiple Targets Mode
=====================
This mode is designed to work with the local database: First you create a mission
to define the scope of the pentest in the database (see :ref:`command-db`), and then
-you run security checks against all or a subset a targets from the scope:
+you run security checks against all or a subset of targets from the scope:
* Example to run checks against **all targets from the mission "MayhemProject"**, using
fast mode (i.e. without asking for any confirmation before targets and checks):
diff --git a/doc/command_db.rst b/doc/command_db.rst
old mode 100644
new mode 100755
diff --git a/doc/command_info.rst b/doc/command_info.rst
old mode 100644
new mode 100755
diff --git a/doc/command_toolbox.rst b/doc/command_toolbox.rst
old mode 100644
new mode 100755
diff --git a/doc/conf.py b/doc/conf.py
old mode 100644
new mode 100755
diff --git a/doc/index.rst b/doc/index.rst
old mode 100644
new mode 100755
diff --git a/doc/installation.rst b/doc/installation.rst
old mode 100644
new mode 100755
index c79d22de..769947fa
--- a/doc/installation.rst
+++ b/doc/installation.rst
@@ -78,4 +78,15 @@ run the following commands:
Manual install
==============
-TODO
\ No newline at end of file
+ .. code-block:: console
+
+ git clone https://github.com/cbk914/jok3r.git
+ cd jok3r
+ chmod +x jok3r.py
+
+* You can install full toolbox or just a few tools targeting a given service.
+See available options with toolbox help command.
+
+ .. code-block:: console
+
+ python3 jok3r.py toolbox -h
\ No newline at end of file
diff --git a/doc/internals.rst b/doc/internals.rst
old mode 100644
new mode 100755
diff --git a/doc/make.bat b/doc/make.bat
old mode 100644
new mode 100755
diff --git a/doc/requirements.txt b/doc/requirements.txt
old mode 100644
new mode 100755
diff --git a/doc/settings.rst b/doc/settings.rst
old mode 100644
new mode 100755
diff --git a/doc/smartmodules.rst b/doc/smartmodules.rst
old mode 100644
new mode 100755
diff --git a/doc/what.rst b/doc/what.rst
old mode 100644
new mode 100755
diff --git a/doc/why.rst b/doc/why.rst
old mode 100644
new mode 100755
diff --git a/doc/wordlists.rst b/doc/wordlists.rst
old mode 100644
new mode 100755
diff --git a/docker/Dockerfile b/docker/Dockerfile
old mode 100644
new mode 100755
diff --git a/docker/NOTES.rst b/docker/NOTES.rst
old mode 100644
new mode 100755
diff --git a/docker_j0k3r.sh b/docker_j0k3r.sh
new file mode 100755
index 00000000..af3419d5
--- /dev/null
+++ b/docker_j0k3r.sh
@@ -0,0 +1,6 @@
+# CONSOLE
+sudo docker run -i -t --name jok3r-container -w /root/jok3r -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --shm-size 2g --net=host koutto/jok3r
+# GUI
+#sudo docker run -i -t -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix koutto/jok3r &
+#xhost +
+
diff --git a/docker_update.sh b/docker_update.sh
new file mode 100755
index 00000000..bcb79fe2
--- /dev/null
+++ b/docker_update.sh
@@ -0,0 +1,2 @@
+sudo docker pull koutto/jok3r
+sudo docker run -i -t --name jok3r-container-updated -w /root/jok3r -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --shm-size 2g --net=host koutto/jok3r
diff --git a/install-dependencies.sh b/install-dependencies.sh
index 86592a77..449e02bc 100755
--- a/install-dependencies.sh
+++ b/install-dependencies.sh
@@ -66,11 +66,16 @@ if [[ ! $(grep "deb http://http.kali.org/kali kali-rolling main" /etc/apt/source
cp /etc/apt/sources.list /etc/apt/sources.list.bak
echo "deb http://http.kali.org/kali kali-rolling main non-free contrib" >> /etc/apt/sources.list
cd /tmp/
- wget -k https://http.kali.org/kali/pool/main/k/kali-archive-keyring/kali-archive-keyring_2018.1_all.deb
- dpkg -i kali-archive-keyring_2018.1_all.deb
- rm -f kali-archive-keyring_2018.1_all.deb
+ wget -k https://http.kali.org/kali/pool/main/k/kali-archive-keyring/kali-archive-keyring_2020.2_all.deb
+ dpkg -i kali-archive-keyring_2020.2_all.deb
+ rm -f kali-archive-keyring_2020.2_all.deb
+ # gpg --keyserver pgpkeys.mit.edu --recv-key ED444FF07D8D0BF6
+ # apt-key adv --keyserver hkp://keys.gnupg.net --recv-keys 7D8D0BF6
+ gpg --keyserver hkp://keys.gnupg.net --recv-key 7D8D0BF6
+ gpg -a --export ED444FF07D8D0BF6 | sudo apt-key add -
apt-get update
apt-get install -y kali-archive-keyring
+
if [ $? -eq 0 ]; then
print_green "[+] Kali repository added with success"
else
@@ -231,7 +236,7 @@ PACKAGES="
python
python2.7
python3
-python-pip
+#python-pip
python3-pip
python-dev
python3-dev
@@ -253,7 +258,7 @@ for package in $PACKAGES; do
fi
done
-pip2 install --upgrade pip
+#pip2 install --upgrade pip
pip3 install --upgrade pip
# pip3 uninstall -y psycopg2
# pip3 install psycopg2-binary
@@ -269,12 +274,12 @@ else
print_red "[!] An error occured during Python2.7 install"
exit 1
fi
-if [ -x "$(command -v pip2)" ]; then
- print_green "[+] pip2 installed successfully"
-else
- print_red "[!] An error occured during pip2 install"
- exit 1
-fi
+#if [ -x "$(command -v pip2)" ]; then
+# print_green "[+] pip2 installed successfully"
+#else
+# print_red "[!] An error occured during pip2 install"
+# exit 1
+#fi
if [ -x "$(command -v pip3)" ]; then
print_green "[+] pip3 installed successfully"
else
@@ -288,7 +293,7 @@ print_delimiter
if ! [ -x "$(command -v virtualenv)" ]; then
print_blue "[~] Install python virtual environment packages"
- pip2 install virtualenv
+ #pip2 install virtualenv
pip3 install virtualenv
# pip3 install virtualenvwrapper
# source /usr/local/bin/virtualenvwrapper.sh
@@ -378,18 +383,19 @@ webencodings
Werkzeug
"
-PIP2FREEZE=$(pip2 freeze)
-for lib in $LIBPY2; do
- if [[ ! $(echo $PIP2FREEZE | grep -i $lib) ]]; then
- echo
- print_blue "[~] Install Python library ${lib} (py2)"
- pip2 install $lib
- fi
-done
+#PIP2FREEZE=$(pip2 freeze)
+#for lib in $LIBPY2; do
+# if [[ ! $(echo $PIP2FREEZE | grep -i $lib) ]]; then
+# echo
+# print_blue "[~] Install Python library ${lib} (py2)"
+# pip2 install $lib
+# fi
+#done
LIBPY3="
aiohttp
ansi2html
+argparse
asn1crypto
async-timeout
asyncio
diff --git a/jok3r-pocs b/jok3r-pocs
new file mode 160000
index 00000000..efb28fc4
--- /dev/null
+++ b/jok3r-pocs
@@ -0,0 +1 @@
+Subproject commit efb28fc4c8861ffba98d9986ccca2840c9d7dc4a
diff --git a/jok3r.py b/jok3r.py
old mode 100644
new mode 100755
diff --git a/jok3r_run.sh b/jok3r_run.sh
new file mode 100755
index 00000000..b0de9c55
--- /dev/null
+++ b/jok3r_run.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+python3 jok3r.py db mission
diff --git a/lib/__init__.py b/lib/__init__.py
old mode 100644
new mode 100755
diff --git a/lib/_version.py b/lib/_version.py
old mode 100644
new mode 100755
index 0c749e74..e1d2a36b
--- a/lib/_version.py
+++ b/lib/_version.py
@@ -1 +1 @@
-__version__ = '3.0 beta 2'
\ No newline at end of file
+__version__ = '3.0 Arkham SubVersion'
diff --git a/lib/controller/AttackController.py b/lib/controller/AttackController.py
old mode 100644
new mode 100755
diff --git a/lib/controller/Controller.py b/lib/controller/Controller.py
old mode 100644
new mode 100755
diff --git a/lib/controller/DbController.py b/lib/controller/DbController.py
old mode 100644
new mode 100755
index fd7c91b6..62c6a1b6
--- a/lib/controller/DbController.py
+++ b/lib/controller/DbController.py
@@ -65,9 +65,9 @@ def __init__(self, arguments, settings, sqlsession):
# Delete useless cmd2 built-in commands
del cmd2.Cmd.do_edit
- del cmd2.Cmd.do_load
+ #del cmd2.Cmd.do_load
del cmd2.Cmd.do_py
- del cmd2.Cmd.do_pyscript
+ #del cmd2.Cmd.do_pyscript
#del cmd2.Cmd.do_set
del cmd2.Cmd.do_shortcuts
@@ -1756,4 +1756,4 @@ def __confirm_for_all(self, action):
print()
return False
else:
- return True
\ No newline at end of file
+ return True
diff --git a/lib/controller/InfoController.py b/lib/controller/InfoController.py
old mode 100644
new mode 100755
diff --git a/lib/controller/MainController.py b/lib/controller/MainController.py
old mode 100644
new mode 100755
diff --git a/lib/controller/ToolboxController.py b/lib/controller/ToolboxController.py
old mode 100644
new mode 100755
diff --git a/lib/controller/__init__.py b/lib/controller/__init__.py
old mode 100644
new mode 100755
diff --git a/lib/core/ArgumentsParser.py b/lib/core/ArgumentsParser.py
old mode 100644
new mode 100755
diff --git a/lib/core/AttackProfiles.py b/lib/core/AttackProfiles.py
old mode 100644
new mode 100755
diff --git a/lib/core/AttackScope.py b/lib/core/AttackScope.py
old mode 100644
new mode 100755
diff --git a/lib/core/Check.py b/lib/core/Check.py
old mode 100644
new mode 100755
diff --git a/lib/core/Command.py b/lib/core/Command.py
old mode 100644
new mode 100755
diff --git a/lib/core/Config.py b/lib/core/Config.py
old mode 100644
new mode 100755
diff --git a/lib/core/Constants.py b/lib/core/Constants.py
old mode 100644
new mode 100755
diff --git a/lib/core/ContextRequirements.py b/lib/core/ContextRequirements.py
old mode 100644
new mode 100755
diff --git a/lib/core/Exceptions.py b/lib/core/Exceptions.py
old mode 100644
new mode 100755
diff --git a/lib/core/ProcessLauncher.py b/lib/core/ProcessLauncher.py
old mode 100644
new mode 100755
diff --git a/lib/core/ServiceChecks.py b/lib/core/ServiceChecks.py
old mode 100644
new mode 100755
diff --git a/lib/core/ServicesConfig.py b/lib/core/ServicesConfig.py
old mode 100644
new mode 100755
diff --git a/lib/core/Settings.py b/lib/core/Settings.py
old mode 100644
new mode 100755
diff --git a/lib/core/Target.py b/lib/core/Target.py
old mode 100644
new mode 100755
diff --git a/lib/core/Tool.py b/lib/core/Tool.py
old mode 100644
new mode 100755
diff --git a/lib/core/Toolbox.py b/lib/core/Toolbox.py
old mode 100644
new mode 100755
diff --git a/lib/core/__init__.py b/lib/core/__init__.py
old mode 100644
new mode 100755
diff --git a/lib/db/CommandOutput.py b/lib/db/CommandOutput.py
old mode 100644
new mode 100755
diff --git a/lib/db/Credential.py b/lib/db/Credential.py
old mode 100644
new mode 100755
diff --git a/lib/db/Host.py b/lib/db/Host.py
old mode 100644
new mode 100755
diff --git a/lib/db/IPAddressType.py b/lib/db/IPAddressType.py
old mode 100644
new mode 100755
diff --git a/lib/db/Mission.py b/lib/db/Mission.py
old mode 100644
new mode 100755
diff --git a/lib/db/Option.py b/lib/db/Option.py
old mode 100644
new mode 100755
diff --git a/lib/db/Product.py b/lib/db/Product.py
old mode 100644
new mode 100755
diff --git a/lib/db/Result.py b/lib/db/Result.py
old mode 100644
new mode 100755
diff --git a/lib/db/Screenshot.py b/lib/db/Screenshot.py
old mode 100644
new mode 100755
diff --git a/lib/db/Service.py b/lib/db/Service.py
old mode 100644
new mode 100755
diff --git a/lib/db/Session.py b/lib/db/Session.py
old mode 100644
new mode 100755
diff --git a/lib/db/Vuln.py b/lib/db/Vuln.py
old mode 100644
new mode 100755
diff --git a/lib/db/__init__.py b/lib/db/__init__.py
old mode 100644
new mode 100755
diff --git a/lib/importer/Config.py b/lib/importer/Config.py
old mode 100644
new mode 100755
diff --git a/lib/importer/NmapResultsParser.py b/lib/importer/NmapResultsParser.py
old mode 100644
new mode 100755
diff --git a/lib/importer/ShodanResultsParser.py b/lib/importer/ShodanResultsParser.py
old mode 100644
new mode 100755
diff --git a/lib/importer/__init__.py b/lib/importer/__init__.py
old mode 100644
new mode 100755
diff --git a/lib/output/Logger.py b/lib/output/Logger.py
old mode 100644
new mode 100755
diff --git a/lib/output/Output.py b/lib/output/Output.py
old mode 100644
new mode 100755
diff --git a/lib/output/StatusBar.py b/lib/output/StatusBar.py
old mode 100644
new mode 100755
diff --git a/lib/output/__init__.py b/lib/output/__init__.py
old mode 100644
new mode 100755
diff --git a/lib/reporter/IconsMapping.py b/lib/reporter/IconsMapping.py
old mode 100644
new mode 100755
diff --git a/lib/reporter/Reporter.py b/lib/reporter/Reporter.py
old mode 100644
new mode 100755
diff --git a/lib/reporter/Reporter.py.bak b/lib/reporter/Reporter.py.bak
new file mode 100755
index 00000000..e424d615
--- /dev/null
+++ b/lib/reporter/Reporter.py.bak
@@ -0,0 +1,860 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+###
+### Reporter > Reporter
+###
+import ansi2html
+import ast
+import base64
+import datetime
+import re
+import warnings
+import webbrowser
+
+from lib.db.Screenshot import ScreenStatus
+from lib.db.Service import Protocol
+from lib.core.Config import *
+from lib.core.Constants import *
+from lib.output.Logger import logger
+from lib.output.Output import Output
+from lib.reporter.IconsMapping import IconsMapping
+from lib.requester.Condition import Condition
+from lib.requester.CredentialsRequester import CredentialsRequester
+from lib.requester.Filter import Filter
+from lib.requester.HostsRequester import HostsRequester
+from lib.requester.OptionsRequester import OptionsRequester
+from lib.requester.ProductsRequester import ProductsRequester
+from lib.requester.ResultsRequester import ResultsRequester
+from lib.requester.ServicesRequester import ServicesRequester
+from lib.requester.VulnsRequester import VulnsRequester
+from lib.screenshoter.ScreenshotsProcessor import ScreenshotsProcessor
+from lib.utils.FileUtils import FileUtils
+from lib.utils.ImageUtils import ImageUtils
+from lib.utils.StringUtils import StringUtils
+
+
+warnings.filterwarnings("ignore",category=FutureWarning)
+
+class Reporter:
+
+ def __init__(self, mission, sqlsession, settings, output_path, do_screens=True):
+ """
+ :param str mission: Mission for which the HTML report will be generated
+ :param Session sqlsession: SQLAlchemy session
+ :param Settings settings: Settings from config files
+ :param str output_path: Output path where directory storing HTML files must
+ be written
+ :param bool do_screens: Boolean indicating if web page screenshots must be
+ taken or not
+ """
+ self.mission = mission
+ self.sqlsession = sqlsession
+ self.settings = settings
+ self.output_path = output_path
+ self.do_screens = do_screens
+
+
+ def run(self):
+
+ # Create report directory
+ dirname = '{mission}-{datetime}'.format(
+ mission=StringUtils.clean(self.mission.replace(' ','_'),
+ allowed_specials=('_', '-')),
+ datetime=datetime.datetime.now().strftime('%Y%m%d%H%M%S'))
+ self.output_path = self.output_path + '/' + dirname
+
+ if not FileUtils.create_directory(self.output_path):
+ logger.error('Unable to create report directory: "{path}"'.format(
+ path=self.output_path))
+ return False
+
+ # Retrieve all services in selected mission
+ req = ServicesRequester(self.sqlsession)
+ req.select_mission(self.mission)
+ services = req.get_results()
+
+ # Generate screenshots
+ processor = ScreenshotsProcessor(self.mission, self.sqlsession)
+ processor.run()
+
+ screens_dir = self.output_path + '/screenshots'
+ if not FileUtils.create_directory(screens_dir):
+ logger.warning('Unable to create screenshots directory: "{path}"'.format(
+ path=screens_dir))
+ else:
+ for service in services:
+ if service.name == 'http' and service.screenshot is not None \
+ and service.screenshot.status == ScreenStatus.OK:
+
+ img_name = 'scren-{ip}-{port}-{id}'.format(
+ ip=str(service.host.ip),
+ port=service.port,
+ id=service.id)
+ path = screens_dir + '/' + img_name
+
+ ImageUtils.save_image(
+ service.screenshot.image, path + '.png')
+ ImageUtils.save_image(
+ service.screenshot.thumbnail, path + '.thumb.png')
+
+ # Create index.html
+ html = self.__generate_index()
+ if FileUtils.write(self.output_path + '/index.html', html):
+ logger.info('index.html file generated')
+ else:
+ logger.error('An error occured while generating index.html')
+ return False
+
+ # Create results-.html (1 for each service)
+ for service in services:
+ # Useless to create page when no check has been run for the service
+ if len(service.results) == 0:
+ continue
+
+ html = self.__generate_results_page(service)
+ # Create a unique name for the service HTML file
+ filename = 'results-{ip}-{port}-{service}-{id}.html'.format(
+ ip=str(service.host.ip),
+ port=service.port,
+ service=service.name,
+ id=service.id)
+ if FileUtils.write(self.output_path + '/' + filename, html):
+ logger.info('{filename} file generated'.format(
+ filename=filename))
+ else:
+ logger.error('An error occured while generating {filename}'.format(
+ filename=filename))
+ return False
+
+ logger.success('HTML Report written with success in: {path}'.format(
+ path=self.output_path))
+ logger.info('Important: If running from Docker container, make sure to run ' \
+ '"xhost +" on the host before')
+ if Output.prompt_confirm('Would you like to open the report now ?',
+ default=True):
+ webbrowser.open(self.output_path + '/index.html')
+
+ return True
+
+
+ #------------------------------------------------------------------------------------
+ # Index.html generation
+
+ def __generate_index(self):
+ """
+ Generate HTML index code from template "index.tpl.html"
+ """
+ tpl = FileUtils.read(REPORT_TPL_DIR + '/index.tpl.html')
+
+ tpl = tpl.replace('{{MISSION_NAME}}', self.mission)
+ tpl = tpl.replace('{{TABLE_SERVICES_CONTENT}}', self.__generate_table_services())
+ tpl = tpl.replace('{{TABLE_HOSTS_CONTENT}}', self.__generate_table_hosts())
+ tpl = tpl.replace('{{TABLE_WEB_CONTENT}}', self.__generate_table_web())
+ tpl = tpl.replace('{{TABLE_OPTIONS_CONTENT}}', self.__generate_table_options())
+ tpl = tpl.replace('{{TABLE_PRODUCTS_CONTENT}}', self.__generate_table_products())
+ tpl = tpl.replace('{{TABLE_CREDS_CONTENT}}', self.__generate_table_credentials())
+ tpl = tpl.replace('{{TABLE_VULNS_CONTENT}}', self.__generate_table_vulns())
+
+ return tpl
+
+
+ def __generate_table_services(self):
+ """
+ Generate the table with all services registered in the mission
+ """
+ req = ServicesRequester(self.sqlsession)
+ req.select_mission(self.mission)
+ services = req.get_results()
+
+ if len(services) == 0:
+ html = """
+
+ No record found |
+
+ """
+ else:
+ html = ''
+ for service in services:
+
+ hostname = service.host.hostname \
+ if service.host.ip != service.host.hostname else ''
+
+ # Number of checks
+ if len(service.results) > 0:
+ nb_checks = len(service.results)
+ else:
+ nb_checks = ''
+
+ # Number of creds
+ nb_userpass = service.get_nb_credentials(single_username=False)
+ nb_usernames = service.get_nb_credentials(single_username=True)
+ nb_creds = '{}{}{}'.format(
+ '{}'.format(str(nb_userpass)) \
+ if nb_userpass > 0 else '',
+ '/' if nb_userpass > 0 and nb_usernames > 0 else '',
+ '{}'.format(
+ str(nb_usernames)) if nb_usernames > 0 else '')
+ #if nb_creds == '':
+ # nb_creds = ''
+
+ # Number of vulns
+ if len(service.vulns) > 0:
+ nb_vulns = '{}'.format(
+ len(service.vulns))
+ else:
+ #nb_vulns = ''
+ nb_vulns = ''
+
+ # Encrypted ? (SSL/TLS)
+ enc = '' \
+ if service.is_encrypted() else ''
+
+ # Service name
+ service_name = IconsMapping.get_icon_html('service', service.name)
+ service_name += str(service.name)
+
+ # Technologies
+ technos = ''
+ # For HTTP, respect a given order for technos for better readability
+ if service.name == 'http':
+ product_types = (
+ 'web-server',
+ 'web-appserver',
+ # 'web-application-firewall', Displayed only in "web" tab
+ # for better readability
+ 'web-cms',
+ 'web-language',
+ 'web-framework',
+ 'web-jslib'
+ )
+ for t in product_types:
+ product = service.get_product(t)
+ if product:
+ technos += '' \
+ '{name}{version}'.format(
+ type=t,
+ name=product.name,
+ version=' '+str(product.version) \
+ if product.version else '')
+ else:
+ for p in service.products:
+ technos += '' \
+ '{name}{version}'.format(
+ type=p.type,
+ name=p.name,
+ version=' '+str(p.version) if p.version else '')
+
+ # Col "Comment/Title" (title is for HTML title for HTTP)
+ if service.html_title:
+ comment = service.html_title
+ else:
+ comment = service.comment
+
+ # Results HTML page name
+ results = 'results-{ip}-{port}-{service}-{id}.html'.format(
+ ip=str(service.host.ip),
+ port=service.port,
+ service=service.name,
+ id=service.id)
+
+ html += """
+
+ {ip} |
+ {hostname}
+ | {port} /{proto} |
+ {service} |
+ {enc} |
+ {banner} |
+ {technos} |
+ {url} |
+ {comment} |
+ {nb_checks} |
+ {nb_creds} |
+ {nb_vulns} |
+
+ """.format(
+ clickable=' class="clickable-row" data-href="{results}"'.format(
+ results=results) if len(service.results) > 0 else '',
+ ip=service.host.ip,
+ hostname=hostname,
+ port=service.port,
+ proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
+ service.protocol),
+ service=service_name,
+ enc=enc,
+ banner=service.banner,
+ technos=technos,
+ url='{}'.format(
+ service.url, service.url, StringUtils.shorten(service.url, 40)) \
+ if service.url else '',
+ comment=StringUtils.shorten(comment, 40),
+ nb_checks=nb_checks,
+ nb_creds=nb_creds,
+ nb_vulns=nb_vulns)
+
+ return html
+
+
+ def __generate_table_hosts(self):
+ """
+ Generate the table with all hosts registered in the mission
+ """
+ req = HostsRequester(self.sqlsession)
+ req.select_mission(self.mission)
+ hosts = req.get_results()
+
+ if len(hosts) == 0:
+ html = """
+
+ No record found |
+
+ """
+ else:
+ html = ''
+ for host in hosts:
+
+ # OS
+ os = IconsMapping.get_icon_html('os_family', host.os_family)
+ os += str(host.os)
+
+ # Device type
+ device_type = IconsMapping.get_icon_html('device_type', host.type)
+ device_type += str(host.type)
+
+ # Number of creds
+ nb_userpass = host.get_nb_credentials(single_username=False)
+ nb_usernames = host.get_nb_credentials(single_username=True)
+ nb_creds = '{}{}{}'.format(
+ '{}'.format(str(nb_userpass)) \
+ if nb_userpass > 0 else '',
+ '/' if nb_userpass > 0 and nb_usernames > 0 else '',
+ '{}'.format(
+ str(nb_usernames)) if nb_usernames > 0 else '')
+
+ # Number of vulns
+ nb_vulns = host.get_nb_vulns()
+ if nb_vulns > 0:
+ nb_vulns = '{}'.format(nb_vulns)
+ else:
+ nb_vulns = ''
+
+ html += """
+
+ {ip} |
+ {hostname} |
+ {os} |
+ {type} |
+ {vendor} |
+ {comment} |
+ {nb_tcp} |
+ {nb_udp} |
+ {nb_creds} |
+ {nb_vulns} |
+
+ """.format(
+ ip=host.ip,
+ hostname=host.hostname if host.hostname != str(host.ip) else '',
+ os=os,
+ type=device_type,
+ vendor=host.vendor,
+ comment=host.comment,
+ nb_tcp=host.get_nb_services(Protocol.TCP) or '',
+ nb_udp=host.get_nb_services(Protocol.UDP) or '',
+ nb_creds=nb_creds,
+ nb_vulns=nb_vulns)
+
+ return html
+
+
+ def __generate_table_web(self):
+ """
+ Generate the table with HTTP services registered in the mission
+ """
+ req = ServicesRequester(self.sqlsession)
+ req.select_mission(self.mission)
+ filter_ = Filter(FilterOperator.AND)
+ filter_.add_condition(Condition('http', FilterData.SERVICE_EXACT))
+ req.add_filter(filter_)
+ services = req.get_results()
+
+ if len(services) == 0:
+ html = """
+
+ No record found |
+
+ """
+ else:
+ html = ''
+
+ # Unavailable thumbnail
+ with open(REPORT_TPL_DIR + '/../img/unavailable.png', 'rb') as f:
+ unavailable_b64 = base64.b64encode(f.read()).decode('ascii')
+
+ for service in services:
+
+ # Results HTML page name
+ results = 'results-{ip}-{port}-{service}-{id}.html'.format(
+ ip=str(service.host.ip),
+ port=service.port,
+ service=service.name,
+ id=service.id)
+
+ # Encrypted ? (SSL/TLS)
+ enc = '' \
+ if service.is_encrypted() else ''
+
+ # Web technos (in a specific order)
+
+ # try:
+ # technos = ast.literal_eval(service.web_technos)
+ # except Exception as e:
+ # logger.debug('Error when retrieving "web_technos" field ' \
+ # 'from db: {exc} for {service}'.format(
+ # exc=e, service=service))
+ # technos = list()
+
+ # tmp = list()
+ # for t in technos:
+ # tmp.append('{}{}{}'.format(
+ # t['name'],
+ # ' ' if t['version'] else '',
+ # t['version'] if t['version'] else ''))
+ # webtechnos = ' | '.join(tmp)
+
+ webtechnos = ''
+ product_types = (
+ 'web-server',
+ 'web-appserver',
+ 'web-cms',
+ 'web-language',
+ 'web-framework',
+ 'web-jslib'
+ )
+ for t in product_types:
+ product = service.get_product(t)
+ if product:
+ webtechnos += '' \
+ '{name}{version}'.format(
+ type=t,
+ name=product.name,
+ version=' '+str(product.version) \
+ if product.version else '')
+
+ # Web Application Firewall
+ product = service.get_product('web-application-firewall')
+ waf = ''
+ if product:
+ waf = '{name}{version}'.format(
+ name=product.name,
+ version=' '+str(product.version) \
+ if product.version else '')
+
+ # Screenshot
+ img_name = 'scren-{ip}-{port}-{id}'.format(
+ ip=str(service.host.ip),
+ port=service.port,
+ id=service.id)
+ path = self.output_path + '/screenshots'
+
+ if service.screenshot is not None \
+ and service.screenshot.status == ScreenStatus.OK \
+ and FileUtils.exists(path + '/' + img_name + '.png') \
+ and FileUtils.exists(path + '/' + img_name + '.thumb.png'):
+
+ screenshot = """
+
+
+
+ """.format(
+ url=service.url,
+ screenlarge='screenshots/' + img_name + '.png',
+ title=service.html_title,
+ screenthumb='screenshots/' + img_name + '.thumb.png')
+
+ else:
+ screenshot = """
+
+ """.format(unavailable=unavailable_b64)
+
+ # HTML for table row
+ html += """
+
+ {url} |
+ {enc} |
+ {title} |
+ {webtechnos} |
+ {waf} |
+ {screenshot} |
+ {checks} |
+
+ """.format(
+ clickable=' class="clickable-row" data-href="{results}"'.format(
+ results=results) if len(service.results) > 0 else '',
+ url='{}'.format(
+ service.url, service.url, StringUtils.shorten(service.url, 50)) \
+ if service.url else '',
+ enc=enc,
+ title=StringUtils.shorten(service.html_title, 40),
+ webtechnos=webtechnos,
+ waf=waf,
+ screenshot=screenshot,
+ checks=len(service.results))
+
+ return html
+
+
+ def __generate_table_options(self):
+ """
+ Generate the table with all context-specific options registered in the mission
+ """
+ req = OptionsRequester(self.sqlsession)
+ req.select_mission(self.mission)
+ options = req.get_results()
+
+ if len(options) == 0:
+ html = """
+
+ No record found |
+
+ """
+ else:
+ html = ''
+ for option in options:
+
+ # Service name
+ service_name = IconsMapping.get_icon_html('service', option.service.name)
+ service_name += str(option.service.name)
+
+ html += """
+
+ {ip} |
+ {hostname} |
+ {service} |
+ {port} /{proto} |
+ {optionname} |
+ {optionvalue} |
+
+ """.format(
+ ip=option.service.host.ip,
+ hostname=option.service.host.hostname \
+ if option.service.host.hostname != str(option.service.host.ip) \
+ else '',
+ service=service_name,
+ port=option.service.port,
+ proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
+ option.service.protocol),
+ optionname=option.name,
+ optionvalue=option.value)
+
+ return html
+
+
+ def __generate_table_products(self):
+ """
+ Generate the table with all products registered in the mission
+ """
+ req = ProductsRequester(self.sqlsession)
+ req.select_mission(self.mission)
+ products = req.get_results()
+
+ if len(products) == 0:
+ html = """
+
+ No record found |
+
+ """
+ else:
+ html = ''
+ for product in products:
+
+ # Service name
+ service_name = IconsMapping.get_icon_html('service', product.service.name)
+ service_name += str(product.service.name)
+
+ html += """
+
+ {ip} |
+ {hostname} |
+ {service} |
+ {port} /{proto} |
+ {producttype} |
+ {productname} |
+ {productversion} |
+
+ """.format(
+ ip=product.service.host.ip,
+ hostname=product.service.host.hostname \
+ if product.service.host.hostname != str(product.service.host.ip)\
+ else '',
+ service=service_name,
+ port=product.service.port,
+ proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
+ product.service.protocol),
+ producttype=product.type,
+ productname=product.name,
+ productversion=product.version)
+
+ return html
+
+
+ def __generate_table_credentials(self):
+ """
+ Generate the table with all credentials registered in the mission
+ """
+
+ req = CredentialsRequester(self.sqlsession)
+ req.select_mission(self.mission)
+ credentials = req.get_results()
+
+ if len(credentials) == 0:
+ html = """
+
+ No record found |
+
+ """
+ else:
+ html = ''
+ for cred in credentials:
+
+ # Service name
+ service_name = IconsMapping.get_icon_html('service', cred.service.name)
+ service_name += str(cred.service.name)
+
+ # Add color to username/password
+ username = '<empty>' if cred.username == '' else cred.username
+ username = '{username}'.format(
+ color='green' if cred.password is not None else 'yellow',
+ username=username)
+
+ password = {'': '<empty>', None: '<???>'}.get(
+ cred.password, cred.password)
+ password = '{password}'.format(
+ color='green' if cred.password is not None else 'yellow',
+ password=password)
+
+ html += """
+
+ {ip} |
+ {hostname} |
+ {service} |
+ {port} /{proto} |
+ {type} |
+ {username} |
+ {password} |
+ {url} |
+ {comment} |
+
+ """.format(
+ ip=cred.service.host.ip,
+ hostname=cred.service.host.hostname \
+ if cred.service.host.hostname != str(cred.service.host.ip)\
+ else '',
+ service=service_name,
+ port=cred.service.port,
+ proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
+ cred.service.protocol),
+ type=cred.type or '',
+ username=username,
+ password=password,
+ url='{}'.format(
+ cred.service.url, cred.service.url,
+ StringUtils.shorten(cred.service.url, 50)) \
+ if cred.service.url else '',
+ comment=cred.comment)
+
+ return html
+
+
+ def __generate_table_vulns(self):
+ """
+ Generate the table with all vulnerabilities registered in the mission
+ """
+
+ req = VulnsRequester(self.sqlsession)
+ req.select_mission(self.mission)
+ vulnerabilities = req.get_results()
+
+ if len(vulnerabilities) == 0:
+ html = """
+
+ No record found |
+
+ """
+ else:
+ html = ''
+ for vuln in vulnerabilities:
+
+ # Service name
+ service_name = IconsMapping.get_icon_html('service', vuln.service.name)
+ service_name += str(vuln.service.name)
+
+ html += """
+
+ {ip} |
+ {service} |
+ {port} /{proto} |
+ {vulnerability} |
+
+ """.format(
+ ip=vuln.service.host.ip,
+ service=service_name,
+ port=vuln.service.port,
+ proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
+ vuln.service.protocol),
+ vulnerability=vuln.name)
+
+ return html
+
+
+ #------------------------------------------------------------------------------------
+ # Results-.html files generation
+
+ def __generate_results_page(self, service):
+ """
+ Generate HTML code that contains command outputs of all the checks that have
+ been run for the specified service.
+
+ :param Service service: Service Model
+ """
+ tpl = FileUtils.read(REPORT_TPL_DIR + '/results.tpl.html')
+
+ # service_string = 'host {ip} | ' \
+ # 'port {port}/{proto} | ' \
+ # 'service {service}'.format(
+ # ip=str(service.host.ip),
+ # port=service.port,
+ # proto={Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
+ # service.protocol),
+ # service=service.name)
+
+ tpl = tpl.replace('{{MISSION_NAME}}', self.mission)
+ tpl = tpl.replace('{{SERVICE_ICON}}',
+ IconsMapping.get_icon_html('service', service.name))
+ tpl = tpl.replace('{{SERVICE_IP}}', str(service.host.ip))
+ tpl = tpl.replace('{{SERVICE_PORT}}', str(service.port))
+ tpl = tpl.replace('{{SERVICE_PROTO}}',
+ {Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(service.protocol))
+ tpl = tpl.replace('{{SERVICE_NAME}}', service.name)
+ tpl = tpl.replace('{{SIDEBAR_CHECKS}}', self.__generate_sidebar_checks(service))
+ tpl = tpl.replace('{{RESULTS}}', self.__generate_command_outputs(service))
+
+ return tpl
+
+
+ def __generate_sidebar_checks(self, service):
+ """
+ Generate the sidebar with the list of checks that have been run for the
+ specified service.
+
+ :param Service service: Service Model
+ """
+ req = ResultsRequester(self.sqlsession)
+ req.select_mission(self.mission)
+
+ # Filter on service id
+ filter_ = Filter(FilterOperator.AND)
+ filter_.add_condition(Condition(service.id, FilterData.SERVICE_ID))
+ req.add_filter(filter_)
+ results = req.get_results()
+
+ html = ''
+ i = 0
+ for r in results:
+
+ # Icon category
+ icon = IconsMapping.get_icon_html('category', r.category)
+
+ html += """
+
+ {icon}{check}
+
+ """.format(
+ class_=' class="active"' if i==0 else '',
+ id=r.check,
+ icon=icon,
+ check=StringUtils.shorten(r.check, 28))
+ i += 1
+
+ return html
+
+
+ def __generate_command_outputs(self, service):
+ """
+ Generate HTML code with all command outputs for the specified service.
+
+ :param Service service: Service Model
+ """
+ req = ResultsRequester(self.sqlsession)
+ req.select_mission(self.mission)
+
+ # Filter on service id
+ filter_ = Filter(FilterOperator.AND)
+ filter_.add_condition(Condition(service.id, FilterData.SERVICE_ID))
+ req.add_filter(filter_)
+ results = req.get_results()
+
+ html = ''
+ i = 0
+ for r in results:
+
+ # Icon category
+ icon = IconsMapping.get_icon_html('category', r.category)
+
+ # Description/Tool of check
+ if service.name in self.settings.services:
+ check = self.settings.services[service.name]['checks'].get_check(r.check)
+ if check is not None:
+ description = check.description
+ tool = check.tool.name
+ else:
+ description = tool = ''
+
+
+ html += """
+
+
+
+
+
{icon}{category} > {check}
+
+
+ {description}
+ (using tool: {tool}).
+
+ """.format(
+ active=' active' if i==0 else '',
+ id=r.check,
+ icon=icon,
+ category=r.category,
+ check=r.check,
+ description=description,
+ tool=tool)
+
+ for o in r.command_outputs:
+ # Convert command output (with ANSI codes) to HTML
+ conv = ansi2html.Ansi2HTMLConverter(
+ inline=True, scheme='solarized', linkify=True)
+ output = conv.convert(o.output)
+
+ # Warning: ansi2html generates HTML document with ,