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 ,