Compare commits

...

804 Commits

Author SHA1 Message Date
Aarush 65bf88e68f
Fix #1147: Add SMB signature to port.yaml (#1162)
* Add regex for SMB protocol in port.yaml to fix the bug #1147

Signed-off-by: Aarush289 <cs24b064@smail.iitm.ac.in>

* smb_fix done

* Enable SMB regex match in port.yaml to fix the bug #1147

Signed-off-by: Aarush289 <cs24b064@smail.iitm.ac.in>

---------

Signed-off-by: Aarush289 <cs24b064@smail.iitm.ac.in>
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-11-18 15:50:22 +00:00
Prabhat Kumar 2d3f39c7a3
Refactor: Correct 'vuln' tag for 5 SSL modules (#1164) 2025-10-30 20:17:00 +00:00
dependabot[bot] 677f13ec2d
Bump actions/upload-artifact from 4 to 5 (#1157)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
2025-10-25 00:36:32 +00:00
dependabot[bot] f6f8c60f11
Bump actions/download-artifact from 5 to 6 (#1156)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-24 23:56:28 +00:00
James 8c538fa065
optimized the sort_loops in module.py and also improved readability (#1150)
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-10-12 21:59:53 +00:00
dependabot[bot] e2b4d7c2d8
Bump github/codeql-action from 3 to 4 (#1149)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-11 20:49:58 +00:00
Sam Stepanyan ad76ce537a
Update README.md (#1141)
* Update README.md

Adding Scarf to Readme

* Update README.md

alt added

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

---------

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-25 18:30:02 +00:00
einsibjarni 0fa6c156e3
Allow running on FreeBSD 13.*, 14.* and 15.* (#1136)
* Allow running on FreeBSD 13.*, 14.* and 15.*

* Update code

---------

Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
2025-09-14 17:31:15 +00:00
Sam Stepanyan a0831bc70a
Added AGENTS.md (#1128)
* add AGENTS.md file

* add AGENTS.md file - link

* moved first two sentences into a comment
2025-09-07 19:09:29 +00:00
Sam Stepanyan bf43de5f71
docs add Codebase Overview (#1129) 2025-09-07 18:29:02 +00:00
Achintya Jai e934f748ee
adding new output types (#1085)
* sarif fully done, dd.json little left

* This is good to go now

* pre-commit fixes

* updated

* removing redundancy and less i/o operations

* ruff fixes

* fixed tests for Path.open

* rabbit suggestions

* added relevant documentation

* slight change in doc

* removing empty files that were added by mistake

* updated datatime format according to coderabbit's suggestions
2025-09-07 18:22:29 +00:00
dependabot[bot] 2fea1e44f0
Bump actions/setup-python from 5 to 6 (#1133)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-05 12:52:25 +00:00
Achintya Jai 1d37e0e3a2
Removing redundancy and cleaning profiles (#1041)
* removed the vulnerability profile as it a subset of vuln

* removed brute_force profile as it is exactly same as brute

* removed cve_2021_38702 as a profile, its already there in cve, cve2021 and more relevant ones

* removed the puneethreddyrc profile

* removed information_gathering profile, added graphql.yaml to info

* removed the wp profile, it was a subset of wordpress

* removed the infortmation profile

* made relevant changes to the doc

* coderabbit suggestions
2025-09-04 18:39:00 +00:00
Achintya Jai cd0d168ab4
pyproject updates to fix warnings issued by pytest (#1130)
* updated pyproject to fix warnings issued by pytest

* Update pyproject.toml

---------

Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
2025-09-02 22:34:18 +00:00
dependabot[bot] 5d905edce4
Bump ruff from 0.7.3 to 0.12.11 (#1131)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.3 to 0.12.11.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.7.3...0.12.11)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.12.11
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-02 22:11:43 +00:00
Sam Stepanyan 1ff4258318
New module: adobe_aem_lastpatcheddate_scan (#1125)
* New module: adobe_aem_lastpatcheddate_scan

* docs update

* Update nettacker/modules/scan/adobe_aem_lastpatcheddate.yaml

coderabbit suggested improvements

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

* Update nettacker/modules/scan/adobe_aem_lastpatcheddate.yaml

coderabbit suggestion

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

---------

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-30 03:29:49 +00:00
Sam Stepanyan 6eb1f5731d
New module to detect CrushFTP CVE-2025-31161 (#1126)
* New module: crushftp_cve_2025_31161_vuln

* Update nettacker/modules/vuln/crushftp_cve_2025_31161.yaml

coderabbit formatting fix

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

* clean-up coderabbit issues

---------

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-30 03:25:18 +00:00
dependabot[bot] 281a072675
Bump flask from 3.0.3 to 3.1.2 (#1127)
Bumps [flask](https://github.com/pallets/flask) from 3.0.3 to 3.1.2.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/3.0.3...3.1.2)

---
updated-dependencies:
- dependency-name: flask
  dependency-version: 3.1.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-29 23:10:18 +00:00
Sam Stepanyan b465808c59
Readme update with updated text, docker commands +docker-compose update (#1121)
* Update README.md

Readme update with the updated tool description text and revised  Docker run commands in Quick Start

* Update docker-compose.yml

fix he command as the new runtime Docker no longer has poetry and runs Nettacker directly
2025-08-13 00:06:20 +00:00
Sam Stepanyan 518321718c
New module: crushftp_lastpatcheddate_scan (#1124)
* crushftp_lastpatcheddate_scan module

* docs update

* Fix typos found by code-rabbit

Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

---------

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-13 00:02:26 +00:00
dependabot[bot] 2cb512bbc0
Bump actions/checkout from 4 to 5 (#1123)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 18:03:16 +00:00
Achintya Jai a9f48be405
removing accidental commit (#1122) 2025-08-12 00:13:57 +00:00
Sam Stepanyan 5fedd73868
Update pyproject.toml URLs (#1119)
* Update pyproject.toml -homepage

added homepage and project email address to pyproject.toml

* Update pyproject.toml

ruff
2025-08-11 20:06:46 +00:00
Achintya Jai a373e23c28
changed nettacker's data directory naming (#1100)
* changed nettacker's data directory naming

* migration from .data to .nettacker

* ruff fixes

* documentation update
2025-08-11 19:47:13 +00:00
Arkadii Yakovets 0f30544584
Add coderabbit config (#1120) 2025-08-09 19:59:21 +00:00
Sam Stepanyan c42460ce2f
Dockerfile change to multi-stage with 'nettacker' as entrypoint + related CI/CD changes (#1115)
* Update Dockerfile

multi-stage Dockerfile

* Update ci_cd.yml

modifications to support Dockerfile entrypoint changes

* Update Dockerfile

added --no-deps --no-cache-dir

* Update Dockerfile

added OCI Label and remove the whl file after installation following the CodeRabbit review

* Update Dockerfile

moved OCI label as copy-pasted in the wrong place

* Update Dockerfile

as per suggestion

Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

---------

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
2025-08-09 15:30:45 +00:00
Davda James c77246f700
Fixed the issue of select all profiles button (#1117)
* earlier selecting the select all profiles selects the all scan methods instead of profiles, fixed that now select all profiles works perfectly

* was taking all_profiles also its name, fixed that by adding condition
2025-08-09 15:19:31 +00:00
Achintya Jai 7c36e44a67
unicode encoding of special characters to avoid breaking WAF scans graph (#1096)
* unicode encoding of special characters to avoid breaking the HTML graph

* rerun checks

* ruff

---------

Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-08-08 21:19:03 +00:00
Achintya Jai cab9b2c2fe
[Feature-Web] adding skipping service discovery, exclude ports and custom HTTP headers to the web (#1113)
* adding new features to the web UI

* minor bug fix

* ruff fixes

* removing debugging statement

* code-rabbit suggested changes

---------

Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-08-07 16:31:10 +00:00
dependabot[bot] 8695749cc5
Bump actions/download-artifact from 4 to 5 (#1114)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-06 16:37:43 +00:00
Sam Stepanyan 070902df5c
Update Dockerfile - bump python to 3.11.13 (#1110)
bump python to 3.11.13
2025-07-31 22:12:05 +00:00
Sam Stepanyan 630de628b9
New module to detect PaloAlto GlobalProtect XSS CVE-2025-0133 (#1109)
* Create paloalto_globalprotect_cve_2025_0133.yaml

new module for CVE-2025-0133

* Updated docs/Modules.md

updated docs

* Update nettacker/modules/vuln/paloalto_globalprotect_cve_2025_0133.yaml

CodeRabbit YAML formatting suggestion - we have this issue pretty much with all YAML files, so a separate tidy-up PR will be needed in the future

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

---------

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-07-30 21:57:08 +00:00
Achintya Jai e04fd1c17e
updated the declarative base import (#1108) 2025-07-28 14:17:58 +00:00
Achintya Jai 9a0006ea42
Feature: Exclude certain ports from being scanned (#1099)
* feature: exclude certain ports from being scanned

* ruff fixes

* handling exception for vulnerablility modules

* not relying on try and except

* updated documentation, changed flag

* test case for module file

* update test

* mocking the database calls, that's probably the issue

* removed breaking test for now

* coderabbit suggested change, minor code refactoring

* ruff fixes

---------

Signed-off-by: Achintya Jai <153343775+pUrGe12@users.noreply.github.com>
2025-07-27 08:11:53 +00:00
Achintya Jai e450c819d8
[feature] add custom headers for http requests via CLI and remove sensitive headers before adding it to the database (#1107)
* [feature] add custom headers for http requests via CLI. Removes sensitive info before logging in the database

* better help message

* input validation - coderabbit changes

* ruff fixes

* allow for header chaining with multiple -H flags and for complex headers involving comma separated values

* test case for http.py that include using headers. Added pytest-asyncio for the same

* ruff fixes

* formatting changes suggested by coderabbit

* docs update

* correct usage and en.yaml file
2025-07-26 20:30:05 +00:00
Son Sulung Suryahatta Asnan a08c328e83
chore: add indonesian translation (#1101) 2025-07-26 19:30:28 +00:00
Achintya Jai 6e7a6519cf
changed rege (#1098) 2025-07-12 10:11:13 +00:00
Achintya Jai 7cbf897e30
handle OSError if port not present in /etc/services (#1093)
* handle unknown ports in /etc/services

* ruff fix

* Update code

---------

Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
2025-07-09 14:04:30 +00:00
Achintya Jai 66c0e919b2
adding tests for graph.py (#1094) 2025-07-08 23:28:54 +00:00
Achintya Jai cd34fba676
fixing the global flags issue in joomla_template_scan and drupal_theme_scan (#1091)
* fixing the global flags issue in joomla template and drupal theme scans, and adding a regex validation testcase

* ruff fixes
2025-06-25 14:06:50 +00:00
dependabot[bot] bb90f09378
Bump urllib3 from 2.2.2 to 2.5.0 (#1089)
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.2 to 2.5.0.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.2.2...2.5.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.5.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-19 17:22:57 +00:00
Arkadii Yakovets dadb3ea9cb
Update PR template (#1084)
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-06-18 08:31:36 +00:00
Achintya Jai e419d227c2
Add die.py tests (#1042)
* created tests for die.py

* updated

* migrate to pytest

* Update deps

* Revert poetry.lock

---------

Signed-off-by: Achintya Jai <153343775+pUrGe12@users.noreply.github.com>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
2025-06-12 00:20:17 +00:00
Achintya Jai 04c2097fbe
regex fixes for mysql and mariaDB (#1083) 2025-06-11 12:43:20 +00:00
Achintya Jai 74e494dd1a
refactor tests and migrate to pytest (#1081)
* refactor tests and migrate to pytest

* Update tests

---------

Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
2025-06-11 01:27:16 +00:00
Achintya Jai 8748df910b
Add API core tests (#1080)
* added tests for api/core

* ruff

* ruff fixes

* migrate to pytest

* Bump requests from 2.32.3 to 2.32.4 (#1082)

Bumps [requests](https://github.com/psf/requests) from 2.32.3 to 2.32.4.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.3...v2.32.4)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.32.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Update code

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
2025-06-11 00:59:40 +00:00
Achintya Jai 6244176c99
Add ip.py tests (#1075)
* tests for ip.py

* migrate to pytest

* Update asserts

* Update tests

---------

Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
2025-06-11 00:38:49 +00:00
dependabot[bot] 6275ead5ed
Bump requests from 2.32.3 to 2.32.4 (#1082)
Bumps [requests](https://github.com/psf/requests) from 2.32.3 to 2.32.4.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.3...v2.32.4)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.32.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-11 00:14:24 +00:00
Packet Phantom 958e1bc075
feature: add smb_brute command (#1070)
* Update dependencies in poetry.lock and pyproject.toml for new packages

* feat: add SMB brute force module

* feat: add unit tests for SMB brute force module

* ran make pre-commit

---------

Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-06-09 15:49:15 +00:00
Achintya Jai af7abb683c
Unittets for database files (#1077)
* unittests for database files

* ruff fixes
2025-06-08 22:59:42 +00:00
Achintya Jai 4fd743a15d
fixed the create database part of postgresql.py (#1072) 2025-05-27 22:10:28 +00:00
Achintya Jai 10c95512e6
Refactoring Ip.py to return proper boolean values (#1043)
* added bool to netaddr instances, removed redundant imports

* created test file for ip.py

* refactoring ip.py
2025-05-27 22:02:59 +00:00
Packet Phantom 75fc06bd31
Handle socket.gaierror when retrieving server certificate (#1069) 2025-05-08 21:30:48 +00:00
Packet Phantom 9bdb94039c
refactor: use class attribute for SSH and Telnet client instantiation (#1068) 2025-05-08 00:34:32 +00:00
Achintya Jai d77becc42a
fixing regex introduced in PR1062 (#1067) 2025-05-06 11:34:34 +00:00
Sam Stepanyan 5eb8f3a506
security improvements (#1066)
* security improvements

* formatting fix

* import sort

* security headers separate function
2025-05-06 01:13:21 +00:00
Manav Acharya 423f66151a
Adding config_file_scan (#1051)
* Config-scan

* Update config_wordlist.txt

Adding possible configuration file names

* Update config_wordlist.txt

Updating the wordlist to remove spaces in the urls

---------

Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-05-05 12:11:37 +00:00
Sam Stepanyan 4c88862c90
Adding ADOPTERS.md (#1065)
* addding ADOPTERS.MD

* example Adopters
2025-05-05 10:38:31 +00:00
Achintya Jai 6c0fbbfd0a
updated relevant parts of the documentation (#1064)
* updated relevant parts of the documentation

* updated request header
2025-04-28 21:11:33 +00:00
Achintya Jai 0c2d21405e
regex updates for port.yaml (#1062)
* updated regexes

* Implementing logging response_dependent conditions in socket.py (#1060)

* logging matched services along with output from tcp_connect_send_and_recieve

* fixed tests

* fixed module.py

---------

Signed-off-by: Achintya Jai <153343775+pUrGe12@users.noreply.github.com>
2025-04-28 19:40:31 +00:00
Achintya Jai 3f214b76cf
Implementing logging response_dependent conditions in socket.py (#1060)
* logging matched services along with output from tcp_connect_send_and_recieve

* fixed tests

* fixed module.py
2025-04-27 22:18:11 +00:00
Achintya Jai a72bdfc9b6
Fixing database issues (#1056)
* fixing mysql connections using pymysql

* fixing threading issues

* fixed postgres conns

* fix ruff

* reverting to original config

* sslmode as a user configurable parameter
2025-04-04 23:08:56 +00:00
Achintya Jai f62da6a605
added clean exit for missing wordlists (#1047)
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-03-18 12:42:37 +00:00
dyp4r cb1a011c13
Fix issues in telent.py located in core/lib (#1048)
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-03-18 10:28:33 +00:00
Achintya Jai 809b6e2e5c
Implemented tests and removed duplicates for wordlists (#1039)
* added tests for wordlists, removed duplicates

* removed src from conftest

---------

Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-03-18 01:26:42 +00:00
Achintya Jai f7ce6a0e2c
added amqp detection regex (#1046) 2025-03-18 00:57:35 +00:00
Sam Stepanyan 6ad4ce083c
added missing url logging (#1040)
* added missing url logging

* Update nettacker/modules/scan/pma.yaml

Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

---------

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
2025-03-18 00:47:32 +00:00
dependabot[bot] 9c4cd46a2d
Bump jinja2 from 3.1.5 to 3.1.6 (#1035)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.5 to 3.1.6.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.5...3.1.6)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-03-07 16:54:19 +00:00
Soumyaditya Batabyal 426ad9f06b
updated the whole italian translation file (#1033)
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-03-07 15:26:37 +00:00
Achintya Jai 7a8bd583d4
small patch for en (#1036) 2025-03-07 14:41:30 +00:00
Achintya Jai 2667369af0
Custom wordlist functionality addition for scan modules (#1026)
* adding default loop policy for asyncio

* added custom wordlist functionality

* lint fix

* bug fixes

* added break after first detection to exit for loop

* removed custom read from brute scans because its already implemented there

* updated according to suggested changes

* cleared old code

* fixed lint

* made requested changes

* made suggested changes

* lint fix

* changed user_wordlist to read_from_file
2025-03-07 11:40:16 +00:00
Soumyaditya Batabyal 8d48b81467
Add some JapaneseTranslation (#1034) 2025-03-05 22:58:42 +00:00
Soumyaditya Batabyal e6f526e5ac
Add some ItalianTranslation (#1030) 2025-03-05 19:20:03 +00:00
Manav Acharya 71ea8a7c5e
create 'wp_plugin_cve_2023_47668_vuln' (#1029)
* create 'wp_plugin_cve_2023_47668_vuln'

* Update wp_plugin_cve_2023_47668.yaml
2025-03-02 23:57:48 +00:00
Achintya Jai 65192c8fc6
Added base path for directory enumeration (#1019)
* added base path addition functionality

* fixed ruff

* unbound variable fix

---------

Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-02-21 21:33:02 +00:00
Sam Stepanyan f257381c2a
Update Dockerfile - bump python to 3.11.11 (#1021)
bumping python image to 3.11.11

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-02-21 20:45:08 +00:00
Achintya Jai c0962bcd9d
adding default loop policy for asyncio (#1020) 2025-02-20 21:31:26 +00:00
Sam Stepanyan 626a765708
adding SonicWALL SSLVPN CVE-2024-53704 module (#1018)
* Update paloalto_panos_cve_2025_0108.yaml added cisa_kev

Adding cisa_kev profile to the module:
The U.S. Cybersecurity and Infrastructure Security Agency (CISA) has just added this CVE-2025-0108 impacting Palo Alto Networks PAN-OS to its Known Exploited Vulnerabilities (KEV) catalog, based on evidence of active exploitation.

* adding sonicwall_sslvpn_cve_2024_53704_vuln module
2025-02-20 02:30:11 +00:00
Sam Stepanyan 2456cd1951
Update paloalto_panos_cve_2025_0108.yaml added cisa_kev (#1017)
Adding cisa_kev profile to the module:
The U.S. Cybersecurity and Infrastructure Security Agency (CISA) has just added this CVE-2025-0108 impacting Palo Alto Networks PAN-OS to its Known Exploited Vulnerabilities (KEV) catalog, based on evidence of active exploitation.
2025-02-19 16:30:59 +00:00
Achintya Jai d143f4302b
updated regex for SSH scanning to include more matches (#1012)
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-02-17 17:53:29 +00:00
Sam Stepanyan 507a098041
palo module location fix (#1014)
* move paloalto_panos_cve_2025_0108.yaml to nettacker/modules/vuln/paloalto_panos_cve_2025_0108.yaml

Fix of the incorrect location for the module

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

* Delete Modules.md in wrong location

location fix

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

* Update Modules.md with CVE-2025-0108

added CVE-2025-0108 module to the docs

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>

---------

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-02-17 17:41:20 +00:00
Sam Stepanyan 6d427e2a3c
adding paloalto_panos_cve_2025_0108_vuln module (#1013) 2025-02-17 02:13:54 +00:00
Sam Stepanyan aff7fe3dc2 Revert "adding paloalto_panos_cve_2025_0108_vuln module"
This reverts commit d76eb0b7d9.
2025-02-17 01:39:23 +00:00
Sam Stepanyan d76eb0b7d9 adding paloalto_panos_cve_2025_0108_vuln module 2025-02-17 01:24:52 +00:00
Soumyaditya Batabyal 012bf5dda2
Add some ChineseTranslation (#1002)
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-02-14 11:03:58 +00:00
Achintya Jai 34523c8e43
fixed the admin_scan output to include the hit URLs (#1008) 2025-02-11 20:00:18 +00:00
Osama Ahmed Tahir cd3d4c6e2e
The Urdu translation has been completed (#994)
Signed-off-by: Osama Ahmed Tahir <31954609+osamaahmed17@users.noreply.github.com>
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2025-02-06 13:38:02 +00:00
dependabot[bot] 40781bf55f
Bump jinja2 from 3.1.4 to 3.1.5 (#984)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.4...3.1.5)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
2025-02-03 17:13:29 +00:00
Soumyaditya Batabyal 4a7c6f3eb9
Add some KoreanTranslation (#996) 2025-02-03 15:45:21 +00:00
Nitin Awari 84d78a1429
Migrate CI/CD to ubuntu-24.04 and test docker images to latest (#993) 2025-01-22 06:31:04 +00:00
Arkadii Yakovets f0ee67f924
Pin runner image OS version (#989) 2025-01-16 23:31:34 +00:00
Arun Krishnan 1463af88bc
Added sanitization to report_path_filename and enhanced authentication cookie (#985) 2024-12-28 20:30:01 +00:00
Bhagyashree dfc637cc4b
Add Some BengaliTranslation (#983)
Co-authored-by: bhagyashree980 <mandlawatbhagyashree@gmai.com>
2024-12-26 13:11:45 +00:00
tanaydin sirin 9aaa7033a5
Correct the issue with port scanner output (#978)
The issue caused the program to erroneously run a regex pattern on HTML content instead of the request data. This was because the port number wasn't displayed in the HTML's body content. The commit rectifies this problem, ensuring that regex operates on the correct data.
2024-12-22 12:34:12 +00:00
Sam Stepanyan f65f9bc972
Update wp_plugin_small.txt (#977)
Adding gutentor to wp_plugin_small.txt to cover CVE-2024-10178

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-12-08 23:12:20 +00:00
tanaydin sirin caaa5e8784
Update wp_plugin_small.txt (#976)
Added Yoast SEO plugin path.

Signed-off-by: tanaydin sirin <huzursuz@gmail.com>
2024-12-08 22:09:21 +00:00
AntonL 246611f731
Updating translations for ru.yaml (#969)
* Updating translations for ru.yaml

* typos
2024-11-28 17:13:28 +00:00
Sam Stepanyan cec376a08b
Update Installation.md - minor formatting fixes (#970)
minor formatting fixes

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-11-28 17:06:54 +00:00
Sam Stepanyan d876e87909
Documentaion update (#966) 2024-11-27 14:22:43 +00:00
Manushya-a 32d7d98847
Update Security.md (#964)
Fixing a small typo.
2024-11-21 18:23:05 +00:00
Sam Stepanyan e806518878
Update wp_plugin_small.txt Add: really-simple-ssl (#962)
Adding  'really-simple-ssl' Wordpress plugin to the list of plugins detected by Nettacker to help identify Wordpress sites vulnerable to CVE-2024-10924
2024-11-17 00:56:32 +00:00
Sam Stepanyan ccdc3be7d7
Update wp_plugin_small.txt: chart-builder & happy-elementor-addons (#959)
Adding happy-elementor-addons and chart-builder to the wordpress plugin list due to the latest CVEs: 
CVE-2024-10538(Stored XSS)  & CVE-2024-10571 (Unauth LFI)

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-11-14 16:26:34 +00:00
Arkadii Yakovets 9f51867da3
Update PR template (#951)
* Update PR template

* Update Developers.md

---------

Co-authored-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-11-14 09:25:12 +00:00
dependabot[bot] 4b7f89dbe1
Bump zipp from 3.20.2 to 3.21.0 (#956)
Bumps [zipp](https://github.com/jaraco/zipp) from 3.20.2 to 3.21.0.
- [Release notes](https://github.com/jaraco/zipp/releases)
- [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst)
- [Commits](https://github.com/jaraco/zipp/compare/v3.20.2...v3.21.0)

---
updated-dependencies:
- dependency-name: zipp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-11 23:38:37 +00:00
dependabot[bot] dda7b32d1c
Bump ruff from 0.7.2 to 0.7.3 (#955)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.2 to 0.7.3.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.7.2...0.7.3)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-08 23:22:40 +00:00
Arkadii Yakovets 5f6bc8e0b3
Remove `numpy` dependency (#947)
* Refactor code for future `numpy` removal

* Remove `numpy` dependency

* Update dependencies
2024-11-05 18:38:42 +00:00
dependabot[bot] a5f55386b3
Bump ruff from 0.7.1 to 0.7.2 (#954)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.1 to 0.7.2.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.7.1...0.7.2)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-01 23:47:23 +00:00
dependabot[bot] 2dc69b6f3c
Bump pytest-cov from 5.0.0 to 6.0.0 (#953)
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 5.0.0 to 6.0.0.
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v5.0.0...v6.0.0)

---
updated-dependencies:
- dependency-name: pytest-cov
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-29 23:59:18 +00:00
Arkadii Yakovets 1391affeb4
Refactor code for future `numpy` removal (#946) 2024-10-27 16:40:44 +00:00
Phantomwise 3583272ecc
Update fr.yaml with scan comparision messages (#952) 2024-10-27 11:17:59 +00:00
dependabot[bot] cd8c7f41cc
Bump werkzeug from 3.0.4 to 3.0.6 (#950)
Bumps [werkzeug](https://github.com/pallets/werkzeug) from 3.0.4 to 3.0.6.
- [Release notes](https://github.com/pallets/werkzeug/releases)
- [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/werkzeug/compare/3.0.4...3.0.6)

---
updated-dependencies:
- dependency-name: werkzeug
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-26 17:58:43 +00:00
dependabot[bot] 0ba7392a9a
Bump ruff from 0.7.0 to 0.7.1 (#949)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.0 to 0.7.1.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.7.0...0.7.1)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-25 17:01:08 +00:00
dependabot[bot] 80615c984a
Bump coverage from 7.6.3 to 7.6.4 (#948)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.6.3 to 7.6.4.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.6.3...7.6.4)

---
updated-dependencies:
- dependency-name: coverage
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-21 22:35:46 +00:00
dependabot[bot] 637aa76508
Bump ruff from 0.6.9 to 0.7.0 (#945)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.9 to 0.7.0.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.6.9...0.7.0)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-18 16:36:35 +00:00
dependabot[bot] 3078b0c308
Bump sqlalchemy from 2.0.35 to 2.0.36 (#944)
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.35 to 2.0.36.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-16 15:39:04 +00:00
dependabot[bot] 4d4600620c
Bump coverage from 7.6.1 to 7.6.3 (#942)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.6.1 to 7.6.3.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.6.1...7.6.3)

---
updated-dependencies:
- dependency-name: coverage
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-15 17:39:38 +00:00
Sam Stepanyan c26625de4e
Adding litespeed-cache to wp_plugin_small.txt (#941)
Adding litespeed-cache plugin affected by CVE-2024-47374 to the list of WordPress plugins to scan for

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-10-14 01:35:10 +00:00
dependabot[bot] 942c398c1e
Bump ruff from 0.6.8 to 0.6.9 (#936)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.8 to 0.6.9.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.6.8...0.6.9)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-05 05:27:55 +00:00
Sam Stepanyan 5dd0fdfb73
Merge pull request #935 from arkid15r/update-ci-cd
Update ci cd
2024-10-03 18:22:32 +00:00
Sam Stepanyan 7afe41519d
Merge branch 'master' into update-ci-cd 2024-10-03 19:13:24 +01:00
Arkadii Yakovets bffb531731
Merge pull request #930 from OWASP/dependabot/pip/aiohttp-3.10.8
Bump aiohttp from 3.10.5 to 3.10.8
2024-10-03 15:51:57 +00:00
Arkadii Yakovets dc40d1912b
Merge pull request #931 from OWASP/dependabot/pip/multiprocess-0.70.17
Bump multiprocess from 0.70.16 to 0.70.17
2024-10-03 15:41:55 +00:00
Arkadii Yakovets d61e78a2f5
Merge pull request #934 from tadash10/patch-2
Added Spanish translations for scan comparison (issue  #905 )
2024-10-03 15:38:57 +00:00
Arkadii Yakovets 4d4751905e
Update the branch name 2024-10-02 08:49:33 -07:00
Arkadii Yakovets 6f60092f42
Update CI/CD triggers
Add main branch push
2024-10-02 08:41:49 -07:00
T1 536b5f0c1f
Update es.yaml
Added Spanish translations for scan comparison (issue  #905 )

Signed-off-by: T1 <126980610+tadash10@users.noreply.github.com>
2024-10-01 18:09:32 -03:00
dependabot[bot] a1b382cd56
Bump multiprocess from 0.70.16 to 0.70.17
Bumps [multiprocess](https://github.com/uqfoundation/multiprocess) from 0.70.16 to 0.70.17.
- [Release notes](https://github.com/uqfoundation/multiprocess/releases)
- [Commits](https://github.com/uqfoundation/multiprocess/compare/0.70.16...0.70.17)

---
updated-dependencies:
- dependency-name: multiprocess
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 22:45:59 +00:00
dependabot[bot] 8b20d5c79d
Bump aiohttp from 3.10.5 to 3.10.8
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.10.5 to 3.10.8.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.10.5...v3.10.8)

---
updated-dependencies:
- dependency-name: aiohttp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 22:45:12 +00:00
Arkadii Yakovets 2fbd9f6fa6
Merge pull request #928 from OWASP/cups_cve
New module: cups_version_scan to help with the vulnerable CUPS printe…
2024-09-29 18:52:37 +00:00
Sam Stepanyan 546042dea5 New module: cups_version_scan to help with the vulnerable CUPS printer detection 2024-09-29 19:41:48 +01:00
Arkadii Yakovets ce06bc504a
Add `merge_group` trigger (#927) 2024-09-29 11:36:10 -07:00
Sam Stepanyan b0db4adb68
Updated wp_plugin_small.txt with the-events-calendar (CVE-2024-8275) (#926)
Added  the-events-calendar to the list as it has Unauthenticated SQL Injection vulnerability (SQLi) CVE-2024-8275

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-29 11:13:49 -07:00
Sam Stepanyan ce60702ef0
Merge pull request #923 from OWASP/securestep9-docs-0.4.0-installation-patch-1
Update docs Installation.md for 0.4.0
2024-09-27 17:11:50 +01:00
Sam Stepanyan 3f1a861200
Update docs/Installation.md
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-27 15:20:58 +01:00
Sam Stepanyan 3131ab0093
Update docs/Installation.md
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-27 15:20:51 +01:00
Sam Stepanyan df1a12c9d0
Update docs Installation.md for 0.4.0
Updated docs to have the correct installation method using 'pip3 install nettacker' command

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-27 04:01:16 +01:00
Sam Stepanyan 12170a372a
Merge pull request #922 from OWASP/securestep9-ivanti_vtm_version_scan-docs-patch-1
add ivanti_vtm_version_scan to docs
2024-09-27 03:31:21 +01:00
Sam Stepanyan 20f5f3cd3a
Merge branch 'master' into securestep9-ivanti_vtm_version_scan-docs-patch-1 2024-09-27 01:24:51 +01:00
Sam Stepanyan d4d0016498
add ivanti_vtm_version_scan to docs
Updated  Modules documentation to include  the new ivanti_vtm_version_scan module

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-27 01:14:37 +01:00
Sam Stepanyan 7c2479a00e
Merge pull request #918 from OWASP/ivanti_vtm_ldate
new module: ivanti_vtm_version_scan
2024-09-27 01:13:19 +01:00
Sam Stepanyan 506b3b4371
Merge branch 'master' into ivanti_vtm_ldate 2024-09-27 00:51:36 +01:00
Sam Stepanyan 42bd36d5a1
Merge pull request #916 from OWASP/ssd
adding "-d" as a shortcut for "--skip-service-discovery" + docs
2024-09-27 00:41:54 +01:00
Arkadii Yakovets 95f6d4f59f
Merge branch 'master' into ivanti_vtm_ldate 2024-09-26 16:35:20 -07:00
dependabot[bot] 4a2aba05e0
Bump ruff from 0.6.7 to 0.6.8 (#920)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.7 to 0.6.8.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.6.7...0.6.8)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-26 16:34:46 -07:00
Arkadii Yakovets 453fefff1c
Add CODEOWNERS (#919) 2024-09-26 14:49:48 -07:00
Sam Stepanyan d01b1aa511
Merge pull request #917 from arkid15r/ark/update-ci-cd
Update CI/CD: trigger PyPI job on tag push
2024-09-26 21:17:01 +01:00
Sam Stepanyan 0a0e2d6fc1 new module: ivanti_vtm_version_scan 2024-09-26 21:05:52 +01:00
Arkadii Yakovets d79426ece7
Update CI/CD: trigger PyPI job on tag push 2024-09-26 13:00:44 -07:00
Sam Stepanyan efa2c4df94 reformat 2024-09-26 08:09:38 +01:00
Sam Stepanyan 14933497e9 adding "-d" as a shortcut for "--skip-service-discovery" with relevant Usage documentation update 2024-09-26 07:59:20 +01:00
Sam Stepanyan 04549d920e
Merge pull request #913 from OWASP/scan_id
ScanID added to CLI and HTML report for easy identification of results
2024-09-25 17:07:40 +01:00
dependabot[bot] 1eb2d5e44c
Bump ruff from 0.6.6 to 0.6.7 (#914)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.6 to 0.6.7.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.6.6...0.6.7)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 11:39:02 -07:00
dependabot[bot] 8bb3a4927f
Bump ruff from 0.6.5 to 0.6.6 (#912)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.5 to 0.6.6.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.6.5...0.6.6)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-20 18:58:57 -07:00
Sam Stepanyan 9b89749389
Update app.py
minor formatting issue 

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-21 02:35:32 +01:00
Sam Stepanyan 987d4c3ed1 ScanID added to CLI and HTML report for easy identification of results 2024-09-21 02:30:26 +01:00
Sam Stepanyan 165e734a27
Merge pull request #911 from OWASP/ivanti_csa
ivanti_csa_lastpatcheddate_scan module
2024-09-20 08:34:35 +01:00
Sam Stepanyan 5eab2709c1
Merge branch 'master' into ivanti_csa 2024-09-20 01:54:07 +01:00
Sam Stepanyan 0de0aa167b ivanti_csa_lastpatcheddate_scan module 2024-09-20 01:44:15 +01:00
Sam Stepanyan cba79bb25c
Merge pull request #910 from OWASP/securestep9-ivanti_ics_lastpatcheddate_yamlpatch-1
YAML indent fix in ivanti_ics_lastpatcheddate.yaml
2024-09-20 01:41:30 +01:00
Sam Stepanyan 8ab4e48ac0
YAML indent fix in ivanti_ics_lastpatcheddate.yaml
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-20 01:05:58 +01:00
Sam Stepanyan 7abe4c2dc6
Merge pull request #909 from OWASP/sam_dirb
dir_scan module
2024-09-20 00:20:57 +01:00
Sam Stepanyan ed9ab85d20
dir_scan module update
removed unnecessary extra trailing newlines

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-19 23:49:20 +01:00
Sam Stepanyan 6c68fb91a4
Merge branch 'master' into sam_dirb 2024-09-19 23:11:55 +01:00
Sam Stepanyan a86b9095fd dir_scan module 2024-09-19 23:08:19 +01:00
Sam Stepanyan 424b8b66d8
Merge pull request #908 from onass1/Arabic-Translation-for-ar.yaml
Adding Arabic translations for scan comparison (issue: #905)
2024-09-19 20:03:36 +01:00
Omar Nasser 9c7bfd0ef3
Updating and adding translations for ar.yaml
Adding translations for ar.yaml and modified old translations with better ones.

Signed-off-by: Omar Nasser <140649004+onass1@users.noreply.github.com>
2024-09-19 02:28:40 +03:00
Omar Nasser 7d7e4158b4
Updating translations for ar.yaml
Added translations for ar.yaml file and modified two old variables with better translations.

Signed-off-by: Omar Nasser <140649004+onass1@users.noreply.github.com>
2024-09-19 02:02:06 +03:00
Sam Stepanyan f08334c9fc
Merge pull request #906 from Captain-T2004/Compare_Scans_Hindi
Added Hindi translations for scan comparison
2024-09-18 23:25:30 +01:00
Sam Stepanyan 38c541201a
Merge pull request #907 from OWASP/securestep9-wp_plugin_scan_improvements_patch-1
Updated wp_plugin.yaml
2024-09-18 13:44:34 +01:00
Sam Stepanyan b62c037900
Update wp_plugin.yaml
yaml update

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-18 09:06:58 +01:00
Sam Stepanyan 4e6cabb331
Updated wp_plugin.yaml
Minor improvements - added plugin version to regex and fixed overlooked previously copy-pasted text from another module

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-18 08:46:23 +01:00
Captain-T2004 9859db19d4 Added Hindi translations for scan comparison 2024-09-18 11:57:33 +05:30
Sam Stepanyan e53fca5707
Merge pull request #877 from Captain-T2004/CREATE_SCAN_COMPARE
Added Scan Compare feature
2024-09-18 00:45:31 +01:00
Arkadii Yakovets 763e998437
Update code 2024-09-17 16:32:56 -07:00
Arkadii Yakovets 6ffbf882cc
Apply suggestions from code review
Signed-off-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
2024-09-17 16:28:06 -07:00
dependabot[bot] 17d53642d2
Bump sqlalchemy from 2.0.34 to 2.0.35 (#904)
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.34 to 2.0.35.
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

---
updated-dependencies:
- dependency-name: sqlalchemy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-17 10:48:14 -07:00
Captain-T2004 97c4f99bb9 Reverted back the results to results_dir directory(.data/results)
Now the comparison results are stored as report_compare_{date_time}_{scan_id}... in the default results_dir
2024-09-16 08:31:47 +05:30
Akshay Behl 13ced2dd6c
Merge branch 'master' into CREATE_SCAN_COMPARE 2024-09-14 10:08:27 +05:30
dependabot[bot] e8c6371594
Bump zipp from 3.20.1 to 3.20.2 (#900)
Bumps [zipp](https://github.com/jaraco/zipp) from 3.20.1 to 3.20.2.
- [Release notes](https://github.com/jaraco/zipp/releases)
- [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst)
- [Commits](https://github.com/jaraco/zipp/compare/v3.20.1...v3.20.2)

---
updated-dependencies:
- dependency-name: zipp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-13 18:46:36 -07:00
dependabot[bot] 6bc979470a
Bump ruff from 0.6.4 to 0.6.5 (#899)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.4 to 0.6.5.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.6.4...0.6.5)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-13 18:22:06 -07:00
Captain-T2004 84e1ed41a9 Fixing last commit 2024-09-13 21:18:08 +05:30
Captain-T2004 9ffa45978e Fix file path handeling 2024-09-13 21:17:15 +05:30
Captain-T2004 f03ea61afe Forgot to run pre-commit 2024-09-12 10:19:12 +05:30
Captain-T2004 c640dcd1cf Adding filepath sanitization 2024-09-12 10:16:52 +05:30
Captain-T2004 d94f11860a CodeQL recommended changes 2024-09-11 21:05:09 +05:30
Akshay Behl 10fd8afd68
Merge branch 'master' into CREATE_SCAN_COMPARE 2024-09-11 18:48:57 +05:30
dependabot[bot] bd6a11a636
Bump pytest from 8.3.2 to 8.3.3 (#898)
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.2 to 8.3.3.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.3.2...8.3.3)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-10 16:50:21 -07:00
Sam Stepanyan 58b18202a0
Merge pull request #897 from arkid15r/update-docker-file
Update Dockerfile
2024-09-10 03:15:54 +01:00
Arkadii Yakovets ba0a30cc7e
Update Dockerfile
- Remove redundant instructions
  - Don't copy local .data to the image
2024-09-09 19:03:04 -07:00
dependabot[bot] 0a6171bde7
Bump python from 3.11.9-slim to 3.11.10-slim (#896)
Bumps python from 3.11.9-slim to 3.11.10-slim.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 18:45:06 -07:00
Sam Stepanyan c5c541b726
Merge pull request #895 from OWASP/securestep9-dockerpulls-counter-badge-add-patch-1
Added docker-pulls counter badge to README.md
2024-09-08 23:09:56 +01:00
Sam Stepanyan d9de1e4c56
Added docker-pulls counter badge to README.md
Added docker-pulls counter badge to README.md

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-08 22:51:33 +01:00
Sam Stepanyan 51b8c9fc53
Merge pull request #894 from arkid15r/update-docker-image
Optimize docker image
2024-09-08 22:17:51 +01:00
Arkadii Yakovets 10eb61a06a
Update docker image build tests 2024-09-07 17:43:24 -07:00
Arkadii Yakovets 6a3aaed8bb
Add README.md 2024-09-07 17:31:47 -07:00
Arkadii Yakovets 5e3103437b
Optimize docker image
- streamline COPY/RUN Dockerfile commands
  - update docker-compose.yml
  - add docker image build tests
2024-09-07 12:24:23 -07:00
Sam Stepanyan 008d673133
Merge pull request #891 from arkid15r/add-nettacker-command
Implement `nettacker` command
2024-09-06 00:34:12 +01:00
Arkadii Yakovets 05b24cd1fa
Remove windows from test matrix 2024-09-05 10:05:14 -07:00
Arkadii Yakovets 9e24c47992
Add tests 2024-09-05 10:01:37 -07:00
Arkadii Yakovets a397fa9e4b
Implement `nettacker` command 2024-09-05 09:44:03 -07:00
Sam Stepanyan 5fe4b03725
Merge pull request #890 from OWASP/securestep9-subdomains-2024-update-patch-1
Updated subdomain.yaml removing defunct services
2024-09-05 01:44:38 +01:00
Sam Stepanyan c91d2db971
Updates subdomain.yaml removing defunct services
Defunct services: bufferoverflow, threatminer and threatcrowd - replaced

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-09-05 01:19:52 +01:00
Sam Stepanyan 28f1d9001d
Merge pull request #876 from Captain-T2004/SSL/TLS_MODULES
Added SSL/TLS Modules
2024-09-05 00:24:24 +01:00
Sam Stepanyan 286c6ea231
Merge branch 'master' into SSL/TLS_MODULES 2024-09-05 00:14:15 +01:00
dependabot[bot] f1ff5ed124
Bump ruff from 0.2.2 to 0.6.3 (#884)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.2.2 to 0.6.3.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.2.2...0.6.3)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
2024-09-03 09:10:59 -07:00
Akshay Behl 21af8cdd33
Merge branch 'master' into CREATE_SCAN_COMPARE 2024-09-03 21:33:58 +05:30
Akshay Behl 820b198d71
Merge branch 'master' into SSL/TLS_MODULES 2024-09-03 21:33:50 +05:30
Arkadii Yakovets 6bd1aaeef6
Update CI/CD: run workflow just once for pull_request/push events 2024-09-03 08:52:15 -07:00
dependabot[bot] 0126926472
Bump pytest from 7.4.4 to 8.3.2 (#886)
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.4 to 8.3.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.4.4...8.3.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-03 08:45:24 -07:00
dependabot[bot] 4593e7790d
Bump pytest-cov from 4.1.0 to 5.0.0 (#883)
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 4.1.0 to 5.0.0.
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v4.1.0...v5.0.0)

---
updated-dependencies:
- dependency-name: pytest-cov
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-03 08:32:22 -07:00
Arkadii Yakovets 591414810a
Update CI/CD: add pre-commit, merge workflow files 2024-09-01 17:02:07 -07:00
Akshay Behl 63e790aaef
Merge branch 'master' into CREATE_SCAN_COMPARE 2024-09-02 00:50:01 +05:30
Akshay Behl 79cb19576f
Merge branch 'master' into SSL/TLS_MODULES 2024-09-02 00:49:20 +05:30
Captain-T2004 0615a1fe2e Fixed ssl_* module responses 2024-09-02 00:25:48 +05:30
Arkadii Yakovets c054aa9d6c
Update CI/CD: set proper workflow dependencies 2024-09-01 10:33:13 -07:00
Captain-T2004 97eb4f9c4c Made suggested changes
1. changed the date format from "%Y/%m/%d" to "%Y-%m-%d" to make it ANSI and ISO 8601 compliant.

2. Changed the issuer and subject to issuer_str and subject_str which are formatted string from the x509 objects.

3. Added subject to  ssl_expired_certificate_vuln and ssl_expiring_certificate_scan modules
2024-09-01 18:03:29 +05:30
Arkadii Yakovets 45943e07a3
Merge branch 'master' into CREATE_SCAN_COMPARE 2024-08-31 19:08:08 -07:00
Arkadii Yakovets 3dd57520bb
Merge branch 'master' into SSL/TLS_MODULES 2024-08-31 19:07:31 -07:00
dependabot[bot] c3259abf9c
Bump numpy from 1.26.4 to 2.0.2 (#881)
Bumps [numpy](https://github.com/numpy/numpy) from 1.26.4 to 2.0.2.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.26.4...v2.0.2)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-31 18:36:10 -07:00
Arkadii Yakovets 0651a8596a
Bump requests from 2.31.0 to 2.32.3
Correct zipp dependency syntax
2024-08-31 18:09:48 -07:00
Arkadii Yakovets deaa85908e
Bump docker/build-push-action from 5 to 6
Based on https://github.com/OWASP/Nettacker/pull/850
2024-08-31 17:58:53 -07:00
Arkadii Yakovets 4ed68f6333
Pin zipp >= 3.19.1
Based on https://github.com/OWASP/Nettacker/pull/856
2024-08-31 17:56:58 -07:00
Arkadii Yakovets 095909c91d
Update CI/CD: streamline CodeQL workflow 2024-08-31 17:52:51 -07:00
Arkadii Yakovets c783a8b5f2
Update CI/CD: consolidate docker publishing workflows 2024-08-31 17:46:35 -07:00
Arkadii Yakovets bdf281cf46
Update CI/CD, add Nettacker PyPI publishing workflow 2024-08-31 17:34:47 -07:00
Arkadii Yakovets 781f9a8299
Skip existing files for PyPI test uploads 2024-08-31 17:04:23 -07:00
dependabot[bot] 9a51832c28
Bump actions/download-artifact from 3 to 4 (#879)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-31 16:58:39 -07:00
dependabot[bot] a98c0ccecd
Bump actions/upload-artifact from 3 to 4 (#878)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-31 16:58:14 -07:00
Arkadii Yakovets 9e2c4b8ca4
Update CI/CD, add Nettacker PyPI test publishing workflow 2024-08-31 16:47:00 -07:00
Akshay Behl 01766065b8
Merge branch 'master' into SSL/TLS_MODULES 2024-09-01 04:20:57 +05:30
Sam Stepanyan f4b0bf827a
Merge pull request #882 from securestep9/apache_ofbiz
New module: Apache OFBiz CVE-2024-38856 vulnerability
2024-08-31 00:37:28 +01:00
Sam Stepanyan b44218bf7a Apache OFBiz CVE-2024-38856 module 2024-08-30 23:19:03 +01:00
Captain-T2004 e47ef52929 Made changes following suggestion
1. Change the date format from d/m/Y to Y-m-d (e.g. 2004-08-28)

2. In the return/output of ssl_certificate_scan in SSL library please  add certificate "subject" and "issuer" so these could be logged

3. Rename ssl_version module to ssl_weak_version

4. Change ssl_expired_certificate module to return expired certs only ( do not count expiring_soon certs - it is not a vulnerability!)

5. Create a separate ssl_expiring_certificate module in modules/scan (remember  'expiring soon'  is not a vulnerability, so we need to make this a 'scan' module)

6. Rename ssl_signed_certificate module to ssl_certificate_weak_signature and remove the self-signed check from it

7. Create a separate ssl_self_signed_certificate module in modules/vuln

Next in  nettacker/core/lib/ssl.py
 in class SslLibrary(BaseLibrary): you have ssl_certificate_scan and ssl_version_and_cipher_scan methods.
 There is a common code in these two methods so these could be refactored to remove the repetition.  Please refactor/improve this.
 In ssl_version_and_cipher_scan also please add add  to the output /return certificate "subject" ,"issuer" and an expiry date.
 This way if a user scans they network using IP addresses and some servers will come up with weak SSL versions/ciphers it will be easier for user to identify the servers using the certificate subject/issuer
2024-08-31 02:42:15 +05:30
Akshay Behl 5518b140f6
Apply suggestions from code review
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Signed-off-by: Akshay Behl <126911424+Captain-T2004@users.noreply.github.com>
2024-08-31 02:35:38 +05:30
Akshay Behl 64b9457a8f
Update nettacker/core/lib/ssl.py
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Signed-off-by: Akshay Behl <126911424+Captain-T2004@users.noreply.github.com>
2024-08-27 01:15:33 +05:30
Captain-T2004 de4e02c2b1 Added Scan Compare feature 2024-08-26 04:02:07 +05:30
Captain-T2004 e8f57c1d16 Added SSL/TLS Modules 2024-08-25 19:49:53 +05:30
Sam Stepanyan 8c86f6239b
Merge pull request #875 from OWASP/securestep9-patch-docs-home-image-fix-patch-1
Update Home.md in docs - fixed broken images
2024-08-25 11:55:04 +01:00
Sam Stepanyan 7c9dc72ca1
Update Home.md in docs - fixed broken images
fixed broken images in Home page of documentation due to web folder move during refactoring

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-25 11:46:01 +01:00
Sam Stepanyan 2b30986ac9
Merge pull request #874 from OWASP/securestep9-docs-badge-patch-1
added docs badge to README.md
2024-08-25 02:39:48 +01:00
Sam Stepanyan 071bf36c20
added docs badge to README.md
added docs badge to README.md

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-25 02:30:53 +01:00
Sam Stepanyan 52fcf41df7
Merge pull request #873 from OWASP/securestep9-readthedocs-readme-patch-1
docs README.md update
2024-08-25 02:20:27 +01:00
Sam Stepanyan b89c50339a
docs README.md update
to include the ReadtheDocs site

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-25 02:11:42 +01:00
Sam Stepanyan dd16c6b51d
Merge pull request #872 from OWASP/securestep9-docs-load-patch-1
Docs initial commit
2024-08-25 02:05:25 +01:00
Sam Stepanyan 75561812b0 mkdocs 2024-08-25 01:56:35 +01:00
Sam Stepanyan 05a5de04be
Docs initial commit
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-25 01:50:48 +01:00
Sam Stepanyan cdbdd2e854
Merge pull request #870 from OWASP/securestep9-docs-folder-create-patch-1
Created docs folder
2024-08-25 01:10:16 +01:00
Sam Stepanyan c97296ebcf
Merge branch 'master' into securestep9-docs-folder-create-patch-1 2024-08-25 00:58:15 +01:00
Sam Stepanyan 81a5f973e4
Merge pull request #871 from OWASP/securestep9-readme-image-refactor-fix-disclaimer-patch-1
Update README.md - fixed broken images
2024-08-25 00:57:53 +01:00
Sam Stepanyan 38e0181adf
Merge branch 'master' into securestep9-readme-image-refactor-fix-disclaimer-patch-1 2024-08-25 00:56:43 +01:00
Sam Stepanyan 4caa47c8f9
Merge pull request #869 from OWASP/securestep9-security-md-create-patch-1
Created SECURITY.md
2024-08-25 00:46:08 +01:00
Sam Stepanyan 4c85a2a55f
Update README.md - fixed broken images
fixed broken images which got affected due to refactoring and updated the disclaimer

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-25 00:45:31 +01:00
Sam Stepanyan 6a9f24ce70
Created docs folder
placeholder for new documentation

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-25 00:26:19 +01:00
Sam Stepanyan 86a9cf564c
Create SECURITY.md
Added security policy

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-25 00:23:18 +01:00
Sam Stepanyan d39ed4a738
Merge pull request #868 from OWASP/securestep9-pypi-publish-create-workflow-patch-1
Create pypi_publish.yml
2024-08-25 00:12:02 +01:00
Sam Stepanyan 21df30d287
Create pypi_publish.yml
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-25 00:00:23 +01:00
Sam Stepanyan a992f24bd0
Merge pull request #867 from OWASP/securestep9-pypi-workflow-cutout-from-cicd-patch-1
Update ci_cd.yml remove PYPI step
2024-08-24 23:48:12 +01:00
Sam Stepanyan a2bb1ae6e3
Update ci_cd.yml remove PYPI step
will be moved to a separate workflow

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-24 23:12:03 +01:00
Sam Stepanyan ba7532606c
Merge pull request #866 from OWASP/securestep9-poetry-readme-patch-1
Updated README.md to include python poetry
2024-08-24 22:54:25 +01:00
Sam Stepanyan 1b53d99ebf
Update README.md to incude python poetry
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-08-24 22:44:23 +01:00
Sam Stepanyan 477d5203b5
Merge pull request #863 from arkid15r/code-base-refactoring
Nettacker code base major refactoring
2024-08-24 22:33:47 +01:00
Arkadii Yakovets 44bd2ab7cd
Run scan in a separate thread when started via API 2024-08-23 17:45:01 -07:00
Arkadii Yakovets 310938b6cf
Simplify module fuzzer config syntax 2024-08-21 08:39:37 -07:00
Arkadii Yakovets 6c56fee299
Update release name/version handling 2024-08-21 08:28:19 -07:00
Arkadii Yakovets 57cf98a036
Update scan/admin config syntax 2024-08-20 16:17:44 -07:00
Arkadii Yakovets 560d94aced
Improve module configuration compatibility 2024-08-20 09:12:08 -07:00
Arkadii Yakovets 335c6cd7ee
Clean up code 2024-08-19 16:52:09 -07:00
Arkadii Yakovets 030c0adf22
Whitelist fuzzers for paths/URLs 2024-08-19 16:44:10 -07:00
Arkadii Yakovets 6dfa9a231b
Update fuzzer configurations 2024-08-19 16:18:26 -07:00
Arkadii Yakovets 7cfb811c25
Update scan/drupal_modules configuration 2024-08-19 14:41:21 -07:00
Arkadii Yakovets 3458f33406
Update ftp_brute module configuration 2024-08-19 12:06:06 -07:00
Arkadii Yakovets ae660c3e6b
Update release name 2024-08-19 09:49:59 -07:00
Arkadii Yakovets c35c55022d
Update docker-compose.yml 2024-08-19 09:42:57 -07:00
Arkadii Yakovets 417821f0cd
Update CI/CD 2024-08-19 09:38:28 -07:00
Arkadii Yakovets 5c77f90000
Update Dockerfile 2024-08-19 09:34:55 -07:00
Arkadii Yakovets cc26caf170
Revert models `scan_id` -> `scan_unique_id` for compatibility 2024-08-19 09:27:34 -07:00
Arkadii Yakovets 22525603b7
Update version 2024-08-19 08:48:11 -07:00
Arkadii Yakovets 8a64187048
Change the entry point name/location
As per request by Sam Stepanyan
2024-08-11 11:31:18 -07:00
Arkadii Yakovets 365b9de0ac
Rewrite comparison statements 2024-08-11 11:10:46 -07:00
Arkadii Yakovets c10b63837a
Fix excluded modules handling 2024-08-11 11:09:29 -07:00
Arkadii Yakovets d006d3b3ef
Update dependencies 2024-08-08 11:10:20 -07:00
Arkadii Yakovets 14f6c06207
Nettacker code base major refactoring
This is a refactor of existing Nettacker code I've been working on recently. The (incomplete) list of changes:

          - add pre-commit checks
          - apply OOP approach to the application architecture
          - consolidate common modules logic into a base class
          - extract YAML parsing logic into a separate module
          - fix some typos
          - get rid of (not all) misused try/except blocks
          - migrate to poetry, remove requirements.* files
          - re-design configuration module
          - re-design logging module
          - split application logic into classes
          - use `pathlib` for path related manipulations
          - use context-based naming for variables, modules, directories, etc
          - use module level imports (vs function level)
          - use the base class for specific protocol libraries
2024-08-08 11:04:35 -07:00
Ali Razmjoo 6baee0fd5e
Merge pull request #855 from ansuhayda/patch-1
Update README.md
2024-07-08 08:59:48 +02:00
AdrianeS 72838c498e
Update README.md
Fixed two typos on line 19 in the last sentence.  It reads "It would make a competitive edge compared to other scanner making it one of the bests."  I added an "s" to "scanner" and removed the "s" from "bests" to correct the grammar.

Signed-off-by: AdrianeS <100097276+ansuhayda@users.noreply.github.com>
2024-07-07 21:01:53 -04:00
Sam Stepanyan facf823cc7
Merge pull request #840 from OWASP/securestep9-nettaker-docker-python-3119-update
Update Python Docker base image to 3.11.9-slim
2024-05-10 08:58:04 +01:00
Sam Stepanyan 4251ab4bb8
Update Dockerfile
Update Python base image to 3.11.9-slim

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-05-10 08:36:08 +01:00
Sam Stepanyan 7e960a48c3
Merge pull request #833 from OWASP/dependabot/pip/aiohttp-3.9.5
Bump aiohttp from 3.9.3 to 3.9.5
2024-05-10 08:33:33 +01:00
dependabot[bot] 1257ef9ed7
Bump aiohttp from 3.9.3 to 3.9.5
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.3 to 3.9.5.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.3...v3.9.5)

---
updated-dependencies:
- dependency-name: aiohttp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-18 22:32:33 +00:00
dependabot[bot] 91f54722bb
Bump actions/checkout from 4.1.1 to 4.1.2 (#824)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.1.1...v4.1.2)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-12 16:34:00 -07:00
Captain-T2004 81b842563b
Detecting open Dropbear server (#808)
* Detecting open Dropbear server

* Making code more readable

After testing it rigorously i have found that without the try and except the code doesn't work, so to improve the readability i have added some comments, also added is finally block to close the connection.

* Replaced try/except with if/else

As per the suggestions i have replaced try/except with if/else and i have ran multiple tests on my localhost to test and it is working.

* Made the code concise

I have made the suggested changes to the code to make it more concise and easy to read. I have taken time to test it and make sure it works( it does ).
2024-03-11 16:23:45 -07:00
dependabot[bot] ecfcf42fb2
Bump flake8 from 6.0.0 to 7.0.0 (#782)
Bumps [flake8](https://github.com/pycqa/flake8) from 6.0.0 to 7.0.0.
- [Commits](https://github.com/pycqa/flake8/compare/6.0.0...7.0.0)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-11 15:52:03 -07:00
Sam Stepanyan 617c16d4d8
Merge pull request #822 from prbhtkumr/master
Fixed Typo in Docstring
2024-03-07 10:12:14 +00:00
Sam Stepanyan f4509a03af
Merge branch 'master' into master 2024-03-07 09:39:01 +00:00
Sam Stepanyan ff0900d2c8
Merge pull request #818 from Freedisch/pagination
[Feature] Added Pagination in webUI
2024-03-06 22:55:42 +00:00
Sam Stepanyan b18497d426
Merge branch 'master' into pagination 2024-03-06 22:38:58 +00:00
Sam Stepanyan 2615723d25
Merge pull request #821 from OWASP/securestep9-patch-cve-2024-27198
Module to detect TeamCity CVE-2024-27198
2024-03-06 22:16:06 +00:00
Sam Stepanyan 2d3eb7654a
Module teamcity_cve_2024_27198.yaml
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-03-06 22:00:12 +00:00
Sam Stepanyan 2b95d60dd3 New Module: JetBrains TeamCity CVE-2024-27198 Vulnerability detection 2024-03-06 19:31:27 +00:00
Prabhat Kumar 17a9751035
Merge branch 'OWASP:master' into master 2024-03-07 00:47:36 +05:30
Prabhat Kumar 13cd610e08 Fixed Docstring Typo 2024-03-06 14:59:27 +05:30
Sam Stepanyan 273ebda720
Merge pull request #815 from OWASP/snyk-fix-c42b5d4e0b442f9a2d1a7dcf51f2625d
[Snyk] Security upgrade python from 3.11.7-slim to 3.11.8-slim
2024-03-03 22:30:35 +00:00
freedisch 0f7e2d2e3f Added pagination feature to the crawler page
Signed-off-by: freedisch <freeproduc@gmail.com>
2024-03-03 19:17:21 +02:00
snyk-bot 0a34a65512
fix: Dockerfile to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-DEBIAN12-GNUTLS28-6159410
- https://snyk.io/vuln/SNYK-DEBIAN12-GNUTLS28-6159418
- https://snyk.io/vuln/SNYK-DEBIAN12-SYSTEMD-6137714
- https://snyk.io/vuln/SNYK-DEBIAN12-SYSTEMD-6137714
- https://snyk.io/vuln/SNYK-DEBIAN12-TAR-3253526
2024-03-01 05:28:33 +00:00
Sam Stepanyan 1574b6ee97
Merge pull request #807 from ab2pentest/patch-1
Update README.md with correct docker image name
2024-02-21 21:04:56 +00:00
Sam Stepanyan 93c0dfa2a3
Merge branch 'master' into patch-1 2024-02-21 20:33:21 +00:00
Sam Stepanyan 9ffa548872
Merge pull request #811 from 0xd4ngi/master
ivanti_ics_name_correction Issue #802
2024-02-14 23:07:30 +00:00
0xd4ngi b58e18dbc3 ivanti_ics_name_correction 2024-02-13 10:51:49 +05:30
AB2 a586444232
Update README.md
rename the docker image name

Signed-off-by: AB2 <84577967+ab2pentest@users.noreply.github.com>
2024-02-06 15:28:03 +01:00
Sam Stepanyan e71b449b90
Merge pull request #799 from OWASP/dependabot/pip/aiohttp-3.9.3
Bump aiohttp from 3.9.1 to 3.9.3
2024-02-05 11:18:11 +00:00
Sam Stepanyan 29844b3452
Merge branch 'master' into dependabot/pip/aiohttp-3.9.3 2024-02-05 10:14:17 +00:00
Sam Stepanyan 3e3f3fea0f
Merge pull request #804 from OWASP/securestep9-patch-nettacker-python3-11-7
Update Dockerfile to use python 3.11.7
2024-02-02 14:52:59 +00:00
Sam Stepanyan 1042c20c0b
Update Dockerfile to use python 3.11.7
reducing vulnerabilities

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-02-02 14:40:23 +00:00
dependabot[bot] 933906b56f
Bump aiohttp from 3.9.1 to 3.9.3
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.1 to 3.9.3.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.1...v3.9.3)

---
updated-dependencies:
- dependency-name: aiohttp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-02 14:06:44 +00:00
Sam Stepanyan 6936844574
Merge pull request #796 from OWASP/dependabot/pip/numpy-1.26.3
Bump numpy from 1.26.2 to 1.26.3
2024-02-02 14:05:56 +00:00
Sam Stepanyan 87ddce04f3
Merge branch 'master' into dependabot/pip/numpy-1.26.3 2024-02-02 13:54:56 +00:00
Sam Stepanyan 31b3dc2e01
Merge pull request #797 from jimmy-ly00/master
New Module: Added Confluence RCE CVE-2023-22527 Vuln
2024-01-24 09:03:45 +00:00
Sam Stepanyan 4480f4eeb7
Merge branch 'master' into master 2024-01-24 00:41:45 +00:00
Jimmy c326796e4d Create confluence_cve_2023_22527.yaml 2024-01-23 02:20:37 +00:00
dependabot[bot] 8deedc465e
Bump numpy from 1.26.2 to 1.26.3
Bumps [numpy](https://github.com/numpy/numpy) from 1.26.2 to 1.26.3.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.26.2...v1.26.3)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 22:31:48 +00:00
Sam Stepanyan 625b507aef
Merge pull request #788 from OWASP/securestep9-patch-v0.3.3-1
Update version.txt
2024-01-20 22:08:16 +00:00
Sam Stepanyan 9e1dbca293
Merge branch 'master' into securestep9-patch-v0.3.3-1 2024-01-20 21:58:44 +00:00
Sam Stepanyan 1ac1462a70
Merge pull request #795 from OWASP/securestep9-ivanti_epmm_lastpatcheddate-patch-1
New Module: Ivanti EPMM Last Patched Date Scan
2024-01-20 21:47:31 +00:00
Sam Stepanyan bf45746350
Update ivanti_epmm_lastpatcheddate.yaml
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-20 21:24:40 +00:00
Sam Stepanyan 93d05aff28
New Module: Ivanti EPMM Last Patched Date Scan
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-20 21:15:12 +00:00
Sam Stepanyan a2a8bc5d3e
Merge pull request #794 from OWASP/securestep9-patch-ivanti_ics_lastpatcheddate-1
New Module: Ivanti ICS Last Patched Date Scan
2024-01-20 21:10:12 +00:00
Sam Stepanyan c5956ba9df
Update ivanti_ics_lastpatcheddate.yaml
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-20 20:50:45 +00:00
Sam Stepanyan 07cc9945c7
New Module: Ivanti ICS Last Patched Date scan
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-20 20:22:25 +00:00
Sam Stepanyan dadc22c1cf
Merge pull request #793 from OWASP/securestep9-ivanti_epmm_cve_2023_35082-1
New Module: Ivanti EPMM CVE-2023-35082
2024-01-20 20:16:50 +00:00
Sam Stepanyan 3111921383
New Module: Ivanti EPMM CVE-2023-35082
detect Ivanti EPMM CVE-2023-35082 vulnerability 

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-20 19:59:02 +00:00
Sam Stepanyan 468bcf60fc
Merge pull request #792 from OWASP/securestep9-patch-ivanti-module-ua-fix
Ivanti ICS module fix: replaced hardcoded User-Agent with variable
2024-01-20 15:41:12 +00:00
Sam Stepanyan 39964d8ce8
Update ivanti_ics_cve_2023_46805.yaml UA fix
replaced hardcoded UserAgent with variable

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-20 15:26:56 +00:00
Sam Stepanyan d7db43eca0
Merge branch 'master' into securestep9-patch-v0.3.3-1 2024-01-20 02:06:01 +00:00
Sam Stepanyan a71a1acda9
Merge pull request #789 from OWASP/dependabot/pip/flask-3.0.1
Bump flask from 3.0.0 to 3.0.1
2024-01-20 02:05:31 +00:00
Sam Stepanyan 41300bf88d
Merge branch 'master' into dependabot/pip/flask-3.0.1 2024-01-20 01:53:32 +00:00
Sam Stepanyan a8e9274503
Merge pull request #791 from OWASP/securestep9-patch-http-html-title-module-1
New Module: HTML Title scan
2024-01-20 01:42:40 +00:00
Sam Stepanyan 4acfac0570
Update http_html_title.yaml
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-20 01:29:37 +00:00
Sam Stepanyan f8a7f60b8f
New Module: HTML Title scan
extract TITLE from the scan target as it can help identify what application is running on the server

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-20 01:18:41 +00:00
Sam Stepanyan 5b3ace3ed4
Merge pull request #790 from OWASP/securestep9-citrix-lastpatcheddate_module-1
New Module: Citrix Gateway Last Patched Date Scan
2024-01-20 00:48:17 +00:00
Sam Stepanyan d2ea491b80
New Module: Citrix Gateway Last Patched Date Scan
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-19 23:58:14 +00:00
dependabot[bot] af3a371122
Bump flask from 3.0.0 to 3.0.1
Bumps [flask](https://github.com/pallets/flask) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/3.0.0...3.0.1)

---
updated-dependencies:
- dependency-name: flask
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-19 22:35:54 +00:00
Sam Stepanyan e9d0ca07fd
Update version.txt
bumping version to 0.3.3 for new release

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-19 01:45:38 +00:00
Sam Stepanyan b7d3648aa0
Merge pull request #787 from OWASP/securestep9-patch-post-smtp-1
Update wp_plugin_small.txt
2024-01-19 01:34:10 +00:00
Sam Stepanyan ae518acaf2
Update wp_plugin_small.txt
Added post-smtp (CVE-2023-6875)

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2024-01-19 01:22:01 +00:00
Sam Stepanyan 0517f51736
Merge pull request #778 from OWASP/snyk-fix-45537895660e2c31d984f2042b819b69
[Snyk] Security upgrade paramiko from 3.3.1 to 3.4.0
2024-01-19 01:08:03 +00:00
Sam Stepanyan 74c8ce94d5
Merge branch 'master' into snyk-fix-45537895660e2c31d984f2042b819b69 2024-01-19 00:56:33 +00:00
Sam Stepanyan d170db99e7
Merge pull request #785 from Captain-T2004/master
Added new module, CVE_2023_6875
2024-01-18 23:57:43 +00:00
Sam Stepanyan a000a235a5
Merge branch 'master' into master 2024-01-18 23:45:32 +00:00
Sam Stepanyan cfa711f400
Merge pull request #786 from jimmy-ly00/master
New Module: Added Ivanti ICS CVE-2023-46805 Vuln
2024-01-18 23:02:48 +00:00
Sam Stepanyan 121bdf8da6
Merge branch 'master' into master 2024-01-18 22:27:33 +00:00
Jimmy d32ce138ae
Update and rename ivanti_ics_cve_2023_46805_and_cve_2024_21887.yaml to ivanti_ics_cve_2023_46805.yaml 2024-01-18 15:00:24 +00:00
Jimmy 826405c4af Create ivanti_ics_cve_2023_46805_and_cve_2024_21887.yaml 2024-01-16 19:53:39 +00:00
Captain-T2004 f80ac79451 Added new module, CVE_2023_6875 2024-01-17 00:26:54 +05:30
snyk-bot 62c5899f9b
fix: requirements.txt to reduce vulnerabilities
The following vulnerabilities are fixed by pinning transitive dependencies:
- https://snyk.io/vuln/SNYK-PYTHON-PARAMIKO-6130887
2023-12-19 16:05:29 +00:00
Ali Razmjoo 90af15d583
Merge pull request #764 from OWASP/dependabot/pip/numpy-1.26.2
Bump numpy from 1.26.0 to 1.26.2
2023-12-15 03:20:11 +01:00
Ali Razmjoo 3a4ed268b7
Merge pull request #772 from OWASP/dependabot/pip/ipython-8.18.1
Bump ipython from 8.16.1 to 8.18.1
2023-12-15 03:19:54 +01:00
Ali Razmjoo 14ddc70adc
Merge pull request #775 from OWASP/dependabot/github_actions/github/codeql-action-3
Bump github/codeql-action from 2 to 3
2023-12-15 03:19:25 +01:00
dependabot[bot] 2d5e9285de
Bump github/codeql-action from 2 to 3
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-13 22:53:33 +00:00
dependabot[bot] 458465ac9c
Bump ipython from 8.16.1 to 8.18.1
Bumps [ipython](https://github.com/ipython/ipython) from 8.16.1 to 8.18.1.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/commits/8.18.1)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 22:48:48 +00:00
Ali Razmjoo 57ea702764
Merge branch 'master' into dependabot/pip/numpy-1.26.2 2023-11-30 08:28:32 +01:00
Ali Razmjoo d005c662d3
Merge pull request #769 from OWASP/dependabot/pip/aiohttp-3.9.1
Bump aiohttp from 3.8.5 to 3.9.1
2023-11-30 08:28:20 +01:00
Ali Razmjoo 71d3f9d78b
Merge branch 'master' into dependabot/pip/aiohttp-3.9.1
Signed-off-by: Ali Razmjoo <ali.razmjoo@owasp.org>
2023-11-30 08:27:49 +01:00
dependabot[bot] 3679ac7ec5
Bump numpy from 1.26.0 to 1.26.2
Bumps [numpy](https://github.com/numpy/numpy) from 1.26.0 to 1.26.2.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.26.0...v1.26.2)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-30 07:27:46 +00:00
Ali Razmjoo 716e7b6a8c
Merge pull request #770 from OWASP/snyk-fix-9d3dbcac003470d5b7bf2e6f12a8e99e
[Snyk] Security upgrade aiohttp from 3.8.5 to 3.9.0
2023-11-30 08:27:00 +01:00
Ali Razmjoo 05db81c725
Merge pull request #771 from OWASP/update-readme
Update README.md
2023-11-30 08:19:42 +01:00
Ali Razmjoo bce2c8d442 Update README.md 2023-11-30 08:19:02 +01:00
snyk-bot 7423a79477
fix: requirements.txt to reduce vulnerabilities
The following vulnerabilities are fixed by pinning transitive dependencies:
- https://snyk.io/vuln/SNYK-PYTHON-AIOHTTP-6091621
- https://snyk.io/vuln/SNYK-PYTHON-AIOHTTP-6091622
- https://snyk.io/vuln/SNYK-PYTHON-AIOHTTP-6091623
2023-11-28 14:51:50 +00:00
dependabot[bot] 2a0727200f
Bump aiohttp from 3.8.5 to 3.9.1
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.5 to 3.9.1.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.5...v3.9.1)

---
updated-dependencies:
- dependency-name: aiohttp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 22:32:36 +00:00
Sam Stepanyan 7af93ebb26
Merge pull request #761 from OWASP/securestep9-0.3.2-version.txt
Update version.txt to 0.3.2
2023-10-31 22:59:36 +00:00
Sam Stepanyan 32ada7decc
Update version.txt
0.3.2

Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2023-10-31 22:47:37 +00:00
Sam Stepanyan c24e3b14e3
Merge pull request #755 from OWASP/dependabot/github_actions/actions/checkout-4.1.1
Bump actions/checkout from 4.1.0 to 4.1.1
2023-10-31 16:28:28 +00:00
Sam Stepanyan 0de31c6d68
Merge branch 'master' into dependabot/github_actions/actions/checkout-4.1.1
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2023-10-31 03:39:19 +00:00
Sam Stepanyan b1a46436ae
Merge pull request #759 from jimmy-ly00/citrix_cve_2023_4966
New Module: Added CVE-2023-4966 vuln
2023-10-29 21:55:18 +00:00
Sam Stepanyan 157ef461d3
Merge branch 'master' into citrix_cve_2023_4966
Signed-off-by: Sam Stepanyan <sam.stepanyan@owasp.org>
2023-10-29 21:44:40 +00:00
Sam Stepanyan f7abce978e
Merge pull request #757 from jimmy-ly00/master
New Module: Added Confluence Version Scan and CVE-2023-22515
2023-10-29 19:53:06 +00:00
Jimmy 4bb4d91136 Create citrix_cve_2023_4966.yaml 2023-10-26 23:50:35 +01:00
Jimmy 4a1c42f023 Create citrix_cve_2023_4966.yaml 2023-10-26 23:46:19 +01:00
Jimmy 2181214c16
Merge branch 'master' into master 2023-10-23 18:33:13 +01:00
Jimmy a31fdf7735 Added Confluence Scans and CVE-2023-22515 2023-10-23 18:14:39 +01:00
Sam Stepanyan fbc60a2241
Merge pull request #749 from arkid15r/correct-sort-dict-method-name
Fix a typo in sort dictionary method name
2023-10-23 02:10:02 +01:00
Sam Stepanyan 40f7b921bb
Merge branch 'master' into correct-sort-dict-method-name 2023-10-23 01:58:50 +01:00
dependabot[bot] faf711c60d
Bump actions/checkout from 4.1.0 to 4.1.1
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-17 22:09:34 +00:00
Sam Stepanyan 9a58504340
Merge pull request #752 from OWASP/snyk-fix-21adb73e7146727149c932fb8de1476f
[Snyk] Security upgrade python from 3.11.5-slim to 3.11.6-slim
2023-10-16 22:59:35 +01:00
Sam Stepanyan c84355565f
Merge branch 'master' into snyk-fix-21adb73e7146727149c932fb8de1476f 2023-10-16 22:44:40 +01:00
Sam Stepanyan b1a65b7b08
Merge pull request #753 from Captain-T2004/LanguageTranslations_HINDI
Update to lib/messages/hi.yaml
2023-10-16 22:43:42 +01:00
Sam Stepanyan 83a1586160
Merge branch 'master' into LanguageTranslations_HINDI 2023-10-16 22:30:52 +01:00
Sam Stepanyan d1275caab1
Merge pull request #750 from arkid15r/update-gitignore
Update .gitignore: exclude VSCode workspace files
2023-10-14 10:53:39 +01:00
Captain-T2004 138df61103 Update to lib/messages/hi.yaml
I have thoroughly reviewed the translations in the '/lib/messages' folder for the Hindi language (hi.yaml). I've made several corrections and incorporated enhancements to ensure they are more grammatically accurate and convey a more meaningful message. I have checked and made sure that the application is running properly with the updated translations.

File Changed: /lib/messages/hi.yaml
2023-10-14 15:01:00 +05:30
snyk-bot ba39a2c279
fix: Dockerfile to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-DEBIAN12-GLIBC-5894114
- https://snyk.io/vuln/SNYK-DEBIAN12-GLIBC-5894115
- https://snyk.io/vuln/SNYK-DEBIAN12-GLIBC-5927132
- https://snyk.io/vuln/SNYK-DEBIAN12-GLIBC-5927132
- https://snyk.io/vuln/SNYK-DEBIAN12-OPENSSL-5812633
2023-10-13 18:50:33 +00:00
Arkadii Yakovets 7d57a3faf4
Update .gitignore: exclude VSCode workspace files 2023-10-10 13:36:13 -07:00
Arkadii Yakovets 1b4e6296a3
Fix a typo in sort dictionary method name 2023-10-10 13:28:09 -07:00
Ali Razmjoo d926de783b
Merge pull request #737 from OWASP/dependabot/pip/netaddr-0.9.0
Bump netaddr from 0.8.0 to 0.9.0
2023-10-05 15:46:35 +02:00
Ali Razmjoo 9f161b7546
Merge pull request #738 from OWASP/dependabot/pip/numpy-1.26.0
Bump numpy from 1.25.2 to 1.26.0
2023-10-05 15:46:24 +02:00
Ali Razmjoo 98a71d87ae
Merge pull request #742 from OWASP/dependabot/github_actions/actions/checkout-4.1.0
Bump actions/checkout from 4.0.0 to 4.1.0
2023-10-05 15:46:15 +02:00
Ali Razmjoo c6813ed31e
Merge pull request #744 from OWASP/dependabot/pip/ipython-8.16.1
Bump ipython from 8.14.0 to 8.16.1
2023-10-05 15:46:07 +02:00
Ali Razmjoo 6f847791fc
Merge pull request #745 from OWASP/dependabot/pip/flask-3.0.0
Bump flask from 2.3.2 to 3.0.0
2023-10-05 15:45:52 +02:00
dependabot[bot] b27e4412a2
Bump flask from 2.3.2 to 3.0.0
Bumps [flask](https://github.com/pallets/flask) from 2.3.2 to 3.0.0.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/2.3.2...3.0.0)

---
updated-dependencies:
- dependency-name: flask
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 22:52:39 +00:00
dependabot[bot] 7ef72940a9
Bump ipython from 8.14.0 to 8.16.1
Bumps [ipython](https://github.com/ipython/ipython) from 8.14.0 to 8.16.1.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/commits)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 22:52:35 +00:00
dependabot[bot] 1cd95719a0
Bump actions/checkout from 4.0.0 to 4.1.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.0.0...v4.1.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-22 22:57:21 +00:00
dependabot[bot] 219ff2280c
Bump numpy from 1.25.2 to 1.26.0
Bumps [numpy](https://github.com/numpy/numpy) from 1.25.2 to 1.26.0.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.25.2...v1.26.0)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 22:16:36 +00:00
dependabot[bot] 95a36d1c58
Bump netaddr from 0.8.0 to 0.9.0
Bumps [netaddr](https://github.com/drkjam/netaddr) from 0.8.0 to 0.9.0.
- [Changelog](https://github.com/netaddr/netaddr/blob/master/CHANGELOG)
- [Commits](https://github.com/drkjam/netaddr/commits)

---
updated-dependencies:
- dependency-name: netaddr
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 22:15:55 +00:00
Sam Stepanyan da0bd3f33f
Merge pull request #736 from OWASP/securestep9-wp-plugins-update0823
Update wp_plugin_small.txt
2023-09-13 01:51:12 +01:00
Sam Stepanyan a5d52dd147
Update wp_plugin_small.txt
Adding to the list the Wordpress plugins with recent Critical CVEs:
media-library-assistant (CVE-2023-463) and
forminator (CVE-2023-4596)
2023-09-13 01:33:09 +01:00
Sam Stepanyan 7fb110f6ef
Merge pull request #734 from OWASP/dependabot/github_actions/docker/login-action-3
Bump docker/login-action from 2 to 3
2023-09-13 01:28:07 +01:00
Sam Stepanyan 2e0c246357
Merge branch 'master' into dependabot/github_actions/docker/login-action-3 2023-09-13 01:16:30 +01:00
Sam Stepanyan c570fb8c16
Merge pull request #735 from OWASP/dependabot/github_actions/docker/setup-qemu-action-3
Bump docker/setup-qemu-action from 2 to 3
2023-09-13 01:15:57 +01:00
dependabot[bot] 73f92d09a2
Bump docker/setup-qemu-action from 2 to 3
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 23:52:31 +00:00
dependabot[bot] 5ade63c4a4
Bump docker/login-action from 2 to 3
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 23:52:26 +00:00
Sam Stepanyan 10ad53d1c4
Merge pull request #733 from OWASP/dependabot/github_actions/docker/setup-buildx-action-3
Bump docker/setup-buildx-action from 2 to 3
2023-09-13 00:51:50 +01:00
Sam Stepanyan d8d887c852
Merge branch 'master' into dependabot/github_actions/docker/setup-buildx-action-3 2023-09-13 00:38:44 +01:00
Sam Stepanyan 2e7886e6e8
Merge pull request #732 from OWASP/dependabot/github_actions/docker/build-push-action-5
Bump docker/build-push-action from 4 to 5
2023-09-13 00:37:53 +01:00
dependabot[bot] 88df5a2851
Bump docker/setup-buildx-action from 2 to 3
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 22:34:46 +00:00
dependabot[bot] 61dbef7f7a
Bump docker/build-push-action from 4 to 5
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 22:34:43 +00:00
Ali Razmjoo ce82452f84
Merge pull request #699 from OWASP/dependabot/pip/py3dns-4.0.0
Bump py3dns from 3.2.1 to 4.0.0
2023-09-10 16:49:09 +02:00
Ali Razmjoo f44f4c7c8f
Merge branch 'master' into dependabot/pip/py3dns-4.0.0 2023-09-10 16:28:19 +02:00
Ali Razmjoo add41136a6
Merge pull request #718 from OWASP/dependabot/pip/pyyaml-6.0.1
Bump pyyaml from 6.0 to 6.0.1
2023-09-10 16:28:13 +02:00
Ali Razmjoo 34e0622268
Merge branch 'master' into dependabot/pip/py3dns-4.0.0 2023-09-10 16:28:07 +02:00
Ali Razmjoo 8c24ed7a61
Merge pull request #722 from OWASP/dependabot/pip/paramiko-3.3.1
Bump paramiko from 3.2.0 to 3.3.1
2023-09-10 16:27:18 +02:00
Ali Razmjoo b3c23de9dd
Merge pull request #723 from OWASP/dependabot/pip/numpy-1.25.2
Bump numpy from 1.24.3 to 1.25.2
2023-09-10 16:27:10 +02:00
Ali Razmjoo 44ae9a67ea
Merge branch 'master' into dependabot/pip/paramiko-3.3.1 2023-09-10 16:13:21 +02:00
Ali Razmjoo 25c6a17dc3
Merge branch 'master' into dependabot/pip/numpy-1.25.2 2023-09-10 16:13:13 +02:00
Ali Razmjoo baa0cf063c
Merge pull request #726 from OWASP/dependabot/docker/python-3.11.5-slim
Bump python from 3.11.4-slim to 3.11.5-slim
2023-09-10 16:13:01 +02:00
Ali Razmjoo 70effc4287
Merge pull request #720 from OWASP/dependabot/pip/aiohttp-3.8.5
Bump aiohttp from 3.8.4 to 3.8.5
2023-09-10 16:12:49 +02:00
Ali Razmjoo b5aa5da20f
Merge branch 'master' into dependabot/docker/python-3.11.5-slim 2023-09-10 16:08:48 +02:00
Ali Razmjoo 22a63788f1
Merge pull request #728 from OWASP/dependabot/github_actions/actions/checkout-4.0.0
Bump actions/checkout from 3.5.3 to 4.0.0
2023-09-10 16:08:28 +02:00
Ali Razmjoo 3c6834523d
Merge branch 'master' into dependabot/pip/pyyaml-6.0.1 2023-09-10 16:07:22 +02:00
Ali Razmjoo 29a33945c9
Merge branch 'master' into dependabot/pip/aiohttp-3.8.5 2023-09-10 16:07:16 +02:00
Ali Razmjoo daee1f0452
Merge branch 'master' into dependabot/pip/py3dns-4.0.0 2023-09-10 16:06:43 +02:00
dependabot[bot] a7889aa474
Bump actions/checkout from 3.5.3 to 4.0.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 4.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.5.3...v4.0.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 22:03:09 +00:00
dependabot[bot] 91c1454b01
Bump python from 3.11.4-slim to 3.11.5-slim
Bumps python from 3.11.4-slim to 3.11.5-slim.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-28 22:37:09 +00:00
dependabot[bot] 0a1b7506b0
Bump numpy from 1.24.3 to 1.25.2
Bumps [numpy](https://github.com/numpy/numpy) from 1.24.3 to 1.25.2.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.24.3...v1.25.2)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 22:25:35 +00:00
dependabot[bot] c3b00de419
Bump paramiko from 3.2.0 to 3.3.1
Bumps [paramiko](https://github.com/paramiko/paramiko) from 3.2.0 to 3.3.1.
- [Commits](https://github.com/paramiko/paramiko/compare/3.2.0...3.3.1)

---
updated-dependencies:
- dependency-name: paramiko
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-28 22:27:54 +00:00
Sam Stepanyan afa1eccea5
Merge pull request #719 from jimmy-ly00/master
New Module: Adobe Coldfusion CVE-2023-26360
2023-07-22 00:59:28 +01:00
Sam Stepanyan 032c54d208
Merge branch 'master' into master 2023-07-22 00:45:10 +01:00
dependabot[bot] ee2e4440a2
Bump py3dns from 3.2.1 to 4.0.0
Bumps py3dns from 3.2.1 to 4.0.0.

---
updated-dependencies:
- dependency-name: py3dns
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-21 14:46:48 +00:00
dependabot[bot] 17c37b997b
Bump aiohttp from 3.8.4 to 3.8.5
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.4 to 3.8.5.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/v3.8.5/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.4...v3.8.5)

---
updated-dependencies:
- dependency-name: aiohttp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-21 14:46:44 +00:00
dependabot[bot] c6cf21738f
Bump pyyaml from 6.0 to 6.0.1
Bumps [pyyaml](https://github.com/yaml/pyyaml) from 6.0 to 6.0.1.
- [Changelog](https://github.com/yaml/pyyaml/blob/6.0.1/CHANGES)
- [Commits](https://github.com/yaml/pyyaml/compare/6.0...6.0.1)

---
updated-dependencies:
- dependency-name: pyyaml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-21 14:46:41 +00:00
Sam Stepanyan be735f705b
Merge pull request #716 from nucr0t/rusal
Correct module name
2023-07-21 15:45:57 +01:00
Jimmy eca9fe0bc2 Update adobe_coldfusion_cve_2023_26360.yaml 2023-07-19 14:12:12 +01:00
Jimmy 239ef4af06 Create adobe_coldfusion_cve_2023_26360.yaml 2023-07-19 14:07:18 +01:00
rusal f93f8613a3 Disconnect Handling to SQL 2023-07-15 08:38:12 -04:00
rusal af2c05bdb8 Correct module name 2023-07-09 12:12:22 -04:00
Sam Stepanyan f1ac6174d0
Merge pull request #713 from OWASP/securestep9-patch-TRENT-UNO
Update version.txt for Release 0.3.1
2023-07-05 01:54:17 +01:00
Sam Stepanyan c53cd8d046
Update version.txt
starting 0.3.1
2023-07-05 01:25:52 +01:00
Sam Stepanyan 32080d4ca4
Merge pull request #711 from OWASP/securestep9-patch-moveit-version-scan-1
New module: moveit_version_scan  - scan for Progress MOVEit instances
2023-07-05 01:22:09 +01:00
Sam Stepanyan c49f949261
Create new module moveit_version_scan 2023-07-05 00:57:37 +01:00
Sam Stepanyan 89d56572f8
Merge pull request #709 from OWASP/securestep9-patch-drupal-version-1
Updates drupal_version_scan module
2023-07-05 00:20:56 +01:00
Sam Stepanyan bd8abd17b0
Update drupal_version.yaml
added version logging and improved regex
2023-07-05 00:07:42 +01:00
Sam Stepanyan 7269995647
Merge pull request #707 from OWASP/securestep9-patch-joomla_version-1
Updated joomla_version_scan module
2023-07-04 20:56:49 +01:00
Sam Stepanyan 78d8d07b00
Update joomla_version.yaml
added version logging
2023-07-04 20:46:35 +01:00
Sam Stepanyan 6966ba9b51
Merge pull request #705 from OWASP/securestep9-patch-server-version-vuln-log-1
Updates server_version_vuln module Server header logging
2023-07-04 20:28:59 +01:00
Sam Stepanyan 2e497dc087
Update server_version.yaml
added logging of the server header
2023-07-04 19:28:22 +01:00
Sam Stepanyan 7b7e138c64
Merge pull request #703 from OWASP/securestep9-patch-x-powered-by-add-log
update X-Powered-By header logging
2023-07-04 18:41:21 +01:00
Sam Stepanyan 4d944c25d4
Update x_powered_by.yaml
added header logging
2023-07-04 18:18:24 +01:00
Sam Stepanyan 61d2d1c670
Merge pull request #701 from OWASP/securestep9-wordpress-version-update-1
Update wordpress_version.yaml
2023-07-04 00:45:02 +01:00
Sam Stepanyan 395dde375b
Update wordpress_version.yaml
update to log the wp version
2023-07-04 00:04:27 +01:00
Sam Stepanyan bacce41df0
Merge pull request #697 from OWASP/securestep9-patch-gitattributes
Create .gitattributes
2023-07-03 11:01:21 +01:00
Sam Stepanyan 0ea41a3d71
Create .gitattributes
to stop GitHub from chowing Nettacker main language as HTML - it should be Python!
2023-07-03 10:25:07 +01:00
Sam Stepanyan fd93fac153
Merge pull request #695 from OWASP/securestep9-module-citrix-cve-2023-24488
New module citrix_cve_2023_24488_vuln
2023-07-03 01:31:30 +01:00
Sam Stepanyan feafb15e91
add module citrix_cve_2023_24488_vuln
new module to detect Citrix XSS and open redirect CVE-2023-24488 for which a POC was published on 29-Jun-2023
2023-07-03 01:10:24 +01:00
Sam Stepanyan 09318468b9
Merge pull request #693 from OWASP/securestep9-module-http_redirect_scan
New Module: http_redirect_scan
2023-07-03 00:58:58 +01:00
Sam Stepanyan 05a2953e6c
Rename http_redirect to http_redirect.yaml 2023-07-03 00:47:57 +01:00
Sam Stepanyan d6eefe7e69
http_redirect_scan module
feature #692  http_redirect_scan module scans for target websites returning 3xx response code and redirecting users to a different location
2023-07-03 00:27:47 +01:00
Sam Stepanyan bcc5bb686e
Merge pull request #691 from OWASP/securestep9-module-http-status-scan
New module: http_status_scan
2023-07-03 00:10:52 +01:00
Sam Stepanyan 8c14b48f1f
http_status_scan module
feature #690 - a simple http_status_scan module returns HTTP Status Code - useful for recon
2023-07-02 23:50:44 +01:00
Sam Stepanyan 686cc2fbe6
Merge pull request #689 from OWASP/securestep9-patch-cve-2023-miniorange-login-openid
Added miniorange-login-openid to wp_plugin_small
2023-07-02 21:53:28 +01:00
Sam Stepanyan 417ce113d8
Merge branch 'master' into securestep9-patch-cve-2023-miniorange-login-openid 2023-07-02 21:30:26 +01:00
Sam Stepanyan e9a32713e3
Merge pull request #687 from OWASP/dependabot/github_actions/actions/checkout-3.5.3
Bump actions/checkout from 3.5.2 to 3.5.3
2023-07-02 21:23:52 +01:00
Sam Stepanyan deaafecffc
Added miniorange-login-openid to wp_plugin_small
Ddded miniorange-login-openid to support detection of Wordpress CVE-2023-2982 (CVSS 9.8 Critical) in WordPress Social Login and Register plugin
2023-07-02 21:16:52 +01:00
Sam Stepanyan 92004bc54a
Merge branch 'master' into dependabot/github_actions/actions/checkout-3.5.3 2023-07-02 20:45:07 +01:00
Sam Stepanyan 0ac09aad56
Merge pull request #686 from OWASP/dependabot/docker/python-3.11.4-slim
Bump python from 3.11.3-slim to 3.11.4-slim
2023-07-02 20:41:52 +01:00
Sam Stepanyan ca42de9aeb
Merge branch 'master' into dependabot/docker/python-3.11.4-slim 2023-07-02 20:17:52 +01:00
Sam Stepanyan 7a3e89dc09
Merge pull request #684 from OWASP/dependabot/pip/ipython-8.14.0
Bump ipython from 8.12.0 to 8.14.0
2023-07-02 20:17:33 +01:00
dependabot[bot] 917ba6995d
Bump ipython from 8.12.0 to 8.14.0
Bumps [ipython](https://github.com/ipython/ipython) from 8.12.0 to 8.14.0.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/8.12.0...8.14.0)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-02 18:58:47 +00:00
Sam Stepanyan 1289aa9e19
Merge pull request #683 from OWASP/dependabot/pip/pyopenssl-23.2.0
Bump pyopenssl from 23.1.1 to 23.2.0
2023-07-02 19:58:11 +01:00
Sam Stepanyan 77b6a8e9b9
Merge branch 'master' into dependabot/pip/pyopenssl-23.2.0 2023-07-02 19:45:55 +01:00
Sam Stepanyan 4b6a6a0461
Merge pull request #682 from OWASP/dependabot/pip/paramiko-3.2.0
Bump paramiko from 3.1.0 to 3.2.0
2023-07-02 19:35:24 +01:00
Sam Stepanyan 10b4b114fb
Merge branch 'master' into dependabot/pip/paramiko-3.2.0 2023-07-02 19:22:03 +01:00
Sam Stepanyan 4a4d5d2a0c
Merge pull request #680 from OWASP/dependabot/pip/requests-2.31.0
Bump requests from 2.28.2 to 2.31.0
2023-07-02 19:15:06 +01:00
Sam Stepanyan 0b65bc5808
Merge branch 'master' into dependabot/pip/requests-2.31.0 2023-07-02 19:04:25 +01:00
Sam Stepanyan bd8dbc59fa
Merge pull request #679 from roddas/feature/#597-select-maximum-cpu-core-unittesting
feat: #597 Add unit testing for select_maximum_cpu_core function
2023-07-02 19:04:02 +01:00
Sam Stepanyan b28c517639
Merge branch 'master' into feature/#597-select-maximum-cpu-core-unittesting 2023-07-02 18:53:24 +01:00
Sam Stepanyan cee831286a
Merge pull request #675 from OWASP/dependabot/pip/flask-2.3.2
Bump flask from 2.2.3 to 2.3.2
2023-07-02 18:46:35 +01:00
dependabot[bot] 506ebfc247
Bump actions/checkout from 3.5.2 to 3.5.3
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.5.2...v3.5.3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-09 22:58:03 +00:00
dependabot[bot] 195ebd127a
Bump python from 3.11.3-slim to 3.11.4-slim
Bumps python from 3.11.3-slim to 3.11.4-slim.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-08 22:58:08 +00:00
dependabot[bot] 795f48a1eb
Bump pyopenssl from 23.1.1 to 23.2.0
Bumps [pyopenssl](https://github.com/pyca/pyopenssl) from 23.1.1 to 23.2.0.
- [Changelog](https://github.com/pyca/pyopenssl/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/pyopenssl/compare/23.1.1...23.2.0)

---
updated-dependencies:
- dependency-name: pyopenssl
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-31 22:58:01 +00:00
dependabot[bot] aa438996d6
Bump paramiko from 3.1.0 to 3.2.0
Bumps [paramiko](https://github.com/paramiko/paramiko) from 3.1.0 to 3.2.0.
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/3.1.0...3.2.0)

---
updated-dependencies:
- dependency-name: paramiko
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-25 22:58:04 +00:00
dependabot[bot] 27cc83a615
Bump requests from 2.28.2 to 2.31.0
Bumps [requests](https://github.com/psf/requests) from 2.28.2 to 2.31.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.28.2...v2.31.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 22:59:56 +00:00
Rodolfo Cabral Neves ad3f85bac5
Merge branch 'master' into feature/#597-select-maximum-cpu-core-unittesting 2023-05-10 20:33:37 -03:00
Rodolfo Cabral Neves 900b46a80b feat: #597 Add unit testing for select_maximum_cpu_core function 2023-05-10 20:30:02 -03:00
dependabot[bot] 40b9dce3d4
Bump flask from 2.2.3 to 2.3.2
Bumps [flask](https://github.com/pallets/flask) from 2.2.3 to 2.3.2.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/2.2.3...2.3.2)

---
updated-dependencies:
- dependency-name: flask
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 21:13:45 +00:00
Sam Stepanyan 6d532f35cb
Merge pull request #676 from OWASP/snyk-fix-646601579312e9219cac0dcbd99bd4de
[Snyk] Security upgrade flask from 2.2.3 to 2.2.5
2023-05-08 22:08:19 +01:00
Sam Stepanyan 5133a193d1
Merge branch 'master' into snyk-fix-646601579312e9219cac0dcbd99bd4de 2023-05-08 21:12:42 +01:00
Sam Stepanyan 649d29c951
Merge pull request #669 from OWASP/dependabot/pip/numpy-1.24.3
Bump numpy from 1.24.2 to 1.24.3
2023-05-08 21:10:52 +01:00
Sam Stepanyan 101e345f07
Merge branch 'master' into dependabot/pip/numpy-1.24.3 2023-05-08 20:53:26 +01:00
Sam Stepanyan 5f913c75f6
Merge pull request #668 from OWASP/dependabot/github_actions/actions/checkout-3.5.2
Bump actions/checkout from 3.5.1 to 3.5.2
2023-05-08 20:50:42 +01:00
Sam Stepanyan e1692fc82c
Merge branch 'master' into dependabot/github_actions/actions/checkout-3.5.2 2023-05-08 20:29:50 +01:00
Sam Stepanyan dbfd6f674b
Merge pull request #673 from roddas/feature/#597-sort-dictionary-unit-testing
feat: #597 Add unit testing for sort_dictionary function
2023-05-08 20:25:10 +01:00
snyk-bot 0512da96bb
fix: requirements.txt to reduce vulnerabilities
The following vulnerabilities are fixed by pinning transitive dependencies:
- https://snyk.io/vuln/SNYK-PYTHON-FLASK-5490129
2023-05-03 20:09:17 +00:00
Rodolfo Cabral Neves 449fb83676 feat: #597 Add unit testing for sort_dictionary function 2023-04-29 14:53:17 -03:00
dependabot[bot] d5e34b2469
Bump numpy from 1.24.2 to 1.24.3
Bumps [numpy](https://github.com/numpy/numpy) from 1.24.2 to 1.24.3.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.24.2...v1.24.3)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 22:59:01 +00:00
dependabot[bot] ff1f1a8cf6
Bump actions/checkout from 3.5.1 to 3.5.2
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.1 to 3.5.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.5.1...v3.5.2)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-13 22:58:14 +00:00
Sam Stepanyan d2ae55a36d
Merge pull request #666 from OWASP/dependabot/github_actions/actions/checkout-3.5.1
Bump actions/checkout from 3.5.0 to 3.5.1
2023-04-13 23:33:52 +01:00
Sam Stepanyan 993950dc9c
Merge branch 'master' into dependabot/github_actions/actions/checkout-3.5.1 2023-04-13 23:14:58 +01:00
Sam Stepanyan 98164dd3d4
Merge pull request #667 from OWASP/securestep9-readme-stargazers
Update README.md
2023-04-13 23:14:19 +01:00
Sam Stepanyan 8789947dd9
Merge branch 'master' into securestep9-readme-stargazers 2023-04-13 22:28:47 +01:00
Sam Stepanyan d70d01a2ca
Merge pull request #665 from OWASP/dependabot/docker/python-3.11.3-slim
Bump python from 3.11.2-slim to 3.11.3-slim
2023-04-13 22:28:06 +01:00
Sam Stepanyan debdd34526
Update README.md
added Stargazers Over Time Chart at the bottom and fixed the image URLs to use the OWASP repo
2023-04-13 22:04:55 +01:00
dependabot[bot] d70609be5e
Bump actions/checkout from 3.5.0 to 3.5.1
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.5.0...v3.5.1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-12 22:57:54 +00:00
dependabot[bot] 3d8c898d94
Bump python from 3.11.2-slim to 3.11.3-slim
Bumps python from 3.11.2-slim to 3.11.3-slim.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-06 22:58:04 +00:00
Ali Razmjoo 3ec7542dbd
Merge pull request #660 from OWASP/dependabot/github_actions/actions/checkout-3.5.0
Bump actions/checkout from 3.4.0 to 3.5.0
2023-04-02 12:57:33 +02:00
Ali Razmjoo 4ea76df5e1
Merge pull request #662 from OWASP/dependabot/pip/pyopenssl-23.1.1
Bump pyopenssl from 23.0.0 to 23.1.1
2023-04-02 12:57:23 +02:00
Ali Razmjoo 3721909808
Merge pull request #663 from OWASP/dependabot/pip/ipython-8.12.0
Bump ipython from 8.11.0 to 8.12.0
2023-04-02 12:57:09 +02:00
dependabot[bot] 4a2f1cdb09
Bump ipython from 8.11.0 to 8.12.0
Bumps [ipython](https://github.com/ipython/ipython) from 8.11.0 to 8.12.0.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/8.11.0...8.12.0)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-30 22:58:15 +00:00
dependabot[bot] 69ae555c5e
Bump pyopenssl from 23.0.0 to 23.1.1
Bumps [pyopenssl](https://github.com/pyca/pyopenssl) from 23.0.0 to 23.1.1.
- [Release notes](https://github.com/pyca/pyopenssl/releases)
- [Changelog](https://github.com/pyca/pyopenssl/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/pyopenssl/compare/23.0.0...23.1.1)

---
updated-dependencies:
- dependency-name: pyopenssl
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-28 22:59:16 +00:00
dependabot[bot] 141dcf2f1d
Bump actions/checkout from 3.4.0 to 3.5.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.4.0...v3.5.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-24 22:58:26 +00:00
Ali Razmjoo c8279ead6e
Merge pull request #654 from OWASP/dependabot/pip/aiohttp-3.8.4
Bump aiohttp from 3.8.3 to 3.8.4
2023-03-24 21:10:48 +01:00
Ali Razmjoo 6a7c2936c1
Merge pull request #655 from OWASP/dependabot/pip/numpy-1.24.2
Bump numpy from 1.24.1 to 1.24.2
2023-03-24 21:10:34 +01:00
Ali Razmjoo 4be08d361e
Merge pull request #656 from OWASP/dependabot/pip/ipython-8.11.0
Bump ipython from 8.10.0 to 8.11.0
2023-03-24 21:10:23 +01:00
Ali Razmjoo 12d3b6bc90
Merge pull request #657 from OWASP/dependabot/pip/paramiko-3.1.0
Bump paramiko from 3.0.0 to 3.1.0
2023-03-24 21:10:09 +01:00
Ali Razmjoo 917977ef79
Merge pull request #658 from OWASP/dependabot/github_actions/actions/checkout-3.4.0
Bump actions/checkout from 3.3.0 to 3.4.0
2023-03-24 21:09:56 +01:00
dependabot[bot] abca858c11
Bump actions/checkout from 3.3.0 to 3.4.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.3.0...v3.4.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 22:58:28 +00:00
dependabot[bot] 8da7964cb8
Bump paramiko from 3.0.0 to 3.1.0
Bumps [paramiko](https://github.com/paramiko/paramiko) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/paramiko/paramiko/releases)
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/3.0.0...3.1.0)

---
updated-dependencies:
- dependency-name: paramiko
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 16:15:11 +00:00
dependabot[bot] ec1c3c04ca
Bump ipython from 8.10.0 to 8.11.0
Bumps [ipython](https://github.com/ipython/ipython) from 8.10.0 to 8.11.0.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/8.10.0...8.11.0)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 16:14:08 +00:00
dependabot[bot] baf058b985
Bump numpy from 1.24.1 to 1.24.2
Bumps [numpy](https://github.com/numpy/numpy) from 1.24.1 to 1.24.2.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.24.1...v1.24.2)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 16:12:44 +00:00
Sam Stepanyan 5d05282b47
Merge branch 'master' into dependabot/pip/aiohttp-3.8.4 2023-03-15 16:11:29 +00:00
Sam Stepanyan 89bebf95d6
Merge pull request #653 from OWASP/dependabot/pip/flask-2.2.3
Bump flask from 2.2.2 to 2.2.3
2023-03-15 16:10:30 +00:00
Sam Stepanyan e1a4be7683
Merge branch 'master' into dependabot/pip/flask-2.2.3 2023-03-15 01:51:24 +00:00
Sam Stepanyan c60f33ecaa
Merge pull request #646 from suyash5053/master
Moved Issues_template and pull_request_template to .github directory
2023-03-15 01:21:25 +00:00
Sam Stepanyan 5f019acb94
Merge branch 'master' into master 2023-03-15 01:11:26 +00:00
dependabot[bot] 5a29248e94
Bump aiohttp from 3.8.3 to 3.8.4
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.3 to 3.8.4.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.3...v3.8.4)

---
updated-dependencies:
- dependency-name: aiohttp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-20 23:00:32 +00:00
dependabot[bot] 91fb4b516f
Bump flask from 2.2.2 to 2.2.3
Bumps [flask](https://github.com/pallets/flask) from 2.2.2 to 2.2.3.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/2.2.2...2.2.3)

---
updated-dependencies:
- dependency-name: flask
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-20 23:00:13 +00:00
Sam Stepanyan 455510bf5c
Merge pull request #652 from OWASP/securestep9-docker-python-update-3112-slim
Update Dockerfile - Python docker image update
2023-02-20 04:21:59 +00:00
Sam Stepanyan 10b7a4e793
Update Dockerfile
Python docker image update
2023-02-20 03:52:33 +00:00
Ali Razmjoo 553d440ff6
Merge pull request #640 from OWASP/dependabot/pip/pyopenssl-23.0.0
Bump pyopenssl from 22.1.0 to 23.0.0
2023-02-19 00:19:16 +01:00
dependabot[bot] 087014f7d7
Bump pyopenssl from 22.1.0 to 23.0.0
Bumps [pyopenssl](https://github.com/pyca/pyopenssl) from 22.1.0 to 23.0.0.
- [Release notes](https://github.com/pyca/pyopenssl/releases)
- [Changelog](https://github.com/pyca/pyopenssl/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/pyopenssl/compare/22.1.0...23.0.0)

---
updated-dependencies:
- dependency-name: pyopenssl
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-18 23:19:08 +00:00
Ali Razmjoo f84349b644
Merge pull request #642 from OWASP/dependabot/pip/requests-2.28.2
Bump requests from 2.28.1 to 2.28.2
2023-02-19 00:18:58 +01:00
Ali Razmjoo 1c34d8a326
Merge pull request #651 from OWASP/dependabot/pip/ipython-8.10.0
Bump ipython from 8.8.0 to 8.10.0
2023-02-19 00:18:40 +01:00
dependabot[bot] fe60d8538b
Bump ipython from 8.8.0 to 8.10.0
Bumps [ipython](https://github.com/ipython/ipython) from 8.8.0 to 8.10.0.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/8.8.0...8.10.0)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-18 23:18:20 +00:00
Ali Razmjoo af1c903ee7
Merge pull request #649 from OWASP/dependabot/github_actions/docker/build-push-action-4
Bump docker/build-push-action from 3 to 4
2023-02-19 00:18:17 +01:00
dependabot[bot] 32c0893090
Bump requests from 2.28.1 to 2.28.2
Bumps [requests](https://github.com/psf/requests) from 2.28.1 to 2.28.2.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.28.1...v2.28.2)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-18 23:18:14 +00:00
Ali Razmjoo 3ac41e720b
Merge pull request #645 from OWASP/dependabot/pip/paramiko-3.0.0
Bump paramiko from 2.12.0 to 3.0.0
2023-02-19 00:17:44 +01:00
Ali Razmjoo d5f2c387d0
Merge pull request #630 from OWASP/dependabot/pip/flake8-6.0.0
Bump flake8 from 5.0.4 to 6.0.0
2023-02-19 00:17:04 +01:00
dependabot[bot] 2211e6f33c
Bump docker/build-push-action from 3 to 4
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3 to 4.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-30 22:05:47 +00:00
suyash5053 e5f45f9b4b Moved issues and pull request template to .github 2023-01-25 01:02:41 +05:30
dependabot[bot] 7fd106b5f3
Bump paramiko from 2.12.0 to 3.0.0
Bumps [paramiko](https://github.com/paramiko/paramiko) from 2.12.0 to 3.0.0.
- [Release notes](https://github.com/paramiko/paramiko/releases)
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/2.12.0...3.0.0)

---
updated-dependencies:
- dependency-name: paramiko
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-23 22:07:07 +00:00
Ali Razmjoo 857b34c8de
Merge branch 'master' into dependabot/pip/flake8-6.0.0 2023-01-06 00:35:04 +01:00
Ali Razmjoo 335e31a4c3
Merge pull request #623 from OWASP/dependabot/pip/paramiko-2.12.0
Bump paramiko from 2.11.0 to 2.12.0
2023-01-06 00:34:50 +01:00
Ali Razmjoo 20c5722fca
Merge pull request #625 from zbraiterman/update_readme
Rename readme.md to README.md
2023-01-06 00:28:48 +01:00
dependabot[bot] 97854ce767
Bump paramiko from 2.11.0 to 2.12.0
Bumps [paramiko](https://github.com/paramiko/paramiko) from 2.11.0 to 2.12.0.
- [Release notes](https://github.com/paramiko/paramiko/releases)
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/2.11.0...2.12.0)

---
updated-dependencies:
- dependency-name: paramiko
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-05 23:23:30 +00:00
dependabot[bot] daafbe4b0a
Bump flake8 from 5.0.4 to 6.0.0
Bumps [flake8](https://github.com/pycqa/flake8) from 5.0.4 to 6.0.0.
- [Release notes](https://github.com/pycqa/flake8/releases)
- [Commits](https://github.com/pycqa/flake8/compare/5.0.4...6.0.0)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-05 23:23:19 +00:00
Ali Razmjoo 445a4de653
Merge pull request #629 from OWASP/dependabot/pip/texttable-1.6.7
Bump texttable from 1.6.4 to 1.6.7
2023-01-06 00:22:56 +01:00
Ali Razmjoo 2ec1659843
Merge pull request #637 from OWASP/dependabot/pip/numpy-1.24.1
Bump numpy from 1.23.4 to 1.24.1
2023-01-06 00:22:21 +01:00
Ali Razmjoo 4c31b81faf
Merge pull request #638 from OWASP/dependabot/pip/ipython-8.8.0
Bump ipython from 8.6.0 to 8.8.0
2023-01-06 00:22:10 +01:00
Ali Razmjoo 2d62ab7e28
Merge pull request #639 from OWASP/dependabot/github_actions/actions/checkout-3.3.0
Bump actions/checkout from 3.1.0 to 3.3.0
2023-01-06 00:21:58 +01:00
dependabot[bot] 49c72744ca
Bump actions/checkout from 3.1.0 to 3.3.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.3.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.1.0...v3.3.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-05 22:03:42 +00:00
dependabot[bot] 76aa6e3adf
Bump ipython from 8.6.0 to 8.8.0
Bumps [ipython](https://github.com/ipython/ipython) from 8.6.0 to 8.8.0.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/8.6.0...8.8.0)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-03 22:03:07 +00:00
dependabot[bot] 879b2147c7
Bump numpy from 1.23.4 to 1.24.1
Bumps [numpy](https://github.com/numpy/numpy) from 1.23.4 to 1.24.1.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.23.4...v1.24.1)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-26 22:09:47 +00:00
dependabot[bot] b77df28864
Bump texttable from 1.6.4 to 1.6.7
Bumps [texttable](https://github.com/foutaise/texttable) from 1.6.4 to 1.6.7.
- [Release notes](https://github.com/foutaise/texttable/releases)
- [Changelog](https://github.com/foutaise/texttable/blob/master/CHANGELOG.md)
- [Commits](https://github.com/foutaise/texttable/compare/v1.6.4...v1.6.7)

---
updated-dependencies:
- dependency-name: texttable
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-23 22:03:16 +00:00
Zoe Braiterman 52750e7928
Rename readme.md to README.md 2022-11-19 22:55:52 -05:00
Ali Razmjoo 1ee00c892f
Merge pull request #606 from Mrinank-Bhowmick/pop3
Added pop3 brute force
2022-11-06 16:58:35 +01:00
Ali Razmjoo 4a9df726ad add pop3 ssl + small fix 2022-11-06 16:46:35 +01:00
Ali Razmjoo 3ab917b926
Merge pull request #619 from OWASP/dependabot/pip/ipython-8.6.0
Bump ipython from 8.5.0 to 8.6.0
2022-11-06 15:31:51 +01:00
Ali Razmjoo 6a9c80f40b
Update modules/brute/pop3.yaml 2022-11-06 00:35:58 +01:00
dependabot[bot] fd7a922f31
Bump ipython from 8.5.0 to 8.6.0
Bumps [ipython](https://github.com/ipython/ipython) from 8.5.0 to 8.6.0.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/8.5.0...8.6.0)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-31 22:29:41 +00:00
Mrinank Bhowmick ac05f9ed5d
Merge branch 'master' into pop3 2022-10-27 04:57:36 -04:00
Ali Razmjoo e9a40ac46b
Merge pull request #617 from OWASP/dependabot/pip/numpy-1.23.4
Bump numpy from 1.23.3 to 1.23.4
2022-10-17 23:40:54 +02:00
dependabot[bot] 7335d3cd8f
Bump numpy from 1.23.3 to 1.23.4
Bumps [numpy](https://github.com/numpy/numpy) from 1.23.3 to 1.23.4.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.23.3...v1.23.4)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-12 22:20:59 +00:00
Ali Razmjoo 7496ecd572
Merge pull request #611 from OWASP/snyk-fix-7221cf3795a5b997cf8e743eb0971b27
[Snyk] Security upgrade python from 3.11.0rc2 to 3.11.0rc2-slim
2022-10-09 12:53:50 +02:00
Mrinank Bhowmick cdc3005387
Merge branch 'master' into pop3 2022-10-09 06:11:11 -04:00
Ali Razmjoo 7bf152acb5
Merge branch 'master' into snyk-fix-7221cf3795a5b997cf8e743eb0971b27 2022-10-09 11:50:35 +02:00
Ali Razmjoo 80ea6728a1
Merge pull request #614 from OWASP/dependabot/github_actions/actions/checkout-3.1.0
Bump actions/checkout from 2 to 3.1.0
2022-10-09 11:50:18 +02:00
Ali Razmjoo a30f37bdc9
Merge pull request #613 from OWASP/dependabot/github_actions/docker/build-push-action-3
Bump docker/build-push-action from 2 to 3
2022-10-09 11:50:10 +02:00
Ali Razmjoo 57d439214b
Merge pull request #612 from OWASP/dependabot/github_actions/docker/setup-buildx-action-2
Bump docker/setup-buildx-action from 1 to 2
2022-10-09 11:50:01 +02:00
Ali Razmjoo e9f6fbd66a
Merge pull request #615 from OWASP/feature/code-cleanups
Small code refactoring
2022-10-09 11:48:55 +02:00
Ali Razmjoo bf8736eead Apply PEP8 2022-10-09 11:37:14 +02:00
dependabot[bot] f74380a2db
Bump actions/checkout from 2 to 3.1.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.1.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3.1.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-06 22:25:18 +00:00
dependabot[bot] 38878750e3
Bump docker/build-push-action from 2 to 3
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2 to 3.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-06 22:25:15 +00:00
dependabot[bot] 8f5461ea61
Bump docker/setup-buildx-action from 1 to 2
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 1 to 2.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-06 22:25:10 +00:00
Ali Razmjoo 89e7b5cb40 remove unused dependencies 2022-10-07 00:24:39 +02:00
Nils Franzen 8a7daa5e1c Removed pointless loop 2022-10-06 19:35:36 +02:00
Nils Franzen d5631b4273 Clean-up initialization of the NettackerModules class and moved socks_proxy to a separate file 2022-10-06 19:27:19 +02:00
Nils Franzen 28c5eb1b16 Refactored core.utility.expand_module_steps to make it easier to maintain and read 2022-10-06 19:12:43 +02:00
snyk-bot 01c5b3fff6
fix: Dockerfile to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-DEBIAN11-AOM-1290331
- https://snyk.io/vuln/SNYK-DEBIAN11-AOM-1298721
- https://snyk.io/vuln/SNYK-DEBIAN11-AOM-1300249
- https://snyk.io/vuln/SNYK-DEBIAN11-MARIADB105-2940588
- https://snyk.io/vuln/SNYK-DEBIAN11-MARIADB105-2940589
2022-10-06 09:19:24 +00:00
Mrinank Bhowmick da4473aa46
Merge branch 'master' into pop3 2022-10-06 02:01:48 -04:00
Ali Razmjoo e1fba7e5d7
Merge pull request #610 from OWASP/docker-publish
push new image to dockerhub from master
2022-10-06 02:07:49 +02:00
Ali Razmjoo fd503e2e92 push new image to dockerhub from master 2022-10-06 01:54:49 +02:00
Mrinank Bhowmick f47b73dff8
Merge branch 'master' into pop3 2022-10-04 07:21:33 -04:00
Ali Razmjoo 45dda887ea
Merge pull request #607 from OWASP/add_http_ssl_verify_in-modules
turn off ssl verification in http modules
2022-09-29 22:35:51 +02:00
Ali Razmjoo 60342ccafa turn off ssl verification in http modules 2022-09-29 22:16:41 +02:00
Mrinank-Bhowmick 8bcd0bfef3 Added pop3 brute force 2022-09-28 19:14:40 +05:30
Ali Razmjoo 70467c777e
Merge pull request #605 from OWASP/dependabot/pip/pyopenssl-22.1.0
Bump pyopenssl from 22.0.0 to 22.1.0
2022-09-27 23:49:13 +02:00
dependabot[bot] e4747032b7
Bump pyopenssl from 22.0.0 to 22.1.0
Bumps [pyopenssl](https://github.com/pyca/pyopenssl) from 22.0.0 to 22.1.0.
- [Release notes](https://github.com/pyca/pyopenssl/releases)
- [Changelog](https://github.com/pyca/pyopenssl/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/pyopenssl/compare/22.0.0...22.1.0)

---
updated-dependencies:
- dependency-name: pyopenssl
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-26 22:19:36 +00:00
Ali Razmjoo da126b3c07
Merge pull request #604 from OWASP/fix-library-name-issue
bug fix in protocol vs actual lib name
2022-09-26 19:16:40 +02:00
Ali Razmjoo 27f563e7f8 bug fix in protocol vs actual lib name 2022-09-26 18:33:35 +02:00
Sam Stepanyan 25f015d4cb
Merge pull request #602 from OWASP/dev-report
added copy to clipboard json_event
2022-09-26 13:18:08 +01:00
Sam Stepanyan efbf0d51e4
Merge branch 'master' into dev-report 2022-09-26 11:16:24 +01:00
itsdivyanshjain 0602baaba5 removed commented debug 2022-09-25 11:41:30 -04:00
itsdivyanshjain 121e6f1eb1 added copy to clipboard json_event 2022-09-25 10:08:12 -04:00
Ali Razmjoo 0e49c377e0
Merge pull request #600 from OWASP/codeql-1
Create codeql-analysis.yml
2022-09-25 14:09:35 +02:00
Ali Razmjoo 869ed25764 fix for Uncontrolled data used in path expression 2022-09-25 13:48:23 +02:00
Ali Razmjoo ceabd1b969
Create codeql-analysis.yml 2022-09-25 12:20:41 +02:00
Sam Stepanyan 02d56f1e6c
Merge pull request #592 from OWASP/dev-report
local html reports improved
2022-09-24 20:53:18 +01:00
Ali Razmjoo 58ec51736c
Merge branch 'master' into dev-report 2022-09-24 21:38:35 +02:00
Ali Razmjoo 19fad5c47c
Merge pull request #591 from OWASP/dependabot/docker/python-3.11.0rc2
Bump python from 3.10.0rc2 to 3.11.0rc2
2022-09-24 21:38:20 +02:00
Sam Stepanyan 2481e47acd
Merge branch 'master' into dev-report 2022-09-24 20:36:28 +01:00
Ali Razmjoo 7df6e9ca4f
Merge branch 'master' into dependabot/docker/python-3.11.0rc2 2022-09-24 20:47:42 +02:00
Ali Razmjoo 7a67fd2f99
Merge pull request #571 from OWASP/bug558
issue558 fix
2022-09-24 20:35:05 +02:00
Ali Razmjoo 80e6b317ad
Merge branch 'master' into dependabot/docker/python-3.11.0rc2 2022-09-24 20:01:38 +02:00
dependabot[bot] d3985a43af
Bump python from 3.10.0rc2 to 3.11.0rc2
Bumps python from 3.10.0rc2 to 3.11.0rc2.

---
updated-dependencies:
- dependency-name: python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-24 18:01:10 +00:00
Ali Razmjoo d79a49c1e7
Merge pull request #545 from OWASP/dependabot/github_actions/actions/checkout-3
Bump actions/checkout from 2 to 3
2022-09-24 20:01:08 +02:00
Ali Razmjoo 52830a4025
Merge pull request #590 from OWASP/dependabot/pip/flake8-5.0.4
Bump flake8 from 4.0.1 to 5.0.4
2022-09-24 20:00:33 +02:00
Ali Razmjoo cf7c9eec77
Update core/load_modules.py 2022-09-24 19:52:18 +02:00
Ali Razmjoo 3ca1d49869 Merge branch 'master' into bug558 2022-09-24 19:46:42 +02:00
Ali Razmjoo 752473623e
Merge branch 'master' into dev-report 2022-09-24 19:42:56 +02:00
Ali Razmjoo c54d73e95d
Merge branch 'master' into dependabot/github_actions/actions/checkout-3 2022-09-24 19:42:01 +02:00
Ali Razmjoo 95ca028907
Merge branch 'master' into dependabot/pip/flake8-5.0.4 2022-09-24 19:41:45 +02:00
Ali Razmjoo 191c466d27
Merge pull request #594 from OWASP/apiserverfix
open index.html by default
2022-09-24 18:15:10 +02:00
Sam Stepanyan 2b621d62c8
Merge branch 'master' into dev-report 2022-09-24 17:14:36 +01:00
Ali Razmjoo 9fa3eebfc6 open index.html by default 2022-09-24 17:07:28 +02:00
dependabot[bot] c400f42a76
Bump flake8 from 4.0.1 to 5.0.4
Bumps [flake8](https://github.com/pycqa/flake8) from 4.0.1 to 5.0.4.
- [Release notes](https://github.com/pycqa/flake8/releases)
- [Commits](https://github.com/pycqa/flake8/compare/4.0.1...5.0.4)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-24 14:59:09 +00:00
dependabot[bot] cf94e642a3
Bump actions/checkout from 2 to 3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-24 14:59:03 +00:00
Ali Razmjoo 0d601e1a91
Merge pull request #593 from OWASP/iohttp
replace requests with iohttp
2022-09-24 16:58:26 +02:00
Ali Razmjoo 594648c1c6 replace requests with iohttp
revert changes

minor issue fixed
2022-09-24 16:30:10 +02:00
itsdivyanshjain 3a7f9fb3d6 return of texttable by default 2022-09-18 10:40:37 -04:00
itsdivyanshjain c544ab4fbb improved html log by implementing html output encoding 2022-09-18 09:39:06 -04:00
itsdivyanshjain fae8f948b8 removed print 2022-09-18 08:16:40 -04:00
itsdivyanshjain 7eb5e5289f local html reports improved 2022-09-18 08:13:14 -04:00
Sam Stepanyan ea1892951d
Merge pull request #575 from OWASP/testing-new
Bug Fixes, New feature and Functionality and modules
2022-09-17 17:07:01 +01:00
itsdivyanshjain 07b78e832f updated web_technologies scan module 2022-09-17 08:54:00 -04:00
itsdivyanshjain c2acd1c88e improved log 2022-09-17 08:54:00 -04:00
itsdivyanshjain b724556289 improvise conditioning 2022-09-17 08:54:00 -04:00
divyansh 5ff0a6a80b waf log edit 2022-09-17 08:54:00 -04:00
divyansh 802d945959 updated waf module
this module is working well, but still requires improvement in handling logs and terminate the request if we get the desired results, instead of iterating the whole list of request urls.
2022-09-17 08:54:00 -04:00
divyansh 50fbd67637 updated subdomain-takeover module 2022-09-17 08:54:00 -04:00
divyansh ec9479c8a8 fixed logic bug finally 2022-09-17 08:54:00 -04:00
divyansh a995bd6302 new web technologies scanner module
This is also meant for testing purposes, it has false negative
2022-09-17 08:54:00 -04:00
divyansh c8b0025ab4 new WAF module with new mentioned functionality
meant for testing new functionalities and demonstration only, more WAF responses will be added soon
2022-09-17 08:53:59 -04:00
divyansh 7273e64e3f enhancements in logs in cli 2022-09-17 08:53:59 -04:00
divyansh 06490a4813 new feature: better approach for storing and showing logs
This is meant for report/show output we still require old storing functionality like events and results. This commit also include response_dependent function which similar to temp_dependent function but it does not store in db, mainly meant to use to replace a certain characters in logs. Demonstration in a modules going to be available in later commits.
2022-09-17 08:53:59 -04:00
divyansh db85f5a491 new feature: iterative_dictionary based response matching functionality
This is going to be helpful in new module like waf_scan, web_technologies_scan, subdomain_takeover_vuln. Demonstartion in modules going to available in later commits.
2022-09-17 08:53:59 -04:00
divyansh 7e72ee95c0 expanding the scope of temp_dependent_events to the response
require for new module and also it is good feature to have
2022-09-17 08:53:59 -04:00
divyansh d84bc51f42 changing return type to dict to match same as returning condition_results 2022-09-17 08:53:59 -04:00
divyansh 72de76fb0a fix conditioning bug
In module where there is or condition between status and header, and status is been match but not header, then it still don't return success
2022-09-17 08:53:59 -04:00
divyansh 93d651df38 fix bug in header match
when regex is .* in header and it follows else empty string which match header in false manner
2022-09-17 08:53:59 -04:00
Sam Stepanyan b6feb15d2b
Merge pull request #589 from OWASP/securestep9-patch-1
Updated readme.md with OWASP official DockerHub link
2022-09-11 18:38:35 +01:00
Sam Stepanyan 33817a7028
Update readme.md 2022-09-11 13:04:03 +01:00
Sam Stepanyan 30acf79c15
Merge pull request #587 from OWASP/dependabot/pip/ipython-8.5.0
Bump ipython from 7.30.1 to 8.5.0
2022-09-11 10:04:51 +01:00
dependabot[bot] 51823637e2
Bump ipython from 7.30.1 to 8.5.0
Bumps [ipython](https://github.com/ipython/ipython) from 7.30.1 to 8.5.0.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/7.30.1...8.5.0)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-11 08:50:23 +00:00
Sam Stepanyan 20bf496f26
Merge pull request #566 from OWASP/dependabot/pip/paramiko-2.11.0
Bump paramiko from 2.8.1 to 2.11.0
2022-09-11 09:49:39 +01:00
dependabot[bot] 818a29a043
Bump paramiko from 2.8.1 to 2.11.0
Bumps [paramiko](https://github.com/paramiko/paramiko) from 2.8.1 to 2.11.0.
- [Release notes](https://github.com/paramiko/paramiko/releases)
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/2.8.1...2.11.0)

---
updated-dependencies:
- dependency-name: paramiko
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-03 19:24:02 +00:00
Sam Stepanyan b53dbe3cbc
Merge pull request #583 from OWASP/dependabot/pip/flask-2.2.2
Bump flask from 2.0.2 to 2.2.2
2022-09-03 20:23:18 +01:00
dependabot[bot] 204ba6e33d
Bump flask from 2.0.2 to 2.2.2
Bumps [flask](https://github.com/pallets/flask) from 2.0.2 to 2.2.2.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/2.0.2...2.2.2)

---
updated-dependencies:
- dependency-name: flask
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-09 22:19:35 +00:00
Ali Razmjoo 4ec8fdd129
Merge pull request #576 from OWASP/dependabot/pip/numpy-1.23.1
Bump numpy from 1.21.4 to 1.23.1
2022-07-18 20:58:35 +02:00
dependabot[bot] f90a89865a
Bump numpy from 1.21.4 to 1.23.1
Bumps [numpy](https://github.com/numpy/numpy) from 1.21.4 to 1.23.1.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.21.4...v1.23.1)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-11 22:44:15 +00:00
divyansh 66a9e2d629 issue558 fix 2022-06-20 17:49:06 +05:30
Sam Stepanyan 6d1653df01
Merge pull request #556 from tristanlatr/patch-1
Fix typo
2022-06-17 10:34:02 +01:00
tristanlatr db443ff78a
Fix typo 2022-04-12 17:33:02 -04:00
Sam Stepanyan 0b79a5b4fc
Merge pull request #535 from OWASP/issue534
bug534 fix
2022-01-09 13:42:22 +00:00
divyansh 6d1c7c9140 bug534 fix 2022-01-08 08:24:38 +05:30
Ali Razmjoo 508f1d90b1
Merge pull request #522 from EFFLUX110/master
Updated Hindi language.
2021-12-18 13:39:08 +01:00
Ali Razmjoo 2ed04165d2
Merge pull request #523 from OWASP/log4j-CVE-2021-44228
possible race condition
2021-12-18 13:38:58 +01:00
Ali Razmjoo f3b613689d
Merge branch 'master' into log4j-CVE-2021-44228 2021-12-18 13:24:28 +01:00
Ali Razmjoo 09d4ac090d possible race condition 2021-12-18 12:42:48 +01:00
EFFLUX f2120a6baa Update readme.md 2021-12-17 16:01:43 +05:30
EFFLUX 24964dfc61 Update hi.yaml
Fixed Quotation error.
2021-12-17 15:48:23 +05:30
EFFLUX 184db93520 Update hi.yaml
Removed unwanted keywords from the file, which is not in use anymore in new version and added new keywords from en.yaml file.
2021-12-17 15:19:59 +05:30
Ali Razmjoo 8933e227b0
Merge pull request #521 from OWASP/log4j-CVE-2021-44228
fix race condition error and sorting steps
2021-12-17 02:21:14 +01:00
Ali Razmjoo f82c25d6e5
Merge pull request #520 from EFFLUX110/master
Created Bengali version for OWASP Nettacker project.
2021-12-17 02:06:18 +01:00
Ali Razmjoo 6089089d66 fix race condition error and sorting steps 2021-12-17 01:52:27 +01:00
EFFLUX 899bfc7b97 Update bn.yaml
Fixed some Quotation Error.
2021-12-16 23:51:28 +05:30
EFFLUX 07916ea985 Create bn.yaml
Created Bengali version for OWASP Nettacker project.
2021-12-16 22:47:25 +05:30
Ali Razmjoo 25e4a8e2bc
Merge pull request #519 from OWASP/log4j-CVE-2021-44228
Log4j CVE 2021 44228
2021-12-15 03:16:07 +01:00
Ali Razmjoo 0063a930f7 increase sleep time 2021-12-15 02:21:42 +01:00
Ali Razmjoo bebc72234f enhancements in log4j vuln fuzzer 2021-12-15 01:32:06 +01:00
Ali Razmjoo 9ce824a0cc
Merge pull request #518 from OWASP/log4j-CVE-2021-44228
Log4j CVE 2021 44228
2021-12-14 02:23:24 +01:00
Ali Razmjoo 6e304974b3 enhancement in log4j module 2021-12-14 02:10:54 +01:00
Ali Razmjoo cce3b90890
Merge pull request #517 from OWASP/log4j-CVE-2021-44228
Log4j CVE 2021 44228
2021-12-13 02:20:39 +01:00
Ali Razmjoo ad4d604168 retry to fix the deadlock 2021-12-13 02:13:28 +01:00
Ali Razmjoo a7f599963b remove headers which cause 400 error 2021-12-13 02:05:27 +01:00
Ali Razmjoo 8c4b87ef8c add more headers 2021-12-13 01:47:19 +01:00
Ali Razmjoo b085388e05 multi dependency on each request and fix race condition 2021-12-13 01:27:47 +01:00
Ali Razmjoo 831ec29175 bug fix in reading dependency 2021-12-12 20:38:12 +01:00
Ali Razmjoo 9c96a72c8c add log4j_cve_2021_44228_vuln 2021-12-12 20:38:00 +01:00
Ali Razmjoo 7c4bc706d0
Merge pull request #515 from OWASP/grafana_zeroday
new grafana zeroday module
2021-12-10 10:13:35 +01:00
Ali Razmjoo 96d376b23d
Update modules/vuln/grafana_cve_2021_43798.yaml 2021-12-10 10:12:58 +01:00
Ali Razmjoo 697ec574fb
Update modules/vuln/grafana_cve_2021_43798.yaml 2021-12-10 10:12:18 +01:00
Ali Razmjoo 895ba165ac
Update modules/vuln/grafana_cve_2021_43798.yaml 2021-12-09 17:20:58 +01:00
Ali Razmjoo b523dafcae
Rename grafana_zeroday.yaml to grafana_cve_2021_43798.yaml 2021-12-09 17:20:00 +01:00
divyansh ab66f7401a new grafana zeroday module 2021-12-07 23:16:30 +05:30
Ali Razmjoo 0b19ba5a69
Merge pull request #513 from OWASP/proto_early_break
auto service discovery
2021-12-05 16:13:16 +01:00
Ali Razmjoo 59f3b0486a load extra args types to affect modules 2021-12-05 11:53:47 +01:00
Ali Razmjoo 72adba9fa7 fix module input error 2021-12-05 11:41:10 +01:00
Ali Razmjoo 8c44b47885 add CI test 2021-12-05 00:31:40 +01:00
Ali Razmjoo 52a465a877 fix logical error in payload index 2021-12-05 00:25:55 +01:00
Ali Razmjoo 6139738c4a ignore core modules in discovery 2021-12-05 00:16:19 +01:00
Ali Razmjoo fb51ec51f8 convert dict to list in modules 2021-12-05 00:03:54 +01:00
Ali Razmjoo 14a5da32c7 remove debuging code 2021-12-04 23:56:09 +01:00
Ali Razmjoo 87a56ae7cc auto service discovery 2021-12-04 23:43:20 +01:00
Ali Razmjoo 615d908550
Merge pull request #502 from spiderxm/improve-web-console
Improvise things in web console
2021-12-04 14:52:57 +01:00
Ali Razmjoo da75203b75
Merge pull request #508 from EFFLUX110/master
Update en.yaml
2021-12-04 14:52:06 +01:00
Ali Razmjoo 727ab2ec4b
Merge pull request #512 from OWASP/dependabot/pip/ipython-7.30.1
Bump ipython from 7.30.0 to 7.30.1
2021-12-04 14:45:49 +01:00
dependabot[bot] 56e97f2c3b
Bump ipython from 7.30.0 to 7.30.1
Bumps [ipython](https://github.com/ipython/ipython) from 7.30.0 to 7.30.1.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/7.30.0...7.30.1)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-02 22:19:19 +00:00
Ali Razmjoo b5dc786d8a
Merge branch 'master' into master 2021-12-02 16:24:57 +01:00
Ali Razmjoo c232a57dd8
Merge branch 'master' into improve-web-console 2021-12-02 16:24:46 +01:00
Ali Razmjoo 9e2dce3f3d
Merge pull request #503 from spiderxm/server-fix
error handling when server fails to start
2021-12-02 16:21:11 +01:00
Ali Razmjoo e92360fb66
Merge pull request #511 from OWASP/dependabot/pip/ipython-7.30.0
Bump ipython from 7.28.0 to 7.30.0
2021-12-02 16:19:30 +01:00
Ali Razmjoo bac63b5ef2
Merge pull request #510 from OWASP/dependabot/pip/paramiko-2.8.1
Bump paramiko from 2.8.0 to 2.8.1
2021-12-02 16:19:23 +01:00
Ali Razmjoo d5a6834739
Merge pull request #506 from OWASP/dependabot/pip/numpy-1.21.4
Bump numpy from 1.21.3 to 1.21.4
2021-12-02 16:19:07 +01:00
dependabot[bot] 814073ee5b
Bump ipython from 7.28.0 to 7.30.0
Bumps [ipython](https://github.com/ipython/ipython) from 7.28.0 to 7.30.0.
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/7.28.0...7.30.0)

---
updated-dependencies:
- dependency-name: ipython
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-29 22:17:37 +00:00
dependabot[bot] b263a3ec84
Bump paramiko from 2.8.0 to 2.8.1
Bumps [paramiko](https://github.com/paramiko/paramiko) from 2.8.0 to 2.8.1.
- [Release notes](https://github.com/paramiko/paramiko/releases)
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/2.8.0...2.8.1)

---
updated-dependencies:
- dependency-name: paramiko
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-29 22:17:24 +00:00
EFFLUX bcfa286bea Update en.yaml
## Added Message

error_platform: "Unfortunately, this version of the software can run on Linux/darwin"
2021-11-12 23:05:17 +05:30
dependabot[bot] a61cb3b296
Bump numpy from 1.21.3 to 1.21.4
Bumps [numpy](https://github.com/numpy/numpy) from 1.21.3 to 1.21.4.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.21.3...v1.21.4)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-05 22:17:29 +00:00
mrigankanand 95dfc2d0ce error handling when server fails to start 2021-10-29 03:46:01 +05:30
mrigankanand 7fff5f62ef update project info in home screen 2021-10-29 01:19:54 +05:30
mrigankanand e56f352999 update a tag to open external urls in new tag 2021-10-29 01:17:53 +05:30
mrigankanand 072ecaa24e improve button styling 2021-10-29 01:17:21 +05:30
Ali Razmjoo 0d6a907f45
Merge pull request #501 from OWASP/dependabot/pip/numpy-1.21.3
Bump numpy from 1.21.2 to 1.21.3
2021-10-21 21:00:37 +02:00
dependabot[bot] 74e6e95ec9
Bump numpy from 1.21.2 to 1.21.3
Bumps [numpy](https://github.com/numpy/numpy) from 1.21.2 to 1.21.3.
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/HOWTO_RELEASE.rst.txt)
- [Commits](https://github.com/numpy/numpy/compare/v1.21.2...v1.21.3)

---
updated-dependencies:
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-20 22:17:13 +00:00
Ali Razmjoo f66a8eb9db
Merge pull request #500 from OWASP/enhacements
add new modules and fix a regex
2021-10-17 16:06:28 +02:00
Ali Razmjoo 3001e0d972 add hsts module 2021-10-17 15:59:59 +02:00
Ali Razmjoo c50b5da508 update module description and regex 2021-10-17 15:59:51 +02:00
Ali Razmjoo b4c8be7da5
Merge pull request #499 from OWASP/enhacements
modules bug fixes and enhacements
2021-10-16 17:05:34 +02:00
Ali Razmjoo 2ee70f8e8e modify tests in ci 2021-10-16 17:00:58 +02:00
Ali Razmjoo 6e4b8574d5 modules bug fixes and enhacements 2021-10-16 16:53:47 +02:00
Ali Razmjoo 67c5f6b698
Merge pull request #498 from OWASP/dependabot/pip/pyyaml-6.0
Bump pyyaml from 5.4.1 to 6.0
2021-10-14 22:53:50 +02:00
dependabot[bot] 7a4e3d98f9
Bump pyyaml from 5.4.1 to 6.0
Bumps [pyyaml](https://github.com/yaml/pyyaml) from 5.4.1 to 6.0.
- [Release notes](https://github.com/yaml/pyyaml/releases)
- [Changelog](https://github.com/yaml/pyyaml/blob/master/CHANGES)
- [Commits](https://github.com/yaml/pyyaml/compare/5.4.1...6.0)

---
updated-dependencies:
- dependency-name: pyyaml
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-13 22:17:29 +00:00
Ali Razmjoo 8d5a7bd7ba
Merge pull request #497 from OWASP/dependabot/pip/flake8-4.0.1
Bump flake8 from 3.9.2 to 4.0.1
2021-10-13 00:06:34 +02:00
Ali Razmjoo 23ca47aed3
Merge pull request #496 from OWASP/dependabot/pip/paramiko-2.8.0
Bump paramiko from 2.7.2 to 2.8.0
2021-10-13 00:06:17 +02:00
dependabot[bot] 1070118b6b
Bump flake8 from 3.9.2 to 4.0.1
Bumps [flake8](https://github.com/pycqa/flake8) from 3.9.2 to 4.0.1.
- [Release notes](https://github.com/pycqa/flake8/releases)
- [Commits](https://github.com/pycqa/flake8/compare/3.9.2...4.0.1)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-11 22:19:58 +00:00
dependabot[bot] 04b5bc5845
Bump paramiko from 2.7.2 to 2.8.0
Bumps [paramiko](https://github.com/paramiko/paramiko) from 2.7.2 to 2.8.0.
- [Release notes](https://github.com/paramiko/paramiko/releases)
- [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS)
- [Commits](https://github.com/paramiko/paramiko/compare/2.7.2...2.8.0)

---
updated-dependencies:
- dependency-name: paramiko
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-11 22:19:49 +00:00
Ali Razmjoo 27fa3ad335
Merge pull request #495 from OWASP/34370
new accela cve module
2021-10-09 19:05:06 +02:00
divyansh 753b1acafc new accela cve module 2021-10-08 17:29:20 +05:30
Ali Razmjoo 2e768f2494
Merge pull request #494 from OWASP/33473
new msexchange cve module
2021-10-08 13:40:20 +02:00
Ali Razmjoo 103fc0d83c
Update modules/vuln/msexchange_cve_2021_34473.yaml 2021-10-08 13:11:27 +02:00
divyansh b09d4c6bb1 no. fix 2021-10-08 16:38:29 +05:30
Ali Razmjoo 641a47bd72
Merge pull request #493 from OWASP/42013
new apache cve module
2021-10-08 13:05:29 +02:00
Ali Razmjoo de55ec6cad
Update modules/vuln/apache_cve_2021_42013.yaml 2021-10-08 13:05:14 +02:00
Ali Razmjoo ab78bc5819
Merge pull request #491 from OWASP/41878
new justwriting cve
2021-10-08 13:03:14 +02:00
divyansh e5196b84b8 new msexchange cve module 2021-10-08 16:26:07 +05:30
divyansh 19b907ec0d new apache cve module 2021-10-08 11:44:44 +05:30
divyansh 3258de637c new justwriting cve 2021-10-07 09:43:07 +05:30
Ali Razmjoo de2b0f9c64
Merge pull request #489 from OWASP/enhance-mp-mt
Enhance multi processing + http lib bug fixed
2021-10-06 18:43:09 +02:00
Ali Razmjoo 89ff9e2683 ssl support for port scan 2021-10-06 17:38:34 +02:00
Ali Razmjoo 60de3df223 fix regex gurock_testrail_cve_2021_40875_vuln 2021-10-06 16:41:45 +02:00
Ali Razmjoo 1557d05ded escape in comment 2021-10-06 16:15:12 +02:00
Ali Razmjoo 42a41dd597 disable security warning 2021-10-06 15:27:51 +02:00
Ali Razmjoo 2c2bb1d7f5 enforce module args for http 2021-10-06 15:22:59 +02:00
Ali Razmjoo 9ac0e334b0 simple enhancement in multiprocessing 2021-10-06 14:51:43 +02:00
Ali Razmjoo cf011a1643
Merge pull request #488 from OWASP/regex-fix
fix regex - python
2021-10-06 09:29:14 +02:00
Ali Razmjoo 33f7cf54bb fix regex - python 2021-10-06 09:28:49 +02:00
Ali Razmjoo ebdd9258cc
Merge pull request #487 from OWASP/41773
path fix
2021-10-06 08:34:13 +02:00
divyansh f93f61868d Merge branch 'master' of https://github.com/OWASP/nettacker into 41773 2021-10-06 09:17:49 +05:30
divyansh f198079ccd path fix 2021-10-06 09:16:10 +05:30
Ali Razmjoo 99283da039
Merge pull request #486 from OWASP/xss_regex_fix
xss_regex_fix
2021-10-06 00:37:06 +02:00
Ali Razmjoo 3627bbc8fb
Merge pull request #485 from OWASP/35265
new maxsite module
2021-10-06 00:36:33 +02:00
Ali Razmjoo d661386b66
Merge pull request #484 from OWASP/35336
new tieline cve module
2021-10-06 00:35:50 +02:00
Ali Razmjoo 590cc890bb
Merge pull request #483 from OWASP/35464
new forgerock openam module
2021-10-06 00:34:04 +02:00
Ali Razmjoo 905620ed17
Merge pull request #482 from OWASP/41773
new apache cve module
2021-10-06 00:33:35 +02:00
Ali Razmjoo cf399c1925 fix regex for lfi 2021-10-06 00:28:41 +02:00
Ali Razmjoo 850e8e92df enhacements 2021-10-06 00:27:41 +02:00
divyansh 34a8776a30 xss_regex_fix 2021-10-06 01:04:48 +05:30
divyansh 23e8c575a9 reference fix 2021-10-06 00:55:43 +05:30
divyansh 6c0fcabb0c regex fix 2021-10-06 00:52:42 +05:30
divyansh 7bfb44f3bd new maxsite module 2021-10-06 00:50:04 +05:30
divyansh b9007c907f new tieline cve module 2021-10-06 00:41:57 +05:30
divyansh b2d79f8dc2 edited profiles 2021-10-06 00:30:28 +05:30
divyansh a0707ba6de new forgerock openam module 2021-10-06 00:29:19 +05:30
divyansh ecb8dd5725 new apache cve module 2021-10-06 00:18:21 +05:30
Ali Razmjoo 787a9f6005
Merge pull request #481 from OWASP/3654
new novnc cve module
2021-10-05 16:13:37 +02:00
Ali Razmjoo c40c3d55c9
Update modules/vuln/novnc_cve_2021_3654.yaml 2021-10-05 16:13:06 +02:00
Ali Razmjoo f7e6b6ebe7
Merge pull request #480 from OWASP/41826
new placeos cve module
2021-10-05 16:12:10 +02:00
Ali Razmjoo 5f887a121d
Merge pull request #479 from OWASP/41649
new puneethreddy cve-41649 module
2021-10-05 16:11:17 +02:00
Ali Razmjoo 9101139745
Update modules/vuln/puneethreddyhc_sqli_cve_2021_41649.yaml 2021-10-05 16:11:06 +02:00
Ali Razmjoo 64d75795f8
Merge pull request #478 from OWASP/41648
New puneethreddy cve-41648 module
2021-10-05 16:09:45 +02:00
Ali Razmjoo f8bccfe05e
Merge pull request #477 from OWASP/dependabot/pip/flask-2.0.2
Bump flask from 2.0.1 to 2.0.2
2021-10-05 16:07:17 +02:00
divyansh ff78900626 allowed redirect 2021-10-05 11:30:53 +05:30
admin 9225cb3a57 new novnc cve module 2021-10-05 11:28:06 +05:30
admin ff08b945c0 new placeos cve module 2021-10-05 11:23:09 +05:30
admin 474feaecbf new puneethreddy cve module 2021-10-05 10:50:11 +05:30
admin 92f51a21c8 renamed 2021-10-05 10:46:16 +05:30
admin 50e86383ad Merge branch 'master' of https://github.com/OWASP/nettacker into 41648 2021-10-05 10:40:19 +05:30
admin cdf67f4ac3 new puneethreddy cve module 2021-10-05 10:39:29 +05:30
dependabot[bot] 36460883c6
Bump flask from 2.0.1 to 2.0.2
Bumps [flask](https://github.com/pallets/flask) from 2.0.1 to 2.0.2.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/2.0.1...2.0.2)

---
updated-dependencies:
- dependency-name: flask
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-04 22:15:48 +00:00
Ali Razmjoo da3d105a62
Merge pull request #476 from OWASP/37216
new qsan module
2021-10-04 19:19:43 +02:00
Ali Razmjoo 28e69eeadb
Merge pull request #474 from OWASP/37704
new phpinfo_cve
2021-10-04 19:19:33 +02:00
Ali Razmjoo 21e6c022f5
Merge pull request #473 from OWASP/37573
new tjws_cve module
2021-10-04 19:13:46 +02:00
Ali Razmjoo d5d09de0ac
Merge branch 'master' into 37216 2021-10-04 19:13:30 +02:00
Ali Razmjoo 6a499b803c
Update modules/vuln/qsan_storage_xss_cve_2021_37216.yaml 2021-10-04 19:11:35 +02:00
Ali Razmjoo 19e79bbfbe
Merge branch 'master' into 37704 2021-10-04 19:10:13 +02:00
Ali Razmjoo 5088c0f7b5
Update modules/vuln/phpinfo_cve_2021_37704.yaml 2021-10-04 19:10:00 +02:00
Ali Razmjoo 871b0e3a40
Merge branch 'master' into 37573 2021-10-04 19:06:53 +02:00
Ali Razmjoo 3bcf6fa4a8
Update modules/vuln/tjws_cve_2021_37573.yaml 2021-10-04 19:06:36 +02:00
Ali Razmjoo f51554944f
Merge pull request #475 from OWASP/37538
new prestashop_sqli module
2021-10-04 11:21:41 +02:00
admin 2a7039ea62 bug fix 2021-10-04 12:21:58 +05:30
admin 51dc0dc8f5 bug fix 2021-10-04 12:16:32 +05:30
admin 2b678d0024 new qsan module 2021-10-04 12:14:13 +05:30
admin a851870155 more spelling fixes 2021-10-04 12:05:02 +05:30
admin c2cdb789dd spelling fixes 2021-10-04 12:04:06 +05:30
admin c34e67556b spelling fixes 2021-10-04 12:02:16 +05:30
admin 440e4c358d new prestashop_sqli module 2021-10-04 12:00:48 +05:30
admin b043eff6ca new phpinfo_cve 2021-10-04 11:45:01 +05:30
admin cb68af768d new tjws_cve module 2021-10-04 11:34:10 +05:30
Ali Razmjoo 47aac611dd
Merge pull request #472 from OWASP/CVE-2021-1497
rename module
2021-10-02 17:06:14 +02:00
Ali Razmjoo 637855f53e rename module 2021-10-02 17:05:45 +02:00
880 changed files with 45020 additions and 6856 deletions

22
.coderabbit.yaml Normal file
View File

@ -0,0 +1,22 @@
chat:
auto_reply: true
code_generation:
docstrings:
language: en-US
early_access: true
language: en-US
reviews:
assess_linked_issues: true
auto_apply_labels: false
auto_review:
enabled: true
drafts: true
collapse_walkthrough: false
high_level_summary: true
high_level_summary_in_walkthrough: true
labeling_instructions: []
poem: false
profile: chill
request_changes_workflow: false
review_status: true
sequence_diagrams: false

View File

@ -1 +0,0 @@
### Mettacker's data path

View File

@ -1 +0,0 @@
### Nettacker's results path

View File

@ -1 +0,0 @@
### Nettacker's tmp path

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
*.py linguist-detectable=true
*.py linguist-language=Python
*.html linguist-detectable=false

6
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,6 @@
# People marked here will be automatically requested for a review.
#
# For more information on CODEOWNERS, see:
# https://help.github.com/en/articles/about-code-owners
* @arkid15r @securestep9

45
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,45 @@
<!--
Thanks for contributing to OWASP Nettacker!
-->
## Proposed change
<!--
Describe the big picture of your changes.
Don't forget to link your PR to an existing issue if any.
-->
Your PR description goes here.
## Type of change
<!--
Type of change you want to introduce. Please, check one (1) box only!
If your PR requires multiple boxes to be checked, most likely it needs to
be split into multiple PRs.
-->
- [ ] New core framework functionality
- [ ] Bugfix (non-breaking change which fixes an issue)
- [ ] Code refactoring without any functionality changes
- [ ] New or existing module/payload change
- [ ] Documentation/localization improvement
- [ ] Test coverage improvement
- [ ] Dependency upgrade
- [ ] Other improvement (best practice, cleanup, optimization, etc)
## Checklist
<!--
Put an `x` in the boxes that apply. You can change them after PR is created.
-->
- [ ] I've followed the [contributing guidelines][contributing-guidelines]
- [ ] I've run `make pre-commit`, it didn't generate any changes
- [ ] I've run `make test`, all tests passed locally
<!--
Thanks again for your contribution!
-->
[contributing-guidelines]: https://nettacker.readthedocs.io/en/latest/Developers/

View File

@ -1,46 +0,0 @@
# 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: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Build the code with docker
run: docker build . -t nettacker
- name: Lint
run: "docker run -e github_ci=true -v $(pwd):/usr/src/owaspnettacker --rm nettacker flake8 --extend-exclude
'*.txt,*.js,*.md,*.html' --count --select=E9,F63,F7,F82 --show-source"
- name: Help Menu
run: "docker run -e github_ci=true -v $(pwd):/usr/src/owaspnettacker --rm nettacker python nettacker.py --help"
- name: Help Menu in Persian
run: "docker run -e github_ci=true -v $(pwd):/usr/src/owaspnettacker --rm nettacker python nettacker.py --help
-L fa"
- name: Show all modules
run: "docker run -e github_ci=true -v $(pwd):/usr/src/owaspnettacker --rm nettacker python nettacker.py
--show-all-modules"
- name: Show all profiles
run: "docker run -e github_ci=true -v $(pwd):/usr/src/owaspnettacker --rm nettacker python nettacker.py --show-all-profiles"
- name: Test all modules command + check if it's finish successfully + without graph
run: "docker run -e github_ci=true -v $(pwd):/usr/src/owaspnettacker --rm -i nettacker python nettacker.py
-i 127.0.0.1 -u user1,user2 -p pass1,pass2 -m all -g 21,25,80,443 -t 1000 -T 3 -v"
- name: Test all modules command + check if it's finish successfully + without graph + Persian
run: "docker run -e github_ci=true -v $(pwd):/usr/src/owaspnettacker --rm -i nettacker python nettacker.py
-i 127.0.0.1 -L fa -u user1,user2 -p pass1,pass2 --profile all -g 21,25,80,443 -t 1000 -T 3 -v"
- name: Test all modules command + check if it's finish successfully + with graph + Persian
run: "docker run -e github_ci=true -v $(pwd):/usr/src/owaspnettacker --rm -i nettacker python nettacker.py -i
127.0.0.1 -L fa -u user1,user2 -p pass1,pass2 --profile all -g 21,25,80,443 -t 1000 -T 3
--graph d3_tree_v2_graph -v"

354
.github/workflows/ci_cd.yml vendored Normal file
View File

@ -0,0 +1,354 @@
name: CI/CD
on:
merge_group:
pull_request:
branches:
- master
push:
branches:
- master
tags:
- '*'
workflow_dispatch:
concurrency:
cancel-in-progress: true
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
jobs:
# Code quality checks.
pre-commit:
name: Run pre-commit
runs-on: ubuntu-24.04
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Run pre-commit
uses: pre-commit/action@v3.0.1
code-ql:
name: CodeQL
needs:
- pre-commit
permissions:
security-events: write
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
language:
- javascript
- python
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: /language:${{ matrix.language }}
# Code tests.
run-tests:
name: Run tests
needs:
- pre-commit
runs-on: ubuntu-24.04
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade poetry
poetry install --with test
- name: Run tests
run: |
poetry run pytest
build-package:
name: Build package
needs:
- run-tests
runs-on: ubuntu-24.04
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip poetry
poetry install
- name: Build package
run: |
poetry build --no-interaction
- name: Upload package artifacts
uses: actions/upload-artifact@v5
with:
name: dist
path: dist
test-build-package:
name: Test build on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: build-package
strategy:
matrix:
os:
- macos-latest
- ubuntu-24.04
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Get package artifacts
uses: actions/download-artifact@v6
with:
name: dist
path: dist
- name: Run tests
shell: bash
run: |
rm -rf nettacker
python -m pip install dist/*.whl
nettacker --version
python -m pip uninstall -y nettacker
python -m pip install dist/*.tar.gz
nettacker --version
# Docker related jobs.
test-docker-image:
name: Test Docker image
needs:
- run-tests
runs-on: ubuntu-24.04
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Build Docker image
run: docker build . -t nettacker
- name: Test help menu
run: |
docker run -e github_ci=true --rm nettacker --help
- name: Test help menu in Persian
run: |
docker run -e github_ci=true --rm nettacker --help -L fa
- name: Show all modules
run: |
docker run -e github_ci=true --rm nettacker --show-all-modules
- name: Show all profiles
run: |
docker run -e github_ci=true --rm nettacker --show-all-profiles
- name: Test all modules command + check if it's finish successfully + csv
run: |
docker run -e github_ci=true --rm -i --add-host=host.docker.internal:host-gateway nettacker \
-i host.docker.internal -u user1,user2 -p pass1,pass2 -m all -g 21,25,80,443 \
-t 1000 -T 3 -o out.csv
- name: Test all modules command + check if it's finish successfully + csv
run: |
docker run -e github_ci=true --rm -i --add-host=host.docker.internal:host-gateway nettacker \
-i host.docker.internal -u user1,user2 -p pass1,pass2 -m all -g 21,25,80,443 \
-t 1000 -T 3 -o out.csv --skip-service-discovery
- name: Test all modules command + check if it's finish successfully + with graph + Persian
run: |
docker run -e github_ci=true --rm -i --add-host=host.docker.internal:host-gateway nettacker \
-i host.docker.internal -L fa -u user1,user2 -p pass1,pass2 --profile all \
-g 21,25,80,443 -t 1000 -T 3 --graph d3_tree_v2_graph -v
- name: Test all modules command + check if it's finish successfully + with graph + Persian
run: |
docker run -e github_ci=true --rm -i --add-host=host.docker.internal:host-gateway nettacker \
-i host.docker.internal -L fa -u user1,user2 -p pass1,pass2 --profile all \
-g 21,25,80,443 -t 1000 -T 3 --graph d3_tree_v2_graph -v --skip-service-discovery
test-docker-image-build:
name: Test Docker ${{ matrix.docker-version }} image build
needs:
- run-tests
runs-on: ubuntu-24.04
strategy:
matrix:
docker-version:
- '27.5.0-1~ubuntu.24.04~noble'
- '26.1.4-1~ubuntu.24.04~noble'
- '26.0.0-1~ubuntu.24.04~noble'
steps:
- name: Uninstall pre-installed Docker
run: |
sudo apt-get remove docker-ce docker-ce-cli
# https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository
- name: Install Docker ${{ matrix.docker-version }}
run: |
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce=5:${{ matrix.docker-version }} docker-ce-cli=5:${{ matrix.docker-version }}
- name: Check out repository
uses: actions/checkout@v5
- name: Print Docker version
run: docker -v
- name: Build Nettacker image
run: docker build . -t nettacker
publish-nettacker-dev-to-docker-registry:
name: Publish nettacker:dev Docker image
if: |
github.repository == 'owasp/nettacker' &&
github.event_name == 'push' &&
github.ref_name == 'master'
needs:
- test-docker-image
- test-docker-image-build
runs-on: ubuntu-24.04
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
push: true
tags: owasp/nettacker:dev
publish-nettacker-latest-to-docker-registry:
name: Publish nettacker:latest Docker image
if: |
github.repository == 'owasp/nettacker' &&
github.event_name == 'push' &&
startsWith(github.event.ref, 'refs/tags/v')
needs:
- test-docker-image
- test-docker-image-build
runs-on: ubuntu-24.04
steps:
- name: Check out repository
uses: actions/checkout@v5
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
push: true
tags: owasp/nettacker:latest
publish-to-test-pypi:
name: Publish Test PyPI package
if: |
github.repository == 'OWASP/Nettacker' &&
github.event_name == 'push' &&
github.ref_name == 'master'
environment: dev
needs:
- test-build-package
permissions:
contents: read
id-token: write
runs-on: ubuntu-24.04
steps:
- name: Get package artifacts
uses: actions/download-artifact@v6
with:
name: dist
path: dist
- name: Publish package distributions to Test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
skip-existing: true
publish-to-pypi:
name: Publish PyPI package
if: |
github.repository == 'OWASP/Nettacker' &&
github.event_name == 'push' &&
startsWith(github.event.ref, 'refs/tags/')
environment: release
needs:
- test-build-package
permissions:
contents: read
id-token: write
runs-on: ubuntu-24.04
steps:
- name: Get package artifacts
uses: actions/download-artifact@v6
with:
name: dist
path: dist
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

11
.gitignore vendored
View File

@ -3,10 +3,12 @@
#ignore IDE settings
*.idea*
*.vscode*
*.code-workspace
#setup
build/*
dist/*
build
dist
*egg-info*
#tmp files
@ -17,7 +19,10 @@ logs.txt
*.log
results.*
.owasp-nettacker*
.nettacker/data*
.data*
*.sarif
*.dd.json
*.DS_Store
*.swp
@ -25,4 +30,4 @@ results.*
.coverage
coverage.xml
venv/*
venv

26
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,26 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-ast
- id: check-builtin-literals
- id: check-yaml
- id: fix-encoding-pragma
args:
- --remove
- id: mixed-line-ending
args:
- --fix=lf
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.13
hooks:
- id: ruff
args:
- --fix
- id: ruff-format

19
.readthedocs.yml Normal file
View File

@ -0,0 +1,19 @@
# Read the Docs configuration file for MkDocs projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.12"
mkdocs:
configuration: mkdocs.yml
python:
install:
- requirements: docs/requirements.txt

32
ADOPTERS.md Normal file
View File

@ -0,0 +1,32 @@
# Adopters
This document highlights organizations, projects, and individuals using OWASP Nettacker in their security workflows.
## Why list adopters?
Showcasing adoption encourages community engagement, provides credibility, and helps new users discover real-world use cases.
## How to add yourself
If you or your organization use OWASP Nettacker, please:
1. Fork this repository.
2. Add your name, logo, and a short description below.
3. Submit a pull request.
## Organizations
| Logo | Name | Description | Website |
| ---- | ---- | ----------- | ------- |
| <!-- ![Acme Logo](path/to/logo.png) --> | **Example Acme Corp** | Uses Nettacker for automated penetration testing. | https://acme.example.com |
| <!-- ![SecurityCo Logo](path/to/securityco-logo.png) --> | **Example SecurityCo** | Integrates Nettacker into their CI/CD pipeline for continuous security assessment. | https://securityco.example.org |
## Community Projects
- **Example project X** — integrates Nettacker for infrastructure scanning in Kubernetes environments.
- **Example tool** — extends Nettacker modules for custom vulnerability detection.
## Individuals
- **Alice Smith example person** — security researcher (Twitter: @alice)
## Thank You
Thanks to everyone using and contributing to OWASP Nettacker! We appreciate your support and feedback.

41
AGENTS.md Normal file
View File

@ -0,0 +1,41 @@
<!--
Think of AGENTS.md as a README for AI agents: a dedicated, predictable place to provide the context and instructions to help AI coding agents work on your project.
See https://agents.md for more info
-->
# Repository Guidelines
## Project Structure & Module Organization
- Source: `nettacker/` (CLI: `nettacker/main.py`, API: `nettacker/api/`, core libs: `nettacker/core/`, modules: `nettacker/modules/`).
- Entry points: `nettacker.py` (Python) and `poetry` script `nettacker`.
- Tests: `tests/` (mirrors package layout: `tests/core/`, `tests/lib/`, etc.).
- Docs & assets: `docs/`, `nettacker/web/static/`.
- Runtime data (not for commit): `.nettacker/data/` (DB at `.nettacker/data/nettacker.db`, results in `.nettacker/data/results/`).
## Build, Test, and Development Commands
- Install: `poetry install` (uses `pyproject.toml`).
- Lint/format (all hooks): `make pre-commit` or `pre-commit run --all-files`.
- Tests: `make test` or `poetry run pytest` (coverage configured via `pyproject.toml`).
- Run CLI: `poetry run nettacker --help` or `python nettacker.py --help`.
- Docker (web UI): `docker-compose up`.
## Coding Style & Naming Conventions
- Python 3.93.12 supported. Use 4-space indents.
- Line length: 99 chars (`ruff`, `ruff-format`, `isort` profile=black).
- Names: modules/files `lower_snake_case`; functions/vars `lower_snake_case`; classes `PascalCase`; constants `UPPER_SNAKE_CASE`.
- Keep functions small, typed where practical, and add docstrings for public APIs.
## Testing Guidelines
- Framework: `pytest` (+ `pytest-asyncio`, `xdist`).
- Location/pattern: place tests under `tests/`; name files `test_*.py`; parametrize where useful.
- Coverage: enforced via `--cov=nettacker` (see `tool.pytest.ini_options`). Add tests with new features and for bug fixes.
- Run subsets: `poetry run pytest -k <expr>`.
## Commit & Pull Request Guidelines
- Commit messages: imperative tense, concise subject; reference issues (`Fixes #123`).
- Before pushing: `pre-commit run --all-files` and `make test` must pass.
- PRs: include a clear description, rationale, linked issue(s), test evidence (logs or screenshots for web UI), and update docs if behavior changes.
## Security & Configuration Tips
- Legal/ethics: only scan assets you are authorized to test.
- Secrets: never commit API keys, DBs, or results; `.nettacker/data/` is runtime-only.
- Config: defaults in `nettacker/config.py` (API key, DB path, paths). Review sensitive headers list before logging.

View File

@ -1,12 +1,53 @@
FROM python:3.10.0rc2
RUN apt update
### Multi-stage Dockerfile
# Define the base image only once as a build argument
ARG PYTHON_IMAGE=python:3.11.13-slim
### Build stage
FROM ${PYTHON_IMAGE} AS builder
### Install OS dependencies and poetry package manager
RUN apt-get update && \
apt-get install -y gcc libssl-dev && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
pip install --upgrade pip poetry
WORKDIR /usr/src/owaspnettacker
COPY . .
RUN mkdir -p .data/results
RUN apt-get update
RUN apt-get install -y < requirements-apt-get.txt
RUN pip3 install --upgrade pip
RUN pip3 install -r requirements.txt
RUN pip3 install -r requirements-dev.txt
# Copy dependency files first to maximize Docker cache usage for installing dependencies
COPY poetry.lock pyproject.toml ./
# Install dependencies
RUN poetry config virtualenvs.in-project true && \
poetry install --no-cache --no-root --without dev --without test
# Now copy the rest of the required source code
COPY nettacker nettacker
COPY nettacker.py README.md ./
# Build the project only after all code is present
RUN poetry build
### Runtime stage - start from a clean Python image
FROM ${PYTHON_IMAGE} AS runtime
WORKDIR /usr/src/owaspnettacker
# OCI Labels (attach to final image)
LABEL org.opencontainers.image.title="OWASP Nettacker" \
org.opencontainers.image.description="Automated Penetration Testing Framework" \
org.opencontainers.image.url="https://owasp.org/nettacker" \
org.opencontainers.image.source="https://github.com/OWASP/Nettacker" \
org.opencontainers.image.licenses="Apache-2.0"
### Bring from 'builder' just the virtualenv and the packaged Nettacker as a wheel
COPY --from=builder /usr/src/owaspnettacker/.venv ./.venv
COPY --from=builder /usr/src/owaspnettacker/dist/*.whl .
ENV PATH=/usr/src/owaspnettacker/.venv/bin:$PATH
### Use pip inside the venv to install just the nettacker wheel saving 50%+ space
RUN pip install --no-deps --no-cache-dir nettacker-*.whl && \
rm -f nettacker-*.whl
### We now have Nettacker installed in the virtualenv with 'nettacker' command which is the new entrypoint
ENV docker_env=true
CMD [ "python3", "./nettacker.py" ]
ENTRYPOINT [ "nettacker" ]
CMD ["--help"]

5
Makefile Normal file
View File

@ -0,0 +1,5 @@
pre-commit:
pre-commit run --all-files
test:
poetry run pytest

View File

@ -1,16 +0,0 @@
#### Checklist
- [ ] I have followed the [Contributor Guidelines](https://github.com/OWASP/Nettacker/wiki/Developers#contribution-guidelines).
- [ ] The code has been thoroughly tested in my local development environment with flake8 and pylint.
- [ ] The code is Python 3 compatible.
- [ ] The code follows the PEP8 styling guidelines with 4 spaces indentation.
- [ ] This Pull Request relates to only one issue or only one feature
- [ ] I have referenced the corresponding issue number in my commit message
- [ ] I have added the relevant documentation.
- [ ] My branch is up-to-date with the Upstream master branch.
#### Changes proposed in this pull request
#### Your development environment
- OS: `x`
- OS Version: `x`
- Python Version: `x`

129
README.md Normal file
View File

@ -0,0 +1,129 @@
OWASP Nettacker
=========
[![Build Status](https://github.com/OWASP/Nettacker/actions/workflows/ci_cd.yml/badge.svg?branch=master)](https://github.com/OWASP/Nettacker/actions/workflows/ci_cd.yml/badge.svg?branch=master)
[![Apache License](https://img.shields.io/badge/License-Apache%20v2-green.svg)](https://github.com/OWASP/Nettacker/blob/master/LICENSE)
[![Twitter](https://img.shields.io/badge/Twitter-@iotscan-blue.svg)](https://twitter.com/iotscan)
![GitHub contributors](https://img.shields.io/github/contributors/OWASP/Nettacker)
[![Documentation Status](https://readthedocs.org/projects/nettacker/badge/?version=latest)](https://nettacker.readthedocs.io/en/latest/?badge=latest)
[![repo size ](https://img.shields.io/github/repo-size/OWASP/Nettacker)](https://github.com/OWASP/Nettacker)
[![Docker Pulls](https://img.shields.io/docker/pulls/owasp/nettacker)](https://hub.docker.com/r/owasp/nettacker)
<img src="https://raw.githubusercontent.com/OWASP/Nettacker/master/nettacker/web/static/img/owasp-nettacker.png" width="200"><img src="https://raw.githubusercontent.com/OWASP/Nettacker/master/nettacker/web/static/img/owasp.png" width="500">
**DISCLAIMER**
* ***THIS SOFTWARE WAS CREATED FOR AUTOMATED PENETRATION TESTING AND INFORMATION GATHERING. YOU MUST USE THIS SOFTWARE IN A RESPONSIBLE AND ETHICAL MANNER. DO NOT TARGET SYSTEMS OR APPLICATIONS WITHOUT OBTAINING PERMISSIONS OR CONSENT FROM THE SYSTEM OWNERS OR ADMINISTRATORS. CONTRIBUTORS WILL NOT BE RESPONSIBLE FOR ANY ILLEGAL USAGE.***
![2018-01-19_0-45-07](https://user-images.githubusercontent.com/7676267/35123376-283d5a3e-fcb7-11e7-9b1c-92b78ed4fecc.gif)
OWASP Nettacker is an open-source, Python-based automated penetration testing and information-gathering framework designed to help cyber security professionals and ethical hackers perform reconnaissance, vulnerability assessments, and network security audits efficiently. Nettacker automates tasks like port scanning, service detection, subdomain enumeration, network mapping, vulnerability scanning, credential brute-force testing making it a powerful tool for identifying weaknesses in networks, web applications, IoT devices and APIs.
### Key Features
- **Modular architecture** - Each task — like port scanning, directory discovery, subdomain enumeration, vulnerability checks, or credential brute-forcing - is implemented as its own module, giving you control over what runs.
- **Multi-protocol & multithreaded scanning** - Supports HTTP/HTTPS, FTP, SSH, SMB, SMTP, ICMP, TELNET, XML-RPC, and can run scans in parallel for speed.
- **Comprehensive output** - Export reports in HTML, JSON, CSV, and plain text.
- **Built-in database & drift detection** - Stores past scans in the database for easy search and comparison with current results: useful to detect new hosts, open ports, or vulnerabilities in CI/CD pipelines.
- **CLI, REST API & Web UI** - Offers both programmatic integration and a user-friendly web interface for defining scans and viewing results.
- **Evasion techniques** - Enables configurable delays, proxy support, and randomized user-agents to reduce detection by firewalls or IDS systems.
- **Flexible targets** - Accepts single IPv4s, IP ranges, CIDR blocks, domain names, and full HTTP/HTTPS URLs. Targets can be mixed in a single command or loaded from a file using the `-l/--targets-list` flag.
### Use Cases
- **Penetration Testing**
Automate reconnaissance, misconfiguration checks, service discovery, and vulnerability scanning to support efficient and repeatable penetration testing workflows.
- **Recon & Vulnerability Assessment**
Map live hosts, open ports, services, default credentials, and directories, then perform credential brute-forcing or fuzzing using built-in or custom wordlists.
- **Attack Surface Mapping**
Discover exposed hosts, ports, subdomains, and services quickly using built-in enumeration modules—ideal for both internal and external assets.
- **Bug Bounty Recon**
Automate and scale common reconnaissance tasks like subdomain enumeration, directory brute-forcing, and default credential checks to speed up finding targets.
- **Network Vulnerability Scanning**
Efficiently scan IPs, IP ranges, or entire CIDR blocks or all subdmains of the organisation in parallel using a modular, multithreaded approach for large-scale network assessments.
- **Shadow IT & Asset Discovery**
Use historical scan data and drift detection to uncover unmanaged or forgotten hosts, open ports/services, and subdomains appearing over time.
- **CI/CD & Compliance Monitoring**
Integrate Nettacker into pipelines to track infrastructure changes and detect new vulnerabilities via stored scan history and comparison features.
### Links
* OWASP Nettacker Project Home Page: https://owasp.org/nettacker
* Documentation: https://nettacker.readthedocs.io
* Slack: [#project-nettacker](https://owasp.slack.com/archives/CQZGG24FQ) on https://owasp.slack.com
* Installation: https://nettacker.readthedocs.io/en/latest/Installation
* Usage: https://nettacker.readthedocs.io/en/latest/Usage
* GitHub repo: https://github.com/OWASP/Nettacker
* Docker Image: https://hub.docker.com/r/owasp/nettacker
* How to use the Dockerfile: https://nettacker.readthedocs.io/en/latest/Installation/#install-nettacker-using-docker
* OpenHub: https://www.openhub.net/p/OWASP-Nettacker
* **Donate**: https://owasp.org/donate/?reponame=www-project-nettacker&title=OWASP+Nettacker
* **Read More**: https://www.secologist.com/open-source-projects
____________
Quick Setup & Run
============
### CLI (Docker)
```bash
# Basic port scan on a single IP address:
$ docker run owasp/nettacker -i 192.168.0.1 -m port_scan
# Scan the entire Class C network for any devices with port 22 open:
$ docker run owasp/nettacker -i 192.168.0.0/24 -m port_scan -g 22
# Scan all subdomains of 'owasp.org' for http/https services and return HTTP status code
$ docker run owasp/nettacker -i owasp.org -d -s -m http_status_scan
# Display Help
$ docker run owasp/nettacker --help
```
### Web UI (Docker)
```bash
$ docker-compose up
```
* Use the API Key displayed in the CLI to login to the Web GUI
* Web GUI is accessible from your (https://localhost:5000) or https://nettacker-api.z3r0d4y.com:5000/ (pointed to your localhost)
* The local database is `.nettacker/data/nettacker.db` (sqlite).
* Default results path is `.nettacker/data/results`
* `docker-compose` will share your nettacker folder, so you will not lose any data after `docker-compose down`
* To see the API key in you can also run `docker logs nettacker_nettacker`.
* More details and install without docker https://nettacker.readthedocs.io/en/latest/Installation
_____________
Thanks to our awesome contributors!
============
OWASP Nettacker is an open-source project, built on the principles of collaboration and shared knowledge. The vibrant OWASP community contributes to its development, ensuring that the tool remains up-to-date, adaptable, and aligned with the latest security practices. Thanks to all our awesome contributors! 🚀
![Awesome Contributors](https://contrib.rocks/image?repo=OWASP/Nettacker)
## Adopters
Were grateful to the organizations, community projects, and individuals who adopt and rely on OWASP Nettacker for their security workflows.
If youre using OWASP Nettacker in your organization or project, wed love to hear from you! Feel free to add your details to the [ADOPTERS.md](ADOPTERS.md) file by submitting a pull request or reach out to us via GitHub issues. Lets showcase how Nettacker is making a difference in the security community!
See [ADOPTERS.md](ADOPTERS.md) for details.
_____________
## ***Google Summer of Code (GSoC) Project***
* ☀️ OWASP Nettacker Project is participating in the Google Summer of Code Initiative
* 🙏 Thanks to Google Summer of Code Initiative and all the students who contributed to this project during their summer breaks:
<a href="https://summerofcode.withgoogle.com"><img src="https://betanews.com/wp-content/uploads/2016/03/vertical-GSoC-logo.jpg" width="200"></img></a>
_____________
## Stargazers over time
[![Stargazers over time](https://starchart.cc/OWASP/Nettacker.svg)](https://starchart.cc/OWASP/Nettacker)
<img alt="" referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=8e922d16-445a-4c63-b4cf-5152fbbaf7fd" />

11
SECURITY.md Normal file
View File

@ -0,0 +1,11 @@
# Security Policy
## Supported Versions
The latest release and the current master branch
## Reporting a Vulnerability
Report a vulnerability to the project maintainers by raising a security advisory [here](https://github.com/OWASP/Nettacker/security/advisories/new)
## Contacting Maintainers
The Project Leaders are listed on the OWASP Nettacker Project page here: [https://owasp.org/nettacker](https://owasp.org/nettacker)

View File

@ -1,3 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
pass

View File

@ -1,631 +0,0 @@
# !/usr/bin/env python
# -*- coding: utf-8 -*-
import multiprocessing
import time
import random
import csv
import json
import string
import os
import copy
from types import SimpleNamespace
from database.db import create_connection, get_logs_by_scan_unique_id
from database.models import Report
from flask import Flask
from flask import jsonify
from flask import request as flask_request
from flask import render_template
from flask import abort
from flask import Response
from flask import make_response
from core.alert import write_to_api_console
from core.alert import messages
from core.die import die_success
from core.time import now
from api.api_core import structure
from api.api_core import get_value
from api.api_core import get_file
from api.api_core import mime_types
from api.api_core import scan_methods
from api.api_core import profiles
from api.api_core import graphs
from api.api_core import languages_to_country
from api.api_core import api_key_is_valid
from database.db import select_reports
from database.db import get_scan_result
from database.db import last_host_logs
from database.db import logs_to_report_json
from database.db import search_logs
from database.db import logs_to_report_html
from config import nettacker_global_config
from core.scan_targers import start_scan_processes
from core.args_loader import check_all_required
app = Flask(
__name__,
template_folder=nettacker_global_config()['nettacker_paths']['web_static_files_path']
)
app.config.from_object(__name__)
nettacker_application_config = nettacker_global_config()['nettacker_user_application_config']
nettacker_application_config.update(nettacker_global_config()['nettacker_api_config'])
del nettacker_application_config['api_access_key']
@app.errorhandler(400)
def error_400(error):
"""
handle the 400 HTTP error
Args:
error: the flask error
Returns:
400 JSON error
"""
return jsonify(
structure(
status="error",
msg=error.description
)
), 400
@app.errorhandler(401)
def error_401(error):
"""
handle the 401 HTTP error
Args:
error: the flask error
Returns:
401 JSON error
"""
return jsonify(
structure(
status="error",
msg=error.description
)
), 401
@app.errorhandler(403)
def error_403(error):
"""
handle the 403 HTTP error
Args:
error: the flask error
Returns:
403 JSON error
"""
return jsonify(
structure(
status="error",
msg=error.description
)
), 403
@app.errorhandler(404)
def error_404(error):
"""
handle the 404 HTTP error
Args:
error: the flask error
Returns:
404 JSON error
"""
return jsonify(
structure(
status="error",
msg=messages("not_found")
)
), 404
@app.before_request
def limit_remote_addr():
"""
check if IP filtering applied and API address is in whitelist
Returns:
None if it's in whitelist otherwise abort(403)
"""
# IP Limitation
if app.config["OWASP_NETTACKER_CONFIG"]["api_client_whitelisted_ips"]:
if flask_request.remote_addr not in app.config["OWASP_NETTACKER_CONFIG"]["api_client_whitelisted_ips"]:
abort(403, messages("unauthorized_IP"))
return
@app.after_request
def access_log(response):
"""
if access log enabled, its writing the logs
Args:
response: the flask response
Returns:
the flask response
"""
if app.config["OWASP_NETTACKER_CONFIG"]["api_access_log"]:
log_request = open(
app.config["OWASP_NETTACKER_CONFIG"]["api_access_log"],
"ab"
)
log_request.write(
"{0} [{1}] {2} \"{3} {4}\" {5} {6} {7}\r\n".format(
flask_request.remote_addr,
now(),
flask_request.host,
flask_request.method,
flask_request.full_path,
flask_request.user_agent,
response.status_code,
json.dumps(flask_request.form)
).encode()
)
log_request.close()
return response
@app.route("/", defaults={"path": ""})
@app.route("/<path:path>")
def get_statics(path):
"""
getting static files and return content mime types
Args:
path: path and filename
Returns:
file content and content type if file found otherwise abort(404)
"""
static_types = mime_types()
return Response(
get_file(
os.path.join(
nettacker_global_config()['nettacker_paths']['web_static_files_path'],
path
)
),
mimetype=static_types.get(
os.path.splitext(path)[1],
"text/html"
)
)
@app.route("/", methods=["GET", "POST"])
def index():
"""
index page for WebUI
Returns:
rendered HTML page
"""
from config import nettacker_user_application_config
filename = nettacker_user_application_config()["report_path_filename"]
return render_template(
"index.html",
selected_modules=scan_methods(),
profile=profiles(),
languages=languages_to_country(),
graphs=graphs(),
filename=filename
)
@app.route("/new/scan", methods=["GET", "POST"])
def new_scan():
"""
new scan through the API
Returns:
a JSON message with scan details if success otherwise a JSON error
"""
api_key_is_valid(app, flask_request)
form_values = dict(flask_request.form)
for key in nettacker_application_config:
if key not in form_values:
form_values[key] = nettacker_application_config[key]
options = check_all_required(
None,
api_forms=SimpleNamespace(**copy.deepcopy(form_values))
)
app.config["OWASP_NETTACKER_CONFIG"]["options"] = options
new_process = multiprocessing.Process(target=start_scan_processes, args=(options,))
new_process.start()
return jsonify(
vars(
options
)
), 200
@app.route("/session/check", methods=["GET"])
def session_check():
"""
check the session if it's valid
Returns:
a JSON message if it's valid otherwise abort(401)
"""
api_key_is_valid(app, flask_request)
return jsonify(
structure(
status="ok",
msg=messages("browser_session_valid")
)
), 200
@app.route("/session/set", methods=["GET", "POST"])
def session_set():
"""
set session on the browser
Returns:
200 HTTP response if session is valid and a set-cookie in the
response if success otherwise abort(403)
"""
api_key_is_valid(app, flask_request)
res = make_response(
jsonify(
structure(
status="ok",
msg=messages("browser_session_valid")
)
)
)
res.set_cookie("key", value=app.config["OWASP_NETTACKER_CONFIG"]["api_access_key"])
return res
@app.route("/session/kill", methods=["GET"])
def session_kill():
"""
unset session on the browser
Returns:
a 200 HTTP response with set-cookie to "expired"
to unset the cookie on the browser
"""
res = make_response(
jsonify(
structure(
status="ok",
msg=messages("browser_session_killed")
)
)
)
res.set_cookie("key", "", expires=0)
return res
@app.route("/results/get_list", methods=["GET"])
def get_results():
"""
get list of scan's results through the API
Returns:
an array of JSON scan's results if success otherwise abort(403)
"""
api_key_is_valid(app, flask_request)
page = get_value(flask_request, "page")
if not page:
page = 1
return jsonify(
select_reports(
int(page)
)
), 200
@app.route("/results/get", methods=["GET"])
def get_result_content():
"""
get a result HTML/TEXT/JSON content
Returns:
content of the scan result
"""
api_key_is_valid(app, flask_request)
scan_id = get_value(flask_request, "id")
if not scan_id:
return jsonify(
structure(
status="error",
msg=messages("invalid_scan_id")
)
), 400
filename, file_content = get_scan_result(scan_id)
return Response(
file_content,
mimetype=mime_types().get(
os.path.splitext(filename)[1],
"text/plain"
),
headers={
'Content-Disposition': 'attachment;filename=' + filename.split('/')[-1]
}
)
@app.route("/results/get_json", methods=["GET"])
def get_results_json():
"""
get host's logs through the API in JSON type
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
session = create_connection()
result_id = get_value(flask_request, "id")
if not result_id:
return jsonify(
structure(
status="error",
msg=messages("invalid_scan_id")
)
), 400
scan_details = session.query(Report).filter(Report.id == result_id).first()
json_object = json.dumps(
get_logs_by_scan_unique_id(
scan_details.scan_unique_id
)
)
filename = ".".join(scan_details.report_path_filename.split('.')[:-1])[1:] + '.json'
return Response(
json_object,
mimetype='application/json',
headers={
'Content-Disposition': 'attachment;filename=' + filename
}
)
@app.route("/results/get_csv", methods=["GET"])
def get_results_csv(): # todo: need to fix time format
"""
get host's logs through the API in JSON type
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
session = create_connection()
result_id = get_value(flask_request, "id")
if not result_id:
return jsonify(
structure(
status="error",
msg=messages("invalid_scan_id")
)
), 400
scan_details = session.query(Report).filter(Report.id == result_id).first()
data = get_logs_by_scan_unique_id(scan_details.scan_unique_id)
keys = data[0].keys()
filename = ".".join(scan_details.report_path_filename.split('.')[:-1])[1:] + '.csv'
with open(filename, "w") as report_path_filename:
dict_writer = csv.DictWriter(
report_path_filename,
fieldnames=keys,
quoting=csv.QUOTE_ALL
)
dict_writer.writeheader()
for event in data:
dict_writer.writerow(
{
key: value for key, value in event.items() if key in keys
}
)
with open(filename, 'r') as report_path_filename:
reader = report_path_filename.read()
return Response(
reader,
mimetype='text/csv',
headers={
'Content-Disposition': 'attachment;filename=' + filename
}
)
@app.route("/logs/get_list", methods=["GET"])
def get_last_host_logs(): # need to check
"""
get list of logs through the API
Returns:
an array of JSON logs if success otherwise abort(403)
"""
api_key_is_valid(app, flask_request)
page = get_value(flask_request, "page")
if not page:
page = 1
return jsonify(
last_host_logs(
int(page)
)
), 200
@app.route("/logs/get_html", methods=["GET"])
def get_logs_html(): # todo: check until here - ali
"""
get host's logs through the API in HTML type
Returns:
HTML report
"""
api_key_is_valid(app, flask_request)
target = get_value(flask_request, "target")
return make_response(
logs_to_report_html(target)
)
@app.route("/logs/get_json", methods=["GET"])
def get_logs():
"""
get host's logs through the API in JSON type
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
target = get_value(flask_request, "target")
data = logs_to_report_json(target)
json_object = json.dumps(data)
filename = "report-" + now(
model="%Y_%m_%d_%H_%M_%S"
) + "".join(
random.choice(string.ascii_lowercase) for _ in range(10)
)
return Response(
json_object,
mimetype='application/json',
headers={
'Content-Disposition': 'attachment;filename=' + filename + '.json'
}
)
@app.route("/logs/get_csv", methods=["GET"])
def get_logs_csv():
"""
get target's logs through the API in JSON type
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
target = get_value(flask_request, "target")
data = logs_to_report_json(target)
keys = data[0].keys()
filename = "report-" + now(
model="%Y_%m_%d_%H_%M_%S"
) + "".join(
random.choice(
string.ascii_lowercase
) for _ in range(10)
)
with open(filename, "w") as report_path_filename:
dict_writer = csv.DictWriter(
report_path_filename,
fieldnames=keys,
quoting=csv.QUOTE_ALL
)
dict_writer.writeheader()
for event in data:
dict_writer.writerow(
{
key: value for key, value in event.items() if key in keys
}
)
with open(filename, 'r') as report_path_filename:
reader = report_path_filename.read()
return Response(
reader, mimetype='text/csv',
headers={
'Content-Disposition': 'attachment;filename=' + filename + '.csv'
}
)
@app.route("/logs/search", methods=["GET"])
def go_for_search_logs():
"""
search in all events
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
try:
page = int(get_value(flask_request, "page"))
if page > 0:
page -= 1
except Exception:
page = 0
try:
query = get_value(flask_request, "q")
except Exception:
query = ""
return jsonify(search_logs(page, query)), 200
def start_api_subprocess(options):
"""
a function to run flask in a subprocess to make kill signal in a better
way!
Args:
options: all options
"""
app.config["OWASP_NETTACKER_CONFIG"] = {
"api_access_key": options.api_access_key,
"api_client_whitelisted_ips": options.api_client_whitelisted_ips,
"api_access_log": options.api_access_log,
"api_cert": options.api_cert,
"api_cert_key": options.api_cert_key,
"language": options.language,
"options": options
}
if options.api_cert and options.api_cert_key:
app.run(
host=options.api_hostname,
port=options.api_port,
debug=options.api_debug_mode,
ssl_context=(
options.api_cert,
options.api_cert_key
),
threaded=True
)
else:
app.run(
host=options.api_hostname,
port=options.api_port,
debug=options.api_debug_mode,
ssl_context='adhoc',
threaded=True
)
def start_api_server(options):
"""
entry point to run the API through the flask
Args:
options: all options
"""
# Starting the API
write_to_api_console(
messages("API_key").format(
options.api_port,
options.api_access_key
)
)
p = multiprocessing.Process(
target=start_api_subprocess,
args=(options,)
)
p.start()
# Sometimes it's take much time to terminate flask with CTRL+C
# So It's better to use KeyboardInterrupt to terminate!
while len(multiprocessing.active_children()) != 0:
try:
time.sleep(0.3)
except KeyboardInterrupt:
for process in multiprocessing.active_children():
process.terminate()
break
die_success()

142
config.py
View File

@ -1,142 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
from core.time import now
from core.utility import generate_random_token
def nettacker_paths():
"""
home path for the framework (could be modify by user)
Returns:
a JSON contain the working, tmp and results path
"""
return {
"requirements_path": os.path.join(sys.path[0], 'requirements.txt'),
"requirements_dev_path": os.path.join(sys.path[0], 'requirements-dev.txt'),
"home_path": os.path.join(sys.path[0]),
"data_path": os.path.join(sys.path[0], '.data'),
"tmp_path": os.path.join(sys.path[0], '.data/tmp'),
"results_path": os.path.join(sys.path[0], '.data/results'),
"database_path": os.path.join(sys.path[0], '.data/nettacker.db'),
"version_file": os.path.join(sys.path[0], 'version.txt'),
"logo_file": os.path.join(sys.path[0], 'logo.txt'),
"messages_path": os.path.join(sys.path[0], 'lib/messages'),
"modules_path": os.path.join(sys.path[0], 'modules'),
"web_browser_user_agents": os.path.join(sys.path[0], 'lib/payloads/User-Agents/web_browsers_user_agents.txt'),
"web_static_files_path": os.path.join(sys.path[0], 'web/static'),
"payloads_path": os.path.join(sys.path[0], 'lib/payloads'),
"module_protocols_path": os.path.join(sys.path[0], 'core/module_protocols'),
}
def nettacker_api_config():
"""
API Config (could be modify by user)
Returns:
a JSON with API configuration
"""
return { # OWASP Nettacker API Default Configuration
"start_api_server": False,
"api_hostname": "0.0.0.0" if os.environ.get("docker_env") == "true" else "nettacker-api.z3r0d4y.com",
"api_port": 5000,
"api_debug_mode": False,
"api_access_key": generate_random_token(32),
"api_client_whitelisted_ips": [], # disabled - to enable please put an array with list of ips/cidr/ranges
# [
# "127.0.0.1",
# "10.0.0.0/24",
# "192.168.1.1-192.168.1.255"
# ],
"api_access_log": os.path.join(sys.path[0], '.data/nettacker.log'),
}
def nettacker_database_config():
"""
Database Config (could be modified by user)
For sqlite database:
fill the name of the DB as sqlite,
DATABASE as the name of the db user wants
other details can be left empty
For mysql users:
fill the name of the DB as mysql
DATABASE as the name of the database you want to create
USERNAME, PASSWORD, HOST and the PORT of the MySQL server
need to be filled respectively
Returns:
a JSON with Database configuration
"""
return {
"DB": "sqlite",
# "DB":"mysql", "DB": "postgres"
"DATABASE": nettacker_paths()["database_path"],
# Name of the database
"USERNAME": "",
"PASSWORD": "",
"HOST": "",
"PORT": ""
}
def nettacker_user_application_config():
"""
core framework default config (could be modify by user)
Returns:
a JSON with all user default configurations
"""
from core.compatible import version_info
return { # OWASP Nettacker Default Configuration
"language": "en",
"verbose_mode": False,
"verbose_event": False,
"show_version": False,
"report_path_filename": "{results_path}/results_{date_time}_{random_chars}.html".format(
results_path=nettacker_paths()["results_path"],
date_time=now(model="%Y_%m_%d_%H_%M_%S"),
random_chars=generate_random_token(10)
),
"graph_name": "d3_tree_v2_graph",
"show_help_menu": False,
"targets": None,
"targets_list": None,
"selected_modules": None,
"excluded_modules": None,
"usernames": None,
"usernames_list": None,
"passwords": None,
"passwords_list": None,
"ports": None,
"timeout": 3.0,
"time_sleep_between_requests": 0.0,
"scan_ip_range": False,
"scan_subdomains": False,
"thread_per_host": 100,
"parallel_module_scan": 1,
"socks_proxy": None,
"retries": 1,
"ping_before_scan": False,
"profiles": None,
"set_hardware_usage": "maximum", # low, normal, high, maximum
"user_agent": "Nettacker {version_number} {version_code}".format(
version_number=version_info()[0], version_code=version_info()[1]
),
"show_all_modules": False,
"show_all_profiles": False,
"modules_extra_args": None
}
def nettacker_global_config():
return {
"nettacker_paths": nettacker_paths(),
"nettacker_api_config": nettacker_api_config(),
"nettacker_database_config": nettacker_database_config(),
"nettacker_user_application_config": nettacker_user_application_config()
}

View File

@ -1,2 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

View File

@ -1,225 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from core import color
from core.messages import load_message
from core.time import now
message_cache = load_message().messages
def run_from_api():
"""
check if framework run from API to prevent any alert
Returns:
True if run from API otherwise False
"""
return "--start-api" in sys.argv
def verbose_mode_is_enabled():
return '--verbose' in sys.argv or '-v' in sys.argv
def event_verbose_mode_is_enabled():
return '--verbose-event' in sys.argv
def messages(msg_id):
"""
load a message from message library with specified language
Args:
msg_id: message id
Returns:
the message content in the selected language if
message found otherwise return message in English
"""
return message_cache[str(msg_id)]
def info(content):
"""
build the info message, log the message in database if requested,
rewrite the thread temporary file
Args:
content: content of the message
Returns:
None
"""
if not run_from_api():
sys.stdout.buffer.write(
bytes(
color.color("yellow")
+ "[{0}][+] ".format(now())
+ color.color("green")
+ content
+ color.color("reset")
+ "\n",
"utf8",
)
)
sys.stdout.flush()
def verbose_event_info(content):
"""
build the info message, log the message in database if requested,
rewrite the thread temporary file
Args:
content: content of the message
Returns:
None
"""
if (not run_from_api()) and (
verbose_mode_is_enabled() or event_verbose_mode_is_enabled()
): # prevent to stdout if run from API
sys.stdout.buffer.write(
bytes(
color.color("yellow")
+ "[{0}][+] ".format(now())
+ color.color("green")
+ content
+ color.color("reset")
+ "\n",
"utf8",
)
)
sys.stdout.flush()
def success_event_info(content):
"""
build the info message, log the message in database if requested,
rewrite the thread temporary file
Args:
content: content of the message
Returns:
None
"""
if not run_from_api():
sys.stdout.buffer.write(
bytes(
color.color("red")
+ "[{0}][+++] ".format(now())
+ color.color("cyan")
+ content
+ color.color("reset")
+ "\n",
"utf8",
)
)
sys.stdout.flush()
def verbose_info(content):
"""
build the info message, log the message in database if requested,
rewrite the thread temporary file
Args:
content: content of the message
Returns:
None
"""
if verbose_mode_is_enabled():
sys.stdout.buffer.write(
bytes(
color.color("yellow")
+ "[{0}][+] ".format(now())
+ color.color("purple")
+ content
+ color.color("reset")
+ "\n",
"utf8",
)
)
sys.stdout.flush()
def write(content):
"""
simple print a message
Args:
content: content of the message
Returns:
None
"""
if not run_from_api():
sys.stdout.buffer.write(
bytes(content, "utf8") if isinstance(content, str) else content
)
sys.stdout.flush()
def warn(content):
"""
build the warn message
Args:
content: content of the message
Returns:
the message in warn structure - None
"""
if not run_from_api():
sys.stdout.buffer.write(
bytes(
color.color("blue")
+ "[{0}][!] ".format(now())
+ color.color("yellow")
+ content
+ color.color("reset")
+ "\n",
"utf8",
)
)
sys.stdout.flush()
def error(content):
"""
build the error message
Args:
content: content of the message
Returns:
the message in error structure - None
"""
data = (
color.color("red")
+ "[{0}][X] ".format(now())
+ color.color("yellow")
+ content
+ color.color("reset")
+ "\n"
)
sys.stdout.buffer.write(data.encode("utf8"))
sys.stdout.flush()
def write_to_api_console(content):
"""
simple print a message in API mode
Args:
content: content of the message
Returns:
None
"""
sys.stdout.buffer.write(bytes(content, "utf8"))
sys.stdout.flush()

View File

@ -1,611 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import sys
from core.alert import write
from core.alert import warn
from core.alert import info
from core.alert import messages
from core.color import color
from core.compatible import version_info
from config import nettacker_global_config
from core.load_modules import load_all_languages
from core.utility import (application_language,
select_maximum_cpu_core)
from core.die import die_success
from core.die import die_failure
from core.color import reset_color
from core.load_modules import load_all_modules
from core.load_modules import load_all_graphs
from core.load_modules import load_all_profiles
def load_all_args():
"""
create the ARGS and help menu
Returns:
the parser, the ARGS
"""
nettacker_global_configuration = nettacker_global_config()
# Language Options
language = application_language()
languages_list = load_all_languages()
if language not in languages_list:
die_failure(
"Please select one of these languages {0}".format(
languages_list
)
)
reset_color()
# Start Parser
parser = argparse.ArgumentParser(prog="Nettacker", add_help=False)
# Engine Options
engineOpt = parser.add_argument_group(
messages("engine"), messages("engine_input")
)
engineOpt.add_argument(
"-L",
"--language",
action="store",
dest="language",
default=nettacker_global_configuration['nettacker_user_application_config']["language"],
help=messages("select_language").format(languages_list),
)
engineOpt.add_argument(
"-v",
"--verbose",
action="store_true",
dest="verbose_mode",
default=nettacker_global_configuration['nettacker_user_application_config']['verbose_mode'],
help=messages("verbose_mode"),
)
engineOpt.add_argument(
"--verbose-event",
action="store_true",
dest="verbose_event",
default=nettacker_global_configuration['nettacker_user_application_config']['verbose_event'],
help=messages("verbose_event"),
)
engineOpt.add_argument(
"-V",
"--version",
action="store_true",
default=nettacker_global_configuration['nettacker_user_application_config']['show_version'],
dest="show_version",
help=messages("software_version"),
)
engineOpt.add_argument(
"-o",
"--output",
action="store",
default=nettacker_global_configuration['nettacker_user_application_config']['report_path_filename'],
dest="report_path_filename",
help=messages("save_logs"),
)
engineOpt.add_argument(
"--graph",
action="store",
default=nettacker_global_configuration['nettacker_user_application_config']["graph_name"],
dest="graph_name",
help=messages("available_graph").format(load_all_graphs()),
)
engineOpt.add_argument(
"-h",
"--help",
action="store_true",
default=nettacker_global_configuration['nettacker_user_application_config']["show_help_menu"],
dest="show_help_menu",
help=messages("help_menu"),
)
# Target Options
target = parser.add_argument_group(
messages("target"), messages("target_input")
)
target.add_argument(
"-i",
"--targets",
action="store",
dest="targets",
default=nettacker_global_configuration['nettacker_user_application_config']["targets"],
help=messages("target_list"),
)
target.add_argument(
"-l",
"--targets-list",
action="store",
dest="targets_list",
default=nettacker_global_configuration['nettacker_user_application_config']["targets_list"],
help=messages("read_target"),
)
# Exclude Module Name
exclude_modules = list(load_all_modules(limit=10).keys())
exclude_modules.remove("all")
# Methods Options
modules = parser.add_argument_group(
messages("Method"), messages("scan_method_options")
)
modules.add_argument(
"-m",
"--modules",
action="store",
dest="selected_modules",
default=nettacker_global_configuration['nettacker_user_application_config']["selected_modules"],
help=messages("choose_scan_method").format(list(load_all_modules(limit=10).keys())),
)
modules.add_argument(
"--modules-extra-args",
action="store",
dest="modules_extra_args",
default=nettacker_global_configuration['nettacker_user_application_config']['modules_extra_args'],
help=messages("modules_extra_args_help")
)
modules.add_argument(
"--show-all-modules",
action="store_true",
dest="show_all_modules",
default=nettacker_global_configuration['nettacker_user_application_config']["show_all_modules"],
help=messages("show_all_modules"),
)
modules.add_argument(
"--profile",
action="store",
default=nettacker_global_configuration['nettacker_user_application_config']["profiles"],
dest="profiles",
help=messages("select_profile").format(list(load_all_profiles(limit=10).keys())),
)
modules.add_argument(
"--show-all-profiles",
action="store_true",
dest="show_all_profiles",
default=nettacker_global_configuration['nettacker_user_application_config']["show_all_profiles"],
help=messages("show_all_profiles"),
)
modules.add_argument(
"-x",
"--exclude-modules",
action="store",
dest="excluded_modules",
default=nettacker_global_configuration['nettacker_user_application_config']["excluded_modules"],
help=messages("exclude_scan_method").format(exclude_modules),
)
modules.add_argument(
"-u",
"--usernames",
action="store",
dest="usernames",
default=nettacker_global_configuration['nettacker_user_application_config']["usernames"],
help=messages("username_list"),
)
modules.add_argument(
"-U",
"--users-list",
action="store",
dest="usernames_list",
default=nettacker_global_configuration['nettacker_user_application_config']["usernames_list"],
help=messages("username_from_file"),
)
modules.add_argument(
"-p",
"--passwords",
action="store",
dest="passwords",
default=nettacker_global_configuration['nettacker_user_application_config']["passwords"],
help=messages("password_seperator"),
)
modules.add_argument(
"-P",
"--passwords-list",
action="store",
dest="passwords_list",
default=nettacker_global_configuration['nettacker_user_application_config']["passwords_list"],
help=messages("read_passwords"),
)
modules.add_argument(
"-g",
"--ports",
action="store",
dest="ports",
default=nettacker_global_configuration['nettacker_user_application_config']["ports"],
help=messages("port_seperator"),
)
modules.add_argument(
"--user-agent",
action="store",
dest="user_agent",
default=nettacker_global_configuration['nettacker_user_application_config']["user_agent"],
help=messages("select_user_agent"),
)
modules.add_argument(
"-T",
"--timeout",
action="store",
dest="timeout",
default=nettacker_global_configuration['nettacker_user_application_config']["timeout"],
type=float,
help=messages("read_passwords"),
)
modules.add_argument(
"-w",
"--time-sleep-between-requests",
action="store",
dest="time_sleep_between_requests",
default=nettacker_global_configuration['nettacker_user_application_config']["time_sleep_between_requests"],
type=float,
help=messages("time_to_sleep"),
)
modules.add_argument(
"-r",
"--range",
action="store_true",
default=nettacker_global_configuration['nettacker_user_application_config']["scan_ip_range"],
dest="scan_ip_range",
help=messages("range"),
)
modules.add_argument(
"-s",
"--sub-domains",
action="store_true",
default=nettacker_global_configuration['nettacker_user_application_config']["scan_subdomains"],
dest="scan_subdomains",
help=messages("subdomains"),
)
modules.add_argument(
"-t",
"--thread-per-host",
action="store",
default=nettacker_global_configuration['nettacker_user_application_config']["thread_per_host"],
type=int,
dest="thread_per_host",
help=messages("thread_number_connections"),
)
modules.add_argument(
"-M",
"--parallel-module-scan",
action="store",
default=nettacker_global_configuration['nettacker_user_application_config']["parallel_module_scan"],
type=int,
dest="parallel_module_scan",
help=messages("thread_number_modules"),
)
modules.add_argument(
"--set-hardware-usage",
action="store",
dest="set_hardware_usage",
default=nettacker_global_configuration['nettacker_user_application_config']['set_hardware_usage'],
help=messages("set_hardware_usage")
)
modules.add_argument(
"-R",
"--socks-proxy",
action="store",
dest="socks_proxy",
default=nettacker_global_configuration['nettacker_user_application_config']["socks_proxy"],
help=messages("outgoing_proxy"),
)
modules.add_argument(
"--retries",
action="store",
dest="retries",
type=int,
default=nettacker_global_configuration['nettacker_user_application_config']["retries"],
help=messages("connection_retries"),
)
modules.add_argument(
"--ping-before-scan",
action="store_true",
dest="ping_before_scan",
default=nettacker_global_configuration['nettacker_user_application_config']["ping_before_scan"],
help=messages("ping_before_scan"),
)
# API Options
api = parser.add_argument_group(
messages("API"),
messages("API_options")
)
api.add_argument(
"--start-api",
action="store_true",
dest="start_api_server",
default=nettacker_global_configuration['nettacker_api_config']["start_api_server"],
help=messages("start_api_server")
)
api.add_argument(
"--api-host",
action="store",
dest="api_hostname",
default=nettacker_global_configuration['nettacker_api_config']["api_hostname"],
help=messages("API_host")
)
api.add_argument(
"--api-port",
action="store",
dest="api_port",
default=nettacker_global_configuration['nettacker_api_config']["api_port"],
help=messages("API_port")
)
api.add_argument(
"--api-debug-mode",
action="store_true",
dest="api_debug_mode",
default=nettacker_global_configuration['nettacker_api_config']["api_debug_mode"],
help=messages("API_debug")
)
api.add_argument(
"--api-access-key",
action="store",
dest="api_access_key",
default=nettacker_global_configuration['nettacker_api_config']["api_access_key"],
help=messages("API_access_key")
)
api.add_argument(
"--api-client-whitelisted-ips",
action="store",
dest="api_client_whitelisted_ips",
default=nettacker_global_configuration['nettacker_api_config']["api_client_whitelisted_ips"],
help=messages("define_whie_list")
)
api.add_argument(
"--api-access-log",
action="store",
dest="api_access_log",
default=nettacker_global_configuration['nettacker_api_config']["api_access_log"],
help=messages("API_access_log_file")
)
api.add_argument(
"--api-cert",
action="store",
dest="api_cert",
help=messages("API_cert")
)
api.add_argument(
"--api-cert-key",
action="store",
dest="api_cert_key",
help=messages("API_cert_key")
)
# Return Options
return parser
def check_all_required(parser, api_forms=None):
"""
check all rules and requirements for ARGS
Args:
parser: parser from argparse
api_forms: values from API
Returns:
all ARGS with applied rules
"""
# Checking Requirements
options = parser.parse_args() if not api_forms else api_forms
modules_list = load_all_modules(full_details=True)
profiles_list = load_all_profiles()
# Check Help Menu
if options.show_help_menu:
parser.print_help()
write("\n\n")
write(messages("license"))
die_success()
# Check version
if options.show_version:
info(
messages("current_version").format(
color("yellow"),
version_info()[0],
color("reset"),
color("cyan"),
version_info()[1],
color("reset"),
color("green"),
)
)
die_success()
if options.show_all_modules:
messages("loading_modules")
for module in modules_list:
info(
messages("module_profile_full_information").format(
color('cyan'),
module,
color('green'),
", ".join(
[
"{key}: {value}".format(
key=key, value=modules_list[module][key]
) for key in modules_list[module]
]
)
)
)
die_success()
if options.show_all_profiles:
messages("loading_profiles")
for profile in profiles_list:
info(
messages("module_profile_full_information").format(
color('cyan'),
profile,
color('green'),
", ".join(profiles_list[profile])
)
)
die_success()
# API mode
if options.start_api_server:
if '--start-api' in sys.argv and api_forms:
die_failure(messages("cannot_run_api_server"))
from api.engine import start_api_server
if options.api_client_whitelisted_ips:
if type(options.api_client_whitelisted_ips) == str:
options.api_client_whitelisted_ips = options.api_client_whitelisted_ips.split(',')
whielisted_ips = []
for ip in options.api_client_whitelisted_ips:
from core.ip import (is_single_ipv4,
is_single_ipv6,
is_ipv4_cidr,
is_ipv6_range,
is_ipv6_cidr,
is_ipv4_range,
generate_ip_range)
if is_single_ipv4(ip) or is_single_ipv6(ip):
whielisted_ips.append(ip)
elif is_ipv4_range(ip) or is_ipv6_range(ip) or is_ipv4_cidr(ip) or is_ipv6_cidr(ip):
whielisted_ips += generate_ip_range(ip)
options.api_client_whitelisted_ips = whielisted_ips
start_api_server(options)
# Check the target(s)
if not (options.targets or options.targets_list) or (options.targets and options.targets_list):
parser.print_help()
write("\n")
die_failure(messages("error_target"))
if options.targets:
options.targets = list(set(options.targets.split(",")))
if options.targets_list:
try:
options.targets = list(set(open(options.targets_list, "rb").read().decode().split()))
except Exception:
die_failure(
messages("error_target_file").format(
options.targets_list
)
)
# check for modules
if not (options.selected_modules or options.profiles):
die_failure(messages("scan_method_select"))
if options.selected_modules:
if options.selected_modules == 'all':
options.selected_modules = modules_list
del options.selected_modules['all']
else:
options.selected_modules = list(set(options.selected_modules.split(',')))
for module_name in options.selected_modules:
if module_name not in modules_list:
die_failure(
messages("scan_module_not_found").format(
module_name
)
)
if options.profiles:
if not options.selected_modules:
options.selected_modules = []
if options.profiles == 'all':
options.selected_modules = modules_list
del options.selected_modules['all']
else:
options.profiles = list(set(options.profiles.split(',')))
for profile in options.profiles:
if profile not in profiles_list:
die_failure(
messages("profile_404").format(
profile
)
)
for module_name in profiles_list[profile]:
if module_name not in options.selected_modules:
options.selected_modules.append(module_name)
# threading & processing
if options.set_hardware_usage not in ['low', 'normal', 'high', 'maximum']:
die_failure(
messages("wrong_hardware_usage")
)
options.set_hardware_usage = select_maximum_cpu_core(options.set_hardware_usage)
options.thread_per_host = int(options.thread_per_host)
if not options.thread_per_host >= 1:
options.thread_per_host = 1
options.parallel_module_scan = int(options.parallel_module_scan)
if not options.parallel_module_scan >= 1:
options.parallel_module_scan = 1
# Check for excluding modules
if options.excluded_modules:
options.excluded_modules = options.excluded_modules.split(",")
if 'all' in options.excluded_modules:
die_failure(messages("error_exclude_all"))
for excluded_module in options.excluded_modules:
if excluded_module in options.selected_modules:
del options.selected_modules[excluded_module]
# Check port(s)
if options.ports:
tmp_ports = []
for port in options.ports.split(","):
try:
if "-" in port:
for port_number in range(int(port.split('-')[0]), int(port.split('-')[1]) + 1):
if port_number not in tmp_ports:
tmp_ports.append(port_number)
else:
if int(port) not in tmp_ports:
tmp_ports.append(int(port))
except Exception:
die_failure(messages("ports_int"))
options.ports = tmp_ports
if options.user_agent == 'random_user_agent':
options.user_agents = open(
nettacker_global_config()['nettacker_paths']['web_browser_user_agents']
).read().split('\n')
# Check user list
if options.usernames:
options.usernames = list(set(options.usernames.split(",")))
elif options.usernames_list:
try:
options.usernames = list(set(open(options.usernames_list).read().split("\n")))
except Exception:
die_failure(
messages("error_username").format(options.usernames_list)
)
# Check password list
if options.passwords:
options.passwords = list(set(options.passwords.split(",")))
elif options.passwords_list:
try:
options.passwords = list(set(open(options.passwords_list).read().split("\n")))
except Exception:
die_failure(
messages("error_passwords").format(options.passwords_list)
)
# Check output file
try:
temp_file = open(options.report_path_filename, "w")
temp_file.close()
except Exception:
die_failure(
messages("file_write_error").format(options.report_path_filename)
)
# Check Graph
if options.graph_name:
if options.graph_name not in load_all_graphs():
die_failure(
messages("graph_module_404").format(options.graph_name)
)
if not (options.report_path_filename.endswith(".html") or options.report_path_filename.endswith(".htm")):
warn(messages("graph_output"))
options.graph_name = None
# check modules extra args
if options.modules_extra_args:
all_args = {}
for args in options.modules_extra_args.split("&"):
all_args[args.split('=')[0]] = args.split('=')[1]
options.modules_extra_args = all_args
options.timeout = float(options.timeout)
options.time_sleep_between_requests = float(options.time_sleep_between_requests)
options.retries = int(options.retries)
return options

View File

@ -1,41 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
def reset_color():
"""
reset the color of terminal before exit
"""
sys.stdout.write("\033[0m")
def color(color_name):
"""
color_names for terminal and windows cmd
Args:
color_name: color name
Returns:
color_name values or empty string
"""
if color_name == "reset":
return "\033[0m"
elif color_name == "grey":
return "\033[1;30m"
elif color_name == "red":
return "\033[1;31m"
elif color_name == "green":
return "\033[1;32m"
elif color_name == "yellow":
return "\033[1;33m"
elif color_name == "blue":
return "\033[1;34m"
elif color_name == "purple":
return "\033[1;35m"
elif color_name == "cyan":
return "\033[1;36m"
elif color_name == "white":
return "\033[1;37m"
return ""

View File

@ -1,148 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import os
import json
from core.die import die_failure
from core import color
def version_info():
"""
version information of the framework
Returns:
an array of version and code name
"""
from config import nettacker_paths
return open(nettacker_paths()['version_file']).read().split()
def logo():
"""
OWASP Nettacker Logo
"""
from core.alert import write_to_api_console
from core import color
from core.color import reset_color
from config import nettacker_paths
from config import nettacker_user_application_config
write_to_api_console(
open(
nettacker_paths()['logo_file']
).read().format(
version_info()[0],
version_info()[1],
color.color('red'),
color.color('reset'),
color.color('yellow'),
color.color('reset'),
color.color('cyan'),
color.color('reset'),
color.color('cyan'),
color.color('reset'),
color.color('cyan'),
color.color('reset')
)
)
reset_color()
def python_version():
"""
version of python
Returns:
integer version of python (2 or 3)
"""
return int(sys.version_info[0])
def os_name():
"""
OS name
Returns:
OS name in string
"""
return sys.platform
def check_dependencies():
if python_version() == 2:
sys.exit(color.color("red") + "[X] " + color.color("yellow") + "Python2 is No longer supported!" + color.color(
"reset"))
# check os compatibility
from config import nettacker_paths, nettacker_database_config
external_modules = open(nettacker_paths()["requirements_path"]).read().split('\n')
for module_name in external_modules:
try:
__import__(
module_name.split('==')[0] if 'library_name=' not in module_name
else module_name.split('library_name=')[1].split()[0]
)
except Exception:
if 'is_optional=true' not in module_name:
sys.exit(
color.color("red") + "[X] " + color.color("yellow") + "pip3 install -r requirements.txt ---> " +
module_name.split('#')[0].strip() + " not installed!" + color.color("reset")
)
logo()
from core.alert import messages
if not ('linux' in os_name() or 'darwin' in os_name()):
die_failure(messages("error_platform"))
if not os.path.exists(nettacker_paths()["home_path"]):
try:
os.mkdir(nettacker_paths()["home_path"])
os.mkdir(nettacker_paths()["tmp_path"])
os.mkdir(nettacker_paths()["results_path"])
except Exception:
die_failure("cannot access the directory {0}".format(
nettacker_paths()["home_path"])
)
if not os.path.exists(nettacker_paths()["tmp_path"]):
try:
os.mkdir(nettacker_paths()["tmp_path"])
except Exception:
die_failure("cannot access the directory {0}".format(
nettacker_paths()["results_path"])
)
if not os.path.exists(nettacker_paths()["results_path"]):
try:
os.mkdir(nettacker_paths()["results_path"])
except Exception:
die_failure("cannot access the directory {0}".format(
nettacker_paths()["results_path"])
)
if nettacker_database_config()["DB"] == "sqlite":
try:
if not os.path.isfile(nettacker_paths()["database_path"]):
from database.sqlite_create import sqlite_create_tables
sqlite_create_tables()
except Exception:
die_failure("cannot access the directory {0}".format(
nettacker_paths()["home_path"])
)
elif nettacker_database_config()["DB"] == "mysql":
try:
from database.mysql_create import (
mysql_create_tables,
mysql_create_database
)
mysql_create_database()
mysql_create_tables()
except Exception:
die_failure(messages("database_connection_failed"))
elif nettacker_database_config()["DB"] == "postgres":
try:
from database.postgres_create import postgres_create_database
postgres_create_database()
except Exception:
die_failure(messages("database_connection_failed"))
else:
die_failure(messages("invalid_database"))

View File

@ -1,190 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import csv
import texttable
from core.alert import messages
from core.alert import info
from core.compatible import version_info
from core.time import now
from core.die import die_failure
from database.db import get_logs_by_scan_unique_id
from database.db import submit_report_to_db
def build_graph(graph_name, events):
"""
build a graph
Args:
graph_name: graph name
events: list of events
Returns:
graph in HTML type
"""
info(messages("build_graph"))
try:
start = getattr(
__import__(
'lib.graph.{0}.engine'.format(
graph_name.rsplit('_graph')[0]
),
fromlist=['start']
),
'start'
)
except Exception:
die_failure(
messages("graph_module_unavailable").format(graph_name)
)
info(messages("finish_build_graph"))
return start(
events
)
def build_texttable(events):
"""
value['date'], value["target"], value['module_name'], value['scan_unique_id'],
value['options'], value['event']
build a text table with generated event related to the scan
:param events: all events
:return:
array [text table, event_number]
"""
_table = texttable.Texttable()
table_headers = [
'date',
'target',
'module_name',
'scan_unique_id',
'port',
'event',
'json_event'
]
_table.add_rows(
[
table_headers
]
)
for event in events:
_table.add_rows(
[
table_headers,
[
event['date'],
event['target'],
event['module_name'],
event['scan_unique_id'],
event['port'],
event['event'],
event['json_event']
]
]
)
return _table.draw().encode('utf8') + b'\n\n' + messages("nettacker_version_details").format(
version_info()[0],
version_info()[1],
now()
).encode('utf8') + b"\n"
def create_report(options, scan_unique_id):
"""
sort all events, create log file in HTML/TEXT/JSON and remove old logs
Args:
options: parsing options
scan_unique_id: scan unique id
Returns:
True if success otherwise None
"""
all_scan_logs = get_logs_by_scan_unique_id(scan_unique_id)
if not all_scan_logs:
info(messages("no_events_for_report"))
return True
report_path_filename = options.report_path_filename
if (
len(report_path_filename) >= 5 and report_path_filename[-5:] == '.html'
) or (
len(report_path_filename) >= 4 and report_path_filename[-4:] == '.htm'
):
if options.graph_name:
html_graph = build_graph(options.graph_name, all_scan_logs)
else:
html_graph = ''
from lib.html_log import log_data
html_table_content = log_data.table_title.format(
html_graph,
log_data.css_1,
'date',
'target',
'module_name',
'scan_unique_id',
'port',
'event',
'json_event'
)
for event in all_scan_logs:
html_table_content += log_data.table_items.format(
event["date"],
event["target"],
event["module_name"],
event["scan_unique_id"],
event["port"],
event["event"],
event["json_event"]
)
html_table_content += log_data.table_end + '<p class="footer">' + messages("nettacker_version_details").format(
version_info()[0],
version_info()[1],
now()
) + '</p>'
with open(report_path_filename, 'w', encoding='utf-8') as save:
save.write(html_table_content + '\n')
save.close()
elif len(report_path_filename) >= 5 and report_path_filename[-5:] == '.json':
with open(report_path_filename, 'w', encoding='utf-8') as save:
save.write(
str(
json.dumps(all_scan_logs)
) + '\n'
)
save.close()
elif len(report_path_filename) >= 5 and report_path_filename[-4:] == '.csv':
keys = all_scan_logs[0].keys()
with open(report_path_filename, 'a') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=keys)
writer.writeheader()
for log in all_scan_logs:
dict_data = {
key: value for key, value in log.items() if key in keys
}
writer.writerow(dict_data)
csvfile.close()
else:
with open(report_path_filename, 'wb') as save:
save.write(
build_texttable(all_scan_logs)
)
save.close()
submit_report_to_db(
{
"date": now(model=None),
"scan_unique_id": scan_unique_id,
"options": vars(options),
}
)
info(messages("file_saved").format(report_path_filename))
return True

View File

@ -1,296 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import socket
import time
from glob import glob
from io import StringIO
def getaddrinfo(*args):
"""
same getaddrinfo() used in socket except its resolve addresses with socks proxy
Args:
args: *args
Returns:
getaddrinfo
"""
return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0], args[1]))]
def set_socks_proxy(socks_proxy):
if socks_proxy:
import socks
socks_version = socks.SOCKS5 if socks_proxy.startswith('socks5://') else socks.SOCKS4
socks_proxy = socks_proxy.split('://')[1] if '://' in socks_proxy else socks_proxy
if '@' in socks_proxy:
socks_username = socks_proxy.split(':')[0]
socks_password = socks_proxy.split(':')[1].split('@')[0]
socks.set_default_proxy(
socks_version,
str(socks_proxy.rsplit('@')[1].rsplit(':')[0]), # hostname
int(socks_proxy.rsplit(':')[-1]), # port
username=socks_username,
password=socks_password
)
else:
socks.set_default_proxy(
socks_version,
str(socks_proxy.rsplit(':')[0]), # hostname
int(socks_proxy.rsplit(':')[1]) # port
)
return socks.socksocket, getaddrinfo
else:
return socket.socket, socket.getaddrinfo
class NettackerModules:
def __init__(self):
from config import nettacker_paths
self.module_name = None
self.module_content = None
self.scan_unique_id = None
self.target = None
self.process_number = None
self.module_thread_number = None
self.total_module_thread_number = None
self.module_inputs = {}
self.libraries = [
module_protocol.split('.py')[0] for module_protocol in
os.listdir(nettacker_paths()['module_protocols_path']) if
module_protocol.endswith('.py') and module_protocol != '__init__.py'
]
def load(self):
import yaml
from config import nettacker_paths
from core.utility import find_and_replace_configuration_keys
self.module_content = find_and_replace_configuration_keys(
yaml.load(
StringIO(
open(
nettacker_paths()['modules_path'] +
'/' +
self.module_name.split('_')[-1].split('.yaml')[0] +
'/' +
'_'.join(self.module_name.split('_')[:-1]) +
'.yaml',
'r'
).read().format(
**self.module_inputs
)
),
Loader=yaml.FullLoader
),
self.module_inputs
)
def generate_loops(self):
from core.utility import expand_module_steps
self.module_content['payloads'] = expand_module_steps(self.module_content['payloads'])
def start(self):
from terminable_thread import Thread
from core.utility import wait_for_threads_to_finish
active_threads = []
from core.alert import warn
from core.alert import verbose_event_info
from core.alert import messages
# counting total number of requests
total_number_of_requests = 0
for payload in self.module_content['payloads']:
if payload['library'] not in self.libraries:
warn(messages("library_not_supported").format(payload['library']))
return None
for step in payload['steps']:
for _ in step:
total_number_of_requests += 1
request_number_counter = 0
for payload in self.module_content['payloads']:
protocol = getattr(
__import__(
'core.module_protocols.{library}'.format(library=payload['library']),
fromlist=['Engine']
),
'Engine'
)
for step in payload['steps']:
for sub_step in step:
thread = Thread(
target=protocol.run,
args=(
sub_step,
self.module_name,
self.target,
self.scan_unique_id,
self.module_inputs,
self.process_number,
self.module_thread_number,
self.total_module_thread_number,
request_number_counter,
total_number_of_requests
)
)
thread.name = f"{self.target} -> {self.module_name} -> {sub_step}"
request_number_counter += 1
verbose_event_info(
messages("sending_module_request").format(
self.process_number,
self.module_name,
self.target,
self.module_thread_number,
self.total_module_thread_number,
request_number_counter,
total_number_of_requests
)
)
thread.start()
time.sleep(self.module_inputs['time_sleep_between_requests'])
active_threads.append(thread)
wait_for_threads_to_finish(
active_threads,
maximum=self.module_inputs['thread_per_host'],
terminable=True
)
wait_for_threads_to_finish(
active_threads,
maximum=None,
terminable=True
)
def load_all_graphs():
"""
load all available graphs
Returns:
an array of graph names
"""
from config import nettacker_paths
graph_names = []
for graph_library in glob(os.path.join(nettacker_paths()['home_path'] + '/lib/graph/*/engine.py')):
graph_names.append(graph_library.split('/')[-2] + '_graph')
return list(set(graph_names))
def load_all_languages():
"""
load all available languages
Returns:
an array of languages
"""
languages_list = []
from config import nettacker_paths
for language in glob(os.path.join(nettacker_paths()['home_path'] + '/lib/messages/*.yaml')):
languages_list.append(language.split('/')[-1].split('.')[0])
return list(set(languages_list))
def load_all_modules(limit=-1, full_details=False):
"""
load all available modules
limit: return limited number of modules
full: with full details
Returns:
an array of all module names
"""
# Search for Modules
from config import nettacker_paths
from core.utility import sort_dictonary
if full_details:
import yaml
module_names = {}
for module_name in glob(os.path.join(nettacker_paths()['modules_path'] + '/*/*.yaml')):
libname = module_name.split('/')[-1].split('.')[0]
category = module_name.split('/')[-2]
module_names[libname + '_' + category] = yaml.load(
StringIO(
open(
nettacker_paths()['modules_path'] +
'/' +
category +
'/' +
libname +
'.yaml',
'r'
).read().split('payload:')[0]
),
Loader=yaml.FullLoader
)['info'] if full_details else None
if len(module_names) == limit:
module_names['...'] = {}
break
module_names = sort_dictonary(module_names)
module_names['all'] = {}
return module_names
def load_all_profiles(limit=-1):
"""
load all available profiles
Returns:
an array of all profile names
"""
from core.utility import sort_dictonary
all_modules_with_details = load_all_modules(limit=limit, full_details=True)
profiles = {}
if '...' in all_modules_with_details:
del all_modules_with_details['...']
del all_modules_with_details['all']
for key in all_modules_with_details:
for tag in all_modules_with_details[key]['profiles']:
if tag not in profiles:
profiles[tag] = []
profiles[tag].append(key)
else:
profiles[tag].append(key)
if len(profiles) == limit:
profiles = sort_dictonary(profiles)
profiles['...'] = []
profiles['all'] = []
return profiles
profiles = sort_dictonary(profiles)
profiles['all'] = []
return profiles
def perform_scan(options, target, module_name, scan_unique_id, process_number, thread_number, total_number_threads):
from core.alert import (verbose_event_info,
messages)
socket.socket, socket.getaddrinfo = set_socks_proxy(options.socks_proxy)
options.target = target
validate_module = NettackerModules()
validate_module.module_name = module_name
validate_module.process_number = process_number
validate_module.module_thread_number = thread_number
validate_module.total_module_thread_number = total_number_threads
validate_module.module_inputs = vars(options)
if options.modules_extra_args:
for module_extra_args in validate_module.module_inputs['modules_extra_args']:
validate_module.module_inputs[module_extra_args] = \
validate_module.module_inputs['modules_extra_args'][module_extra_args]
validate_module.scan_unique_id = scan_unique_id
validate_module.target = target
validate_module.load()
validate_module.generate_loops()
validate_module.start()
verbose_event_info(
messages("finished_parallel_module_scan").format(
process_number,
module_name,
target,
thread_number,
total_number_threads
)
)
return os.EX_OK

View File

@ -1,36 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import yaml
from io import StringIO
def load_yaml(filename):
return yaml.load(
StringIO(
open(filename, 'r').read()
),
Loader=yaml.FullLoader
)
class load_message:
def __init__(self):
from core.utility import application_language
from config import nettacker_global_config
self.language = application_language()
self.messages = load_yaml(
"{messages_path}/{language}.yaml".format(
messages_path=nettacker_global_config()['nettacker_paths']['messages_path'],
language=self.language
)
)
if self.language != 'en':
self.messages_en = load_yaml(
"{messages_path}/en.yaml".format(
messages_path=nettacker_global_config()['nettacker_paths']['messages_path']
)
)
for message_id in self.messages_en:
if message_id not in self.messages:
self.messages[message_id] = self.messages_en[message_id]

View File

@ -1,2 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

View File

@ -1,93 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import copy
import ftplib
# from core.utility import reverse_and_regex_condition
from core.utility import process_conditions
from core.utility import get_dependent_results_from_database
from core.utility import replace_dependent_values
# def response_conditions_matched(sub_step, response):
# return response
class NettackFTPLib:
def ftp_brute_force(host, ports, usernames, passwords, timeout):
ftp_connection = ftplib.FTP(timeout=int(timeout))
ftp_connection.connect(host, int(ports))
ftp_connection.login(usernames, passwords)
ftp_connection.close()
return {
"host": host,
"username": usernames,
"password": passwords,
"port": ports
}
def ftps_brute_force(host, ports, usernames, passwords, timeout):
ftp_connection = ftplib.FTP_TLS(timeout=int(timeout))
ftp_connection.connect(host, int(ports))
ftp_connection.login(usernames, passwords)
ftp_connection.close()
return {
"host": host,
"username": usernames,
"password": passwords,
"port": ports
}
class Engine:
def run(
sub_step,
module_name,
target,
scan_unique_id,
options,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
):
backup_method = copy.deepcopy(sub_step['method'])
backup_response = copy.deepcopy(sub_step['response'])
del sub_step['method']
del sub_step['response']
if 'dependent_on_temp_event' in backup_response:
temp_event = get_dependent_results_from_database(
target,
module_name,
scan_unique_id,
backup_response['dependent_on_temp_event']
)
sub_step = replace_dependent_values(
sub_step,
temp_event
)
action = getattr(NettackFTPLib, backup_method, None)
for _ in range(options['retries']):
try:
response = action(**sub_step)
break
except Exception as _:
response = []
sub_step['method'] = backup_method
sub_step['response'] = backup_response
sub_step['response']['conditions_results'] = response
# sub_step['response']['conditions_results'] = response_conditions_matched(sub_step, response)
return process_conditions(
sub_step,
module_name,
target,
scan_unique_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
)

View File

@ -1,148 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import requests
import copy
import random
from core.utility import reverse_and_regex_condition
from core.utility import process_conditions
from core.utility import get_dependent_results_from_database
from core.utility import replace_dependent_values
def response_conditions_matched(sub_step, response):
if not response:
return []
condition_type = sub_step['response']['condition_type']
conditions = sub_step['response']['conditions']
condition_results = {}
for condition in conditions:
if condition in ['reason', 'status_code', 'content']:
regex = re.findall(re.compile(conditions[condition]['regex']), response[condition])
reverse = conditions[condition]['reverse']
condition_results[condition] = reverse_and_regex_condition(regex, reverse)
if condition == 'headers':
# convert headers to case insensitive dict
for key in response["headers"].copy():
response['headers'][key.lower()] = response['headers'][key]
condition_results['headers'] = {}
for header in conditions['headers']:
reverse = conditions['headers'][header]['reverse']
regex = re.findall(
re.compile(conditions['headers'][header]['regex']),
response['headers'][header.lower()] if header.lower() in response['headers'] else ""
)
condition_results['headers'][header] = reverse_and_regex_condition(regex, reverse)
if condition == 'responsetime':
if len(conditions[condition].split()) == 2 and conditions[condition].split()[0] in [
"==",
"!=",
">=",
"<=",
">",
"<"
]:
exec(
"condition_results['responsetime'] = response['responsetime'] if (" +
"response['responsetime'] {0} float(conditions['responsetime'].split()[-1])".format(
conditions['responsetime'].split()[0]
) +
") else []"
)
else:
condition_results['responsetime'] = []
if condition_type.lower() == "or":
# if one of the values are matched, it will be a string or float object in the array
# we count False in the array and if it's not all []; then we know one of the conditions is matched.
if (
'headers' not in condition_results and
(
list(condition_results.values()).count([]) != len(list(condition_results.values()))
)
) or (
'headers' in condition_results and
(
(
list(condition_results.values()).count([]) - 1 !=
len(list(condition_results.values()))
) and
(
list(condition_results['headers'].values()).count([]) !=
len(list(condition_results['headers'].values()))
)
)
):
return condition_results
else:
return []
if condition_type.lower() == "and":
if [] in condition_results.values() or \
('headers' in condition_results and [] in condition_results['headers'].values()):
return []
else:
return condition_results
return []
class Engine:
def run(
sub_step,
module_name,
target,
scan_unique_id,
options,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
):
backup_method = copy.deepcopy(sub_step['method'])
backup_response = copy.deepcopy(sub_step['response'])
action = getattr(requests, backup_method, None)
if options['user_agent'] == 'random_user_agent':
sub_step['headers']['User-Agent'] = random.choice(options['user_agents'])
del sub_step['method']
del sub_step['response']
if 'dependent_on_temp_event' in backup_response:
temp_event = get_dependent_results_from_database(
target,
module_name,
scan_unique_id,
backup_response['dependent_on_temp_event']
)
sub_step = replace_dependent_values(
sub_step,
temp_event
)
for _ in range(options['retries']):
try:
response = action(**sub_step)
response = {
"reason": response.reason,
"status_code": str(response.status_code),
"content": response.content.decode(errors="ignore"),
"headers": dict(response.headers),
"responsetime": response.elapsed.total_seconds()
}
break
except Exception:
response = []
sub_step['method'] = backup_method
sub_step['response'] = backup_response
sub_step['response']['conditions_results'] = response_conditions_matched(sub_step, response)
return process_conditions(
sub_step,
module_name,
target,
scan_unique_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
)

View File

@ -1,92 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import copy
import smtplib
# from core.utility import reverse_and_regex_condition
from core.utility import process_conditions
from core.utility import get_dependent_results_from_database
from core.utility import replace_dependent_values
# def response_conditions_matched(sub_step, response):
# return response
class NettackSMTPLib:
def smtp_brute_force(host, ports, usernames, passwords, timeout):
smtp_connection = smtplib.SMTP(host, int(ports), timeout=int(timeout))
smtp_connection.login(usernames, passwords)
smtp_connection.close()
return {
"host": host,
"username": usernames,
"password": passwords,
"port": ports
}
def smtps_brute_force(host, ports, usernames, passwords, timeout):
smtp_connection = smtplib.SMTP(host, int(ports), timeout=int(timeout))
smtp_connection.starttls()
smtp_connection.login(usernames, passwords)
smtp_connection.close()
return {
"host": host,
"username": usernames,
"password": passwords,
"port": ports
}
class Engine:
def run(
sub_step,
module_name,
target,
scan_unique_id,
options,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
):
backup_method = copy.deepcopy(sub_step['method'])
backup_response = copy.deepcopy(sub_step['response'])
del sub_step['method']
del sub_step['response']
if 'dependent_on_temp_event' in backup_response:
temp_event = get_dependent_results_from_database(
target,
module_name,
scan_unique_id,
backup_response['dependent_on_temp_event']
)
sub_step = replace_dependent_values(
sub_step,
temp_event
)
action = getattr(NettackSMTPLib, backup_method, None)
for _ in range(options['retries']):
try:
response = action(**sub_step)
break
except Exception as _:
response = []
sub_step['method'] = backup_method
sub_step['response'] = backup_response
sub_step['response']['conditions_results'] = response
# sub_step['response']['conditions_results'] = response_conditions_matched(sub_step, response)
return process_conditions(
sub_step,
module_name,
target,
scan_unique_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
)

View File

@ -1,266 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import copy
import re
import os
import select
import struct
import time
from core.utility import reverse_and_regex_condition
from core.utility import process_conditions
from core.utility import get_dependent_results_from_database
from core.utility import replace_dependent_values
def response_conditions_matched(sub_step, response):
conditions = sub_step['response']['conditions']
condition_type = sub_step['response']['condition_type']
condition_results = {}
if sub_step['method'] == 'tcp_connect_only':
return response
if sub_step['method'] == 'tcp_connect_send_and_receive':
if response:
received_content = response['response']
for condition in conditions:
regex = re.findall(re.compile(conditions[condition]['regex']), received_content)
reverse = conditions[condition]['reverse']
condition_results[condition] = reverse_and_regex_condition(regex, reverse)
for condition in copy.deepcopy(condition_results):
if not condition_results[condition]:
del condition_results[condition]
if 'open_port' in condition_results and len(condition_results) > 1:
del condition_results['open_port']
del conditions['open_port']
if condition_type == 'and':
return condition_results if len(condition_results) == len(conditions) else []
if condition_type == 'or':
return condition_results if condition_results else []
return []
if sub_step['method'] == 'socket_icmp':
return response
return []
class NettackerSocket:
def tcp_connect_only(host, ports, timeout):
socket_connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_connection.settimeout(timeout)
socket_connection.connect((host, int(ports)))
peer_name = socket_connection.getpeername()
socket_connection.close()
return {
"peer_name": peer_name,
"service": socket.getservbyport(int(ports))
}
def tcp_connect_send_and_receive(host, ports, timeout):
socket_connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_connection.settimeout(timeout)
socket_connection.connect((host, int(ports)))
peer_name = socket_connection.getpeername()
try:
socket_connection.send(b"ABC\x00\r\n" * 10)
response = socket_connection.recv(1024 * 1024 * 10)
socket_connection.close()
except Exception:
try:
socket_connection.close()
response = b""
except Exception:
response = b""
return {
"peer_name": peer_name,
"service": socket.getservbyport(int(ports)),
"response": response.decode(errors='ignore')
}
def socket_icmp(host, timeout):
"""
A pure python ping implementation using raw socket.
Note that ICMP messages can only be sent from processes running as root.
Derived from ping.c distributed in Linux's netkit. That code is
copyright (c) 1989 by The Regents of the University of California.
That code is in turn derived from code written by Mike Muuss of the
US Army Ballistic Research Laboratory in December, 1983 and
placed in the public domain. They have my thanks.
Bugs are naturally mine. I'd be glad to hear about them. There are
certainly word - size dependenceies here.
Copyright (c) Matthew Dixon Cowles, <http://www.visi.com/~mdc/>.
Distributable under the terms of the GNU General Public License
version 2. Provided with no warranties of any sort.
Original Version from Matthew Dixon Cowles:
-> ftp://ftp.visi.com/users/mdc/ping.py
Rewrite by Jens Diemer:
-> http://www.python-forum.de/post-69122.html#69122
Rewrite by George Notaras:
-> http://www.g-loaded.eu/2009/10/30/python-ping/
Fork by Pierre Bourdon:
-> http://bitbucket.org/delroth/python-ping/
Revision history
~~~~~~~~~~~~~~~~
November 22, 1997
-----------------
Initial hack. Doesn't do much, but rather than try to guess
what features I (or others) will want in the future, I've only
put in what I need now.
December 16, 1997
-----------------
For some reason, the checksum bytes are in the wrong order when
this is run under Solaris 2.X for SPARC but it works right under
Linux x86. Since I don't know just what's wrong, I'll swap the
bytes always and then do an htons().
December 4, 2000
----------------
Changed the struct.pack() calls to pack the checksum and ID as
unsigned. My thanks to Jerome Poincheval for the fix.
May 30, 2007
------------
little rewrite by Jens Diemer:
- change socket asterisk import to a normal import
- replace time.time() with time.clock()
- delete "return None" (or change to "return" only)
- in checksum() rename "str" to "source_string"
November 8, 2009
----------------
Improved compatibility with GNU/Linux systems.
Fixes by:
* George Notaras -- http://www.g-loaded.eu
Reported by:
* Chris Hallman -- http://cdhallman.blogspot.com
Changes in this release:
- Re-use time.time() instead of time.clock(). The 2007 implementation
worked only under Microsoft Windows. Failed on GNU/Linux.
time.clock() behaves differently under the two OSes[1].
[1] http://docs.python.org/library/time.html#time.clock
September 25, 2010
------------------
Little modifications by Georgi Kolev:
- Added quiet_ping function.
- returns percent lost packages, max round trip time, avrg round trip
time
- Added packet size to verbose_ping & quiet_ping functions.
- Bump up version to 0.2
------------------
5 Aug 2021 - Modified by Ali Razmjoo Qalaei (Reformat the code and more human readable)
"""
icmp_socket = socket.getprotobyname("icmp")
socket_connection = socket.socket(
socket.AF_INET,
socket.SOCK_RAW,
icmp_socket
)
random_integer = os.getpid() & 0xFFFF
icmp_echo_request = 8
# Make a dummy header with a 0 checksum.
dummy_checksum = 0
header = struct.pack("bbHHh", icmp_echo_request, 0, dummy_checksum, random_integer, 1)
data = struct.pack("d", time.time()) + struct.pack("d", time.time()) + str(
(76 - struct.calcsize("d")) * "Q"
).encode() # packet size = 76 (removed 8 bytes size of header)
source_string = header + data
# Calculate the checksum on the data and the dummy header.
calculate_data = 0
max_size = (len(source_string) / 2) * 2
counter = 0
while counter < max_size:
calculate_data += source_string[counter + 1] * 256 + source_string[counter]
calculate_data = calculate_data & 0xffffffff # Necessary?
counter += 2
if max_size < len(source_string):
calculate_data += source_string[len(source_string) - 1]
calculate_data = calculate_data & 0xffffffff # Necessary?
calculate_data = (calculate_data >> 16) + (calculate_data & 0xffff)
calculate_data = calculate_data + (calculate_data >> 16)
calculated_data = ~calculate_data & 0xffff
# Swap bytes. Bugger me if I know why.
dummy_checksum = calculated_data >> 8 | (calculated_data << 8 & 0xff00)
header = struct.pack(
"bbHHh", icmp_echo_request, 0, socket.htons(dummy_checksum), random_integer, 1
)
socket_connection.sendto(header + data, (socket.gethostbyname(host), 1)) # Don't know about the 1
while True:
started_select = time.time()
what_ready = select.select([socket_connection], [], [], timeout)
how_long_in_select = (time.time() - started_select)
if not what_ready[0]: # Timeout
break
time_received = time.time()
received_packet, address = socket_connection.recvfrom(1024)
icmp_header = received_packet[20:28]
packet_type, packet_code, packet_checksum, packet_id, packet_sequence = struct.unpack(
"bbHHh", icmp_header
)
if packet_id == random_integer:
packet_bytes = struct.calcsize("d")
time_sent = struct.unpack("d", received_packet[28:28 + packet_bytes])[0]
delay = time_received - time_sent
break
timeout = timeout - how_long_in_select
if timeout <= 0:
break
socket_connection.close()
return {
"host": host,
"response_time": delay
}
class Engine:
def run(
sub_step,
module_name,
target,
scan_unique_id,
options,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
):
backup_method = copy.deepcopy(sub_step['method'])
backup_response = copy.deepcopy(sub_step['response'])
del sub_step['method']
del sub_step['response']
if 'dependent_on_temp_event' in backup_response:
temp_event = get_dependent_results_from_database(
target,
module_name,
scan_unique_id,
backup_response['dependent_on_temp_event']
)
sub_step = replace_dependent_values(
sub_step,
temp_event
)
action = getattr(NettackerSocket, backup_method, None)
for _ in range(options['retries']):
try:
response = action(**sub_step)
break
except Exception:
response = []
sub_step['method'] = backup_method
sub_step['response'] = backup_response
sub_step['response']['conditions_results'] = response_conditions_matched(sub_step, response)
return process_conditions(
sub_step,
module_name,
target,
scan_unique_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
)

View File

@ -1,90 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import copy
import paramiko
import logging
# from core.utility import reverse_and_regex_condition
from core.utility import process_conditions
from core.utility import get_dependent_results_from_database
from core.utility import replace_dependent_values
# def response_conditions_matched(sub_step, response):
# return response
class NettackSSHLib:
def ssh_brute_force(host, ports, usernames, passwords, timeout):
paramiko_logger = logging.getLogger("paramiko.transport")
paramiko_logger.disabled = True
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(
hostname=host,
username=usernames,
password=passwords,
port=int(ports),
timeout=int(timeout)
)
ssh.close()
return {
"host": host,
"username": usernames,
"password": passwords,
"port": ports
}
class Engine:
def run(
sub_step,
module_name,
target,
scan_unique_id,
options,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
):
backup_method = copy.deepcopy(sub_step['method'])
backup_response = copy.deepcopy(sub_step['response'])
del sub_step['method']
del sub_step['response']
if 'dependent_on_temp_event' in backup_response:
temp_event = get_dependent_results_from_database(
target,
module_name,
scan_unique_id,
backup_response['dependent_on_temp_event']
)
sub_step = replace_dependent_values(
sub_step,
temp_event
)
action = getattr(NettackSSHLib, backup_method, None)
for _ in range(options['retries']):
try:
response = action(**sub_step)
break
except Exception:
response = []
sub_step['method'] = backup_method
sub_step['response'] = backup_response
sub_step['response']['conditions_results'] = response
# sub_step['response']['conditions_results'] = response_conditions_matched(sub_step, response)
return process_conditions(
sub_step,
module_name,
target,
scan_unique_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
)

View File

@ -1,83 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import copy
import telnetlib
# from core.utility import reverse_and_regex_condition
from core.utility import process_conditions
from core.utility import get_dependent_results_from_database
from core.utility import replace_dependent_values
# def response_conditions_matched(sub_step, response):
# return response
class NettackTelnetLib:
def telnet_brute_force(host, ports, usernames, passwords, timeout):
telnet_connection = telnetlib.Telnet(host, port=int(ports), timeout=int(timeout))
telnet_connection.read_until(b"login: ")
telnet_connection.write(usernames + "\n")
telnet_connection.read_until(b"Password: ")
telnet_connection.write(passwords + "\n")
telnet_connection.close()
return {
"host": host,
"username": usernames,
"password": passwords,
"port": ports
}
class Engine:
def run(
sub_step,
module_name,
target,
scan_unique_id,
options,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
):
backup_method = copy.deepcopy(sub_step['method'])
backup_response = copy.deepcopy(sub_step['response'])
del sub_step['method']
del sub_step['response']
if 'dependent_on_temp_event' in backup_response:
temp_event = get_dependent_results_from_database(
target,
module_name,
scan_unique_id,
backup_response['dependent_on_temp_event']
)
sub_step = replace_dependent_values(
sub_step,
temp_event
)
action = getattr(NettackTelnetLib, backup_method, None)
for _ in range(options['retries']):
try:
response = action(**sub_step)
break
except Exception as _:
response = []
sub_step['method'] = backup_method
sub_step['response'] = backup_response
sub_step['response']['conditions_results'] = response
# sub_step['response']['conditions_results'] = response_conditions_matched(sub_step, response)
return process_conditions(
sub_step,
module_name,
target,
scan_unique_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
)

View File

@ -1,28 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from core.scan_targers import start_scan_processes
from core.alert import info
from core.alert import write
from core.alert import messages
from core.load_modules import load_all_modules
from core.args_loader import load_all_args
from core.args_loader import check_all_required
def load():
"""
load all ARGS, Apply rules and go for attacks
Returns:
True if success otherwise None
"""
write("\n\n")
options = check_all_required(load_all_args())
info(messages("scan_started"))
info(messages("loaded_modules").format(len(load_all_modules())))
exit_code = start_scan_processes(options)
info(messages("done"))
return exit_code

View File

@ -1,22 +0,0 @@
OWASP Nettacker core functions
==============================
OWASP Nettacker core functions are stored in here.
* `die.py` exit functions
* `time.py` time functions
* `alert.py` user alerts and printing functions
* `args_loader.py` ARGV commands and apply rules
* `attack.py` start new attacks and multi-processing managements
* `color.py` color founds for windows and linux/mac.
* `compatible.py` compatibility functions
* `config.py` user configs (could be modify by user)
* `config_builder.py` core static configs (same as user configs but should not be change by users)
* `get_input.py` get inputs from users functions
* `ip.py` IPv4 and IPv6 functions
* `load_modules` load modules, requirements, paths functions
* `log.py` log the scans and generate reports
* `parse.py` parse the ARGV and pass it
* `targets.py` process, calculate and count targets
* `update.py` updates functions of the framework
* `wizard.py` wizard mode for the framework

View File

@ -1,102 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy
import multiprocessing
from core.alert import (info,
verbose_event_info,
messages)
from core.targets import expand_targets
from core.utility import generate_random_token
from core.load_modules import perform_scan
from terminable_thread import Thread
from core.utility import wait_for_threads_to_finish
from core.graph import create_report
def parallel_scan_process(options, targets, scan_unique_id, process_number):
active_threads = []
verbose_event_info(messages("single_process_started").format(process_number))
total_number_of_modules = len(targets) * len(options.selected_modules)
total_number_of_modules_counter = 1
for target in targets:
for module_name in options.selected_modules:
thread = Thread(
target=perform_scan,
args=(
options,
target,
module_name,
scan_unique_id,
process_number,
total_number_of_modules_counter,
total_number_of_modules
)
)
thread.name = f"{target} -> {module_name}"
thread.start()
verbose_event_info(
messages("start_parallel_module_scan").format(
process_number,
module_name,
target,
total_number_of_modules_counter,
total_number_of_modules
)
)
total_number_of_modules_counter += 1
active_threads.append(thread)
if not wait_for_threads_to_finish(active_threads, options.parallel_module_scan, True):
return False
wait_for_threads_to_finish(active_threads, maximum=None, terminable=True)
return True
def start_scan_processes(options):
"""
preparing for attacks and managing multi-processing for host
Args:
options: all options
Returns:
True when it ends
"""
scan_unique_id = generate_random_token(32)
# find total number of targets + types + expand (subdomain, IPRanges, etc)
# optimize CPU usage
info(messages("regrouping_targets"))
options.targets = [
targets.tolist() for targets in numpy.array_split(
expand_targets(options, scan_unique_id),
options.set_hardware_usage if options.set_hardware_usage >= len(options.targets) else len(options.targets)
)
]
info(messages("removing_old_db_records"))
from database.db import remove_old_logs
for target_group in options.targets:
for target in target_group:
for module_name in options.selected_modules:
remove_old_logs(
{
"target": target,
"module_name": module_name,
"scan_unique_id": scan_unique_id,
}
)
for _ in range(options.targets.count([])):
options.targets.remove([])
active_processes = []
info(messages("start_multi_process").format(len(options.targets)))
process_number = 0
for targets in options.targets:
process_number += 1
process = multiprocessing.Process(
target=parallel_scan_process,
args=(options, targets, scan_unique_id, process_number,)
)
process.start()
active_processes.append(process)
exit_code = wait_for_threads_to_finish(active_processes, sub_process=True)
create_report(options, scan_unique_id)
return exit_code

View File

@ -1,74 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import copy
import json
from core.ip import (get_ip_range,
generate_ip_range,
is_single_ipv4,
is_ipv4_range,
is_ipv4_cidr,
is_single_ipv6,
is_ipv6_range,
is_ipv6_cidr)
from database.db import find_events
def expand_targets(options, scan_unique_id):
"""
analysis and calulcate targets.
Args:
options: all options
scan_unique_id: unique scan identifier
Returns:
a generator
"""
from core.load_modules import perform_scan
targets = []
for target in options.targets:
if '://' in target:
# remove url proto; uri; port
target = target.split('://')[1].split('/')[0].split(':')[0]
targets.append(target)
# single IPs
elif is_single_ipv4(target) or is_single_ipv6(target):
if options.scan_ip_range:
targets += get_ip_range(target)
else:
targets.append(target)
# IP ranges
elif is_ipv4_range(target) or is_ipv6_range(target) or is_ipv4_cidr(target) or is_ipv6_cidr(target):
targets += generate_ip_range(target)
# domains
elif options.scan_subdomains:
targets.append(target)
perform_scan(
options,
target,
'subdomain_scan',
scan_unique_id,
'pre_process',
'pre_process_thread',
'unknown'
)
for row in find_events(target, 'subdomain_scan', scan_unique_id):
for sub_domain in json.loads(row.json_event)['response']['conditions_results']['content']:
if sub_domain not in targets:
targets.append(sub_domain)
else:
targets.append(target)
if options.ping_before_scan:
for target in copy.deepcopy(targets):
perform_scan(
options,
target,
'icmp_scan',
scan_unique_id,
'pre_process',
'pre_process_thread',
'unknown'
)
if not find_events(target, 'icmp_scan', scan_unique_id):
targets.remove(target)
return list(set(targets))

View File

@ -1,16 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import datetime
def now(model="%Y-%m-%d %H:%M:%S"):
"""
get now date and time
Args:
model: the date and time model, default is "%Y-%m-%d %H:%M:%S"
Returns:
the date and time of now
"""
return datetime.datetime.now().strftime(model) if model else datetime.datetime.now()

View File

@ -1,498 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import copy
import random
import string
import sys
import ctypes
import time
import json
import os
import multiprocessing
import yaml
import hashlib
from core.load_modules import load_all_languages
from core.time import now
from core.color import color
def process_conditions(
event,
module_name,
target,
scan_unique_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
):
from core.alert import (success_event_info,
verbose_info,
messages)
if 'save_to_temp_events_only' in event.get('response', ''):
from database.db import submit_temp_logs_to_db
submit_temp_logs_to_db(
{
"date": now(model=None),
"target": target,
"module_name": module_name,
"scan_unique_id": scan_unique_id,
"event_name": event['response']['save_to_temp_events_only'],
"port": event.get('ports', ''),
"event": event,
"data": response
}
)
if event['response']['conditions_results'] and 'save_to_temp_events_only' not in event.get('response', ''):
from database.db import submit_logs_to_db
# remove sensitive information before submitting to db
from config import nettacker_api_config
options = copy.deepcopy(options)
for key in nettacker_api_config():
try:
del options[key]
except Exception:
continue
del event['response']['conditions']
del event['response']['condition_type']
event_request_keys = copy.deepcopy(event)
del event_request_keys['response']
submit_logs_to_db(
{
"date": now(model=None),
"target": target,
"module_name": module_name,
"scan_unique_id": scan_unique_id,
"port": event.get('ports') or event.get('port') or (
event.get('url').split(':')[2].split('/')[0] if
type(event.get('url')) == str and len(event.get('url').split(':')) >= 3 and
event.get('url').split(':')[2].split('/')[0].isdigit() else ""
),
"event": " ".join(
yaml.dump(event_request_keys).split()
) + "conditions: " + " ".join(
yaml.dump(event['response']['conditions_results']).split()
),
"json_event": event
}
)
success_event_info(
messages("send_success_event_from_module").format(
process_number,
module_name,
target,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests,
" ".join(
[
color('yellow') + key + color('reset') if ':' in key
else color('green') + key + color('reset')
for key in yaml.dump(event_request_keys).split()
]
),
filter_large_content(
"conditions: " + " ".join(
[
color('purple') + key + color('reset') if ':' in key
else color('green') + key + color('reset')
for key in yaml.dump(event['response']['conditions_results']).split()
]
),
filter_rate=150
)
)
)
verbose_info(
json.dumps(event)
)
return True
else:
del event['response']['conditions']
verbose_info(
messages("send_unsuccess_event_from_module").format(
process_number,
module_name,
target,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests
)
)
verbose_info(
json.dumps(event)
)
return 'save_to_temp_events_only' in event['response']
def filter_large_content(content, filter_rate=150):
from core.alert import messages
if len(content) <= filter_rate:
return content
else:
filter_rate -= 1
filter_index = filter_rate
for char in content[filter_rate:]:
if char == ' ':
return content[0:filter_index] + messages('filtered_content')
else:
filter_index += 1
return content
def get_dependent_results_from_database(target, module_name, scan_unique_id, event_name):
from database.db import find_temp_events
while True:
event = find_temp_events(target, module_name, scan_unique_id, event_name)
if event:
break
time.sleep(0.1)
return json.loads(event.event)['response']['conditions_results']
def find_and_replace_dependent_values(sub_step, dependent_on_temp_event):
if type(sub_step) == dict:
for key in copy.deepcopy(sub_step):
if type(sub_step[key]) not in [str, float, int, bytes]:
sub_step[key] = find_and_replace_dependent_values(
copy.deepcopy(sub_step[key]), dependent_on_temp_event
)
else:
if type(sub_step[key]) == str:
if 'dependent_on_temp_event' in sub_step[key]:
globals().update(locals())
exec('sub_step[key] = {sub_step}'.format(sub_step=sub_step[key]), globals(), {})
if type(sub_step) == list:
value_index = 0
for value in copy.deepcopy(sub_step):
if type(sub_step[value_index]) not in [str, float, int, bytes]:
sub_step[key] = find_and_replace_dependent_values(
copy.deepcopy(sub_step[value_index]), dependent_on_temp_event
)
else:
if type(sub_step[value_index]) == str:
if 'dependent_on_temp_event' in sub_step[value_index]:
globals().update(locals())
exec('sub_step[value_index] = {sub_step}'.format(sub_step=sub_step[value_index]), globals(), {})
value_index += 1
return sub_step
def replace_dependent_values(sub_step, dependent_on_temp_event):
return find_and_replace_dependent_values(sub_step, dependent_on_temp_event)
def reverse_and_regex_condition(regex, reverse):
if regex:
if reverse:
return []
return list(set(regex))
else:
if reverse:
return True
return []
def select_maximum_cpu_core(mode):
if mode == 'maximum':
return int(multiprocessing.cpu_count() - 1) if int(multiprocessing.cpu_count() - 1) >= 1 else 1
elif mode == 'high':
return int(multiprocessing.cpu_count() / 2) if int(multiprocessing.cpu_count() - 1) >= 1 else 1
elif mode == 'normal':
return int(multiprocessing.cpu_count() / 4) if int(multiprocessing.cpu_count() - 1) >= 1 else 1
elif mode == 'low':
return int(multiprocessing.cpu_count() / 8) if int(multiprocessing.cpu_count() - 1) >= 1 else 1
else:
return 1
def wait_for_threads_to_finish(threads, maximum=None, terminable=False, sub_process=False):
while threads:
try:
for thread in threads[:]:
if not thread.is_alive():
threads.remove(thread)
if maximum and len(threads) < maximum:
break
time.sleep(0.01)
except KeyboardInterrupt:
if terminable:
for thread in threads:
terminate_thread(thread)
if sub_process:
for thread in threads:
thread.kill()
return False
return True
def terminate_thread(thread, verbose=True):
"""
kill a thread https://stackoverflow.com/a/15274929
Args:
thread: an alive thread
verbose: verbose mode/boolean
Returns:
True/None
"""
from core.alert import info
if verbose:
info("killing {0}".format(thread.name))
if not thread.is_alive():
return
exc = ctypes.py_object(SystemExit)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_long(thread.ident),
exc
)
if res == 0:
raise ValueError("nonexistent thread id")
elif res > 1:
# if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
return True
def find_args_value(args_name):
try:
return sys.argv[sys.argv.index(args_name) + 1]
except Exception:
return None
def application_language():
from config import nettacker_global_config
nettacker_global_configuration = nettacker_global_config()
if "-L" in sys.argv:
language = find_args_value('-L') or 'en'
elif "--language" in sys.argv:
language = find_args_value('--language') or 'en'
else:
language = nettacker_global_configuration['nettacker_user_application_config']['language']
if language not in load_all_languages():
language = 'en'
return language
def generate_random_token(length=10):
return "".join(
random.choice(string.ascii_lowercase) for _ in range(length)
)
def re_address_repeaters_key_name(key_name):
return "".join(['[\'' + _key + '\']' for _key in key_name.split('/')[:-1]])
def generate_new_sub_steps(sub_steps, data_matrix, arrays):
original_sub_steps = copy.deepcopy(sub_steps)
steps_array = []
for array in data_matrix:
array_name_position = 0
for array_name in arrays:
for sub_step in sub_steps:
exec(
"original_sub_steps{key_name} = {matrix_value}".format(
key_name=re_address_repeaters_key_name(array_name),
matrix_value='"' + str(array[array_name_position]) + '"' if type(
array[array_name_position]) == int or type(array[array_name_position]) == str else array[
array_name_position]
)
)
array_name_position += 1
steps_array.append(copy.deepcopy(original_sub_steps))
return steps_array
def find_repeaters(sub_content, root, arrays):
if type(sub_content) == dict and 'nettacker_fuzzer' not in sub_content:
temprory_content = copy.deepcopy(sub_content)
original_root = root
for key in sub_content:
root = original_root
root += key + '/'
temprory_content[key], _root, arrays = find_repeaters(sub_content[key], root, arrays)
sub_content = copy.deepcopy(temprory_content)
root = original_root
if (type(sub_content) not in [bool, int, float]) and (
type(sub_content) == list or 'nettacker_fuzzer' in sub_content):
arrays[root] = sub_content
return (sub_content, root, arrays) if root != '' else arrays
def find_and_replace_configuration_keys(module_content, module_inputs):
if type(module_content) == dict:
for key in copy.deepcopy(module_content):
if key in module_inputs:
if module_inputs[key]:
module_content[key] = module_inputs[key]
elif type(module_content[key]) in [dict, list]:
module_content[key] = find_and_replace_configuration_keys(module_content[key], module_inputs)
elif type(module_content) == list:
array_index = 0
for key in copy.deepcopy(module_content):
module_content[array_index] = find_and_replace_configuration_keys(key, module_inputs)
array_index += 1
else:
return module_content
return module_content
class value_to_class:
def __init__(self, value):
self.value = value
def class_to_value(arrays):
original_arrays = copy.deepcopy(arrays)
array_index = 0
for array in arrays:
value_index = 0
for value in array:
if type(value) == value_to_class:
original_arrays[array_index][value_index] = value.value
value_index += 1
array_index += 1
return original_arrays
def generate_and_replace_md5(content):
# todo: make it betetr and document it
md5_content = content.split('NETTACKER_MD5_GENERATOR_START')[1].split('NETTACKER_MD5_GENERATOR_STOP')[0]
md5_content_backup = md5_content
if type(md5_content) == str:
md5_content = md5_content.encode()
md5_hash = hashlib.md5(md5_content).hexdigest()
return content.replace(
'NETTACKER_MD5_GENERATOR_START' + md5_content_backup + 'NETTACKER_MD5_GENERATOR_STOP',
md5_hash
)
def arrays_to_matrix(arrays):
import numpy
return numpy.array(
numpy.meshgrid(*[
arrays[array_name] for array_name in arrays
])
).T.reshape(
-1,
len(arrays.keys())
).tolist()
def string_to_bytes(string):
return string.encode()
def fuzzer_function_read_file_as_array(filename):
from config import nettacker_paths
return open(
os.path.join(
nettacker_paths()['payloads_path'],
filename
)
).read().split('\n')
def apply_data_functions(data):
original_data = copy.deepcopy(data)
function_results = {}
globals().update(locals())
for data_name in data:
if type(data[data_name]) == str and data[data_name].startswith('fuzzer_function'):
exec(
"fuzzer_function = {fuzzer_function}".format(
fuzzer_function=data[data_name]
),
globals(),
function_results
)
original_data[data_name] = function_results['fuzzer_function']
return original_data
def nettacker_fuzzer_repeater_perform(arrays):
original_arrays = copy.deepcopy(arrays)
for array_name in arrays:
if 'nettacker_fuzzer' in arrays[array_name]:
data = arrays[array_name]['nettacker_fuzzer']['data']
data_matrix = arrays_to_matrix(apply_data_functions(data))
prefix = arrays[array_name]['nettacker_fuzzer']['prefix']
input_format = arrays[array_name]['nettacker_fuzzer']['input_format']
interceptors = copy.deepcopy(arrays[array_name]['nettacker_fuzzer']['interceptors'])
if interceptors:
interceptors = interceptors.split(',')
suffix = arrays[array_name]['nettacker_fuzzer']['suffix']
processed_array = []
for sub_data in data_matrix:
formatted_data = {}
index_input = 0
for value in sub_data:
formatted_data[list(data.keys())[index_input]] = value
index_input += 1
interceptors_function = ''
interceptors_function_processed = ''
if interceptors:
interceptors_function += 'interceptors_function_processed = '
for interceptor in interceptors[::-1]:
interceptors_function += '{interceptor}('.format(interceptor=interceptor)
interceptors_function += 'input_format.format(**formatted_data)' + str(
')' * interceptors_function.count('('))
expected_variables = {}
globals().update(locals())
exec(interceptors_function, globals(), expected_variables)
interceptors_function_processed = expected_variables['interceptors_function_processed']
else:
interceptors_function_processed = input_format.format(**formatted_data)
processed_sub_data = interceptors_function_processed
if prefix:
processed_sub_data = prefix + processed_sub_data
if suffix:
processed_sub_data = processed_sub_data + suffix
processed_array.append(copy.deepcopy(processed_sub_data))
original_arrays[array_name] = processed_array
return original_arrays
def expand_module_steps(content):
original_content = copy.deepcopy(content)
for protocol_lib in content:
for sub_step in content[content.index(protocol_lib)]['steps']:
arrays = nettacker_fuzzer_repeater_perform(find_repeaters(sub_step, '', {}))
if arrays:
original_content[content.index(protocol_lib)]['steps'][
original_content[content.index(protocol_lib)]['steps'].index(sub_step)
] = generate_new_sub_steps(sub_step, class_to_value(arrays_to_matrix(arrays)), arrays)
else:
original_content[content.index(protocol_lib)]['steps'][
original_content[content.index(protocol_lib)]['steps'].index(sub_step)
] = [ # minimum 1 step in array
original_content[content.index(protocol_lib)]['steps'][
original_content[content.index(protocol_lib)]['steps'].index(sub_step)
]
]
return original_content
def sort_dictonary(dictionary):
etc_flag = '...' in dictionary
if etc_flag:
del dictionary['...']
sorted_dictionary = {}
for key in sorted(dictionary):
sorted_dictionary[key] = dictionary[key]
if etc_flag:
sorted_dictionary['...'] = {}
return sorted_dictionary

View File

@ -1,3 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
pass

View File

@ -1,57 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from config import nettacker_database_config
from database.models import Base
USER = nettacker_database_config()["USERNAME"]
PASSWORD = nettacker_database_config()["PASSWORD"]
HOST = nettacker_database_config()["HOST"]
PORT = nettacker_database_config()["PORT"]
DATABASE = nettacker_database_config()["DATABASE"]
def mysql_create_database():
"""
when using mysql database, this is the function that is used to create the database for the first time when you run
the nettacker module.
Args:
None
Returns:
True if success otherwise False
"""
try:
engine = create_engine('mysql://{0}:{1}@{2}:{3}'.format(USER, PASSWORD, HOST, PORT))
existing_databases = engine.execute("SHOW DATABASES;")
existing_databases = [
d[0] for d in existing_databases
]
if DATABASE not in existing_databases:
engine.execute("CREATE DATABASE {0} ".format(DATABASE))
return True
except Exception:
return False
def mysql_create_tables():
"""
when using mysql database, this is the function that is used to create the tables in the database for the first
time when you run the nettacker module.
Args:
None
Returns:
True if success otherwise False
"""
try:
db_engine = create_engine('mysql://{0}:{1}@{2}:{3}/{4}'.format(USER, PASSWORD, HOST, PORT, DATABASE))
Base.metadata.create_all(db_engine)
return True
except Exception:
return False

View File

@ -1,53 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from config import nettacker_database_config
from database.models import Base
from sqlalchemy.exc import OperationalError
USER = nettacker_database_config()["USERNAME"]
PASSWORD = nettacker_database_config()["PASSWORD"]
HOST = nettacker_database_config()["HOST"]
PORT = nettacker_database_config()["PORT"]
DATABASE = nettacker_database_config()["DATABASE"]
def postgres_create_database():
"""
when using postgres database, this is the function that is used to create the database for the first time when you
the nettacker run module.
Args:
None
Returns:
True if success otherwise False
"""
try:
engine = create_engine(
'postgres+psycopg2://{0}:{1}@{2}:{3}/{4}'.format(USER, PASSWORD, HOST, PORT, DATABASE)
)
Base.metadata.create_all(engine)
return True
except OperationalError:
# if the database does not exist
engine = create_engine(
"postgres+psycopg2://postgres:postgres@localhost/postgres")
conn = engine.connect()
conn.execute("commit")
conn.execute('CREATE DATABASE {0}'.format(DATABASE))
conn.close()
engine = create_engine(
'postgres+psycopg2://{0}:{1}@{2}:{3}/{4}'.format(
USER,
PASSWORD,
HOST,
PORT,
DATABASE
)
)
Base.metadata.create_all(engine)
except Exception:
return False

View File

@ -1,33 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from database.models import Base
from config import nettacker_database_config
DATABASE = nettacker_database_config()["DATABASE"]
def sqlite_create_tables():
"""
when using sqlite database, this is the function that is used to create the database schema for the first time when
you run the nettacker module.
Args:
None
Returns:
True if success otherwise False
"""
try:
db_engine = create_engine(
'sqlite:///{0}'.format(DATABASE),
connect_args={
'check_same_thread': False
}
)
Base.metadata.create_all(db_engine)
return True
except Exception:
return False

View File

@ -1,14 +1,13 @@
version: "3"
services:
nettacker:
build:
context: .
dockerfile: "Dockerfile"
command: python3 nettacker.py --start-api --api-host 0.0.0.0
dockerfile: Dockerfile
command: --start-api --api-host 0.0.0.0
container_name: nettacker
environment:
- docker_env=true
ports:
- 5000:5000
volumes:
- ./:/usr/src/owaspnettacker
environment:
- docker_env=true
- ./nettacker:/usr/src/owaspnettacker/nettacker

744
docs/API.md Normal file
View File

@ -0,0 +1,744 @@
WebUI/API Manual usage explained in the [Usage](Usage#api-and-webui) page but let's get into the structure of the request now.
- [Purpose](#purpose)
- [Requests Structure](#requests-structure)
- [New Scan](#new-scan)
- [Set Session](#set-session)
* [Set Cookie](#set-cookie)
* [Check Cookie](#check-cookie)
* [UnSet Cookie](#unset-cookie)
- [Results List](#results-list)
* [Get a Scan Result](#get-a-scan-result)
- [Hosts List](#hosts-list)
* [Search in the Hosts](#search-in-the-hosts)
- [Generate a HTML Scan Result for a Host](#generate-a-html-scan-result-for-a-host)
* [Get the Scan Result in JSON Type](#get-the-scan-result-in-json-type)
## Purpose
API usage purposes depend on the users, Some of them may want to scan their local company to monitor the network, This feature let all security staff use OWASP Nettacker on a shared server safely. API supports SSL. User can give their own Certificate and the key to run server on HTTPS.
## Requests Structure
```
am4n@am4n-HP-ProBook-450-G4:~/Documents/OWASP-Nettacker$ python nettacker.py --start-api
______ __ _____ _____
/ __ \ \ / /\ / ____| __ \
| | | \ \ /\ / / \ | (___ | |__) |
| | | |\ \/ \/ / /\ \ \___ \| ___/
| |__| | \ /\ / ____ \ ____) | | Version 0.0.1
\____/ \/ \/_/ \_\_____/|_| SAME
_ _ _ _ _
| \ | | | | | | | |
github.com/zdresearch | \| | ___| |_| |_ __ _ ___| | _____ _ __
owasp.org | . ` |/ _ \ __| __/ _` |/ __| |/ / _ \ '__|
zdresearch.com | |\ | __/ |_| || (_| | (__| < __/ |
|_| \_|\___|\__|\__\__,_|\___|_|\_\___|_|
* API Key: 2608863752f1f89fa385e43c76c2853b
* Serving Flask app "api.engine" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on https://127.0.0.1:5000/ (Press CTRL+C to quit)
```
At the first, you must send an API key through the request each time you send a request in `GET`, `POST`, or `Cookies` in the value named `key` or you will get `401` error in the restricted area.
```python
>>> import requests
>>> from requests.packages.urllib3.exceptions import InsecureRequestWarning
>>> requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
>>> r = requests.get('https://127.0.0.1:5000/?key=8370bd0a0b9a98ac25b341833fb0fb07')
>>> r.status_code
200
>>> r = requests.post('https://127.0.0.1:5000/', data={"key": "8370bd0a0b9a98ac25b341833fb0fb07"})
>>> r.status_code
200
>>> r = requests.get('https://127.0.0.1:5000/', cookies={"key": "8370bd0a0b9a98ac25b341833fb0fb07"})
>>> r.status_code
200
>>> r = requests.get('https://127.0.0.1:5000/new/scan', cookies={"key": "wrong_key"})
>>> r.status_code
401
```
## New Scan
To submit a new scan follow this step.
```python
>>> r = requests.post('https://127.0.0.1:5000/new/scan', data={"key": "8370bd0a0b9a98ac25b341833fb0fb07", "targets": "127.0.0.1,owasp.org", "selected_modules": "port_scan", "report_path_filename": "/home/test.html"})
>>> r.status_code
200
>>> import json
>>> print json.dumps(json.loads(r.content), sort_keys=True, indent=4)
{
"backup_ports": null,
"check_ranges": false,
"check_subdomains": false,
"database_host": "",
"database_name": "/home/am4n/owasp-nettacker/.nettacker/data/nettacker.db",
"database_password": "",
"database_port": "",
"database_type": "sqlite",
"database_username": "",
"graph_flag": "d3_tree_v2_graph",
"home_path": "/home/am4n/owasp-nettacker/.nettacker/data",
"language": "en",
"log_in_file": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_10_36_56_mibtrtoacd.html",
"methods_args": {
"as_user_set": "set_successfully"
},
"passwds": null,
"ping_flag": false,
"ports": null,
"profile": null,
"results_path": "/home/am4n/owasp-nettacker/.nettacker/data/results",
"retries": 3,
"scan_method": [
"port_scan"
],
"socks_proxy": null,
"targets": [
"owasp.org"
],
"thread_number": 100,
"thread_number_host": 5,
"time_sleep": 0.0,
"timeout_sec": 3,
"tmp_path": "/home/am4n/owasp-nettacker/.nettacker/data/tmp",
"users": null,
"verbose_level": 0
}
```
Please note, `targets` and `selected_modules` are **necessary** to submit a new scan unless you modify the config file before! The `selected_modules` could be empty if you define the `profile`.
```python
>>> r = requests.post('https://127.0.0.1:5000/new/scan', data={"key": "8370bd0a0b9a98ac25b341833fb0fb07"})
>>> r.content
'{"msg":"Cannot specify the target(s)","status":"error"}\n'
>>> r = requests.post('https://127.0.0.1:5000/new/scan', data={"key": "09877e92c75f6afdca6ae61ad3f53727", "targets": "127.0.0.1"})
>>> r.content
u'{"msg":"please choose your scan method!","status":"error"}\n'
>>> r = requests.post('https://127.0.0.1:5000/new/scan', data={"key": "09877e92c75f6afdca6ae61ad3f53727", "targets": "127.0.0.1", "selected_modules": "dir_scan,port_scan", "report_path_filename": "/home/test.html"})
>>> print json.dumps(json.loads(r.content), sort_keys=True, indent=4)
{
"backup_ports": null,
"check_ranges": false,
"check_subdomains": false,
"database_host": "",
"database_name": "/home/am4n/owasp-nettacker/.nettacker/data/nettacker.db",
"database_password": "",
"database_port": "",
"database_type": "sqlite",
"database_username": "",
"graph_flag": "d3_tree_v2_graph",
"home_path": "/home/am4n/owasp-nettacker/.nettacker/data",
"language": "en",
"log_in_file": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_10_47_08_dugacttfmf.html",
"methods_args": {
"as_user_set": "set_successfully"
},
"passwds": null,
"ping_flag": false,
"ports": null,
"profile": null,
"results_path": "/home/am4n/owasp-nettacker/.nettacker/data/results",
"retries": 3,
"scan_method": [
"dir_scan",
"port_scan"
],
"socks_proxy": null,
"targets": [
"127.0.0.1"
],
"thread_number": 100,
"thread_number_host": 5,
"time_sleep": 0.0,
"timeout_sec": 3,
"tmp_path": "/home/am4n/owasp-nettacker/.nettacker/data/tmp",
"users": null,
"verbose_level": 0
}
>>> r = requests.post('https://127.0.0.1:5000/new/scan', data={"key": "09877e92c75f6afdca6ae61ad3f53727", "targets": "127.0.0.1", "profile": "information_gathering"})
>>> print json.dumps(json.loads(r.content), sort_keys=True, indent=4)
{
"backup_ports": null,
"check_ranges": false,
"check_subdomains": false,
"database_host": "",
"database_name": "/home/am4n/owasp-nettacker/.nettacker/data/nettacker.db",
"database_password": "",
"database_port": "",
"database_type": "sqlite",
"database_username": "",
"graph_flag": "d3_tree_v2_graph",
"home_path": "/home/am4n/owasp-nettacker/.nettacker/data",
"language": "en",
"log_in_file": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_10_50_09_xjqatmkngn.html",
"methods_args": {
"as_user_set": "set_successfully"
},
"passwds": null,
"ping_flag": false,
"ports": null,
"profile": "information_gathering",
"results_path": "/home/am4n/owasp-nettacker/.nettacker/data/results",
"retries": 3,
"scan_method": [
"port_scan"
],
"socks_proxy": null,
"targets": [
"127.0.0.1"
],
"thread_number": 100,
"thread_number_host": 5,
"time_sleep": 0.0,
"timeout_sec": 3,
"tmp_path": "/home/am4n/owasp-nettacker/.nettacker/data/tmp",
"users": null,
"verbose_level": 0
}
>>>
```
All variables in JSON you've got in results could be changed in `GET`/`POST`/`Cookies`, you can fill them all just like normal CLI commands. (e.g. same scan method name (modules), you can separate with `,`, you can use `ports` like `80,100-200,1000,2000`, set users and passwords `user1,user2`, `passwd1,passwd2`). You cannot use `read_from_file:/tmp/users.txt` syntax in `methods_args`. if you want to send a big password list, just send it through the `POST` requests and separated with `,`.
## Set Session
To enable session-based requests, like (e.g. Python `requests.session()` or browsers), I developed a feature to interact with Cookie.
### Set Cookie
```python
>>> s = requests.session()
>>> r = s.get("https://localhost:5000/session/set?key=09877e92c75f6afdca6ae61ad3f53727")
>>> print json.dumps(json.loads(r.content), sort_keys=True, indent=4)
{
"msg": "your browser session is valid",
"status": "ok"
}
>>> print r.cookies
<RequestsCookieJar[<Cookie key=09877e92c75f6afdca6ae61ad3f53727 for localhost.local/>]>
>>> r = s.get("https://localhost:5000/new/scan")
>>> print r.content
{
"msg": "Cannot specify the target(s)",
"status": "error"
}
>>>
```
### Check Cookie
```python
>>> r = s.get("https://localhost:5000/session/check")
>>> print r.content
{
"msg": "your browser session is valid",
"status": "ok"
}
```
### UnSet Cookie
```python
>>> r = s.get("https://localhost:5000/session/kill")
>>> print r.content
{
"msg": "your browser session killed",
"status": "ok"
}
>>> print r.cookies
<RequestsCookieJar[]>
>>>
```
## Results List
```python
>>> r = s.get("https://localhost:5000/results/get_list?page=1")
>>> print(json.dumps(json.loads(r.content), sort_keys=True, indent=4))
[
{
"api_flag": 0,
"category": "vuln,brute,scan",
"date": "2020-06-09 11:08:45",
"events_num": 317,
"graph_flag": "d3_tree_v2_graph",
"id": 8,
"language": "en",
"ports": "default",
"profile": null,
"report_filename": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_11_04_17_pisajfbfyp.html",
"report_type": "HTML",
"scan_cmd": "nettacker.py -i 127.0.0.1 -m all -M 100",
"scan_id": "b745337b4feeb99cee3eb4ff4cb45fad",
"scan_method": "XSS_protection_vuln,ProFTPd_directory_traversal_vuln,port_scan,telnet_brute,ssl_certificate_expired_vuln,http_form_brute,ProFTPd_integer_overflow_vuln,heartbleed_vuln,joomla_user_enum_scan,http_basic_auth_brute,http_ntlm_brute,wp_user_enum_scan,ProFTPd_restriction_bypass_vuln,http_cors_vuln,apache_struts_vuln,wordpress_version_scan,clickjacking_vuln,wp_xmlrpc_bruteforce_vuln,cms_detection_scan,wordpress_dos_cve_2018_6389_vuln,content_security_policy_vuln,pma_scan,ftp_brute,wp_theme_scan,wappalyzer_scan,wp_xmlrpc_brute,wp_xmlrpc_pingback_vuln,smtp_brute,drupal_version_scan,ProFTPd_memory_leak_vuln,wp_plugin_scan,ssh_brute,joomla_template_scan,wp_timthumbs_scan,self_signed_certificate_vuln,Bftpd_memory_leak_vuln,CCS_injection_vuln,dir_scan,viewdns_reverse_ip_lookup_scan,Bftpd_parsecmd_overflow_vuln,icmp_scan,ProFTPd_exec_arbitary_vuln,server_version_vuln,x_powered_by_vuln,admin_scan,citrix_cve_2019_19781_vuln,joomla_version_scan,sender_policy_scan,ProFTPd_cpu_consumption_vuln,Bftpd_double_free_vuln,drupal_theme_scan,ProFTPd_heap_overflow_vuln,weak_signature_algorithm_vuln,drupal_modules_scan,subdomain_scan,Bftpd_remote_dos_vuln,content_type_options_vuln,xdebug_rce_vuln,options_method_enabled_vuln,ProFTPd_bypass_sqli_protection_vuln",
"verbose": 0
},
{
"api_flag": 0,
"category": "vuln,brute,scan",
"date": "2020-06-09 11:08:42",
"events_num": 372,
"graph_flag": "d3_tree_v2_graph",
"id": 7,
"language": "en",
"ports": "default",
"profile": null,
"report_filename": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_11_04_04_bdzipsmtcc.html",
"report_type": "HTML",
"scan_cmd": "nettacker.py -i 127.0.0.1 -m all",
"scan_id": "8e9a1b2fd03cb7b969d99beea1cff2aa",
"scan_method": "XSS_protection_vuln,ProFTPd_directory_traversal_vuln,port_scan,telnet_brute,ssl_certificate_expired_vuln,http_form_brute,ProFTPd_integer_overflow_vuln,heartbleed_vuln,joomla_user_enum_scan,http_basic_auth_brute,http_ntlm_brute,wp_user_enum_scan,ProFTPd_restriction_bypass_vuln,http_cors_vuln,apache_struts_vuln,wordpress_version_scan,clickjacking_vuln,wp_xmlrpc_bruteforce_vuln,cms_detection_scan,wordpress_dos_cve_2018_6389_vuln,content_security_policy_vuln,pma_scan,ftp_brute,wp_theme_scan,wappalyzer_scan,wp_xmlrpc_brute,wp_xmlrpc_pingback_vuln,smtp_brute,drupal_version_scan,ProFTPd_memory_leak_vuln,wp_plugin_scan,ssh_brute,joomla_template_scan,wp_timthumbs_scan,self_signed_certificate_vuln,Bftpd_memory_leak_vuln,CCS_injection_vuln,dir_scan,viewdns_reverse_ip_lookup_scan,Bftpd_parsecmd_overflow_vuln,icmp_scan,ProFTPd_exec_arbitary_vuln,server_version_vuln,x_powered_by_vuln,admin_scan,citrix_cve_2019_19781_vuln,joomla_version_scan,sender_policy_scan,ProFTPd_cpu_consumption_vuln,Bftpd_double_free_vuln,drupal_theme_scan,ProFTPd_heap_overflow_vuln,weak_signature_algorithm_vuln,drupal_modules_scan,subdomain_scan,Bftpd_remote_dos_vuln,content_type_options_vuln,xdebug_rce_vuln,options_method_enabled_vuln,ProFTPd_bypass_sqli_protection_vuln",
"verbose": 0
},
{
"api_flag": 0,
"category": "vuln,brute,scan",
"date": "2020-06-09 11:06:52",
"events_num": 1016,
"graph_flag": "d3_tree_v2_graph",
"id": 6,
"language": "en",
"ports": "default",
"profile": null,
"report_filename": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_11_03_23_ubytvgauvj.html",
"report_type": "HTML",
"scan_cmd": "nettacker.py -i 127.0.0.1 -m all -M 100 -t 1000",
"scan_id": "7d84af54f343e19671d1c52357bf928f",
"scan_method": "XSS_protection_vuln,ProFTPd_directory_traversal_vuln,port_scan,telnet_brute,ssl_certificate_expired_vuln,http_form_brute,ProFTPd_integer_overflow_vuln,heartbleed_vuln,joomla_user_enum_scan,http_basic_auth_brute,http_ntlm_brute,wp_user_enum_scan,ProFTPd_restriction_bypass_vuln,http_cors_vuln,apache_struts_vuln,wordpress_version_scan,clickjacking_vuln,wp_xmlrpc_bruteforce_vuln,cms_detection_scan,wordpress_dos_cve_2018_6389_vuln,content_security_policy_vuln,pma_scan,ftp_brute,wp_theme_scan,wappalyzer_scan,wp_xmlrpc_brute,wp_xmlrpc_pingback_vuln,smtp_brute,drupal_version_scan,ProFTPd_memory_leak_vuln,wp_plugin_scan,ssh_brute,joomla_template_scan,wp_timthumbs_scan,self_signed_certificate_vuln,Bftpd_memory_leak_vuln,CCS_injection_vuln,dir_scan,viewdns_reverse_ip_lookup_scan,Bftpd_parsecmd_overflow_vuln,icmp_scan,ProFTPd_exec_arbitary_vuln,server_version_vuln,x_powered_by_vuln,admin_scan,citrix_cve_2019_19781_vuln,joomla_version_scan,sender_policy_scan,ProFTPd_cpu_consumption_vuln,Bftpd_double_free_vuln,drupal_theme_scan,ProFTPd_heap_overflow_vuln,weak_signature_algorithm_vuln,drupal_modules_scan,subdomain_scan,Bftpd_remote_dos_vuln,content_type_options_vuln,xdebug_rce_vuln,options_method_enabled_vuln,ProFTPd_bypass_sqli_protection_vuln",
"verbose": 0
},
{
"api_flag": 0,
"category": "vuln,brute,scan",
"date": "2020-06-09 11:01:14",
"events_num": 1017,
"graph_flag": "d3_tree_v2_graph",
"id": 5,
"language": "en",
"ports": "default",
"profile": null,
"report_filename": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_10_59_29_oyzxmegtuk.html",
"report_type": "HTML",
"scan_cmd": "nettacker.py -i 127.0.0.1 -m all -t 1000",
"scan_id": "d944c9a02053fd387d1e3343fec6b320",
"scan_method": "XSS_protection_vuln,ProFTPd_directory_traversal_vuln,port_scan,telnet_brute,ssl_certificate_expired_vuln,http_form_brute,ProFTPd_integer_overflow_vuln,heartbleed_vuln,joomla_user_enum_scan,http_basic_auth_brute,http_ntlm_brute,wp_user_enum_scan,ProFTPd_restriction_bypass_vuln,http_cors_vuln,apache_struts_vuln,wordpress_version_scan,clickjacking_vuln,wp_xmlrpc_bruteforce_vuln,cms_detection_scan,wordpress_dos_cve_2018_6389_vuln,content_security_policy_vuln,pma_scan,ftp_brute,wp_theme_scan,wappalyzer_scan,wp_xmlrpc_brute,wp_xmlrpc_pingback_vuln,smtp_brute,drupal_version_scan,ProFTPd_memory_leak_vuln,wp_plugin_scan,ssh_brute,joomla_template_scan,wp_timthumbs_scan,self_signed_certificate_vuln,Bftpd_memory_leak_vuln,CCS_injection_vuln,dir_scan,viewdns_reverse_ip_lookup_scan,Bftpd_parsecmd_overflow_vuln,icmp_scan,ProFTPd_exec_arbitary_vuln,server_version_vuln,x_powered_by_vuln,admin_scan,citrix_cve_2019_19781_vuln,joomla_version_scan,sender_policy_scan,ProFTPd_cpu_consumption_vuln,Bftpd_double_free_vuln,drupal_theme_scan,ProFTPd_heap_overflow_vuln,weak_signature_algorithm_vuln,drupal_modules_scan,subdomain_scan,Bftpd_remote_dos_vuln,content_type_options_vuln,xdebug_rce_vuln,options_method_enabled_vuln,ProFTPd_bypass_sqli_protection_vuln",
"verbose": 0
},
{
"api_flag": 0,
"category": "scan",
"date": "2020-06-09 10:50:18",
"events_num": 9,
"graph_flag": "d3_tree_v2_graph",
"id": 4,
"language": "en",
"ports": "default",
"profile": "information_gathering",
"report_filename": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_10_50_09_xjqatmkngn.html",
"report_type": "HTML",
"scan_cmd": "Through the OWASP Nettacker API",
"scan_id": "05ba4e5b839b5ba525c9a35baa8864a1",
"scan_method": "port_scan",
"verbose": 0
},
{
"api_flag": 0,
"category": "scan",
"date": "2020-06-09 10:47:17",
"events_num": 9,
"graph_flag": "d3_tree_v2_graph",
"id": 3,
"language": "en",
"ports": "default",
"profile": null,
"report_filename": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_10_47_08_dugacttfmf.html",
"report_type": "HTML",
"scan_cmd": "Through the OWASP Nettacker API",
"scan_id": "18af7af856b4ceefac659a59c4908088",
"scan_method": "dir_scan,port_scan",
"verbose": 0
},
{
"api_flag": 0,
"category": "scan",
"date": "2020-06-09 10:38:50",
"events_num": 0,
"graph_flag": "d3_tree_v2_graph",
"id": 2,
"language": "en",
"ports": "default",
"profile": null,
"report_filename": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_10_35_10_jvxotwxako.html",
"report_type": "HTML",
"scan_cmd": "Through the OWASP Nettacker API",
"scan_id": "78d253c3a28d2bb4f467ac040ccaa854",
"scan_method": "port_scan",
"verbose": 0
},
{
"api_flag": 0,
"category": "scan",
"date": "2020-06-09 10:38:49",
"events_num": 3,
"graph_flag": "d3_tree_v2_graph",
"id": 1,
"language": "en",
"ports": "default",
"profile": null,
"report_filename": "/home/am4n/owasp-nettacker/.nettacker/data/results/results_2020_06_09_10_36_56_mibtrtoacd.html",
"report_type": "HTML",
"scan_cmd": "Through the OWASP Nettacker API",
"scan_id": "708e1dcf0f2ce9fe71038ccea7bf28bb",
"scan_method": "port_scan",
"verbose": 0
}
]
```
### Get a Scan Result
```python
>>> r = s.get("https://localhost:5000/results/get?id=8")
>>> print r.content[:500]
<!DOCTYPE html>
<!-- THIS PAGE COPIED AND MODIFIED FROM http://bl.ocks.org/robschmuecker/7880033-->
<title>OWASP Nettacker Report</title>
<meta charset="utf-8">
<div class="header">
<h3><a href="https://github.com/zdresearch/nettacker">OWASP Nettacker</a></h3>
<h3>Penetration Testing Graphs</h3>
</div>
<style type="text/css">
.header{
margin:2%;
text-align:center;
}
.node {
cursor: pointer;
}
.overlay{
background-color:#EEE;
}
.node circle {
fill: #f
...
```
## Hosts List
```python
>>> r = s.get("https://localhost:5000/logs/search?q=&page=1")
>>> print json.dumps(json.loads(r.content), sort_keys=True, indent=4)
[
{
"host": "owasp.org",
"info": {
"category": [
"scan"
],
"descriptions": [
"8443/http/TCP_CONNECT",
"80/http/TCP_CONNECT",
"443/http/TCP_CONNECT"
],
"open_ports": [],
"scan_methods": [
"port_scan"
]
}
}
]
>>>
```
### Search in the Hosts
```python
>>> r = s.get("https://localhost:5000/logs/search?q=port_scan&page=3")
>>> print r.content
[
{
"host": "owasp4.owasp.org",
"info": {
"category": [
"scan"
],
"descriptions": [
"22/TCP_CONNECT",
"80/TCP_CONNECT"
],
"open_ports": [
22,
80
],
"scan_methods": [
"port_scan"
]
}
},
{
"host": "new-wiki.owasp.org",
"info": {
"category": [
"scan"
],
"descriptions": [
"22/TCP_CONNECT",
"80/TCP_CONNECT"
],
"open_ports": [
22,
80
],
"scan_methods": [
"port_scan"
]
}
},
{
"host": "cheesemonkey.owasp.org",
"info": {
"category": [
"scan"
],
"descriptions": [
"80/TCP_CONNECT"
],
"open_ports": [
80
],
"scan_methods": [
"port_scan"
]
}
},
{
"host": "5.79.66.240",
"info": {
"category": [
"scan"
],
"descriptions": [
"filesmog.com",
"\u062f\u0631\u06af\u0627\u0647 \u0628\u0627\u0632"
],
"open_ports": [
5901,
6001,
22
],
"scan_methods": [
"viewdns_reverse_ip_lookup_scan",
"port_scan"
]
}
},
{
"host": "5.79.66.237",
"info": {
"category": [
"scan"
],
"descriptions": [
"\u062f\u0631\u06af\u0627\u0647 \u0628\u0627\u0632",
"http://5.79.66.237/robots.txt \u067e\u06cc\u062f\u0627 \u0634\u062f!(OK:200)",
"http://5.79.66.237/.htaccess.txt \u067e\u06cc\u062f\u0627 \u0634\u062f!(Forbidden:403)",
"http://5.79.66.237/.htaccess.save \u067e\u06cc\u062f\u0627 \u0634\u062f!(Forbidden:403)",
"http://5.79.66.237/phpmyadmin \u067e\u06cc\u062f\u0627 \u0634\u062f!(OK:200)",
"http://5.79.66.237/.htaccess.old \u067e\u06cc\u062f\u0627 \u0634\u062f!(Forbidden:403)",
"http://5.79.66.237/.htaccess \u067e\u06cc\u062f\u0627 \u0634\u062f!(Forbidden:403)",
"http://5.79.66.237/server-status \u067e\u06cc\u062f\u0627 \u0634\u062f!(Forbidden:403)",
"http://5.79.66.237//phpmyadmin/ \u067e\u06cc\u062f\u0627 \u0634\u062f!(OK:200)",
"http://5.79.66.237//phpMyAdmin/ \u067e\u06cc\u062f\u0627 \u0634\u062f!(OK:200)",
"offsec.ir"
],
"open_ports": [
8083,
8000,
443,
80,
22,
21
],
"scan_methods": [
"port_scan",
"dir_scan",
"pma_scan",
"viewdns_reverse_ip_lookup_scan"
]
}
},
{
"host": "192.168.1.124",
"info": {
"category": [
"scan"
],
"descriptions": [
"2179/TCP_CONNECT",
"445/TCP_CONNECT",
"135/TCP_CONNECT",
"22/TCP_CONNECT",
"139/TCP_CONNECT",
"zhanpang.cn",
"yowyeh.cn",
"treelights.website",
"sxyhed.com",
"redlxin.com",
"ppoo6.com",
"miancan.cn",
"maynard.top",
"liyedai.site",
"linterfund.com",
"li5xs.com",
"hxinglan.win",
"heresylly.top",
"gzptjwangye.bid",
"eatpeanutfree.com",
"comgmultiservices.com",
"biyao123.com"
],
"open_ports": [
2179,
445,
135,
22,
139
],
"scan_methods": [
"port_scan",
"viewdns_reverse_ip_lookup_scan"
]
}
},
{
"host": "192.168.1.127",
"info": {
"category": [
"scan"
],
"descriptions": [
"49152/TCP_CONNECT",
"49154/TCP_CONNECT",
"49155/TCP_CONNECT",
"49153/TCP_CONNECT"
],
"open_ports": [
49152,
49154,
49155,
49153
],
"scan_methods": [
"port_scan"
]
}
}
]
>>>
```
## Generate a HTML Scan Result for a Host
```python
>>> r = s.get("https://localhost:5000/logs/get_html?target=127.0.0.1&key=<your_api_key>")
>>> print r.content[:1000]
<!DOCTYPE html>
<!-- THIS PAGE COPIED AND MODIFIED FROM http://bl.ocks.org/robschmuecker/7880033-->
<title>OWASP Nettacker Report</title>
<meta charset="utf-8">
<div class="header">
<h3><a href="https://github.com/zdresearch/nettacker">OWASP Nettacker</a></h3>
<h3>Penetration Testing Graphs</h3>
</div>
<style type="text/css">
.header{
margin:2%;
text-align:center;
}
.node {
cursor: pointer;
}
.overlay{
background-color:#EEE;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font-size:12px;
font-family:sans-serif;
}
...
...
>>>
```
### Get the Scan Result in JSON Type
```python
>>> r = s.get("https://localhost:5000/logs/get_json?target=owasp.org&key=<your_api_key>")
>>> print(json.dumps(json.loads(r.content), sort_keys=True, indent=4))
[
{
"DESCRIPTION": "443/http/TCP_CONNECT",
"HOST": "owasp.org",
"PASSWORD": "",
"PORT": "443",
"SCAN_ID": "708e1dcf0f2ce9fe71038ccea7bf28bb",
"TIME": "2020-06-09 10:36:59",
"TYPE": "port_scan",
"USERNAME": ""
},
{
"DESCRIPTION": "80/http/TCP_CONNECT",
"HOST": "owasp.org",
"PASSWORD": "",
"PORT": "80",
"SCAN_ID": "708e1dcf0f2ce9fe71038ccea7bf28bb",
"TIME": "2020-06-09 10:36:59",
"TYPE": "port_scan",
"USERNAME": ""
},
{
"DESCRIPTION": "8443/http/TCP_CONNECT",
"HOST": "owasp.org",
"PASSWORD": "",
"PORT": "8443",
"SCAN_ID": "708e1dcf0f2ce9fe71038ccea7bf28bb",
"TIME": "2020-06-09 10:38:17",
"TYPE": "port_scan",
"USERNAME": ""
}
]
>>>
```

78
docs/CodebaseOverview.md Normal file
View File

@ -0,0 +1,78 @@
## OWASP Nettacker Codebase Overview
OWASP Nettacker is an opensource, Pythonbased framework for automated penetration testing and information gathering. It supports modular tasks such as port scanning, service detection, subdomain enumeration, vulnerability scans, and credential brute forcing, all driven by a unified CLI, REST API, and Web UI.
## Project layout
```
.
├── docs
├── nettacker
│   ├── api
│   ├── core
│   │   ├── lib
│   │   └── utils
│   ├── database
│   ├── lib
│   │   ├── compare_report
│   │   ├── graph
│   │   │   ├── d3_tree_v1
│   │   │   └── d3_tree_v2
│   │   ├── html_log
│   │   ├── icmp
│   │   └── payloads
│   │   ├── User-Agents
│   │   ├── passwords
│   │   └── wordlists
│   ├── locale
│   ├── modules
│   │   ├── brute
│   │   ├── scan
│   │   └── vuln
│   └── web
│   └── static
│   ├── css
│   ├── fonts
│   ├── img
│   │   └── flags
│   │   ├── 1x1
│   │   └── 4x3
│   ├── js
│   └── report
└── tests
├── api
├── core
│   ├── lib
│   └── utils
├── database
└── lib
└── payloads
```
- **Entry point** `nettacker/main.py` creates a `Nettacker` application instance and runs it when invoked via the provided script or CLI
- **Core engine (`nettacker/core`)**
- `app.py` orchestrates scans: parsing arguments, expanding targets (including IP ranges and subdomains), launching multiprocess/multithread modules, and generating reports
- `module.py` loads YAML-defined modules, applies service discovery results, expands payload loops, and dispatches protocol-specific engines in threaded fashion
- `arg_parser.py`, `ip.py`, `messages.py`, and `utils` provide CLI parsing, IP range handling, internationalized messages, and common helpers
- Protocol engines reside in `core/lib` (e.g., HTTP, FTP, SSH, SMTP, socket) and are invoked by modules
- **Modules (`nettacker/modules`)** Scanning logic is defined declaratively in YAML under three categories (`brute`, `scan`, `vuln`). Each module contains an `info` block and a list of `payloads` that specify library, request parameters, fuzzing rules, and response conditions. Example: `dir_scan` performs directory discovery over HTTP using wordlists and response conditions
- **Database layer (`nettacker/database`)** Uses SQLAlchemy to interface with SQLite, MySQL, or PostgreSQL for persisting events and reports
- **API & Web UI (`nettacker/api`, `nettacker/web`)** Flask-based REST API plus static assets enabling webbased scan management
- **Supporting libraries (`nettacker/lib`)** Reporting helpers, ICMP tools, graph generation, and payload wordlists
- **Configuration** `config.py` defines default paths, database settings, and runtime options
- **Tests** The `tests` directory includes unit tests and validation checks; for example, `test_yaml_regexes.py` ensures regex definitions in YAML modules compile correctly
- **Build & dependencies** `pyproject.toml` defines the project as a Poetry package and lists dependencies such as `aiohttp`, `multiprocess`, `paramiko`, and `sqlalchemy`
## Important concepts
- **Modular architecture:** Modules are YAML files; the engine interprets them and runs protocol-specific steps.
- **Target expansion:** Before scanning, the engine normalizes URLs, enumerates IP ranges, resolves subdomains, and runs preliminary checks like ICMP and port scans
- **Service discovery:** Results from `port_scan` feed into subsequent modules, allowing conditional execution based on discovered services. Service discovery can be turned off during scans using `-d` or `--skip-service-discovery` run-time option.
- **Concurrency:** Scans are distributed across processes and threads for performance, with configurable limits per host and module using the `-t` and `-M` runtime options. The requests can be rate-limited using the `-w` option.
## Where to go next
- **Documentation:** Review `docs/Installation.md` and `docs/Usage.md` for setup and basic usage; `docs/Modules.md` explains module types and parameters; `docs/Developers.md` covers contribution guidelines and how to add languages or modules
- **Explore modules:** Study YAML files under `nettacker/modules/*` to see how scans, brute-force checks, and vulnerability tests are structured.
- **Understand protocol engines:** Read files in `nettacker/core/lib/` to learn how HTTP, socket, and other protocol interactions are implemented.
- **Run locally:** Use the CLI (`nettacker`) or Docker instructions in [Installation](Installation.md) and [Usage](Usage.md)
- **Contribute:** Follow the guidelines in `docs/Developers.md` and run `make pre-commit` and `make test` before submitting changes.

38
docs/Contributors.md Normal file
View File

@ -0,0 +1,38 @@
People who helped to create the OWASP Nettacker. You can see the complete list of Developers on [OpenHub](https://www.openhub.net/p/OWASP-Nettacker/contributors) and [GitHub](https://github.com/OWASP/Nettacker/graphs/contributors) contributors.
### Leaders & Mentors
* [Ali Razmjoo Qalaei](mailto:ali.razmjoo@owasp.org)
* [Arkadii Yakovets](mailto:arkadii.yakovets@owasp.org)
* [Sam Stepanyan](mailto:sam.stepanyan@owasp.org)
* [Sri Harsha Gajavalli](mailto:sriharsha.g@owasp.org)
### Contributors
* [Shaddy Garg](mailto:shaddygarg1@gmail.com)
* [Pradeep Jairamani](mailto:pradeepjairamani22@gmail.com)
* [Hannah Brand](mailto:bran0793@umn.edu)
* [Vahid Behzadan](mailto:behzadan@ksu.edu)
* [Mohammad Reza Zamiri](mailto:mr.zamiri@ieee.org)
* [Mojtaba MasoumPour](mailto:mojtaba6892@gmail.com)
* [Ehsan Nezami](mailto:ehsan.empire1@gmail.com)
* [camel32bit](https://github.com/camel32bit)
* [Ravindra Sharma](mailto:sha.ravindra1307@gmail.com)
* [Harshavardhan Reddy](mailto:harsha010@outlook.com)
* [ArianPH](mailto:pandkhahiarian@gmail.com)
* [omdmhd](mailto:om.mo1375@gmail.com)
* [Mahdi Rasouli](mailto:mahdirasouli007@gmail.com)
* [Tikam Singh Alma](mailto:timonalma81@gmail.com)
* [Jecky](mailto:ht974@nyu.edu)
* [VictorSuraj](https://github.com/VictorSuraj)
* [Clarence Cromwell](mailto:clarencewcromwell@gmail.com)
* [Aman Gupta](mailto:aman.gupta@owasp.org)
* [Kunal Khandelwal](mailto:khandelwal.kunal4@gmail.com)
* [Pinaki Mondal aka 0xInfection](https://github.com/0xInfection)
* [Divyansh Jain](https://github.com/itsdivyanshjain)
* [Akshay Behl](https://github.com/Captain-T2004)
* **[FULL LIST](https://github.com/OWASP/Nettacker/graphs/contributors)**
The OWASP Nettacker Project Team is very grateful to Google's Summer of Code (GSoC - summerofcode.withgoogle.com) and to all GSoC students who helped to enhance Nettacker while working during their summer break!

174
docs/Developers.md Normal file
View File

@ -0,0 +1,174 @@
We gladly support and appreciate anyone who is interested in contributing to OWASP Nettacker. Overall contributors may focus on developing core framework, modules or payloads, language libraries, and media. After reading this document you should be able to get the basic knowledge to start developing. Please note that we are using PEP8 Python code style and [GitHub Actions](https://github.com/OWASP/Nettacker/actions) for checking all new PRs automatically against supported Python versions. If you use any code/library/module with a license, add the license into external license file.
* [Code of Conduct](https://github.com/OWASP/Nettacker/blob/master/CODE_OF_CONDUCT.md)
* [Issue Template](https://github.com/OWASP/Nettacker/blob/master/.github/ISSUE_TEMPLATE.md)
* [PR Template](https://github.com/OWASP/Nettacker/blob/master/.github/PULL_REQUEST_TEMPLATE.md)
* [License](https://github.com/OWASP/Nettacker/blob/master/LICENSE)
* [External Licenses](https://github.com/OWASP/Nettacker/blob/master/EXTERNAL_LIBRARIES_LICENSES.md)
________
* [Contribution Guidelines](#contribution-guidelines)
* [Roadmap](#roadmap)
* [Creating Media](#creating-media)
* [Contribute to Language Libraries](#contribute-to-language-libraries)
* [Add a New Language Library](#add-a-new-language-library)
* [Modify/Update Language Libraries](#modify-update-language-libraries)
# Contribution Guidelines
These are the guidelines you need to keep in mind while contributing:
* Start by familiarising yourself with the Nettacker Codebase: [Codebase Overview](CodebaseOverview.md)
* Use the automated checks: run `make pre-commit` and `make test`
* Thoroughly test your code locally.
* Be sure to add/update related documentation.
In case of any doubts regarding the guidelines please contact the project leaders.
# Roadmap
Developers always could be aware of the OWASP Nettacker roadmap by checking
* 1- Project Management Page <https://github.com/OWASP/Nettacker/projects>
* 2- Issues Page <https://github.com/OWASP/OWASP-Nettacker/issues>
# Creating Media
We appreciated all kind of media to demonstrate the OWASP Nettacker in any language and environment. It is a great activity to help us grow our framework and get more publicity. Currently, we collected a few media on [Media](https://github.com/OWASP/Nettacker/wiki/Media) page. Feel free to post your Media on [this](https://github.com/OWASP/Nettacker/issues/1) page.
# Contribute to Language Libraries
OWASP Nettacker is using multi-language libraries (default English) to create a better user experience. Currently we are supporting `Greek/el`, `French/fr`, `English/en`, `Dutch/nl`, `Pashto/ps`, `Turkish/tr`, `German/de`, `Korean/ko`, `Italian/it`, `Japanese/ja`, `Persian/fa`, `Armenian/hy`, `Arabic/ar`, `Chinese(Simplified)/zh-cn`, `Vietnamese/vi`, `Russian/ru`, `Hindi/hi`, `Urdu/ur`, `Indonesian/id`, `Spanish/es`, `Hebrew/iw`) languages. If you are an expert in one these languages, It would be a great favor to contribute to one of these. If any language you want to contribute is not listed, feel free to follow the below steps to add it.
## Add a New Language Library
In some cases language library does not exist, you can create a new file and add it to the framework.
* 1- Goto `nettacker/locale`
* 2- Name your message library in accordance with the ISO two-letter code e.g. `fa.yaml`
* 3- Copy the default language lib (`en.yaml`) and start your translation.
* 4- **Please notice that you should not change the key-value like `scan_started`, `options` and etc. you just need to modify the Values.**
## Modify/Update Language Libraries
To contribute to the existing libraries, You may go to `lib/messages` select the file you want to contribute and
* 1- Translate English messages to the selected language.
* 2- Compare the language library with **English** library and add new messages to this library and translate them.
* 3- Modify the translated messages to better translations.
# Contribute to Modules
Modules exist in path `nettacker/modules/module_category`. Currently, we have three categories (scan, brute, vuln). if you need to add more just create a directory with a name! To start a new module you should understand what kind of protocol you want to use. The list of protocols and module functionalities are in `core/module_protocols`. To understand how they work read the below example.
```yaml
info: # this section is to store information about module
name: dir_scan
author: OWASP Nettacker Team
severity: 3
description: Directory, Backup finder
reference: https://www.zaproxy.org/docs/alerts/10095/
profiles: # module will be added to below profiles and user can use --profile scan to run this and other modules in same profile
- scan
- http
- backup
- low_severity
payloads: # this section stores the payloads
- library: http # the time of library, you can use multiple library if needed as an array
verify: false
timeout: 3
cert: ""
stream: false
proxies: ""
steps:
- method: get # type of request
headers: # headers
User-Agent: "{user_agent}" # this will be replaced by default user-agent or user input
URL: # URL is the input we want to fuzz
nettacker_fuzzer:
input_format: "{{schema}}://{target}:{{ports}}/{{urls}}" # format of url
prefix: ""
suffix: ""
interceptors:
data:
urls:
- "administrator"
- "admin"
- "old"
- "_vti_bin"
- "_private"
- "cgi-bin"
- "public_html"
- "images"
schema:
- "http"
- "https"
ports:
- 80
- 443
response: # response will check if the payload were success
condition_type: or # could be and/or
conditions: # could be in header/content/status_code/reason/timeresponse
status_code:
regex: 200|403|401
reverse: false # if true, it will reverse the regex
```
The `http` protocol uses exactly the same inputs as the python `requests` library. if we want to convert the yaml code to python requests it will be:
```python
In [5]: import requests
In [6]: lib=requests
In [7]: lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:443/url", headers={'User-Agent': 'whatever'})
```
The inputs such as `ports` will be replaced by user input and 80,443 is just a default value to hold in case the user did not enter any ports. you can see all user inputs from `config.py`.
Any value that comes in an array in the YAML files will be treated as a loop and it will regenerate the request until all loops are finished.
```python
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:443/url1", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:443/url2", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:443/url3", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:443/url4", headers={'User-Agent': 'whatever'})
```
or
```python
dynamics: http, https, url1, url2 , url3, url4, port 80, port 443
# https
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:443/url1", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:443/url2", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:443/url3", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:443/url4", headers={'User-Agent': 'whatever'})
# http
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="http://www.owasp.org:80/url1", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="http://www.owasp.org:80/url2", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="http://www.owasp.org:80/url3", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="http://www.owasp.org:80/url4", headers={'User-Agent': 'whatever'})
# https on 80
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:80/url1", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:80/url2", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:80/url3", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="https://www.owasp.org:80/url4", headers={'User-Agent': 'whatever'})
# http on 443
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="http://www.owasp.org:443/url1", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="http://www.owasp.org:443/url2", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="http://www.owasp.org:443/url3", headers={'User-Agent': 'whatever'})
lib.get(verify=False, timeout=3, cert="", stream=False, proxies="", url="http://www.owasp.org:443/url4", headers={'User-Agent': 'whatever'})
```
# Contribute to Code Functionality & API & WebUI
Go nuts!

28
docs/Events.md Normal file
View File

@ -0,0 +1,28 @@
# Events
The OWASP Nettacker Events page lists various conferences and meetups where the OWASP Nettacker project has been presented. These include notable appearances at OFFSECONF 2017, BlackHat Europe, OWASP Global AppSec and Security BSides Dublin and Athens, among others. The page provides links to presentations, webinars, podcasts, and video content from these events:
* OWASP Nettacker was introduced in **OFFSECONF 2017** [[1](https://groups.google.com/forum/#!topic/owasp-nettacker/3gscDww2sf4)]
* OFFSECONF 2017 Introduction Presentation [[1](https://drive.google.com/file/d/1Ox1xpvncPgSZPaFjvTQvkOwxP3to7Rqk/view?usp=sharing)]
* OWASP Nettacker Accepted for **Google Summer of Code 2018** [[1](https://www.owasp.org/index.php/GSOC2018_Ideas)] [[2](https://summerofcode.withgoogle.com/organizations/6664778743808000/)]
* OWASP Nettacker Video Conference/Webinar for GSoC Team 1 May 2018 - **Vahid Behzadan - ML/AI in CyberSecurity** [[1](https://www.youtube.com/watch?v=7RQH8oECSyg)]
* **Shaddy Garg**'s GSoC Experince [[1](https://medium.com/@shaddygarg/google-summer-of-code-final-submission-12eb98993ba8)]
* **Pradeep Jairamani**'s GSoC Experince [[1](https://medium.com/@pradeepjairamani/google-summer-of-code-final-submission-7a498856c914)]
* OWASP Nettacker Tutorial by at **OWASP Bay Area** meetup (Presented by **Vahid Behzadan** - Sponsered by **OWASP Bay Area**) [[1](https://www.youtube.com/watch?v=4pu4hJMk6m8)]
* OWASP Nettacker Presented By Ali Razmjoo in OWASP Iran Chapter Meeting July 2018 [[1](https://www.owasp.org/index.php/Iran#tab=Past_Events)]
* OWASP Nettacker ICS Section Presented in **P0SCON 2018 By Mohammad Reza Zamiri** [[1](http://www.poscon.ir/)]
* OWASP Nettacker ICS Section will be presented in **KasperSky Industrial Cybersecurity**: Opportunities and challenges in Digital Transformation 2018 by **Mohammad Reza Zamiri** [[1](https://github.com/zdresearch/OWASP-Nettacker/tree/master/lib/payload/scanner/ics_honeypot)] [[2](https://ics.kaspersky.com/conference/)]
* OWASP Nettacker was presented at **BlackHat Europe Arsenal 2018** by Sam Stepanyan and Dr Grigorios "Greg" Fragkos
* OWASP Nettacker was presented at **BlackHat Europe Arsenal 2019** (more In-Depth Demo) by Paul Harragan and Sam Stepanyan [[1](https://www.blackhat.com/eu-19/arsenal/schedule/#owasp-nettacker-updated---more-in-depth-demo-18100)]
* OWASP Nettacker was presented at **AppSec California 2020** by **Sam Stepanyan** [[1](https://appseccalifornia2020.sched.com/event/XLtt/introducing-the-owasp-nettacker-project?iframe=no&w=100%&sidebar=yes&bg=no)] [[2](https://youtu.be/rZfCFFewfiU)]
* OWASP Nettacker was presented at **OWASP Chapters All-Day** conference (June 7th 2020) by **Sam Stepanyan** [[1](https://youtu.be/-klGZ7AaMc4)]
* OWASP Nettacker was presented at **BSides Athens 2020** conference by **Sam Stepanyan** [[1](https://youtu.be/vNNDC_ScxCA)]
* OWASP Nettacker was presented at **AppSecIL 2020** conference by **Sam Stepanyan** [[1](https://appsecil2020.sched.com/event/fF7u/using-owasp-nettacker-for-recon-and-vulnerability-scanning)]
* OWASP Nettacker was presented at **BlackHat Asia 2020** conference by **Sam Stepanyan** [[1](https://www.blackhat.com/asia-20/arsenal/schedule/#owasp-nettacker-19079)]
* OWASP Nettacker Presentation Slides (as presented at **OWASP Jakarta** 2021 event): [[1](https://speakerdeck.com/samstepanyanowasp/using-owasp-nettacker-project-for-recon-and-vulnerability-scanning)]
* OWASP Nettacker was presented at **OWASP Ottawa** Chapter by **Sam Stepanyan** [[1](https://www.youtube.com/watch?v=HvXPcByShgI)]
* OWASP Nettacker was presented at **OWASP Kyiv** Chapter by **Sam Stepanyan** [[1](https://www.youtube.com/watch?v=KrwQlgeZn7I)]
* OWASP Nettacker was presented at the **AppSec Engineer** session by **Sam Stepanyan** [[1](https://www.youtube.com/watch?v=eXzIPuTtqAQ)]
* OWASP Nettacker was presented at **Security BSides Dublin 2022** conference by **Sam Stepanyan** [[1](https://www.youtube.com/watch?v=GcRFkZEaWqI)]
* OWASP Nettacker was presented at the **Application Security Podcast** by **Sam Stepanyan** [[1](https://www.youtube.com/watch?v=tqZ8Lmucujw)]
* OWASP Nettacker was presented at the **OWASP Global AppSec DC 2023 Conference** by **Sam Stepanyan** [[1](https://www.youtube.com/watch?v=yZxjBme029A)]

41
docs/Home.md Normal file
View File

@ -0,0 +1,41 @@
## Introduction
OWASP Nettacker is an automated penetration testing framework designed to help cyber security professionals and ethical hackers perform reconnaissance, vulnerability assessments, and network security audits efficiently.
Nettacker automates information gathering, vulnerability scanning, and credential brute forcing tasks, making it a powerful tool for identifying weaknesses in networks, web applications, IoT devices and APIs.
OWASP Nettacker is an open-source software written in Python language. OWASP Nettacker uses YAML files to define **modules** in a structured and human-readable format.
OWASP Nettacker's modular architecture is one of its core strengths, allowing users to perform specific tasks by leveraging a range of pre-built and customizable modules.
By leveraging a modular framework, Nettacker supports multiple protocols and scanning methods, making it highly adaptable to various security testing scenarios.
## Key Features
1. Multi-Protocol Support
OWASP Nettacker can scan a wide range of protocols, including HTTP/HTTPS, FTP, SSH, SMTP, ICMP, TELNET, XML-RPC and more.
This flexibility allows users to assess diverse systems and applications effectively.
2. Automation of Information Gathering Security Tests
With Nettacker, users can automate reconnaissance, port scanning, vulnerability detection, and brute forcing workflows, minimizing the time and effort required for manual security testing.
3. Modular and Scalable
Its modular design enables users to customize and extend functionality by adding new modules for specific tasks. Nettacker can scale from small, targeted security assessments to large, enterprise-wide scans.
4. Built-In Port Scanner and Subdomain Enumeration module
Nettacker includes powerful Built-In Port Scanner and Subdomain Enumeration modules that streamline the initial stages of penetration testing. The Port Scanner module automatically identifies open ports on target systems, providing valuable insights into the services and potential attack surfaces exposed by a system. This is crucial for mapping a network and targeting specific services during vulnerability assessments. The Subdomain Enumeration module helps uncover hidden subdomains within a domain, which can be critical for identifying additional attack vectors or overlooked assets. Together, these built-in modules simplify the reconnaissance phase, helping security professionals gather key information efficiently before moving on to more advanced testing.
5. Multi-Format Reporting
The tool generates scan reports in multiple formats, including HTML, JSON, CSV and text. Nettackers ability to generate reports in JSON and CSV formats offers significant advantages. JSON provides a structured, machine-readable format that is easily parsed and integrated with other tools or systems, making it ideal for automated processing, data analysis, and integration with custom workflows. CSV, on the other hand, offers a simple, tabular format that is easy to read and process using spreadsheets or other data analysis tools. These formats make it easy to analyze findings and share results with stakeholders.
6. Built-in Database
Nettacker includes a built-in database for storing scan results. This ensures data persistence, allowing users to track past assessments, easily search and retrieve previous data from scan results, and generate reports for audit and compliance purposes
6. The Web UI and API provide enhanced user interaction and integration capabilities. The Web UI offers a user-friendly interface for configuring scans, visualizing results, andsearching the scan data, making Nettacker accessible to both technical and less-technical users. The API allows for programmatic access, enabling automation and integration with third-party tools, CI/CD pipelines, and custom applications.
## Links
* OWASP Nettacker Project Page: [https://www.owasp.org/nettacker](https://www.owasp.org/nettacker)
* GitHub Repo: [https://github.com/OWASP/Nettacker](https://github.com/OWASP/Nettacker)
* Official Docker Image: [https://hub.docker.com/r/owasp/nettacker/](https://hub.docker.com/r/owasp/nettacker/)
* Slack: **#project-nettacker** on https://owasp.slack.com (get OWASP Slack invite at https://owasp.org/slack/invite)
* OpenHub: [https://www.openhub.net/p/OWASP-Nettacker](https://www.openhub.net/p/OWASP-Nettacker)
* CI: [https://github.com/OWASP/Nettacker/actions](https://github.com/OWASP/Nettacker/actions)
* **Donate to support this project**: [https://www.owasp.org/](https://owasp.org/donate/?reponame=www-project-nettacker&title=OWASP+Nettacker)
* Original Creator/Maintainer: [https://www.secologist.com/](https://www.secologist.com/)

155
docs/Installation.md Normal file
View File

@ -0,0 +1,155 @@
# Installation
You have multiple options for installing OWASP Nettacker, each with specific instructions provided in dedicated sections below.
### Supported Platforms
OWASP Nettacker is designed to run on Linux and macOS systems. However, you can leverage the Docker image to run it on other operating systems as well. Although native Windows support was initially dropped, we are currently working towards reintroducing it in future versions, along with FreeBSD support.
PLEASE NOTE: Starting from Nettacker version 0.3.1 the support for Python2 and Python <3.10 has been dropped. If you have a requirement to use Nettacker on Python 2.x or 3.0-3.9 you can use the legacy version of Nettacker [v0.0.2](https://github.com/OWASP/Nettacker/releases/tag/0.0.2)
PLEASE NOTE: Python version 3.10-3.12 is required to run Nettacker. You can check the version of Python3 installed by running:
```
python3 -V
```
### Pre-requisites
OWASP Nettacker depends on several libraries and tools which you might need to install if they are not already installed on your system:
* python3-dev
* python3-pip
* libcurl4-openssl-dev
* libcurl4-gnutls-dev
* librtmp-dev
* libssl-dev
* libpq-dev (required if you wish to use PostgreSQL database)
* libffi-dev
* musl-dev
* make
* gcc
* git
Before using this software, please install the prerequisites by following the commands below):
Install Python3, PIP and VENV first (e.g. on Debian Linux/Ubuntu):
```
sudo apt-get update
sudo apt-get install -y python3 python3-dev python3-pip python3-venv
pip3 install --upgrade pip3
```
### Install Nettacker From PyPI Using PIPX
Installing OWASP Nettacker using `pipx` is a convenient method for managing Python applications with isolated environments. `pipx` ensures that each installed tool has its own environment, avoiding dependency conflicts.
Heres how you can install OWASP Nettacker using `pipx`:
1. Install pipx using apt or pip
Using apt:
```
sudo apt update
sudo apt install pipx
pipx ensurepath
pipx --version
```
or install pipx using using pip:
```
python3 -m pip install --user pipx
python3 -m pipx ensurepath
```
2. Install **nettacker** using pipx
```
pipx install nettacker
nettacker --help
```
### Install Nettacker from PyPI using PIP
Starting from version 0.4.0 Nettacker and can be installed directly from PyPI.
```
sudo apt update
sudo apt install python3-venv python3-pip
python3 -m venv venv
. venv/bin/activate
pip3 install nettacker
nettacker --help
```
### Install Nettacker using Git Clone and PIP
```
sudo apt update
sudo apt install python3-venv python3-pip git
python3 -m venv venv
. venv/bin/activate
git clone https://github.com/OWASP/Nettacker --depth 1
cd Nettacker
pip3 install .
python3 nettacker.py --help
```
You can also run Nettacker after installation like this:
```
nettacker --help
```
### Install Nettacker using Git Clone and Poetry
```
sudo apt update
sudo apt install python3-poetry git
git clone https://github.com/OWASP/Nettacker --depth 1
cd Nettacker
poetry install
poetry run nettacker --help
```
### What Happened to requirements.txt in Nettacker?
In recent updates to OWASP Nettacker, the project has transitioned away from using the traditional `requirements.txt` file for dependency management. Starting from version 0.4.0, Nettacker adopted Poetry as its package manager instead of the `requirements.txt` file. Poetry simplifies dependency management, handling both the installation of dependencies and packaging more efficiently.
Now, the dependencies for Nettacker are listed in `pyproject.toml`, which is a modern PEP 518 standard. `pyproject.toml` is also used by Poetry package manager, and the installation process follows a different approach:
You can install Nettacker directly from PyPI with the command:
`pip3 install nettacker`
or if you have already cloned Nettacker git repo you can run:
`pip install .`
inside the Nettacker folder.
To see the list of command options you can use:
```
nettacker --help
```
or
```
nettacker -h
```
### Install Nettacker Using Docker
```
docker pull owasp/nettacker
docker run -it owasp/nettacker /bin/bash
```
For usage instructions and examples please read [Usage.md](Usage.md)

View File

@ -0,0 +1,38 @@
0. _**In the beginning, there was … GIT**_:
Clone the latest revision of Nettacker
`> git clone https://github.com/zdresearch/OWASP-Nettacker.git && cd OWASP-Nettacker && pip install -r requirements.txt`
Make sure it works - in the command line, go to the root folder of Nettacker and run the following:
`> python nettacker.py -h`
1. _**Let there be targets:**_
For the purposes of this tutorial, we have created a shooting range somewhere in the realm of z3r0d4y.com . Let's see what subdomains are available there:
`> python nettacker.py -i z3r0d4y.com -m subdomain_scan`
What sorcery is this? To see behind the curtains:
`> python nettacker.py -i z3r0d4y.com -m subdomain_scan -v 5`
OK, but which of these is smells fishier than others? Let's run a quick port scan:
`python nettacker.py -i z3r0d4y.com -m port_scan`
2. _**For thou shalt p4wn**_: Hmm... that "tg1" fellow smells funny. Let's see what its port 80 has to say:
`open tg1.z3r0d4y.com in browser`
A login page - we shall knock on its door soon. But now: Shall we see if we can bruteforce our way into its SSH service?
`> python nettacker.py -i tg1.z3r0d4y.com -m ssh_brute -T 10 -v 5`
Cool. Now, comrades, let us go back to the gates of the login page on port 80...
Shall we write our own fuzzer to brute force our way into this login page? Why not... https://drive.google.com/open?id=1aFgKrdzhV6jb9HDi7LvrM9fjCd8n_hly
Now that we are in, let's see what else is lurking in these dark corners. Notice the URL. Shall we fuzz and see if exploration in the numerical realm gets us anywhere? Why not... https://drive.google.com/open?id=1bG01UT5_VApHFLLf3FD8VV1o_lu_pRC1
Ok, we now have the IP address of an internal docker and access to the WebUI of Nettacker installed there. Let's play.

42
docs/Media.md Normal file
View File

@ -0,0 +1,42 @@
Gathered a few media to show how to work with OWASP Nettacker.
Simple Usage
============
![](https://user-images.githubusercontent.com/7676267/35123376-283d5a3e-fcb7-11e7-9b1c-92b78ed4fecc.gif)
API Usage
=========
![](https://user-images.githubusercontent.com/7676267/39006688-118f7f0c-4419-11e8-874a-c417f0bd9081.gif)
Wizard Usage
=============
![](https://user-images.githubusercontent.com/24669027/39022564-bf96bde2-4453-11e8-9814-c30db364aa4d.gif)
Youtube
=======
* Created By Volunteers
[![IMAGE](http://img.youtube.com/vi/2XQiA7fEFck/0.jpg)](https://www.youtube.com/watch?v=2XQiA7fEFck)
* Created By Volunteers
[![IMAGE](http://img.youtube.com/vi/EUb8q0Whx4s/0.jpg)](https://www.youtube.com/watch?v=EUb8q0Whx4s)
* Created By Volunteers
[![IMAGE](http://img.youtube.com/vi/MnCOpiLY0Xc/0.jpg)](https://www.youtube.com/watch?v=MnCOpiLY0Xc)
* Created By Volunteers
[![IMAGE](http://img.youtube.com/vi/6trmP4xn2Sw/0.jpg)](https://www.youtube.com/watch?v=6trmP4xn2Sw)
* Created By Volunteers
[![IMAGE](http://img.youtube.com/vi/cZKQja2YO3A/0.jpg)](https://www.youtube.com/watch?v=cZKQja2YO3A)
* Created By Volunteers
[![IMAGE](http://img.youtube.com/vi/BF7G763xIKM/0.jpg)](https://www.youtube.com/watch?v=BF7G763xIKM)
Feel free to send your media to us to share it in here.

185
docs/Modules.md Normal file
View File

@ -0,0 +1,185 @@
# Nettacker Modules aka 'Methods'
OWASP Nettacker Modules can be of type **Scan** (scan for something), **Vuln** (check for some vulnerability) and **Brute** (Brute force)
- [Scan Modules](#scan-modules)
- [Ports Scanned by Nettacker](#ports-scanned-by-nettacker)
- [Vuln Modules](#vuln-modules)
- [Brute Modules](#brute-modules)
## Scan Modules
* '**adobe_aem_lastpatcheddate_scan**' - Scan the target for Adobe Experience Manager (AEM) and return its last patched date
* '**admin_scan**' - Scan the target for various Admin folders such as /admin /phpmyadmin /cmsadmin /wp-admin etc
* '**citrix_lastpatcheddate_scan**' Scan the target and try to detect Citrix Netscaler Gateway and it's last patched date
* '**cms_detection_scan**' - Scan the target and try to detect the CMS (Wordpress, Drupal or Joomla) using response fingerprinting
* '**confluence_version_scan**' - Scan the target and identify the Confluence version
* '**crushftp_lastpatcheddate_scan**' - Scan the target and try to detect CrushFTP and its last patched date
* '**cups_version_scan**' - Scan the target and identify the CUPS version (on port 631)
* '**dir_scan**' - Scan the target for well-known directories
* '**drupal_modules_scan**' - Scan the target for popular Drupal modules
* '**drupal_theme_scan**' - Scan the target for popular Drupal themes
* '**drupal_version_scan**' - Scan the target and identify the Drupal version
* '**icmp_scan**' - Ping the target and log the response time if it responds.
* '**http_redirect_scan**' - Scan the target and test if it returns an HTTP redirect 3xx response code and print the destination
* '**http_status_scan**' - Scan the target and return the HTTP status code
* '**ivanti_csa_lastpatcheddate_scan**' - Scan the target for Ivanti CSA appliance and return its last patched date
* '**ivanti_vtm_version_scan**' - Scan the target for Ivanti vTM appliance and return its version number
* '**joomla_template_scan**' - Scan the target for Joomla templates (identify Joomla sites)
* '**joomla_user_enum_scan**' - Scan the target and enumerate Joomla users
* '**joomla_version_scan**' - Scan the target and identify the Joomla version
* '**moveit_version_scan**' - Scan the target and identify the Progress MOVEit version
* '**pma_scan**' - Scan the target for PHP MyAdmin presence
* '**port_scan**' - Scan the target for open ports identifying the popular services using signatures (.e.g SSH on port 2222)
* '**sender_policy_scan**' - Scan the target domains/subdomains for SPF policy settings
* '**shodan_scan**' - Scan the target domains/subdomains/IP in Shodan. Put your Shodan API key i "shodan_api_key" method arg, "shodan_query_override" to run any Shodan query overriding the Nettacker target
* '**subdomain_scan**' - Scan the target for subdomains (target must be a domain e.g. owasp.org)
* '**viewdns_reverse_ip_lookup_scan**' - Identify which sites/domains are hosted on the target host using ViewDNS.info
* '**wappalyzer_scan**' - Scan the target and try to identify the technologies and libraries used using Wappalyzer
* '**wordpress_version_scan**' - Scan the target and identify the WordPress version
* '**wp_plugin_scan**' - Scan the target for popular WordPress Plugins
* '**wp_theme_scan**' - Scan the target for popular WordPress themes
* '**wp_timthumbs_scan**' - Scan the target for WordPress TimThumb.php script in various possible locations
* '**wp_user_enum_scan**' - Scan the target WordPress site and Enumerate Users
## Ports Scanned by Nettacker
If you want to scan all ports please define -g 1-65535 range. Otherwise Nettacker will scan for these 1000 most popular ports:
`[1, 3, 4, 6, 7, 9, 13, 17, 19, 20, 21, 22, 23, 24, 25, 26, 30, 32, 33, 37, 42,`
`43, 49, 53, 67, 68, 69, 70, 79, 80, 81, 82, 83, 84, 85, 88, 89, 90, 99, 100, 106, 109, 110,`
`111, 113, 119, 125, 135, 139, 143, 144, 146, 161, 162, 163, 179, 199, 211, 212, 222,`
`254, 255, 256, 259, 264, 280, 301, 306, 311, 340, 366, 389, 406, 407, 416, 417,`
`425, 427, 443, 444, 445, 458, 464, 465, 481, 497, 500, 512, 513, 514, 515, 524,`
`541, 543, 544, 545, 548, 554, 555, 563, 587, 593, 616, 617, 625, 631, 636, 646,`
`648, 666, 667, 668, 683, 687, 691, 700, 705, 711, 714, 720, 722, 726, 749, 765,`
`777, 783, 787, 800, 801, 808, 843, 873, 880, 888, 898, 900, 901, 902, 903, 911,`
`912, 981, 987, 990, 992, 993, 995, 999, 1000, 1001, 1002, 1007, 1009, 1010,`
`1011, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032,`
`1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045,`
`1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058,`
`1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071,`
`1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084,`
`1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097,`
`1098, 1099, 1100, 1102, 1104, 1105, 1106, 1107, 1108, 1110, 1111, 1112, 1113,`
`1114, 1117, 1119, 1121, 1122, 1123, 1124, 1126, 1130, 1131, 1132, 1137, 1138,`
`1141, 1145, 1147, 1148, 1149, 1151, 1152, 1154, 1163, 1164, 1165, 1166, 1169,`
`1174, 1175, 1183, 1185, 1186, 1187, 1192, 1198, 1199, 1201, 1213, 1216, 1217,`
`1218, 1233, 1234, 1236, 1244, 1247, 1248, 1259, 1271, 1272, 1277, 1287, 1296,`
`1300, 1301, 1309, 1310, 1311, 1322, 1328, 1334, 1352, 1417, 1433, 1434, 1443,`
`1455, 1461, 1494, 1500, 1501, 1503, 1521, 1524, 1533, 1556, 1580, 1583, 1594,`
`1600, 1641, 1658, 1666, 1687, 1688, 1700, 1717, 1718, 1719, 1720, 1721, 1723,`
`1755, 1761, 1782, 1783, 1801, 1805, 1812, 1839, 1840, 1862, 1863, 1864, 1875,`
`1900, 1914, 1935, 1947, 1971, 1972, 1974, 1984, 1998, 1999, 2000, 2001, 2002,`
`2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2020, 2021, 2022, 2030,`
`2033, 2034, 2035, 2038, 2040, 2041, 2042, 2043, 2045, 2046, 2047, 2048, 2049,`
`2065, 2068, 2099, 2100, 2103, 2105, 2106, 2107, 2111, 2119, 2121, 2126, 2135,`
`2144, 2160, 2161, 2170, 2179, 2190, 2191, 2196, 2200, 2222, 2251, 2260, 2288,`
`2301, 2323, 2366, 2381, 2382, 2383, 2393, 2394, 2399, 2401, 2492, 2500, 2522,`
`2525, 2557, 2601, 2602, 2604, 2605, 2607, 2608, 2638, 2701, 2702, 2710, 2717,`
`2718, 2725, 2800, 2809, 2811, 2869, 2875, 2909, 2910, 2920, 2967, 2968, 2998,`
`3000, 3001, 3003, 3005, 3006, 3007, 3011, 3013, 3017, 3030, 3031, 3052, 3071,`
`3077, 3128, 3168, 3211, 3221, 3260, 3261, 3268, 3269, 3283, 3300, 3301, 3306,`
`3322, 3323, 3324, 3325, 3333, 3351, 3367, 3369, 3370, 3371, 3372, 3389, 3390,`
`3404, 3476, 3493, 3517, 3527, 3546, 3551, 3580, 3659, 3689, 3690, 3703, 3737,`
`3766, 3784, 3800, 3801, 3809, 3814, 3826, 3827, 3828, 3851, 3869, 3871, 3878,`
`3880, 3889, 3905, 3914, 3918, 3920, 3945, 3971, 3986, 3995, 3998, 4000, 4001,`
`4002, 4003, 4004, 4005, 4006, 4045, 4111, 4125, 4126, 4129, 4224, 4242, 4279,`
`4321, 4343, 4443, 4444, 4445, 4446, 4449, 4550, 4567, 4662, 4848, 4899, 4900,`
`4998, 5000, 5001, 5002, 5003, 5004, 5009, 5030, 5033, 5050, 5051, 5054, 5060,`
`5061, 5080, 5087, 5100, 5101, 5102, 5120, 5190, 5200, 5214, 5221, 5222, 5225,`
`5226, 5269, 5280, 5298, 5357, 5405, 5414, 5431, 5432, 5440, 5500, 5510, 5544,`
`5550, 5555, 5560, 5566, 5631, 5633, 5666, 5678, 5679, 5718, 5730, 5800, 5801,`
`5802, 5810, 5811, 5815, 5822, 5825, 5850, 5859, 5862, 5877, 5900, 5901, 5902,`
`5903, 5904, 5906, 5907, 5910, 5911, 5915, 5922, 5925, 5950, 5952, 5959, 5960,`
`5961, 5962, 5963, 5987, 5988, 5989, 5998, 5999, 6000, 6001, 6002, 6003, 6004,`
`6005, 6006, 6007, 6009, 6025, 6059, 6100, 6101, 6106, 6112, 6123, 6129, 6156,`
`6346, 6389, 6502, 6510, 6543, 6547, 6565, 6566, 6567, 6580, 6646, 6666, 6667,`
`6668, 6669, 6689, 6692, 6699, 6779, 6788, 6789, 6792, 6839, 6881, 6901, 6969,`
`7000, 7001, 7002, 7004, 7007, 7019, 7025, 7070, 7100, 7103, 7106, 7200, 7201,`
`7402, 7435, 7443, 7496, 7512, 7625, 7627, 7676, 7741, 7777, 7778, 7800, 7911,`
`7920, 7921, 7937, 7938, 7999, 8000, 8001, 8002, 8007, 8008, 8009, 8010, 8011,`
`8021, 8022, 8031, 8042, 8045, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087,`
`8088, 8089, 8090, 8093, 8099, 8100, 8180, 8181, 8192, 8193, 8194, 8200, 8222,`
`8254, 8290, 8291, 8292, 8300, 8333, 8383, 8400, 8402, 8443, 8500, 8600, 8649,`
`8651, 8652, 8654, 8701, 8800, 8873, 8888, 8899, 8994, 9000, 9001, 9002, 9003,`
`9009, 9010, 9011, 9040, 9050, 9071, 9080, 9081, 9090, 9091, 9099, 9100, 9101,`
`9102, 9103, 9110, 9111, 9200, 9207, 9220, 9290, 9415, 9418, 9485, 9500, 9502,`
`9503, 9535, 9575, 9593, 9594, 9595, 9618, 9666, 9876, 9877, 9878, 9898, 9900,`
`9917, 9929, 9943, 9944, 9968, 9998, 9999, 10000, 10001, 10002, 10003, 10004,`
`10009, 10010, 10012, 10024, 10025, 10082, 10180, 10215, 10243, 10566, 10616,`
`10617, 10621, 10626, 10628, 10629, 10778, 11110, 11111, 11967, 12000, 12174,`
`12265, 12345, 13456, 13722, 13782, 13783, 14000, 14238, 14441, 14442, 15000,`
`15002, 15003, 15004, 15660, 15742, 16000, 16001, 16012, 16016, 16018, 16080,`
`16113, 16992, 16993, 17877, 17988, 18040, 18101, 18988, 19101, 19283, 19315,`
`19350, 19780, 19801, 19842, 20000, 20005, 20031, 20221, 20222, 20828, 21571,`
`22939, 23502, 24444, 24800, 25734, 25735, 26214, 27000, 27352, 27353, 27355,`
`27356, 27715, 28201, 30000, 30718, 30951, 31038, 31337, 32768, 32769, 32770,`
`32771, 32772, 32773, 32774, 32775, 32776, 32777, 32778, 32779, 32780, 32781,`
`32782, 32783, 32784, 32785, 33354, 33899, 34571, 34572, 34573, 35500, 38292,`
`40193, 40911, 41511, 42510, 44176, 44442, 44443, 44501, 45100, 48080, 49152,`
`49153, 49154, 49155, 49156, 49157, 49158, 49159, 49160, 49161, 49163, 49165,`
`49167, 49175, 49176, 49400, 49999, 50000, 50001, 50002, 50003, 50006, 50300,`
`50389, 50500, 50636, 50800, 51103, 51493, 52673, 52822, 52848, 52869, 54045,`
`54328, 55055, 55056, 55555, 55600, 56737, 56738, 57294, 57797, 58080, 60020,`
`60443, 61532, 61900, 62078, 63331, 64623, 64680, 65000, 65129, 65389]`
## Vuln Modules
* '**apache_ofbiz_cve_2024_38856**' - check the target for Apache OFBiz CVE-2024-38856
* '**apache_struts_vuln**' - check Apache Struts for CVE-2017-5638
* '**Bftpd_double_free_vuln**' - check bftpd for CVE-2007-2010
* '**Bftpd_memory_leak_vuln**' - check bftpd for CVE-2017-16892
* '**Bftpd_parsecmd_overflow_vuln**'- check bftpd for CVE-2007-2051
* '**Bftpd_remote_dos_vuln**' - check bftpd for CVE-2009-4593
* '**CCS_injection_vuln**' - check SSL for Change Cipher Spec (CCS Injection) CVE-2014-0224
* '**citrix_cve_2019_19781_vuln**' - check the target for Citrix CVE-2019-19781 vulnerability
* '**citrix_cve_2023_24488_vuln**' - check the target for Citrix CVE-2023-24488 XSS vulnerability
* '**clickjacking_vuln**' - check the web server for missing 'X-Frame-Options' header (clickjacking protection)
* '**content_security_policy_vuln**' - check the web server for missing 'Content-Security-Policy' header
* '**content_type_options_vuln**' - check the web server for missing 'X-Content-Type-Options'=nosniff header
* '**crushftp_cve_2025_31161_vuln**' - check the target for CrushFTP CVE-2025-31161 vulnerability
* '**f5_cve_2020_5902_vuln**' - check the target for F5 RCE CVE-2020-5902 vulnerability
* '**heartbleed_vuln**' - check SSL for Heartbleed vulnerability (CVE-2014-0160)
* '**msexchange_cve_2021_26855**' - check the target for MS Exchange SSRF CVE-2021-26855 (proxylogon/hafnium)
* '**http_cors_vuln**' - check the web server for overly-permissive CORS (header 'Access-Control-Allow-Origin'=*)
* '**options_method_enabled_vuln**' - check if OPTIONS method is enabled on the web server
* '**paloalto_panos_cve_2025_0108_vuln**' - check the target for PaloAlto PAN-OS CVE-2025-0108 vulnerability
* '**paloalto_globalprotect_cve_2025_0133_vuln**' - check the target for PaloAlto GlobalProtect CVE-2025-0133 XSS vulnerability
* '**ProFTPd_bypass_sqli_protection_vuln**' - check ProFTPd for CVE-2009-0543
* '**ProFTPd_cpu_consumption_vuln**' - check ProFTPd for CVE-2008-7265
* '**ProFTPd_directory_traversal_vuln**' - check ProFTPd for CVE-2010-3867
* '**ProFTPd_exec_arbitary_vuln**' - check ProFTPd for CVE-2011-4130
* '**ProFTPd_heap_overflow_vuln**' - check ProFTPd for CVE-2010-4652
* '**ProFTPd_integer_overflow_vuln**' - check ProFTPd for CVE-2011-1137
* '**ProFTPd_memory_leak_vuln**' - check ProFTPd for CVE-2001-0136
* '**ProFTPd_restriction_bypass_vuln**' - check ProFTPd for CVE-2009-3639
* '**server_version_vuln**' - check if the web server is leaking server banner in 'Server' response header
* '**sonicwall_sslvpn_cve_2024_53704_vuln**' - check the target for SonicWALL SSLVPN CVE-2024-53704 vulnerability
* '**ssl_signed_certificate_vuln**' - check for self-signed & other signing issues(weak signing algorithm) in SSL certificate
* '**ssl_expired_certificate_vuln**' - check if SSL certificate has expired or is close to expiring
* '**ssl_version_vuln**' - check if the server's SSL configuration supports old and insecure SSL versions
* '**ssl_weak_cipher_vuln**' - check if server's SSL configuration supports weak cipher suites
* '**wordpress_dos_cve_2018_6389_vuln**' - check if Wordpress is vulnerable to CVE-2018-6389 Denial Of Service (DOS)
* '**wp_plugin_cve_2023_47668_vuln**' - check the target for CVE-2023-47668
* '**wp_xmlrpc_bruteforce_vuln**' - check if Wordpress is vulnerable to credential Brute Force via XMLRPC wp.getUsersBlogs
* '**wp_xmlrpc_pingback_vuln**' - check if Wordpress is vulnerable to XMLRPC pingback
* '**x_powered_by_vuln**' - check if the web server is leaking server configuration in 'X-Powered-By' response header
* '**xdebug_rce_vuln**' - checks if web server is running XDebug version 2.5.5 vulnerable to RCE
* '**XSS_protection_vuln**' - check if header 'X-XSS-Protection' header is set to '1; mode=block'
* '**vbulletin_cve_2019_16759_vuln**' - check the target for vBulletin RCE CVE-2019-16759 vulnerability
## Brute Modules
If no extra users/passwords parameters are specified the following default usernames will be used on brute force checks: ["admin", "root", "test", "ftp", "anonymous", "user", "support", "1"] with the following passwords: ["admin", "root", "test", "ftp", "anonymous", "user", "1", "12345",123456", "124567", "12345678", "123456789", "1234567890", "admin1", "password!@#", "support", "1qaz2wsx", "qweasd", "qwerty", "!QAZ2wsx","password1", "1qazxcvbnm", "zxcvbnm", "iloveyou", "password", "p@ssw0rd","admin123", ""]
* '**ftp_brute**' - try to brute force FTP users.
* '**http_basic_auth_brute**' - try to brute for HTTP Basic Auth users.
* '**http_form_brute**' - try to brute force using HTTP form - assuming that the form has 'username' and 'password' fields
* '**http_ntlm_brute**' - try to brute force using HTTP NTLM
* '**smtp_brute**' - - try to brute force SMTP (ports ["25", "465", "587"])
* '**ssh_brute**' - try to brute force SSH (port 22)
* '**telnet_brute**' - try to brute force via telnet (port23) (expects "login" and "Password" prompt)
* '**wp_xmlrpc_brute**' - try to brute force Wordpress users using XMLRPC and wp.getUsersBlogs method

3
docs/README.md Normal file
View File

@ -0,0 +1,3 @@
# Documentation
OWASP Nettacker documentaion is now available on ReadTheDocs: [https://nettacker.readthedocs.io](https://nettacker.readthedocs.io)

703
docs/Usage.md Normal file
View File

@ -0,0 +1,703 @@
# Help Menu
- [Target inputs Option](#target-inputs-option)
* [Command Examples](#command-examples)
- [API and WebUI](#api-and-webui)
* [API Options](#api-options)
* [API Examples](#api-examples)
- [Database](#database)
* [SQLite configuration](#sqlite-configuration)
* [MySQL configuration](#mysql-configuration)
- [Maltego Transforms](#maltego-transforms)
By using the `--help`/`-h` switch you can read the help menu in the CLI:
`python3 nettacker.py --help`
* Note: This example may not reflect the latest version.
```
______ __ _____ _____
/ __ \ \ / /\ / ____| __ \
| | | \ \ /\ / / \ | (___ | |__) |
| | | |\ \/ \/ / /\ \ \___ \| ___/
| |__| | \ /\ / ____ \ ____) | | Version 0.4.0
\____/ \/ \/_/ \_\_____/|_| QUIN
_ _ _ _ _
| \ | | | | | | | |
github.com/OWASP | \| | ___| |_| |_ __ _ ___| | _____ _ __
owasp.org | . ` |/ _ \ __| __/ _` |/ __| |/ / _ \ '__|
z3r0d4y.com | |\ | __/ |_| || (_| | (__| < __/ |
|_| \_|\___|\__|\__\__,_|\___|_|\_\___|_|
[2024-09-26 07:51:08][+] Nettacker engine started ...
[2024-09-26 07:51:09][+] 106 modules loaded ...
usage: Nettacker [-L LANGUAGE] [-v] [--verbose-event] [-V] [-o REPORT_PATH_FILENAME] [--graph GRAPH_NAME] [-h]
[-i TARGETS] [-l TARGETS_LIST] [-m SELECTED_MODULES] [--modules-extra-args MODULES_EXTRA_ARGS]
[--show-all-modules] [--profile PROFILES] [--show-all-profiles] [-x EXCLUDED_MODULES]
[-X EXCLUDED_PORTS] [-u USERNAMES] [-U USERNAMES_LIST] [-p PASSWORDS] [-P PASSWORDS_LIST] [-g PORTS]
[--user-agent USER_AGENT] [-T TIMEOUT] [-w TIME_SLEEP_BETWEEN_REQUESTS] [-r] [-s] [-d] [-t THREAD_PER_HOST]
[--show-all-modules] [--profile PROFILES] [--show-all-profiles] [-x EXCLUDED_MODULES] [-H HTTP_HEADER]
[-M PARALLEL_MODULE_SCAN] [--set-hardware-usage SET_HARDWARE_USAGE] [-R SOCKS_PROXY]
[--retries RETRIES] [--ping-before-scan] [-K SCAN_COMPARE_ID] [-J COMPARE_REPORT_PATH_FILENAME]
[--start-api] [--api-host API_HOSTNAME] [--api-port API_PORT] [--api-debug-mode]
[--api-access-key API_ACCESS_KEY] [--api-client-whitelisted-ips API_CLIENT_WHITELISTED_IPS]
[--api-access-log API_ACCESS_LOG] [--api-cert API_CERT] [--api-cert-key API_CERT_KEY]
Engine:
Engine input options
-L LANGUAGE, --language LANGUAGE
select a language ['iw', 'nl', 'es', 'ru', 'de', 'ur', 'pt-br', 'fr', 'el', 'hy', 'ko', 'en',
'ja', 'bn', 'it', 'tr', 'ar', 'zh-cn', 'hi', 'vi', 'id', 'fa', 'ps']
-v, --verbose verbose mode level (0-5) (default 0)
--verbose-event enable verbose event to see state of each thread
-V, --version show software version
-o REPORT_PATH_FILENAME, --output REPORT_PATH_FILENAME
save all logs in file (results.txt, results.csv, results.html, results.json, results.sarif, results.dd.json)
--graph GRAPH_NAME build a graph of all activities and information, you must use HTML output. available graphs:
['d3_tree_v2_graph', 'd3_tree_v1_graph']
-h, --help Show Nettacker Help Menu
Target:
Target input options
-i TARGETS, --targets TARGETS
target(s) list, separate with ","
-l TARGETS_LIST, --targets-list TARGETS_LIST
read target(s) from file
Method:
Scan method options
-m SELECTED_MODULES, --modules SELECTED_MODULES
choose modules ['accela_cve_2021_34370_vuln', 'admin_scan',
'adobe_coldfusion_cve_2023_26360_vuln', 'apache_cve_2021_41773_vuln',
'apache_cve_2021_42013_vuln', 'apache_ofbiz_cve_2024_38856_vuln', 'apache_struts_vuln',
'aviatrix_cve_2021_40870_vuln', 'cisco_hyperflex_cve_2021_1497_vuln',
'citrix_cve_2019_19781_vuln'] to see full list use --show-all-modules
--modules-extra-args MODULES_EXTRA_ARGS
add extra args to pass to modules (e.g. --modules-extra-args "x_api_key=123&xyz_passwd=abc"
--show-all-modules show all modules and their information
--profile PROFILES select profile ['accela', 'adobe', 'apache', 'apache_ofbiz', 'apache_struts', 'atlassian',
'aviatrix', 'backup', 'brute']
--show-all-profiles show all profiles and their information
-x EXCLUDED_MODULES, --exclude-modules EXCLUDED_MODULES
choose scan method to exclude ['accela_cve_2021_34370_vuln', 'admin_scan',
'adobe_coldfusion_cve_2023_26360_vuln', 'apache_cve_2021_41773_vuln',
'apache_cve_2021_42013_vuln', 'apache_ofbiz_cve_2024_38856_vuln', 'apache_struts_vuln',
'aviatrix_cve_2021_40870_vuln', 'cisco_hyperflex_cve_2021_1497_vuln']
-X EXCLUDED_PORTS, --exclude-ports
Ports to exclude (e.g. 80 || 80,443|| 1000-1300)
-u USERNAMES, --usernames USERNAMES
username(s) list, separate with ","
-U USERNAMES_LIST, --users-list USERNAMES_LIST
read username(s) from file
-p PASSWORDS, --passwords PASSWORDS
password(s) list, separate with ","
-P PASSWORDS_LIST, --passwords-list PASSWORDS_LIST
read password(s) from file
-g PORTS, --ports PORTS
port(s) list, separate with ","
--user-agent USER_AGENT
Select a user agent to send with HTTP requests or enter "random_user_agent" to randomize the
User-Agent in the requests.
-T TIMEOUT, --timeout TIMEOUT
read password(s) from file
-w TIME_SLEEP_BETWEEN_REQUESTS, --time-sleep-between-requests TIME_SLEEP_BETWEEN_REQUESTS
time to sleep between each request
-r, --range scan all IPs in the range
-s, --sub-domains find and scan subdomains
-d, --skip-service-discovery
skip service discovery before scan and enforce all modules to scan anyway
-t THREAD_PER_HOST, --thread-per-host THREAD_PER_HOST
thread numbers for connections to a host
-M PARALLEL_MODULE_SCAN, --parallel-module-scan PARALLEL_MODULE_SCAN
parallel module scan for hosts
--set-hardware-usage SET_HARDWARE_USAGE
Set hardware usage while scanning. (low, normal, high, maximum)
-R SOCKS_PROXY, --socks-proxy SOCKS_PROXY
outgoing connections proxy (socks). example socks5: 127.0.0.1:9050, socks://127.0.0.1:9050
socks5://127.0.0.1:9050 or socks4: socks4://127.0.0.1:9050, authentication: socks://username:
password@127.0.0.1, socks4://username:password@127.0.0.1, socks5://username:password@127.0.0.1
--retries RETRIES Retries when the connection timeout (default 3)
--ping-before-scan ping before scan the host
-K SCAN_COMPARE_ID, --scan-compare SCAN_COMPARE_ID
compare current scan to old scans using the unique scan_id
-J COMPARE_REPORT_PATH_FILENAME, --compare-report-path COMPARE_REPORT_PATH_FILENAME
the file-path to store the compare_scan report
-H HTTP_HEADER, --add-http-header HTTP_HEADER
Add custom HTTP headers to requests (format: 'key: value'). For multiple headers, use multiple -H flags
API:
API options
--start-api start the API service
--api-host API_HOSTNAME
API host address
--api-port API_PORT API port number
--api-debug-mode API debug mode
--api-access-key API_ACCESS_KEY
API access key
--api-client-whitelisted-ips API_CLIENT_WHITELISTED_IPS
define white list hosts, separate with , (examples: 127.0.0.1, 192.168.0.1/24,
10.0.0.1-10.0.0.255)
--api-access-log API_ACCESS_LOG
API access log filename
--api-cert API_CERT API CERTIFICATE
--api-cert-key API_CERT_KEY
API CERTIFICATE Key
Please read license and agreements https://github.com/OWASP/Nettacker%
```
## Language Selection
You can choose from 21 languages when using Nettacker. Use the language flag:
`$ nettacker -L fa`
The `-L` is the language flag and in this case sets the output language to Farsi, indicated by the `fa`. Farsi and 20 other languages are available, as listed in the command line help: `el`, `fr`, `en`, `nl`, `ps`, `tr`, `de`, `ko`, `it`, `ja`, `fa`, `hy`, `ar`, `zh-cn`, `vi`, `ru`, `hi`, `ur`, `id`, `es`, `iw`.
* Your CLI must support Unicode to make use of multiple languages. Search the web for "How to use Farsi on cmd/terminal."
* You can fix Persian (Farsi) and other Unicode languages RTL and Chars with [bicon](https://www.google.com/search?q=Persian+support+with+bicon&oq=Persian+support+with+bicon&aqs=chrome..69i57.178j0j7&sourceid=chrome&ie=UTF-8) in terminal/windows bash.
```
$ python nettacker.py --help -L fa
______ __ _____ _____
/ __ \ \ / /\ / ____| __ \
| | | \ \ /\ / / \ | (___ | |__) |
| | | |\ \/ \/ / /\ \ \___ \| ___/
| |__| | \ /\ / ____ \ ____) | | Version 0.4.0
\____/ \/ \/_/ \_\_____/|_| QUIN
_ _ _ _ _
| \ | | | | | | | |
github.com/OWASP | \| | ___| |_| |_ __ _ ___| | _____ _ __
owasp.org | . ` |/ _ \ __| __/ _` |/ __| |/ / _ \ '__|
z3r0d4y.com | |\ | __/ |_| || (_| | (__| < __/ |
|_| \_|\___|\__|\__\__,_|\___|_|\_\___|_|
[2024-09-26 07:53:24][+] انجین Nettacker آغاز به کار کرد ...
[2024-09-26 07:53:25][+] 106 ماژول بارگزاری شد ...
usage: Nettacker [-L LANGUAGE] [-v] [--verbose-event] [-V] [-o REPORT_PATH_FILENAME] [--graph GRAPH_NAME] [-h]
[-i TARGETS] [-l TARGETS_LIST] [-m SELECTED_MODULES] [--modules-extra-args MODULES_EXTRA_ARGS]
[--show-all-modules] [--profile PROFILES] [--show-all-profiles] [-x EXCLUDED_MODULES] [-u USERNAMES]
[-U USERNAMES_LIST] [-p PASSWORDS] [-P PASSWORDS_LIST] [-g PORTS] [--user-agent USER_AGENT]
[-T TIMEOUT] [-w TIME_SLEEP_BETWEEN_REQUESTS] [-r] [-s] [-d] [-t THREAD_PER_HOST]
[-M PARALLEL_MODULE_SCAN] [--set-hardware-usage SET_HARDWARE_USAGE] [-R SOCKS_PROXY]
[--retries RETRIES] [--ping-before-scan] [-K SCAN_COMPARE_ID] [-J COMPARE_REPORT_PATH_FILENAME]
[--start-api] [--api-host API_HOSTNAME] [--api-port API_PORT] [--api-debug-mode]
[--api-access-key API_ACCESS_KEY] [--api-client-whitelisted-ips API_CLIENT_WHITELISTED_IPS]
[--api-access-log API_ACCESS_LOG] [--api-cert API_CERT] [--api-cert-key API_CERT_KEY]
انجین:
گزینه های ورودی انجین
-L LANGUAGE, --language LANGUAGE
یک زبان انتخاب کنید ['bn', 'de', 'nl', 'iw', 'es', 'pt-br', 'ar', 'tr', 'el', 'ko', 'ru', 'hi',
'it', 'en', 'fr', 'id', 'ps', 'ur', 'zh-cn', 'hy', 'fa', 'ja', 'vi']
-v, --verbose سطح حالت پرگویی (0-5) (پیشفرض 0)
--verbose-event enable verbose event to see state of each thread
-V, --version نمایش ورژن نرم افزار
-o REPORT_PATH_FILENAME, --output REPORT_PATH_FILENAME
ذخیره کردن کل لاگ ها در فایل (results.txt، results.html، results.csv, results.json, results.sarif, results.dd.json)
--graph GRAPH_NAME ساخت گراف از همه فعالیت ها و اطلاعات، شما باید از خروجی HTML استفاده کنید. گراف های در دسترس:
['d3_tree_v1_graph', 'd3_tree_v2_graph']
-h, --help نشان دادن منوی کمک Nettacker
هدف:
گزینه های ورودی هدف
-i TARGETS, --targets TARGETS
لیست هدف (ها)، با "," جدا کنید
-l TARGETS_LIST, --targets-list TARGETS_LIST
خواندن هدف (ها) از فایل
متود:
گزینه های متود های اسکن
-m SELECTED_MODULES, --modules SELECTED_MODULES
متود اسکن را انتخاب کنید ['accela_cve_2021_34370_vuln', 'admin_scan',
'adobe_coldfusion_cve_2023_26360_vuln', 'apache_cve_2021_41773_vuln',
'apache_cve_2021_42013_vuln', 'apache_ofbiz_cve_2024_38856_vuln', 'apache_struts_vuln',
'aviatrix_cve_2021_40870_vuln', 'cisco_hyperflex_cve_2021_1497_vuln',
'citrix_cve_2019_19781_vuln']
--modules-extra-args MODULES_EXTRA_ARGS
add extra args to pass to modules (e.g. --modules-extra-args "x_api_key=123&xyz_passwd=abc"
--show-all-modules show all modules and their information
--profile PROFILES انتخاب پروفایل ['accela', 'adobe', 'apache', 'apache_ofbiz', 'apache_struts', 'atlassian',
'aviatrix', 'backup', 'brute']
--show-all-profiles show all profiles and their information
-x EXCLUDED_MODULES, --exclude-modules EXCLUDED_MODULES
انتخاب متود اسکن استثنا ['accela_cve_2021_34370_vuln', 'admin_scan',
'adobe_coldfusion_cve_2023_26360_vuln', 'apache_cve_2021_41773_vuln',
'apache_cve_2021_42013_vuln', 'apache_ofbiz_cve_2024_38856_vuln', 'apache_struts_vuln',
'aviatrix_cve_2021_40870_vuln', 'cisco_hyperflex_cve_2021_1497_vuln']
-u USERNAMES, --usernames USERNAMES
لیست نام کاربری (ها)، با "," جدا شود
-U USERNAMES_LIST, --users-list USERNAMES_LIST
خواندن نام کاربری (ها) از لیست
-p PASSWORDS, --passwords PASSWORDS
لیست کلمه عبور (ها)، با "," جدا شود
-P PASSWORDS_LIST, --passwords-list PASSWORDS_LIST
خواندن کلمه عبور (ها) از فایل
-g PORTS, --ports PORTS
لیست درگاه (ها)، با "," جدا شود
--user-agent USER_AGENT
Select a user agent to send with HTTP requests or enter "random_user_agent" to randomize the
User-Agent in the requests.
-T TIMEOUT, --timeout TIMEOUT
خواندن کلمه عبور (ها) از فایل
-w TIME_SLEEP_BETWEEN_REQUESTS, --time-sleep-between-requests TIME_SLEEP_BETWEEN_REQUESTS
زمان مکث بین هر درخواست
-r, --range اسکن تمام آی پی ها در رنج
-s, --sub-domains پیدا کردن و اسکن کردن ساب دامین ها
-d, --skip-service-discovery
skip service discovery before scan and enforce all modules to scan anyway
-t THREAD_PER_HOST, --thread-per-host THREAD_PER_HOST
تعداد ریسه ها برای ارتباطات با یک هاست
-M PARALLEL_MODULE_SCAN, --parallel-module-scan PARALLEL_MODULE_SCAN
parallel module scan for hosts
--set-hardware-usage SET_HARDWARE_USAGE
Set hardware usage while scanning. (low, normal, high, maximum)
-R SOCKS_PROXY, --socks-proxy SOCKS_PROXY
پراکسی ارتباطات خروجی (socks) مثال: 127.0.0.1:9050، socks://127.0.0.1:9050،
socks5:127.0.0.1:9050 یا socks4: socks4://127.0.0.1:9050, احراز هویت:
socks://username:password@127.0.0.1, socks4://username:password@127.0.0.1,
socks5://username:password@127.0.0.1
--retries RETRIES سعی مجدد وقتی که ارتباط قطع شد (پیشفرض 3)
--ping-before-scan پینگ کردن هست قبل از اسکن
-K SCAN_COMPARE_ID, --scan-compare SCAN_COMPARE_ID
compare current scan to old scans using the unique scan_id
-J COMPARE_REPORT_PATH_FILENAME, --compare-report-path COMPARE_REPORT_PATH_FILENAME
the file-path to store the compare_scan report
API:
API گزینه های
--start-api شروع سرویس API
--api-host API_HOSTNAME
آدرس هاست API
--api-port API_PORT شماره درگاه API
--api-debug-mode حالت اشکال زدایی API
--api-access-key API_ACCESS_KEY
کلید دسترسی API
--api-client-whitelisted-ips API_CLIENT_WHITELISTED_IPS
تعریف کردن لیست سفید، با "," جدا کنید (مثال: 127.0.0.1, 192.168.1.1/24, 10.0.0.1-10.0.0.255)
--api-access-log API_ACCESS_LOG
اسم فایل لیست دسترسی به API
--api-cert API_CERT API CERTIFICATE
--api-cert-key API_CERT_KEY
API CERTIFICATE Key
لطفا مجوز و موافقت نامه را مطالعه فرمایید https://github.com/OWASP/Nettacker
```
***
# Target inputs Option
* OWASP Nettacker supports several types of targets, including `IPv4`, `IPv4_Range`, `IPv4_CIDR`, `DOMAIN`, and `HTTP` (which may be useful for some of the modules).
## Command Examples
```
192.168.1.1
192.168.1.1-192.168.255.255
192.168.1.1.1-192.255.255.255
192.168.1.1/24
owasp.org
http://owasp.org
https://owasp.org
```
* Targets can be read from a list by using the `-l` or `--target-list` command or you can split them with a comma if you don't want to use a text list.
```
python nettacker.py -i 192.168.1.1,192.168.1.2-192.168.1.10,127.0.0.1,owasp.org,192.168.2.1/24 -m port_scan -g 20-100 -t 10
python nettacker.py -l targets.txt -m all -x port_scan -g 20-100 -t 5 -u root -p 123456,654321,123123
python nettacker.py -l targets.txt -m all -t 100 -d -u root -p 12345,432123 -X 80
```
* Here are some more command line examples:
```
python nettacker.py -i 192.168.1.1/24 -m port_scan -t 10 -M 35 -g 20-100 --graph d3_tree_v2_graph -o result.html
python nettacker.py -i 192.168.1.1/24 -m port_scan -t 10 -M 35 -g 20-100 -o file.html --graph jit_circle_v1_graph
python nettacker.py -i 192.168.1.1/24 -m all -t 10 -M 35 -g 20-100 -o result.json -u root,user -P passwords.txt
python nettacker.py -i 192.168.1.1/24 -m all -x ssh_brute -t 10 -M 35 -g 20-100 -o file.txt -U users.txt -P passwords.txt -T 3 -w 2
```
* Using Whatcms Scan: API key can be found [here](https://whatcms.org/APIKey)
```
python nettacker.py -i eng.uber.com -m whatcms_scan --method-args whatcms_api_key=XXXX
```
* Finding CVE 2020-5902:
```
python nettacker.py -i <CIDR/IP/Domain> -m f5_cve_2020_5902
python nettacker.py -l <List of IP/CIDR/Domain> -m f5_cve_2020_5902
python nettacker.py -i <CIDR/IP/Domain> -m f5_cve_2020_5902 -s
```
* OWASP Nettacker can also scan subdomains by using this command: `-s`
```
python nettacker.py -i owasp.org -s -m port_scan -t 10 -M 35 -g 20-100 --graph d3_tree_v2_graph
```
* Using the `-H` command you can add your own HTTP headers to requests (useful for authentication) and chain it using multiple `-H` commands
```
python nettacker.py -i owasp.org -s -m http_status_scan -H "Authorization: Basic abcd" -H "Content-Type: abcd" -t 100 -d
```
* If you use `-r` command, it will scan the IP range automatically by getting the range from the RIPE database online.
```
python nettacker.py -i owasp.org -s -r -m port_scan -t 10 -M 35 -g 20-100 --graph d3_tree_v2_graph
python nettacker.py -i nettackerwebsiteblabla.com,owasp.org,192.168.1.1 -s -r -m all -t 10 -M 35 -g 20-100 -o file.txt -u root,user -P passwords.txt
```
* Note: If host scan finishes, and couldn't get any result nothing will be listed in the output file unless you change the verbosity mode to a value from 1 to 5.
```
python nettacker.py -i 192.168.1.1/24 -m all -t 10 -M 35 -g 20-100 -o file.txt -u root,user -P passwords.txt -v 1
```
* Use `*` pattern for selecting modules
```
python nettacker.py -i 192.168.1.1/24 -m *_scan
python nettacker.py -i 192.168.1.1/24 -m *_scan,*_vuln
```
* Use profiles for using all modules inside a given profile
```
python nettacker.py -i 192.168.1.1/24 --profile info
python nettacker.py -i 192.168.1.1/24 --profile info,vuln
python nettacker.py -i 192.168.1.1/24 --profile all
```
![](https://user-images.githubusercontent.com/24669027/39022564-bf96bde2-4453-11e8-9814-c30db364aa4d.gif)
* Use socks proxy for outgoing connections (default socks version is 5)
```
python nettacker.py -i 192.168.1.1 -m tcp_connect_port_scan -T 5 --socks-proxy socks://127.0.0.1:9050
python nettacker.py -i 192.168.1.1 -m tcp_connect_port_scan -T 5 --socks-proxy socks4://127.0.0.1:9050
python nettacker.py -i 192.168.1.1 -m tcp_connect_port_scan -T 5 --socks-proxy socks5://127.0.0.1:9050
python nettacker.py -i 192.168.1.1 -m tcp_connect_port_scan -T 5 --socks-proxy socks://username:password@127.0.0.1:9050
python nettacker.py -i 192.168.1.1 -m tcp_connect_port_scan -T 5 --socks-proxy socks4://username:password@127.0.0.1:9050
python nettacker.py -i 192.168.1.1 -m tcp_connect_port_scan -T 5 --socks-proxy socks5://username:password@127.0.0.1:9050
```
* Get the list of all modules with details about it using `--show-all-modules`
```
python nettacker.py --show-all-modules
______ __ _____ _____
/ __ \ \ / /\ / ____| __ \
| | | \ \ /\ / / \ | (___ | |__) |
| | | |\ \/ \/ / /\ \ \___ \| ___/
| |__| | \ /\ / ____ \ ____) | | Version 0.0.2
\____/ \/ \/_/ \_\_____/|_| BIST
_ _ _ _ _
| \ | | | | | | | |
github.com/OWASP | \| | ___| |_| |_ __ _ ___| | _____ _ __
owasp.org | . ` |/ _ \ __| __/ _` |/ __| |/ / _ \ '__|
z3r0d4y.com | |\ | __/ |_| || (_| | (__| < __/ |
|_| \_|\___|\__|\__\__,_|\___|_|\_\___|_|
[2021-08-31 17:42:06][+] http_options_enabled_vuln: name: http_options_enabled_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity']
[2021-08-31 17:42:06][+] clickjacking_vuln: name: clickjacking_vuln, author: OWASP Nettacker Team, severity: 5, description: Clickjacking, also known as a "UI redress attack", is when an attacker uses multiple transparent or opaque layers to trick a user into clicking on a button, reference: https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html, profiles: ['vuln', 'http', 'medium_severity']
[2021-08-31 17:42:06][+] wp_xmlrpc_bruteforce_vuln: name: wp_xmlrpc_bruteforce_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity', 'wordpress']
[2021-08-31 17:42:06][+] graphql_vuln: name: graphql_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity', 'graphql']
[2021-08-31 17:42:06][+] content_security_policy_vuln: name: content_security_policy_vuln, author: OWASP Nettacker Team, severity: 3, description: Content-Security-Policy is the name of a HTTP response header that modern browsers use to enhance the security of the document (or web page). The Content-Security-Policy header allows you to restrict how resources such as JavaScript, CSS, or pretty much anything that the browser loads., reference: https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html, profiles: ['vuln', 'http', 'low_severity', 'csp']
[2021-08-31 17:42:06][+] xdebug_rce_vuln: name: xdebug_rce_vuln, author: OWASP Nettacker Team, severity: 10, description: None, reference: None, profiles: ['vuln', 'http', 'critical_severity']
[2021-08-31 17:42:06][+] x_powered_by_vuln: name: x_powered_by_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity']
[2021-08-31 17:42:06][+] wp_xmlrpc_pingback_vuln: name: wp_xmlrpc_pingback_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'wordpress']
[2021-08-31 17:42:06][+] http_cors_vuln: name: http_cors_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity']
[2021-08-31 17:42:06][+] f5_cve_2020_5902_vuln: name: f5_cve_2020_5902_vuln, author: OWASP Nettacker Team, severity: 9, description: None, reference: None, profiles: ['vuln', 'http', 'critical_severity', 'cve', 'f5']
[2021-08-31 17:42:06][+] subdomain_takeover_vuln: name: subdomain_takeover_vuln, author: OWASP Nettacker Team, severity: 5, description: let us assume that example.com is the target and that the team running example.com have a bug bounty programme. While enumerating all of the subdomains belonging to example.com — a process that we will explore later — a hacker stumbles across subdomain.example.com, a subdomain pointing to GitHub pages. We can determine this by reviewing the subdomain's DNS records; in this example, subdomain.example.com has multiple A records pointing to GitHub's dedicated IP addresses for custom pages., reference: https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/10-Test_for_Subdomain_Takeover, profiles: ['vuln', 'http', 'medium_severity', 'takeover']
[2021-08-31 17:42:06][+] http_trace_enabled_vuln: name: http_trace_enabled_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity']
[2021-08-31 17:42:06][+] http_cookie_vuln: name: http_cookie_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity']
[2021-08-31 17:42:06][+] wp_xmlrpc_dos_vuln: name: wp_xmlrpc_dos_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'wordpress']
[2021-08-31 17:42:06][+] server_version_vuln: name: server_version_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity']
[2021-08-31 17:42:06][+] x_xss_protection_vuln: name: x_xss_protection_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity']
[2021-08-31 17:42:06][+] citrix_cve_2019_19781_vuln: name: citrix_cve_2019_19781_vuln, author: OWASP Nettacker Team, severity: 8, description: None, reference: None, profiles: ['vuln', 'http', 'high_severity', 'cve', 'citrix']
[2021-08-31 17:42:06][+] content_type_options_vuln: name: content_type_options_vuln, author: OWASP Nettacker Team, severity: 2, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity']
[2021-08-31 17:42:06][+] apache_struts_vuln: name: apache_struts_vuln, author: OWASP Nettacker Team, severity: 3, description: None, reference: None, profiles: ['vuln', 'http', 'low_severity', 'apache_struts']
[2021-08-31 17:42:06][+] vbulletin_cve_2019_16759_vuln: name: vbulletin_cve_2019_16759_vuln, author: OWASP Nettacker Team, severity: 9, description: None, reference: None, profiles: ['vuln', 'http', 'critical_severity', 'vbulletin', 'cve']
[2021-08-31 17:42:06][+] msexchange_cve_2021_26855_vuln: name: msexchange_cve_2021_26855_vuln, author: OWASP Nettacker Team, severity: 9, description: None, reference: None, profiles: ['vuln', 'http', 'critical_severity', 'msexchange', 'cve']
[2021-08-31 17:42:06][+] telnet_brute: name: telnet_brute, author: OWASP Nettacker Team, severity: 3, description: Telnet Bruteforcer, reference: None, profiles: ['brute', 'telnet']
[2021-08-31 17:42:06][+] ssh_brute: name: ssh_brute, author: OWASP Nettacker Team, severity: 3, description: SSH Bruteforcer, reference: None, profiles: ['brute', 'ssh']
[2021-08-31 17:42:06][+] smtp_brute: name: smtp_brute, author: OWASP Nettacker Team, severity: 3, description: SMTP Bruteforcer, reference: None, profiles: ['brute', 'smtp']
[2021-08-31 17:42:06][+] ftps_brute: name: ftps_brute, author: OWASP Nettacker Team, severity: 3, description: FTPS Bruteforcer, reference: None, profiles: ['brute', 'ftp']
[2021-08-31 17:42:06][+] smtps_brute: name: smtps_brute, author: OWASP Nettacker Team, severity: 3, description: SMTPS Bruteforcer, reference: None, profiles: ['brute', 'smtp']
[2021-08-31 17:42:06][+] ftp_brute: name: ftp_brute, author: OWASP Nettacker Team, severity: 3, description: FTP Bruteforcer, reference: None, profiles: ['brute', 'ftp']
[2021-08-31 17:42:06][+] whatcms_scan: name: dir_scan, author: OWASP Nettacker Team, severity: 3, description: Directory, Backup finder, reference: https://www.zaproxy.org/docs/alerts/10095/, profiles: ['scan', 'http', 'backup', 'low_severity']
[2021-08-31 17:42:06][+] icmp_scan: name: icmp_scan, author: OWASP Nettacker Team, severity: 0, description: check if host is alive through ICMP, reference: None, profiles: ['scan', 'info', 'low_severity']
[2021-08-31 17:42:06][+] subdomain_scan: name: subdomain_scan, author: OWASP Nettacker Team, severity: 0, description: Find subdomains using different sources on internet, reference: None, profiles: ['scan', 'info', 'low_severity']
[2021-08-31 17:42:06][+] port_scan: id: port_scan, author: OWASP Nettacker Team, severity: 0, description: Find open ports and services, reference: None, profiles: ['scan', 'http', 'info', 'low_severity']
[2021-08-31 17:42:06][+] admin_scan: name: admin_scan, author: OWASP Nettacker Team, severity: 3, description: Admin Directory Finder, reference: None, profiles: ['scan', 'http', 'backup', 'low_severity']
[2021-08-31 17:42:06][+] dir_scan: name: dir_scan, author: OWASP Nettacker Team, severity: 3, description: Directory, Backup finder, reference: https://www.zaproxy.org/docs/alerts/10095/, profiles: ['scan', 'http', 'backup', 'low_severity']
[2021-08-31 17:42:06][+] viewdns_reverse_iplookup_scan: name: viewdns_reverse_iplookup_scan, author: OWASP Nettacker Team, severity: 3, description: reverse lookup for target ip, reference: None, profiles: ['scan', 'http', 'backup', 'low_severity', 'reverse_lookup']
[2021-08-31 17:42:06][+] drupal_version_scan: name: drupal_version_scan, author: OWASP Nettacker Team, severity: 3, description: fetch drupal version from target, reference: None, profiles: ['scan', 'http', 'backup', 'low_severity', 'drupal']
[2021-08-31 17:42:06][+] joomla_version_scan: name: drupal_version_scan, author: OWASP Nettacker Team, severity: 3, description: fetch drupal version from target, reference: None, profiles: ['scan', 'http', 'backup', 'low_severity', 'drupal']
[2021-08-31 17:42:06][+] wordpress_version_scan: name: wordpress_version_scan, author: OWASP Nettacker Team, severity: 3, description: Directory, Backup finder, reference: None, profiles: ['scan', 'http', 'backup', 'low_severity', 'wordpress']
[2021-08-31 17:42:06][+] pma_scan: name: pma_scan, author: OWASP Nettacker Team, severity: 3, description: php my admin finder, reference: None, profiles: ['scan', 'http', 'backup', 'low_severity']
[2021-08-31 17:42:06][+] all:
```
- you can quick run the tool by using profiles
```
python nettacker.py -i example.com --profile vulnerabilities
python nettacker.py -i example.com --profile high_severity
```
* You may want to create a new profile. To do that, you need to edit the particular modules by adding profiles name to it inside modules directory. for e.g i want add profile as `asset_discovery` to subdomain_scan,port_scan module, then i can just edit profile field in `modules/scan/subdomain.yaml` and `port_scan.yaml`
```
info:
name: subdomain_scan
author: OWASP Nettacker Team
severity: 0
description: Find subdomains using different sources on internet
reference:
profiles:
- scan
- info
- low_severity
- asset_discovery(new added profile)
```
* You may want to change the default values (`timeout`, `socks proxy`, `target`, `ports`) or anything that could be set with the command line.To do that, you will have to edit them in the config.py `nettacker_user_application_config()` function in the main directory in JSON style.
```python
def nettacker_user_application_config():
"""
core framework default config (could be modify by user)
Returns:
a JSON with all user default configurations
"""
from core.compatible import version_info
return { # OWASP Nettacker Default Configuration
"language": "en",
"verbose_mode": False,
"show_version": False,
"report_path_filename": "{results_path}/results_{date_time}_{random_chars}.html".format(
results_path=nettacker_paths()["results_path"],
date_time=now(model="%Y_%m_%d_%H_%M_%S"),
random_chars=generate_random_token(10)
),
"graph_name": "d3_tree_v2_graph",
"show_help_menu": False,
"targets": None,
"url_base_path": None,
"http_header": None,
"targets_list": None,
"selected_modules": None,
"excluded_modules": None,
"usernames": None,
"usernames_list": None,
"passwords": None,
"passwords_list": None,
"ports": None,
"timeout": 3.0,
"time_sleep_between_requests": 0.0,
"scan_ip_range": False,
"scan_subdomains": False,
"thread_per_host": 250,
"parallel_module_scan": 20,
"socks_proxy": None,
"retries": 1,
"ping_before_scan": False,
"profiles": None,
"set_hardware_usage": "maximum", # low, normal, high, maximum
"user_agent": "Nettacker {version_number} {version_code} - https://github.com/OWASP/Nettacker".format(
version_number=version_info()[0], version_code=version_info()[1]
),
"show_all_modules": False,
"show_all_profiles": False,
"modules_extra_args": None
}
```
* Nettacker supports five different output types for the final report
1. HTML (.html) -> This also renders the graph
2. CSV (.csv)
3. JSON (.json)
4. SARIF (.sarif)
5. DefectDojo compatible json (.dd.json)
These output types will help with integration with different softwares and dashboards. To set the output mode use the `-o` or `--output` flag
```
python nettacker.py -i 192.168.1.1/24 --profile information_gathering -o report.sarif
python nettacker.py -i 192.168.1.1/24 --profile information_gathering -o report.json
python nettacker.py -i 192.168.1.1/24 --profile information_gathering --output report.dd.json
```
# API and WebUI
API and WebUI are new interfaces through which you can send your commands to Nettacker. Technically WebUI was developed based on the present API to demonstrate an example of the current API and can be used as another easier interface. To start using this feature, simply run `python nettacker.py --start-api`.
```
______ __ _____ _____
/ __ \ \ / /\ / ____| __ \
| | | \ \ /\ / / \ | (___ | |__) |
| | | |\ \/ \/ / /\ \ \___ \| ___/
| |__| | \ /\ / ____ \ ____) | | Version 0.0.1
\____/ \/ \/_/ \_\_____/|_| SAME
_ _ _ _ _
| \ | | | | | | | |
github.com/zdresearch | \| | ___| |_| |_ __ _ ___| | _____ _ __
owasp.org | . ` |/ _ \ __| __/ _` |/ __| |/ / _ \ '__|
zdresearch.com | |\ | __/ |_| || (_| | (__| < __/ |
|_| \_|\___|\__|\__\__,_|\___|_|\_\___|_|
* API Key: ec5e067581f29a28d8c8bbfc6e548f02
* Serving Flask app "api.engine" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on https://127.0.0.1:5000/ (Press CTRL+C to quit)
```
As you can see, the API key will be a random MD5 hash every time you run the API. You don't need to set the key.
You can also add your own SSL certificate and the key to run the API on an https connection.
```python nettacker.py --start-api --api-cert ~/cert.crt --api-cert-key ~/key.pem```
You can modify the default API config by editing the `config.py`.
```python
def nettacker_api_config():
"""
API Config (could be modify by user)
Returns:
a JSON with API configuration
"""
return { # OWASP Nettacker API Default Configuration
"start_api_server": False,
"api_hostname": "0.0.0.0" if os.environ.get("docker_env") == "true" else "nettacker-api.z3r0d4y.com",
"api_port": 5000,
"api_debug_mode": False,
"api_access_key": generate_random_token(32),
"api_client_whitelisted_ips": [], # disabled - to enable please put an array with list of ips/cidr/ranges
# [
# "127.0.0.1",
# "10.0.0.0/24",
# "192.168.1.1-192.168.1.255"
# ],
"api_access_log": os.path.join(sys.path[0], '.data/nettacker.log'),
}
```
## API Options
```
--start-api start the API service
--api-host API_HOST API host address
--api-port API_PORT API port number
--api-debug-mode API debug mode
--api-access-key API_ACCESS_KEY
API access key
--api-client-white-list
just allow white list hosts to connect to the API
--api-client-white-list-ips API_CLIENT_WHITE_LIST_IPS
define white list hosts, separate with , (examples:
127.0.0.1, 192.168.0.1/24, 10.0.0.1-10.0.0.255)
--api-access-log generate API access log
--api-access-log-filename API_ACCESS_LOG_FILENAME
API access log filename
--api-cert API_CERT API CERTIFICATE
--api-cert-key API_CERT_KEY
API CERTIFICATE Key
```
## API Examples
```
python nettacker.py --start-api --api-cert ~/cert.crt --api-cert-key ~/key.pem
python nettacker.py --start-api --api-access-key mysecretkey
python nettacker.py --start-api --api-client-white-list
python nettacker.py --start-api --api-client-white-list --api-client-white-list-ips 127.0.0.1,192.168.0.1/24,10.0.0.1-10.0.0.255
python nettacker.py --start-api --api-access-log
python nettacker.py --start-api --api-access-log --api-access-log-filename log.txt
python nettacker.py --start-api --api-access-key mysecretkey --api-client-white-list --api-access-log
python nettacker.py --start-api --api-access-key mysecretkey --api-client-white-list --api-access-log
python nettacker.py --start-api --api-access-key mysecretkey --api-host 192.168.1.2 --api-port 80
python nettacker.py --start-api --api-access-log --api-port 8080 --api-debug-mode
```
* For further information on how to use the RESTful API please visit the [API page](https://github.com/zdresearch/OWASP-Nettacker/wiki/API).
![](https://github.com/aman566/DiceGameJS/blob/master/Screencast-from-Tuesday-09-June-2020-02-32-32-IST-_online-video-cutter.com_.gif)
# Database
OWASP Nettacker, currently supports two databases:
- SQLite
- MySQL
The default database is SQLite. You can, however, configure the db to your liking.
## SQLite configuration
The SQLite database can be configured in `core/config.py` file under the `_database_config()` function. Here is a sample configuration:
```
return {
"DB": "sqlite",
"DATABASE": _paths()["home_path"] + "/nettacker.db", # This is the location of your db
"USERNAME": "",
"PASSWORD": "",
"HOST": "",
"PORT": ""
}
```
## MySQL configuration:
The MySQL database can be configured in `core/config.py` file under the `_database_config()` function. Here is a sample configuration:
```
return {
"DB": "mysql",
"DATABASE": "nettacker", # This is the name of your db
"USERNAME": "username",
"PASSWORD": "password",
"HOST": "localhost or some other host",
"PORT": "3306 or some other custom port"
}
```
After this configuration:
1. Open the configuration file of mysql(`/etc/mysql/my.cnf` in case of linux) as a sudo user
2. Add this to the end of the file :
```
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
```
3. Restart MySQL
## Postgres Configuration
The Postgres database can be configured in core/config.py file under the _database_config() function. Here is a sample configuration:
`
return {
"DB": "postgreas",
"DATABASE": "nettacker" # Name of db
"USERNAME": "username",
"PASSWORD": "password",
"HOST": "localhost or some other host",
"PORT": "5432 or some other custom port"
}
`
After this configuration please comment out the following line in database/db.py `connect_args={'check_same_thread': False}`
Let me know if you have any more questions.

10
docs/index.md Normal file
View File

@ -0,0 +1,10 @@
# OWASP Nettacker Documentation
This documentation is generated using [mkdocs.org](https://www.mkdocs.org) and [Material for MkDocs theme](https://github.com/squidfunk/mkdocs-material)
## Nettacker
OWASP Nettacker is an automated penetration testing framework designed to help cyber security professionals and ethical hackers perform reconnaissance, vulnerability assessments, and network security audits efficiently. Nettacker automates information gathering, vulnerability scanning, and credential brute forcing tasks, making it a powerful tool for identifying weaknesses in networks, web applications, IoT devices and APIs.
Documentation [Home](Home.md)

1
docs/requirements.txt Normal file
View File

@ -0,0 +1 @@
mkdocs-material

View File

@ -1,3 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
pass

View File

@ -1,3 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
pass

View File

@ -1,3 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
pass

View File

@ -1,94 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import os
from core.alert import messages
def start(events):
"""
generate the d3_tree_v1_graph with events
Args:
events: all events
Returns:
a graph in HTML
"""
# define a normalised_json
normalisedjson = {
"name": "Started attack",
"children": {}
}
# get data for normalised_json
for event in events:
if event['target'] not in normalisedjson['children']:
normalisedjson['children'].update(
{
event['target']: {}
}
)
normalisedjson['children'][event['target']].update(
{
event['module_name']: []
}
)
if event['module_name'] not in normalisedjson['children'][event['target']]:
normalisedjson['children'][event['target']].update(
{
event['module_name']: []
}
)
normalisedjson['children'][event['target']][event['module_name']].append(
f"target: {event['target']}, module_name: {event['module_name']}, port: "
f"{event['port']}, event: {event['event']}"
)
# define a d3_structure_json
d3_structure = {
"name": "Starting attack",
"children": []
}
# get data for normalised_json
for target in list(normalisedjson['children'].keys()):
for module_name in list(normalisedjson['children'][target].keys()):
for description in normalisedjson["children"][target][module_name]:
children_array = [
{
"name": module_name,
"children": [
{
"name": description
}
]
}
]
d3_structure["children"].append(
{
"name": target,
"children": children_array
}
)
from config import nettacker_paths
data = open(
os.path.join(
nettacker_paths()['web_static_files_path'],
'report/d3_tree_v1.html'
)
).read().replace(
'__data_will_locate_here__',
json.dumps(d3_structure)
).replace(
'__title_to_replace__',
messages("pentest_graphs")
).replace(
'__description_to_replace__',
messages("graph_message")
).replace(
'__html_title_to_replace__',
messages("nettacker_report")
)
return data

View File

@ -1,3 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
pass

View File

@ -1,3 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
pass

View File

@ -1,33 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
from config import nettacker_paths
css_1 = open(
os.path.join(
nettacker_paths()['web_static_files_path'],
'report/html_table.css'
)
).read()
table_title = open(
os.path.join(
nettacker_paths()['web_static_files_path'],
'report/table_title.html'
)
).read()
table_items = open(
os.path.join(
nettacker_paths()['web_static_files_path'],
'report/table_items.html'
)
).read()
table_end = open(
os.path.join(
nettacker_paths()['web_static_files_path'],
'report/table_end.html'
)
).read()

View File

@ -1,3 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
pass

View File

@ -1,272 +0,0 @@
---
scan_started: नेटटेकर इंजन शुरू हुआ ...
options: पायथन nettacker.py [विकल्प]
help_menu: नेटटेकर सहायता मेनू दिखाएं
license: कृपया लाइसेंस और समझौते https://github.com/OWASP/Nettacker पढ़ें
engine: इंजन
engine_input: इंजन इनपुट विकल्प
select_language: एक भाषा का चयन करें {0}
range: सीमा में सभी आईपी स्कैन करें
subdomains: सबडोमेन ढूंढें और स्कैन करें
thread_number_connections: एक मेजबान के कनेक्शन के लिए धागे संख्या
thread_number_hosts: स्कैन मेजबान के लिए धागे संख्या
save_logs: फ़ाइल में सभी लॉग सहेजें (results.txt, results.html, results.json)
target: लक्ष्य
target_input: लक्ष्य इनपुट विकल्प
target_list: लक्ष्य (ओं) सूची, "," से अलग
read_target: फ़ाइल से लक्ष्य (लक्ष्य) पढ़ें
scan_method_options: स्कैन विधि विकल्प
choose_scan_method: स्कैन विधि का चयन करें {0}
exclude_scan_method: "{0} को बाहर करने के लिए स्कैन विधि का चयन करें"
username_list: उपयोगकर्ता नाम (ओं) सूची, "," से अलग
username_from_file: फ़ाइल से उपयोगकर्ता नाम (ओं) पढ़ें
password_seperator: पासवर्ड (ओं) सूची, "," से अलग
read_passwords: फ़ाइल से पासवर्ड पढ़ें
port_seperator: पोर्ट (ओं) सूची, "," से अलग
time_to_sleep: प्रत्येक अनुरोध के बीच सोने के लिए समय
error_target: लक्ष्य निर्दिष्ट नहीं कर सकते
error_target_file:
"फ़ाइल को खोलने में असमर्थ लक्ष्य (लक्ष्य) निर्दिष्ट नहीं कर सकते:
{0}"
thread_number_warning:
100 से कम थ्रेड नंबर का उपयोग करना बेहतर है, बीटीडब्ल्यू हम
जारी हैं ...
settimeout:
"{0} सेकंड में टाइमआउट सेट करें, यह बहुत बड़ा है, है ना? जिस तरह से हम
जारी रहे हैं ..."
scan_module_not_found: यह स्कैन मॉड्यूल [{0}] नहीं मिला!
error_exclude_all: आप सभी स्कैन विधियों को बाहर नहीं कर सकते हैं
exclude_module_error: आपके द्वारा चुने गए {0} मॉड्यूल को नहीं मिला है!
method_inputs:
"विधियों इनपुट दर्ज करें, उदाहरण: ftp_brute_users = परीक्षण, व्यवस्थापक
और ftp_brute_passwds = read_from_file: /tmp/pass.txt&ftp_brute_port=21"
error_reading_file: फ़ाइल नहीं पढ़ सकता {0}
error_username: "फ़ाइल खोलने में असमर्थ उपयोगकर्ता नाम निर्दिष्ट नहीं कर सकते: {0}"
found: "{0} मिला! ({1}: {2})"
error_password_file:
"फ़ाइल खोलने में असमर्थ पासवर्ड (पासवर्ड) निर्दिष्ट नहीं कर सकता:
{0}"
file_write_error: फ़ाइल "{0}" लिखने योग्य नहीं है!
scan_method_select: कृपया अपनी स्कैन विधि चुनें!
remove_temp: temp फ़ाइलों को हटा रहा है!
sorting_results: सॉर्टिंग परिणाम!
done: किया हुआ!
start_attack: "{2} पर {0}, {1} पर हमला करना शुरू करें"
module_not_available: यह मॉड्यूल "{0}" उपलब्ध नहीं है
error_platform:
दुर्भाग्यवश सॉफ़्टवेयर का यह संस्करण बस लिनक्स / ओएसएक्स / विंडोज़
पर चलाया जा सकता है।
python_version_error: आपका पायथन संस्करण समर्थित नहीं है!
skip_duplicate_target:
डुप्लिकेट लक्ष्य छोड़ें (कुछ सबडोमेन / डोमेन में एक ही आईपी
और रेंज हो सकते हैं)
unknown_target: अज्ञात प्रकार का लक्ष्य [{0}]
checking_range: चेकिंग {0} रेंज ...
checking: जांच {0} ...
HOST: मेज़बान
USERNAME: उपयोगकर्ता नाम
PASSWORD: पारण शब्द
PORT: बंदरगाह
TYPE: प्रकार
DESCRIPTION: विवरण
verbose_mode: वर्बोज़ मोड स्तर (0-5) (डिफ़ॉल्ट 0)
software_version: सॉफ्टवेयर संस्करण दिखाओ
check_updates: अपडेट के लिये जांचें
outgoing_proxy:
"आउटगोइंग कनेक्शन प्रॉक्सी (मोजे)। उदाहरण मोजे 5: 127.0.0.1:9050,
मोजे: //127.0.0.1: 9050 मोजे 5: //127.0.0.1: 9050 या मोजे 4: मोजे 4: //127.0.0.1:
9050, प्रमाणीकरण: मोजे: // उपयोगकर्ता नाम: पासवर्ड @ 127.0.0.1, मोजे 4: // उपयोगकर्ता
नाम: password@127.0.0.1, socks5: // उपयोगकर्ता नाम: password@127.0.0.1"
valid_socks_address:
"कृपया मान्य मोजे पता और बंदरगाह दर्ज करें। उदाहरण मोजे 5: 127.0.0.1:9050,
मोजे: //127.0.0.1: 9050, मोजे 5: //127.0.0.1: 9050 या मोजे 4: मोजे 4: //127.0.0.1:
9050, प्रमाणीकरण: मोजे: // उपयोगकर्ता नाम: पासवर्ड @ 127.0.0.1, मोजे 4: // उपयोगकर्ता
नाम: password@127.0.0.1, socks5: // उपयोगकर्ता नाम: password@127.0.0.1"
connection_retries: कनेक्शन टाइमआउट (डिफ़ॉल्ट 3) पर पुनः प्रयास करता है
ftp_connectiontimeout: "{0} के लिए FTP कनेक्शन: {1} टाइमआउट, छोड़ना {2}: {3}"
login_successful: सफलतापूर्वक लॉग इन हो चुका है!
login_list_error: सफलतापूर्वक लॉग इन, लाइव कमांड के लिए अनुमति दी गई अनुमति!
ftp_connection_failed:
"{0} के लिए FTP कनेक्शन: {1} असफल रहा, पूरे चरण को छोड़ना [प्रक्रिया
{2} {3}]! अगले कदम पर जा रहे हैं"
input_target_error:
"{0} मॉड्यूल के लिए इनपुट लक्ष्य DOMAIN, HTTP या SINGLE_IPv4 होना
चाहिए, {1} छोड़ना"
user_pass_found: "उपयोगकर्ता: {0} पास: {1} होस्ट: {2} पोर्ट: {3} मिला!"
file_listing_error: "(सूची फाइलों के लिए कोई अनुमति नहीं)"
trying_message:
"{3} {4}: {5} ({6}) की प्रक्रिया {2} में {1} की {0} की कोशिश कर रहा
है"
smtp_connectiontimeout: "{0} के लिए smtp कनेक्शन: {1} टाइमआउट, छोड़ना {2}: {3}"
smtp_connection_failed:
"{0} के लिए smtp कनेक्शन: {1} असफल रहा, पूरे चरण को छोड़ना
[प्रक्रिया {2} {3}]! अगले कदम पर जा रहे हैं"
ssh_connectiontimeout: "एसएसएच कनेक्शन {0}: {1} टाइमआउट, छोड़ना {2}: {3}"
ssh_connection_failed:
"{0}: {1} से एसएसएच कनेक्शन विफल रहा, पूरे चरण को छोड़ना [प्रक्रिया
{2} {3}]! अगले कदम पर जा रहे हैं"
port/type: "{0} / {1}"
port_found: "होस्ट: {0} पोर्ट: {1} ({2}) मिला!"
target_submitted: लक्ष्य {0} जमा!
current_version:
आप OWASP Nettacker संस्करण {0} {1} {2} {6} कोड नाम {3} {4} {5} के
साथ चल रहे हैं
feature_unavailable:
यह सुविधा अभी तक उपलब्ध नहीं है! अंतिम संस्करण प्राप्त करने के
लिए कृपया "गिट क्लोन https://github.com/OWASP/Nettacker.git या पाइप इंस्टॉल -यू
OWASP-Nettacker चलाएं।
available_graph:
"सभी गतिविधियों और जानकारी का एक ग्राफ बनाएं, आपको HTML आउटपुट का
उपयोग करना होगा। उपलब्ध ग्राफ: {0}"
graph_output:
ग्राफ़ सुविधा का उपयोग करने के लिए आपका आउटपुट फ़ाइल नाम ".html" या
".htm" के साथ समाप्त होना चाहिए!
build_graph: ग्राफ निर्माण ...
finish_build_graph: निर्माण ग्राफ खत्म करो!
pentest_graphs: प्रवेश परीक्षण ग्राफ
graph_message:
यह ग्राफ OWASP Nettacker द्वारा बनाया गया है। ग्राफ़ में सभी मॉड्यूल
गतिविधियां, नेटवर्क मानचित्र और संवेदनशील जानकारी शामिल है, अगर यह विश्वसनीय नहीं
है तो कृपया इस फ़ाइल को किसी के साथ साझा न करें।
nettacker_report: ओडब्ल्यूएएसपी नेटटेकर रिपोर्ट
nettacker_version_details:
"सॉफ्टवेयर विवरण: ओडब्ल्यूएएसपी नेटटेकर संस्करण {0} [{1}]
{2} में"
no_open_ports: कोई खुला बंदरगाह नहीं मिला!
no_user_passwords: कोई उपयोगकर्ता / पासवर्ड नहीं मिला!
loaded_modules: "{0} मॉड्यूल लोड ..."
graph_module_404: "यह ग्राफ मॉड्यूल नहीं मिला: {0}"
graph_module_unavailable: यह ग्राफ मॉड्यूल "{0}" उपलब्ध नहीं है
ping_before_scan: मेजबान स्कैन करने से पहले पिंग
skipping_target:
पूरे लक्ष्य को छोड़ना {0} और स्कैनिंग विधि {1} - -पिंग-पहले-स्कैन
सत्य होने के कारण और प्रतिक्रिया नहीं मिली!
not_last_version:
आप ओडब्ल्यूएएसपी नेटटेकर के अंतिम संस्करण का उपयोग नहीं कर रहे हैं,
कृपया अपडेट करें।
cannot_update: अद्यतन के लिए जांच नहीं कर सकते, कृपया अपना इंटरनेट कनेक्शन जांचें।
last_version: आप ओडब्ल्यूएएसपी नेटटेकर के अंतिम संस्करण का उपयोग कर रहे हैं ...
directoy_listing: "{0} में मिली निर्देशिका सूची"
insert_port_message:
कृपया यूआरएल के बजाय -g या - methods-args स्विच के माध्यम से
पोर्ट डालें
http_connectiontimeout: http कनेक्शन {0} टाइमआउट!
wizard_mode: विज़ार्ड मोड शुरू करें
directory_file_404: पोर्ट {1} में {0} के लिए कोई निर्देशिका या फ़ाइल नहीं मिली
open_error: "{0} खोलने में असमर्थ"
dir_scan_get:
dir_scan_http_method मान GET या HEAD होना चाहिए, GET को डिफ़ॉल्ट सेट
करें।
list_methods: सभी विधियों के तर्क सूचीबद्ध करें
module_args_error: "{0} मॉड्यूल तर्क नहीं मिल सकता है"
trying_process: "{4} ({5} पर {3} की प्रक्रिया {2} में {1} की {0} की कोशिश कर रहा है"
domain_found: "डोमेन मिला: {0}"
TIME: पहर
CATEGORY: वर्ग
module_pattern_404: "{0} पैटर्न के साथ कोई मॉड्यूल नहीं मिल रहा है!"
enter_default: कृपया {0} | दर्ज करें डिफ़ॉल्ट [{1}]>
enter_choices_default: कृपया {0} | दर्ज करें विकल्प [{1}] | डिफ़ॉल्ट [{2}]>
all_targets: लक्ष्य
all_thread_numbers: धागा संख्या
out_file: आउटपुट फ़ाइल नाम
all_scan_methods: स्कैन विधियों
all_scan_methods_exclude: बाहर करने के लिए स्कैन विधियों
all_usernames: उपयोगकर्ता नाम
all_passwords: पासवर्ड
timeout_seconds: टाइमआउट सेकेंड
Invalid_shodan_api_key: "{0}"
shodan_api_key: शोदन के लिए शोडान एपीआई कुंजी
shodan_results_found: शोदन के परिणाम मिले
shodan_results_not_found: शोदन डेटाबेस में कुछ भी नहीं मिला
shodan_plan_upgrade:
कृपया फ़िल्टर या पेजिंग का उपयोग करने के लिए अपनी एपीआई योजना
को अपग्रेड करें और बेहतर परिणाम प्राप्त करें
searching_shodan_database: खोज रहे शोदन डेटाबेस...
all_ports: बंदरगाह संख्या
all_verbose_level: वर्बोज़ स्तर
all_socks_proxy: मोजे प्रॉक्सी
retries_number: retries संख्या
graph: एक ग्राफ
subdomain_found: "सबडोमेन मिला: {0}"
select_profile: प्रोफ़ाइल का चयन करें {0}
profile_404: प्रोफाइल "{0}" नहीं मिला!
waiting: "{0} की प्रतीक्षा"
vulnerable: "{0} के लिए कमजोर"
target_vulnerable: "लक्ष्य {0}: {1} {2} के लिए कमजोर है!"
no_vulnerability_found: कोई भेद्यता नहीं मिली! ({0})
Method: तरीका
API: एपीआई
API_options: एपीआई विकल्प
start_api_server: एपीआई सेवा शुरू करें
API_host: एपीआई होस्ट पता
API_port: एपीआई पोर्ट नंबर
API_debug: एपीआई डीबग मोड
API_access_key: एपीआई एक्सेस कुंजी
white_list_API: बस सफेद सूची होस्ट को एपीआई से कनेक्ट करने की अनुमति दें
define_whie_list:
"सफेद सूची होस्ट को परिभाषित करें, इसके साथ अलग, (उदाहरण: 127.0.0.1,
1 9 2.168.0.1/24, 10.0.0.1-10.0.0.255)"
gen_API_access_log: एपीआई एक्सेस लॉग उत्पन्न करें
API_access_log_file: एपीआई एक्सेस लॉग फ़ाइल नाम
API_port_int: एपीआई पोर्ट एक पूर्णांक होना चाहिए!
unknown_ip_input:
अज्ञात इनपुट प्रकार, स्वीकृत प्रकार हैं SINGLE_IPv4, RANGE_IPv4,
CIDR_IPv4
API_key: "* एपीआई कुंजी: {0}"
ports_int: बंदरगाह पूर्णांक होना चाहिए! (उदाहरण के लिए 80 || 80,1080 || 80,1080-1300,9000,12000-15000)
through_API: ओडब्ल्यूएएसपी नेटटेकर एपीआई के माध्यम से
API_invalid: अवैध एपीआई कुंजी
API_cert: एपीआई प्रमाण पत्र
API_cert_key: एपीआई प्रमाणपत्र कुंजी
api_cert: कृपया अपने एसएसपी सर्टिफिकेट की लोकेशन --api-cert स्विच का उपयोग करके दें
api_cert_key: कृपया --api-cert-key स्विच का उपयोग करके अपनी निजी कुंजी का स्थान दें
wrong_values: कृपया सही एसएसएल प्रमाणपत्र और निजी कुंजी फ़ाइल प्रदान करें!
unauthorized_IP: आपका आईपी अधिकृत नहीं है
not_found: नहीं मिला!
no_subdomain_found: "subdomain_scan: कोई सबडोमेन की स्थापना की!"
viewdns_domain_404: "viewdns_reverse_ip_lookup_scan: कोई डोमेन नहीं मिला!"
browser_session_valid: आपका ब्राउज़र सत्र मान्य है
browser_session_killed: आपका ब्राउज़र सत्र मारे गए
updating_database: डेटाबेस अपडेट कर रहा है ...
database_connect_fail: डेटाबेस के कनेक्ट नहीं कर सके!
inserting_report_db: डेटाबेस में रिपोर्ट डालना
inserting_logs_db: डेटाबेस में लॉग डालने
removing_logs_db: डीबी से पुराने लॉग को हटा रहा है
len_subdomain_found: "{0} सबडोमेन मिला है!"
len_domain_found: "{0} डोमेन पाए गए!"
phpmyadmin_dir_404: कोई phpmyadmin डीआईआर नहीं मिला!
DOS_send: "{0} को डीओएस पैकेट भेजना"
host_up: "{0} ऊपर है! वापस पिंग करने के लिए समय {1} है"
host_down: पिंग नहीं कर सकते {0}!
root_required: इसे जड़ के रूप में चलाने की जरूरत है
admin_scan_get:
admin_scan_http_method मान GET या HEAD होना चाहिए, GET को डिफ़ॉल्ट
सेट करें।
telnet_connectiontimeout: "{0} के लिए टेलनेट कनेक्शन: {1} टाइमआउट, छोड़ना {2}: {3}"
telnet_connection_failed:
"{0} के लिए टेलनेट कनेक्शन: {1} असफल रहा, पूरे चरण को छोड़ना
[प्रक्रिया {2} {3}]! अगले कदम पर जा रहे हैं"
http_auth_success:
"http मूल प्रमाणीकरण सफलता - होस्ट: {2}: {3}, उपयोगकर्ता: {0},
पास: {1} मिला!"
http_auth_failed: "http मूलभूत प्रमाणीकरण {0}: {3} {1} का उपयोग करके विफल रहा: {2}"
http_form_auth_success:
"http फॉर्म प्रमाणीकरण सफलता - होस्ट: {2}: {3}, उपयोगकर्ता:
{0}, पास: {1} मिला!"
http_form_auth_failed:
"{1}: {3} का उपयोग करके http फॉर्म प्रमाणीकरण विफल रहा {0}:
{2}"
http_ntlm_success:
"http ntlm प्रमाणीकरण सफलता - होस्ट: {2}: {3}, उपयोगकर्ता: {0},
पास: {1} मिला!"
http_ntlm_failed: "http ntlm प्रमाणीकरण {0}: {3} {1} का उपयोग करके विफल रहा: {2}"
no_response: लक्ष्य से प्रतिक्रिया प्राप्त नहीं कर सकते हैं
category_framework: "श्रेणी: {0}, ढांचे: {1} मिला!"
nothing_found: "{0} में {1} में कुछ भी नहीं मिला!"
no_auth: "{0}: {1} पर कोई लेख नहीं मिला"
invalid_database: कृपया कॉन्फ़िगरेशन फ़ाइल में माई एसक्यूएल या sqlite से चुनें
database_connection_failed: चयनित डाटाबेस से कनेक्शन विफल हुआ
fuzzer_no_response: एचटीटीपी फ़ज़र को कोई आउटपुट नहीं मिला {0}
summary_report: सारांश रिपोर्ट तालिका
file_saved: रिपोर्ट डेटाबेस और {0} में सहेजी गई
no_event_found: इस स्कैन में कोई ईवेंट नहीं मिला

View File

@ -1,249 +0,0 @@
---
scan_started: Mesin Nettacker mulai ...
options: python nettacker.py [opsi]
help_menu: Tampilkan Menu Bantuan Nettacker
license: Harap baca lisensi dan perjanjian https://github.com/OWASP/Nettacker
engine: Mesin
engine_input: Opsi masukan mesin
select_language: pilih bahasa {0}
range: pindai semua IP dalam rentang
subdomains: cari dan pindai subdomain
thread_number_connections: nomor utas untuk koneksi ke host
thread_number_hosts: nomor utas untuk host pemindaian
save_logs: simpan semua log dalam file (results.txt, results.html, results.json)
target: Target
target_input: Opsi masukan target
target_list: daftar target (s), terpisah dengan ","
read_target: baca target (s) dari file
scan_method_options: Pindai opsi metode
choose_scan_method: pilih metode pemindaian {0}
exclude_scan_method: pilih metode pemindaian untuk mengecualikan {0}
username_list: daftar nama pengguna (s), terpisah dengan ","
username_from_file: baca nama pengguna (s) dari file
password_seperator: daftar kata sandi, terpisah dengan ","
read_passwords: baca kata sandi (s) dari file
port_seperator: daftar port (s), terpisah dengan ","
time_to_sleep: waktu untuk tidur di antara setiap permintaan
error_target: Tidak dapat menentukan target (s)
error_target_file: "Tidak dapat menentukan target (s), tidak dapat membuka file: {0}"
thread_number_warning:
lebih baik menggunakan nomor utas lebih rendah dari 100, BTW
kami terus ...
settimeout:
mengatur waktu tunggu hingga {0} detik, itu terlalu besar, bukan? dengan
cara kita melanjutkan ...
scan_module_not_found: modul pemindaian ini [{0}] tidak ditemukan!
error_exclude_all: Anda tidak dapat mengecualikan semua metode pemindaian
exclude_module_error: "{0} modul yang Anda pilih untuk dikecualikan tidak ditemukan!"
method_inputs:
"masukkan input metode, contoh: ftp_brute_users = test, admin & ftp_brute_passwds
= baca_from_file: /tmp/pass.txt&ftp_brute_port=21"
error_reading_file: tidak bisa membaca file {0}
error_username:
"Tidak dapat menentukan nama pengguna (s), tidak dapat membuka file:
{0}"
found: "{0} ditemukan! ({1}: {2})"
error_password_file:
"Tidak dapat menentukan kata sandi (s), tidak dapat membuka file:
{0}"
file_write_error: file "{0}" tidak dapat ditulis!
scan_method_select: silakan pilih metode pemindaian Anda!
remove_temp: menghapus file temp!
sorting_results: hasil penyortiran!
done: selesai!
start_attack: mulai menyerang {0}, {1} dari {2}
module_not_available: modul ini "{0}" tidak tersedia
error_platform:
sayangnya versi perangkat lunak ini hanya bisa dijalankan di linux
/ osx / windows.
python_version_error: Versi Python Anda tidak didukung!
skip_duplicate_target:
lewati target duplikat (beberapa subdomain / domain mungkin
memiliki IP dan Rentang yang sama)
unknown_target: jenis target yang tidak diketahui [{0}]
checking_range: memeriksa {0} rentang ...
checking: memeriksa {0} ...
HOST: TUAN RUMAH
USERNAME: NAMA PENGGUNA
PASSWORD: KATA SANDI
PORT: PELABUHAN
TYPE: MENGETIK
DESCRIPTION: DESKRIPSI
verbose_mode: tingkat modus verbose (0-5) (default 0)
software_version: tampilkan versi perangkat lunak
check_updates: memeriksa pembaruan
outgoing_proxy:
"proxy koneksi keluar (kaus kaki). contoh kaus kaki5: 127.0.0.1:9050,
kaus kaki: //127.0.0.1: 9050 kaus kaki5: //127.0.0.1: 9050 atau kaus kaki4: kaus
kaki4: //127.0.0.1: 9050, autentikasi: kaus kaki: // namapengguna: kata sandi @
127.0.0.1, socks4: // username: password@127.0.0.1, socks5: // username: password@127.0.0.1"
valid_socks_address:
"masukkan alamat dan port kaus kaki yang valid. contoh kaus kaki5:
127.0.0.1:9050, kaus kaki: //127.0.0.1: 9050, kaus kaki5: //127.0.0.1: 9050 atau
kaus kaki4: kaus kaki4: //127.0.0.1: 9050, autentikasi: kaus kaki: // namapengguna:
kata sandi @ 127.0.0.1, socks4: // username: password@127.0.0.1, socks5: // username:
password@127.0.0.1"
connection_retries: Retries ketika batas waktu koneksi (default 3)
ftp_connectiontimeout: "koneksi ftp ke {0}: {1} timeout, skipping {2}: {3}"
login_successful: DITERUKAN SECARA SUKSES!
login_list_error: DITERUKAN SECARA SUKSES, IZIN DITOLAK UNTUK DAFTAR!
ftp_connection_failed:
"koneksi ftp ke {0}: {1} gagal, melewati seluruh langkah [proses
{2} {3}]! akan ke langkah berikutnya"
input_target_error:
target input untuk {0} modul harus DOMAIN, HTTP atau SINGLE_IPv4,
skipping {1}
user_pass_found: "pengguna: {0} lulus: {1} host: {2} port: {3} ditemukan!"
file_listing_error: "(TIDAK ADA IZIN UNTUK DAFTAR DAFTAR)"
trying_message: "mencoba {0} dari {1} dalam proses {2} dari {3} {4}: {5} ({6})"
smtp_connectiontimeout: "koneksi smtp ke {0}: {1} timeout, skipping {2}: {3}"
smtp_connection_failed:
"koneksi smtp ke {0}: {1} gagal, melewati seluruh langkah
[proses {2} {3}]! akan ke langkah berikutnya"
ssh_connectiontimeout: "koneksi ssh ke {0}: {1} timeout, skipping {2}: {3}"
ssh_connection_failed:
"koneksi ssh ke {0}: {1} gagal, melewati seluruh langkah [proses
{2} {3}]! akan ke langkah berikutnya"
port/type: "{0} / {1}"
port_found: "host: {0} port: {1} ({2}) ditemukan!"
target_submitted: target {0} dikirimkan!
current_version:
Anda menjalankan OWASP Nettacker versi {0} {1} {2} {6} dengan nama
kode {3} {4} {5}
feature_unavailable:
fitur ini belum tersedia! silakan jalankan "git clone https://github.com/OWASP/Nettacker.git
atau install pip -U OWASP-Nettacker untuk mendapatkan versi terakhir.
available_graph:
"membangun grafik dari semua aktivitas dan informasi, Anda harus
menggunakan output HTML. grafik yang tersedia: {0}"
graph_output:
untuk menggunakan fitur grafik, nama file output Anda harus diakhiri
dengan ".html" atau ".htm"!
build_graph: membangun grafik ...
finish_build_graph: selesaikan grafik bangunan!
pentest_graphs: Grafik Pengujian Penetrasi
graph_message:
Grafik ini dibuat oleh OWASP Nettacker. Grafik berisi semua kegiatan
modul, peta jaringan, dan informasi sensitif. Jangan bagikan file ini dengan siapa
pun jika tidak dapat diandalkan.
nettacker_report: Laporan OWASP Nettacker
nettacker_version_details:
"Detail Perangkat Lunak: OWASP Nettacker versi {0} [{1}]
di {2}"
no_open_ports: tidak ada port terbuka ditemukan!
no_user_passwords: tidak ada pengguna / kata sandi yang ditemukan!
loaded_modules: "{0} modul dimuat ..."
graph_module_404: "modul grafik ini tidak ditemukan: {0}"
graph_module_unavailable: modul grafik ini "{0}" tidak tersedia
ping_before_scan: ping sebelum memindai host
skipping_target:
melewatkan seluruh target {0} dan metode pemindaian {1} karena --ping-before-scan
adalah benar dan tidak ada respon!
not_last_version: Anda tidak menggunakan versi terakhir OWASP Nettacker, harap perbarui.
cannot_update: tidak dapat memeriksa pembaruan, periksa koneksi internet Anda.
last_version: Anda menggunakan versi terakhir OWASP Nettacker ...
directoy_listing: daftar direktori ditemukan di {0}
insert_port_message:
tolong masukkan port melalui switch -g atau --methods-args sebagai
ganti url
http_connectiontimeout: koneksi http {0} timeout!
wizard_mode: mulai mode wizard
directory_file_404:
tidak ada direktori atau file yang ditemukan untuk {0} di port
{1}
open_error: tidak dapat membuka {0}
dir_scan_get: nilai dir_scan_http_method harus GET atau HEAD, atur default ke GET.
list_methods: daftar semua metode args
module_args_error: tidak bisa mendapatkan argumen modul {0}
trying_process: mencoba {0} dari {1} dalam proses {2} dari {3} pada {4} ({5})
domain_found: "domain ditemukan: {0}"
TIME: WAKTU
CATEGORY: KATEGORI
module_pattern_404: tidak dapat menemukan modul apa pun dengan pola {0}!
enter_default: masukkan {0} | Default [{1}]>
enter_choices_default: masukkan {0} | pilihan [{1}] | Default [{2}]>
all_targets: targetnya
all_thread_numbers: nomor utas
out_file: nama file keluaran
all_scan_methods: metode pemindaian
all_scan_methods_exclude: metode pemindaian untuk dikecualikan
all_usernames: nama pengguna
all_passwords: kata sandi
timeout_seconds: batas waktu detik
all_ports: nomor port
all_verbose_level: tingkat verbose
all_socks_proxy: proxy kaus kaki
retries_number: nomor retries
graph: sebuah grafik
subdomain_found: "subdomain ditemukan: {0}"
select_profile: pilih profil {0}
profile_404: profil "{0}" tidak ditemukan!
waiting: menunggu {0}
vulnerable: rentan terhadap {0}
target_vulnerable: "target {0}: {1} rentan terhadap {2}!"
no_vulnerability_found: tidak ditemukan kerentanan! ({0})
Method: metode
API: API
API_options: Opsi API
start_api_server: memulai layanan API
API_host: Alamat host API
API_port: Nomor port API
API_debug: Mode debug API
API_access_key: Kunci akses API
white_list_API: cukup izinkan host daftar putih untuk terhubung ke API
define_whie_list:
"mendefinisikan host daftar putih, terpisah dengan, (contoh: 127.0.0.1,
192.168.0.1/24, 10.0.0.1-10.0.0.255)"
gen_API_access_log: menghasilkan log akses API
API_access_log_file: Nama file log akses API
API_port_int: Port API harus berupa bilangan bulat!
unknown_ip_input:
jenis masukan tidak dikenal, jenis yang diterima adalah SINGLE_IPv4,
RANGE_IPv4, CIDR_IPv4
API_key: "* Kunci API: {0}"
ports_int: port harus berupa bilangan bulat! (mis. 80 || 80,1080 || 80,1080-1300,9000,12000-15000)
through_API: Melalui API OWASP Nettacker
API_invalid: kunci API tidak valid
unauthorized_IP: IP Anda tidak diotorisasi
not_found: Tidak ditemukan!
no_subdomain_found: "subdomain_scan: tidak ada subdomain yang ditemukan!"
viewdns_domain_404: "viewdns_reverse_ip_lookup_scan: tidak ada domain yang ditemukan!"
browser_session_valid: sesi browser Anda valid
browser_session_killed: sesi browser Anda terbunuh
updating_database: memperbarui basis data ...
database_connect_fail: tidak bisa terhubung ke database!
inserting_report_db: memasukkan laporan ke database
inserting_logs_db: memasukkan log ke database
removing_logs_db: menghapus log lama dari db
len_subdomain_found: "{0} subdomain (s) ditemukan!"
len_domain_found: "{0} domain (s) ditemukan!"
phpmyadmin_dir_404: tidak ada dir phpmyadmin ditemukan!
DOS_send: mengirim paket DoS ke {0}
host_up:
"{0} sudah habis! Waktu yang diambil untuk melakukan ping kembali adalah
{1}"
host_down: Tidak bisa melakukan ping {0}!
root_required: ini harus dijalankan sebagai root
admin_scan_get:
admin_scan_http_method value harus GET atau HEAD, atur default ke
GET.
telnet_connectiontimeout: "koneksi telnet ke {0}: {1} timeout, skipping {2}: {3}"
telnet_connection_failed:
"koneksi telnet ke {0}: {1} gagal, melewati seluruh langkah
[proses {2} dari {3}]! akan ke langkah berikutnya"
http_auth_success:
"sukses otentikasi dasar http - host: {2}: {3}, pengguna: {0},
lulus: {1} ditemukan!"
http_auth_failed: "Otentikasi dasar http gagal {0}: {3} menggunakan {1}: {2}"
http_form_auth_success:
"keberhasilan otentikasi bentuk http - host: {2}: {3}, pengguna:
{0}, lulus: {1} ditemukan!"
http_form_auth_failed: "Otentikasi bentuk http gagal {0}: {3} menggunakan {1}: {2}"
http_ntlm_success:
"Keberhasilan autentikasi ntlm http: host: {2}: {3}, pengguna:
{0}, lulus: {1} ditemukan!"
http_ntlm_failed: "Otentikasi ntlm http gagal {0}: {3} menggunakan {1}: {2}"
no_response: tidak bisa mendapatkan respons dari target
category_framework: "kategori: {0}, kerangka kerja: {1} ditemukan!"
nothing_found: tidak ditemukan apa pun di {0} dalam {1}!
no_auth: "Tidak ada auth yang ditemukan pada {0}: {1}"

View File

@ -1,3 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
pass

View File

@ -1,15 +0,0 @@
______ __ _____ _____
/ __ \ \ / /\ / ____| __ \
| | | \ \ /\ / / \ | (___ | |__) |
| | | |\ \/ \/ / /\ \ \___ \| ___/
| |__| | \ /\ / ____ \ ____) | | {2}Version {0}{3}
\____/ \/ \/_/ \_\_____/|_| {4}{1}{5}
_ _ _ _ _
| \ | | | | | | | |
{6}github.com/OWASP {7} | \| | ___| |_| |_ __ _ ___| | _____ _ __
{8}owasp.org{9} | . ` |/ _ \ __| __/ _` |/ __| |/ / _ \ '__|
{10}z3r0d4y.com{11} | |\ | __/ |_| || (_| | (__| < __/ |
|_| \_|\___|\__|\__\__,_|\___|_|\_\___|_|

12
mkdocs.yml Normal file
View File

@ -0,0 +1,12 @@
site_name: OWASP Nettacker Documentation
theme:
name: material
nav:
- Home: Home.md
- Installation: Installation.md
- Usage: Usage.md
- Modules: Modules.md
- Media: Media.md
- API: API.md
- Contributing: Developers.md
- Events: Events.md

View File

@ -1,45 +0,0 @@
info:
name: subdomain_takeover_vuln
author: OWASP Nettacker Team
severity: 5
description: "let us assume that example.com is the target and that the team running example.com have a bug bounty programme. While enumerating all of the subdomains belonging to example.com — a process that we will explore later — a hacker stumbles across subdomain.example.com, a subdomain pointing to GitHub pages. We can determine this by reviewing the subdomain's DNS records; in this example, subdomain.example.com has multiple A records pointing to GitHub's dedicated IP addresses for custom pages."
reference: "https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/10-Test_for_Subdomain_Takeover"
profiles:
- vuln
- vulnerability
- http
- medium_severity
- takeover
payloads:
- library: http
verify: false
timeout: 3
cert: ""
stream: false
proxies: ""
steps:
- method: get
headers:
User-Agent: "{user_agent}"
allow_redirects: false
url:
nettacker_fuzzer:
input_format: "{{schema}}://{target}:{{ports}}"
prefix: ""
suffix: ""
interceptors:
data:
schema:
- "http"
- "https"
ports:
- 80
- 443
response:
condition_type: or
conditions:
content:
# more to be added
regex: The specified bucket does not exist|Repository not found|The page you have requested does not exist|There isn\'t a GitHub Pages site here.
reverse: false

View File

@ -1,18 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""OWASP Nettacker application entry point."""
from core.compatible import check_dependencies
from nettacker.main import run
"""
entry point of OWASP Nettacker framework
"""
# __check_external_modules created to check requirements before load the engine
if __name__ == "__main__":
check_dependencies() # check for dependencies
# if dependencies and OS requirements are match then load the program
from core.parse import load
load() # load and parse the ARGV
# sys.exit(main())
run()

1
nettacker/__init__.py Normal file
View File

@ -0,0 +1 @@
all_module_severity_and_desc = {}

View File

View File

@ -1,34 +1,16 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
from core.load_modules import load_all_modules, load_all_profiles
from core.load_modules import load_all_graphs
from core.alert import messages
from flask import abort
from config import nettacker_paths
def structure(status="", msg=""):
"""
basic JSON message structure
Args:
status: status (ok, failed)
msg: the message content
Returns:
a JSON message
"""
return {
"status": status,
"msg": msg
}
from nettacker.config import Config
from nettacker.core.app import Nettacker
from nettacker.core.messages import messages as _
from nettacker.core.messages import get_languages
def get_value(flask_request, key):
"""
get a value from GET, POST or CCOKIES
get a value from GET, POST or COOKIES
Args:
flask_request: the flask request
@ -37,13 +19,12 @@ def get_value(flask_request, key):
Returns:
the value content if found otherwise None
"""
return dict(
flask_request.args
).get(key) or dict(
flask_request.form
).get(key) or dict(
flask_request.cookies
).get(key) or ""
return (
dict(flask_request.args).get(key)
or dict(flask_request.form).get(key)
or dict(flask_request.cookies).get(key)
or ""
)
def mime_types():
@ -54,6 +35,9 @@ def mime_types():
all mime types in json
"""
return {
".3g2": "video/3gpp2",
".3gp": "video/3gpp",
".7z": "application/x-7z-compressed",
".aac": "audio/aac",
".abw": "application/x-abiword",
".arc": "application/octet-stream",
@ -90,8 +74,8 @@ def mime_types():
".ogv": "video/ogg",
".ogx": "application/ogg",
".otf": "font/otf",
".png": "image/png",
".pdf": "application/pdf",
".png": "image/png",
".ppt": "application/vnd.ms-powerpoint",
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
".rar": "application/x-rar-compressed",
@ -118,11 +102,8 @@ def mime_types():
".xml": "application/xml",
".xul": "application/vnd.mozilla.xul+xml",
".zip": "application/zip",
".3gp": "video/3gpp",
"audio/3gpp": "video",
".3g2": "video/3gpp2",
"audio/3gpp2": "video",
".7z": "application/x-7z-compressed"
}
@ -136,10 +117,13 @@ def get_file(filename):
Returns:
content of the file or abort(404)
"""
if not os.path.normpath(filename).startswith(str(Config.path.web_static_dir)):
abort(404)
try:
return open(filename, 'rb').read()
return open(filename, "rb").read()
except ValueError:
abort(404)
except IOError:
print(filename)
abort(404)
@ -156,7 +140,7 @@ def api_key_is_valid(app, flask_request):
"""
if app.config["OWASP_NETTACKER_CONFIG"]["api_access_key"] != get_value(flask_request, "key"):
abort(401, messages("API_invalid"))
abort(401, _("API_invalid"))
return
@ -167,39 +151,37 @@ def languages_to_country():
Returns:
HTML code for each language with its country flag
"""
from core.load_modules import load_all_languages
languages = load_all_languages()
languages = get_languages()
res = ""
flags = {
"ar": "sa",
"bn": "in",
"de": "de",
"el": "gr",
"fr": "fr",
"en": "us",
"es": "es",
"fa": "ir",
"fr": "fr",
"hi": "in",
"hy": "am",
"id": "id",
"it": "it",
"iw": "il",
"ja": "jp",
"ko": "kr",
"nl": "nl",
"ps": "ps",
"tr": "tr",
"de": "de",
"ko": "kr",
"it": "it",
"ja": "jp",
"fa": "ir",
"hy": "am",
"ar": "sa",
"zh-cn": "cn",
"vi": "vi",
"pt-br": "br",
"ru": "ru",
"hi": "in",
"tr": "tr",
"ur": "pk",
"id": "id",
"es": "es",
"iw": "il",
"pt-br": "br"
"vi": "vi",
"zh-cn": "cn",
}
for language in languages:
res += """<option {2} id="{0}" data-content='<span class="flag-icon flag-icon-{1}"
res += """<option {2} id="{0}" data-content='<span class="flag-icon flag-icon-{1}"
value="{0}"></span> {0}'></option>""".format(
language,
flags[language],
"selected" if language == "en" else ""
language, flags[language], "selected" if language == "en" else ""
)
return res
@ -211,11 +193,15 @@ def graphs():
Returns:
HTML content or available graphs
"""
res = """<label><input id="" type="radio" name="graph_name" value="" class="radio"><a
class="label label-default">None</a></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"""
for graph in load_all_graphs():
res += """<label><input id="{0}" type="radio" name="graph_name" value="{0}" class="radio"><a
class="label label-default">{0}</a></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;""".format(graph)
res = """
<label><input id="" type="radio" name="graph_name" value="" class="radio">
<a class="label label-default">None</a></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"""
for graph in Nettacker.load_graphs():
res += """
<label><input id="{0}" type="radio" name="graph_name" value="{0}" class="radio">
<a class="label label-default">{0}</a></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;""".format(
graph
)
return res
@ -227,16 +213,21 @@ def profiles():
HTML content or available profiles
"""
res = ""
for profile in sorted(load_all_profiles().keys()):
label = "success" if (
profile == "scan"
) else "warning" if (
profile == "brute"
) else "danger" if (
profile == "vulnerability"
) else "default"
res += """<label><input id="{0}" type="checkbox" class="checkbox checkbox-{0}"><a class="label
label-{1}">{0}</a></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;""".format(profile, label)
for profile in sorted(Nettacker.load_profiles().keys()):
label = (
"success"
if (profile == "scan")
else "warning"
if (profile == "brute")
else "danger"
if (profile == "vulnerability")
else "default"
)
res += """
<label><input id="{0}" type="checkbox" class="checkbox checkbox-{0}">
<a class="label label-{1}">{0}</a></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;""".format(
profile, label
)
return res
@ -247,24 +238,30 @@ def scan_methods():
Returns:
HTML content or available modules
"""
methods = load_all_modules()
methods = Nettacker.load_modules()
methods.pop("all")
res = ""
for sm in methods.keys():
label = "success" if sm.endswith(
"_scan"
) else "warning" if sm.endswith(
"_brute"
) else "danger" if sm.endswith(
"_vuln"
) else "default"
profile = "scan" if sm.endswith(
"_scan"
) else "brute" if sm.endswith(
"_brute"
) else "vuln" if sm.endswith(
"_vuln"
) else "default"
label = (
"success"
if sm.endswith("_scan")
else "warning"
if sm.endswith("_brute")
else "danger"
if sm.endswith("_vuln")
else "default"
)
profile = (
"scan"
if sm.endswith("_scan")
else "brute"
if sm.endswith("_brute")
else "vuln"
if sm.endswith("_vuln")
else "default"
)
res += """<label><input id="{0}" type="checkbox" class="checkbox checkbox-{2}-module">
<a class="label label-{1}">{0}</a></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;""".format(sm, label, profile)
<a class="label label-{1}">{0}</a></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;""".format(
sm, label, profile
)
return res

615
nettacker/api/engine.py Normal file
View File

@ -0,0 +1,615 @@
import csv
import json
import multiprocessing
import os
import random
import string
import time
from threading import Thread
from types import SimpleNamespace
from flask import Flask, jsonify
from flask import request as flask_request
from flask import render_template, abort, Response, make_response
from werkzeug.serving import WSGIRequestHandler
from werkzeug.utils import secure_filename
from nettacker import logger
from nettacker.api.core import (
get_value,
get_file,
mime_types,
scan_methods,
profiles,
graphs,
languages_to_country,
api_key_is_valid,
)
from nettacker.api.helpers import structure
from nettacker.config import Config
from nettacker.core.app import Nettacker
from nettacker.core.die import die_failure
from nettacker.core.graph import create_compare_report
from nettacker.core.messages import messages as _
from nettacker.core.utils.common import now, generate_compare_filepath
from nettacker.database.db import (
create_connection,
get_logs_by_scan_id,
select_reports,
get_scan_result,
last_host_logs,
logs_to_report_json,
search_logs,
logs_to_report_html,
)
from nettacker.database.models import Report
# Monkey-patching the Server header to avoid exposing the actual version
WSGIRequestHandler.version_string = lambda self: "API"
log = logger.get_logger()
app = Flask(__name__, template_folder=str(Config.path.web_static_dir))
app.config.from_object(__name__)
nettacker_path_config = Config.path
nettacker_application_config = Config.settings.as_dict()
nettacker_application_config.update(Config.api.as_dict())
del nettacker_application_config["api_access_key"]
@app.errorhandler(400)
def error_400(error):
"""
handle the 400 HTTP error
Args:
error: the flask error
Returns:
400 JSON error
"""
return jsonify(structure(status="error", msg=error.description)), 400
@app.errorhandler(401)
def error_401(error):
"""
handle the 401 HTTP error
Args:
error: the flask error
Returns:
401 JSON error
"""
return jsonify(structure(status="error", msg=error.description)), 401
@app.errorhandler(403)
def error_403(error):
"""
handle the 403 HTTP error
Args:
error: the flask error
Returns:
403 JSON error
"""
return jsonify(structure(status="error", msg=error.description)), 403
@app.errorhandler(404)
def error_404(error):
"""
handle the 404 HTTP error
Args:
error: the flask error
Returns:
404 JSON error
"""
return jsonify(structure(status="error", msg=_("not_found"))), 404
@app.before_request
def limit_remote_addr():
"""
check if IP filtering applied and API address is in whitelist
Returns:
None if it's in whitelist otherwise abort(403)
"""
# IP Limitation
if app.config["OWASP_NETTACKER_CONFIG"]["api_client_whitelisted_ips"]:
if (
flask_request.remote_addr
not in app.config["OWASP_NETTACKER_CONFIG"]["api_client_whitelisted_ips"]
):
abort(403, _("unauthorized_IP"))
return
@app.after_request
def set_security_headers(response):
"""
Add common security headers to every response.
"""
response.headers.setdefault("Content-Security-Policy", "upgrade-insecure-requests")
response.headers.setdefault("X-Content-Type-Options", "nosniff")
response.headers.setdefault("X-Frame-Options", "SAMEORIGIN")
response.headers.setdefault("X-XSS-Protection", "1; mode=block")
response.headers.setdefault("Referrer-Policy", "no-referrer-when-downgrade")
return response
@app.after_request
def access_log(response):
"""
Write to the access log file if enabled.
Args:
response: the flask response
Returns:
the flask response
"""
if app.config["OWASP_NETTACKER_CONFIG"]["api_access_log"]:
log_request = open(app.config["OWASP_NETTACKER_CONFIG"]["api_access_log"], "ab")
log_request.write(
'{0} [{1}] {2} "{3} {4}" {5} {6} {7}\r\n'.format(
flask_request.remote_addr,
now(),
flask_request.host,
flask_request.method,
flask_request.full_path,
flask_request.user_agent,
response.status_code,
json.dumps(flask_request.form),
).encode()
)
log_request.close()
return response
@app.route("/<path:path>")
def get_statics(path):
"""
getting static files and return content mime types
Args:
path: path and filename
Returns:
file content and content type if file found otherwise abort(404)
"""
static_types = mime_types()
return Response(
get_file(os.path.join(Config.path.web_static_dir, path)),
mimetype=static_types.get(os.path.splitext(path)[1], "text/html"),
)
@app.route("/", methods=["GET", "POST"])
def index():
"""
index page for WebUI
Returns:
rendered HTML page
"""
return render_template(
"index.html",
selected_modules=scan_methods(),
profile=profiles(),
languages=languages_to_country(),
graphs=graphs(),
filename=Config.settings.report_path_filename,
)
def sanitize_report_path_filename(report_path_filename):
"""
sanitize the report_path_filename
Args:
report_path_filename: the report path filename
Returns:
the sanitized report path filename
"""
filename = secure_filename(os.path.basename(report_path_filename))
if not filename:
return False
# Define a list or tuple of valid extensions
VALID_EXTENSIONS = (".html", ".htm", ".txt", ".json", ".csv")
if "." in filename:
if filename.endswith(VALID_EXTENSIONS):
safe_report_path = nettacker_path_config.results_dir / filename
else:
return False
else:
safe_report_path = nettacker_path_config.results_dir / filename
if not safe_report_path.is_relative_to(nettacker_path_config.results_dir):
return False
return safe_report_path
@app.route("/new/scan", methods=["GET", "POST"])
def new_scan():
"""
new scan through the API
Returns:
a JSON message with scan details if success otherwise a JSON error
"""
api_key_is_valid(app, flask_request)
form_values = dict(flask_request.form)
# variables for future reference
raw_report_path_filename = form_values.get("report_path_filename")
http_header = form_values.get("http_header")
report_path_filename = sanitize_report_path_filename(raw_report_path_filename)
if not report_path_filename:
return jsonify(structure(status="error", msg="Invalid report filename")), 400
form_values["report_path_filename"] = str(report_path_filename)
for key in nettacker_application_config:
if key not in form_values:
form_values[key] = nettacker_application_config[key]
# Handle HTTP headers
if http_header:
form_values["http_header"] = [
line.strip() for line in http_header.split("\n") if line.strip()
]
# Handle service discovery
form_values["skip_service_discovery"] = form_values.get("skip_service_discovery", "") == "true"
nettacker_app = Nettacker(api_arguments=SimpleNamespace(**form_values))
app.config["OWASP_NETTACKER_CONFIG"]["options"] = nettacker_app.arguments
thread = Thread(target=nettacker_app.run)
thread.start()
return jsonify(vars(nettacker_app.arguments)), 200
@app.route("/compare/scans", methods=["POST"])
def compare_scans():
"""
compare two scans through the API
Returns:
Success if the comparision is successfull and report is saved and error if not.
"""
api_key_is_valid(app, flask_request)
scan_id_first = get_value(flask_request, "scan_id_first")
scan_id_second = get_value(flask_request, "scan_id_second")
if not scan_id_first or not scan_id_second:
return jsonify(structure(status="error", msg="Invalid Scan IDs")), 400
compare_report_path_filename = get_value(flask_request, "compare_report_path")
if not compare_report_path_filename:
compare_report_path_filename = generate_compare_filepath(scan_id_first)
compare_options = {
"scan_compare_id": scan_id_second,
"compare_report_path_filename": compare_report_path_filename,
}
try:
result = create_compare_report(compare_options, scan_id_first)
if result:
return jsonify(
structure(
status="success",
msg="scan_comparison_completed",
)
), 200
return jsonify(structure(status="error", msg="Scan ID not found")), 404
except (FileNotFoundError, PermissionError, IOError):
return jsonify(structure(status="error", msg="Invalid file path")), 400
@app.route("/session/check", methods=["GET"])
def session_check():
"""
check the session if it's valid
Returns:
a JSON message if it's valid otherwise abort(401)
"""
api_key_is_valid(app, flask_request)
return jsonify(structure(status="ok", msg=_("browser_session_valid"))), 200
@app.route("/session/set", methods=["GET", "POST"])
def session_set():
"""
set session on the browser
Returns:
200 HTTP response if session is valid and a set-cookie in the
response if success otherwise abort(403)
"""
api_key_is_valid(app, flask_request)
res = make_response(jsonify(structure(status="ok", msg=_("browser_session_valid"))))
res.set_cookie(
"key",
value=app.config["OWASP_NETTACKER_CONFIG"]["api_access_key"],
httponly=True,
samesite="Lax",
secure=True,
)
return res
@app.route("/session/kill", methods=["GET"])
def session_kill():
"""
unset session on the browser
Returns:
a 200 HTTP response with set-cookie to "expired"
to unset the cookie on the browser
"""
res = make_response(jsonify(structure(status="ok", msg=_("browser_session_killed"))))
res.set_cookie("key", "", expires=0)
return res
@app.route("/results/get_list", methods=["GET"])
def get_results():
"""
get list of scan's results through the API
Returns:
an array of JSON scan's results if success otherwise abort(403)
"""
api_key_is_valid(app, flask_request)
page = get_value(flask_request, "page")
if not page:
page = 1
return jsonify(select_reports(int(page))), 200
@app.route("/results/get", methods=["GET"])
def get_result_content():
"""
get a result HTML/TEXT/JSON content
Returns:
content of the scan result
"""
api_key_is_valid(app, flask_request)
scan_id = get_value(flask_request, "id")
if not scan_id:
return jsonify(structure(status="error", msg=_("invalid_scan_id"))), 400
try:
filename, file_content = get_scan_result(scan_id)
except Exception:
return jsonify(structure(status="error", msg="database error!")), 500
return Response(
file_content,
mimetype=mime_types().get(os.path.splitext(filename)[1], "text/plain"),
headers={"Content-Disposition": "attachment;filename=" + filename.split("/")[-1]},
)
@app.route("/results/get_json", methods=["GET"])
def get_results_json():
"""
get host's logs through the API in JSON type
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
session = create_connection()
result_id = get_value(flask_request, "id")
if not result_id:
return jsonify(structure(status="error", msg=_("invalid_scan_id"))), 400
scan_details = session.query(Report).filter(Report.id == result_id).first()
json_object = json.dumps(get_logs_by_scan_id(scan_details.scan_unique_id))
filename = ".".join(scan_details.report_path_filename.split(".")[:-1])[1:] + ".json"
return Response(
json_object,
mimetype="application/json",
headers={"Content-Disposition": "attachment;filename=" + filename},
)
@app.route("/results/get_csv", methods=["GET"])
def get_results_csv(): # todo: need to fix time format
"""
get host's logs through the API in JSON type
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
session = create_connection()
result_id = get_value(flask_request, "id")
if not result_id:
return jsonify(structure(status="error", msg=_("invalid_scan_id"))), 400
scan_details = session.query(Report).filter(Report.id == result_id).first()
data = get_logs_by_scan_id(scan_details.scan_unique_id)
keys = data[0].keys()
filename = ".".join(scan_details.report_path_filename.split(".")[:-1])[1:] + ".csv"
with open(filename, "w") as report_path_filename:
dict_writer = csv.DictWriter(report_path_filename, fieldnames=keys, quoting=csv.QUOTE_ALL)
dict_writer.writeheader()
for event in data:
dict_writer.writerow({key: value for key, value in event.items() if key in keys})
with open(filename, "r") as report_path_filename:
reader = report_path_filename.read()
return Response(
reader,
mimetype="text/csv",
headers={"Content-Disposition": "attachment;filename=" + filename},
)
@app.route("/logs/get_list", methods=["GET"])
def get_last_host_logs(): # need to check
"""
get list of logs through the API
Returns:
an array of JSON logs if success otherwise abort(403)
"""
api_key_is_valid(app, flask_request)
page = get_value(flask_request, "page")
if not page:
page = 1
return jsonify(last_host_logs(int(page))), 200
@app.route("/logs/get_html", methods=["GET"])
def get_logs_html(): # todo: check until here - ali
"""
get host's logs through the API in HTML type
Returns:
HTML report
"""
api_key_is_valid(app, flask_request)
target = get_value(flask_request, "target")
return make_response(logs_to_report_html(target))
@app.route("/logs/get_json", methods=["GET"])
def get_logs():
"""
get host's logs through the API in JSON type
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
target = get_value(flask_request, "target")
data = logs_to_report_json(target)
json_object = json.dumps(data)
filename = (
"report-"
+ now(format="%Y_%m_%d_%H_%M_%S")
+ "".join(random.choice(string.ascii_lowercase) for _ in range(10))
)
return Response(
json_object,
mimetype="application/json",
headers={"Content-Disposition": "attachment;filename=" + filename + ".json"},
)
@app.route("/logs/get_csv", methods=["GET"])
def get_logs_csv():
"""
get target's logs through the API in JSON type
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
target = get_value(flask_request, "target")
data = logs_to_report_json(target)
keys = data[0].keys()
filename = (
"report-"
+ now(format="%Y_%m_%d_%H_%M_%S")
+ "".join(random.choice(string.ascii_lowercase) for _ in range(10))
)
with open(filename, "w") as report_path_filename:
dict_writer = csv.DictWriter(report_path_filename, fieldnames=keys, quoting=csv.QUOTE_ALL)
dict_writer.writeheader()
for event in data:
dict_writer.writerow({key: value for key, value in event.items() if key in keys})
with open(filename, "r") as report_path_filename:
reader = report_path_filename.read()
return Response(
reader,
mimetype="text/csv",
headers={"Content-Disposition": f"attachment;filename={filename}.csv"},
)
@app.route("/logs/search", methods=["GET"])
def go_for_search_logs():
"""
search in all events
Returns:
an array with JSON events
"""
api_key_is_valid(app, flask_request)
try:
page = int(get_value(flask_request, "page"))
if page > 0:
page -= 1
except Exception:
page = 0
try:
query = get_value(flask_request, "q")
except Exception:
query = ""
return jsonify(search_logs(page, query)), 200
def start_api_subprocess(options):
"""
a function to run flask in a subprocess to make kill signal in a better
way!
Args:
options: all options
"""
app.config["OWASP_NETTACKER_CONFIG"] = {
"api_access_key": options.api_access_key,
"api_client_whitelisted_ips": options.api_client_whitelisted_ips,
"api_access_log": options.api_access_log,
"api_cert": options.api_cert,
"api_cert_key": options.api_cert_key,
"language": options.language,
"options": options,
}
try:
if options.api_cert and options.api_cert_key:
app.run(
host=options.api_hostname,
port=options.api_port,
debug=options.api_debug_mode,
ssl_context=(options.api_cert, options.api_cert_key),
threaded=True,
)
else:
app.run(
host=options.api_hostname,
port=options.api_port,
debug=options.api_debug_mode,
ssl_context="adhoc",
threaded=True,
)
except Exception as e:
die_failure(str(e))
def start_api_server(options):
"""
entry point to run the API through the flask
Args:
options: all options
"""
# Starting the API
log.write_to_api_console(_("API_key").format(options.api_port, options.api_access_key))
p = multiprocessing.Process(target=start_api_subprocess, args=(options,))
p.start()
# Sometimes it's take much time to terminate flask with CTRL+C
# So It's better to use KeyboardInterrupt to terminate!
while len(multiprocessing.active_children()) != 0:
try:
time.sleep(0.3)
except KeyboardInterrupt:
for process in multiprocessing.active_children():
process.terminate()
break

12
nettacker/api/helpers.py Normal file
View File

@ -0,0 +1,12 @@
def structure(status="", msg=""):
"""
basic JSON message structure
Args:
status: status (ok, failed)
msg: the message content
Returns:
a JSON message
"""
return {"status": status, "msg": msg}

View File

@ -7,4 +7,4 @@ OWASP Nettacker API files are stored in here.
* `engine.py` is entry point of API and main functions
* `api_core.py` has core functions
* `start_scan.py` run new scans
* `database.sqlite3` an empty API database for sample, its copy to `./.data/database.sqlite3` and stores data i there.
* `database.sqlite3` an empty API database for sample, its copy to `./.nettacker/data/database.sqlite3` and stores data in there.

187
nettacker/config.py Normal file
View File

@ -0,0 +1,187 @@
import inspect
from functools import lru_cache
from pathlib import Path
from nettacker import version
from nettacker.core.utils.common import now, generate_random_token
CWD = Path.cwd()
PACKAGE_PATH = Path(__file__).parent
@lru_cache(maxsize=128)
def version_info():
"""
version information of the framework
Returns:
an array of version and code name
"""
return version.__version__, version.__release_name__
class ConfigBase:
@classmethod
def as_dict(cls):
return {attr_name: getattr(cls, attr_name) for attr_name in cls()}
def __init__(self) -> None:
self.attributes = sorted(
(
attribute[0]
for attribute in inspect.getmembers(self)
if not attribute[0].startswith("_") and not inspect.ismethod(attribute[1])
)
)
self.idx = 0
def __iter__(self):
yield from self.attributes
# Some sensitive header fields for HTTP requests.
# Please edit this if you don't want your HTTP header to be present in the logs
sensitive_headers = {
"authorization",
"proxy-authorization",
"cookie",
"set-cookie",
"x-api-key",
"x-amz-security-token",
"x-amz-credential",
"x-amz-signature",
"x-session-id",
"x-csrf-token",
"x-auth-token",
"x-user-token",
"x-id-token",
}
class ApiConfig(ConfigBase):
"""OWASP Nettacker API Default Configuration"""
api_access_log = str(CWD / ".nettacker/data/nettacker.log")
api_access_key = generate_random_token(32)
api_client_whitelisted_ips = [] # disabled - to enable please put an array with list of ips/cidr/ranges
# [
# "127.0.0.1",
# "10.0.0.0/24",
# "192.168.1.1-192.168.1.255"
# ],
api_debug_mode = False
api_hostname = "0.0.0.0"
api_port = 5000
start_api_server = False
class DbConfig(ConfigBase):
"""
Database Config (could be modified by user)
For sqlite database:
fill the name of the DB as sqlite,
DATABASE as the name of the db user wants
other details can be left empty
For mysql users:
fill the ENGINE name of the DB as mysql
NAME as the name of the database you want to create
USERNAME, PASSWORD, HOST and the PORT of the MySQL server
need to be filled respectively (default port is 3306)
For postgres users:
fill the Engine name of the DB as postgres
NAME as the name of the database user wants
USERNAME, PASSWORD, HOST and the PORT of the Postgres server
need to be filled respectively (default port is 5432)
Set ssl_mode to "require" if you need to use encrypted
databases.
"""
engine = "sqlite"
name = str(CWD / ".nettacker/data/nettacker.db")
host = ""
port = ""
username = ""
password = ""
ssl_mode = "disable"
class PathConfig:
"""
home path for the framework (could be modify by user)
Returns:
a JSON contain the working, tmp and results path
"""
data_dir = CWD / ".nettacker/data"
new_database_file = CWD / ".nettacker/data/nettacker.db"
old_database_file = CWD / ".data/nettacker.db"
graph_dir = PACKAGE_PATH / "lib/graph"
home_dir = CWD
locale_dir = PACKAGE_PATH / "locale"
logo_file = PACKAGE_PATH / "logo.txt"
module_protocols_dir = PACKAGE_PATH / "core/lib"
modules_dir = PACKAGE_PATH / "modules"
payloads_dir = PACKAGE_PATH / "lib/payloads"
release_name_file = PACKAGE_PATH / "release_name.txt"
results_dir = CWD / ".nettacker/data/results"
tmp_dir = CWD / ".nettacker/data/tmp"
web_static_dir = PACKAGE_PATH / "web/static"
user_agents_file = PACKAGE_PATH / "lib/payloads/User-Agents/web_browsers_user_agents.txt"
class DefaultSettings(ConfigBase):
"""OWASP Nettacker Default Configuration"""
excluded_modules = None
excluded_ports = None
graph_name = "d3_tree_v2_graph"
language = "en"
modules_extra_args = None
parallel_module_scan = 1
passwords = None
passwords_list = None
ping_before_scan = False
ports = None
profiles = None
report_path_filename = "{results_path}/results_{date_time}_{random_chars}.html".format(
results_path=PathConfig.results_dir,
date_time=now(format="%Y_%m_%d_%H_%M_%S"),
random_chars=generate_random_token(10),
)
retries = 1
scan_ip_range = False
scan_subdomains = False
selected_modules = None
url_base_path = None
http_header = None
read_from_file = ""
set_hardware_usage = "maximum" # low, normal, high, maximum
show_all_modules = False
show_all_profiles = False
show_help_menu = False
show_version = False
skip_service_discovery = False
socks_proxy = None
targets = None
targets_list = None
thread_per_host = 100
time_sleep_between_requests = 0.0
timeout = 3.0
user_agent = "Nettacker {version_number} {version_code}".format(
version_number=version_info()[0], version_code=version_info()[1]
)
usernames = None
usernames_list = None
verbose_event = False
verbose_mode = False
scan_compare_id = None
compare_report_path_filename = ""
class Config:
api = ApiConfig()
db = DbConfig()
path = PathConfig()
settings = DefaultSettings()

View File

329
nettacker/core/app.py Normal file
View File

@ -0,0 +1,329 @@
import copy
import json
import os
import shutil
import socket
import sys
from threading import Thread
import multiprocess
from nettacker import logger
from nettacker.config import Config, version_info
from nettacker.core.arg_parser import ArgParser
from nettacker.core.die import die_failure
from nettacker.core.graph import create_report, create_compare_report
from nettacker.core.ip import (
get_ip_range,
generate_ip_range,
is_single_ipv4,
is_ipv4_range,
is_ipv4_cidr,
is_single_ipv6,
is_ipv6_range,
is_ipv6_cidr,
)
from nettacker.core.messages import messages as _
from nettacker.core.module import Module
from nettacker.core.socks_proxy import set_socks_proxy
from nettacker.core.utils import common as common_utils
from nettacker.core.utils.common import wait_for_threads_to_finish
from nettacker.database.db import find_events, remove_old_logs
from nettacker.database.mysql import mysql_create_database, mysql_create_tables
from nettacker.database.postgresql import postgres_create_database
from nettacker.database.sqlite import sqlite_create_tables
from nettacker.logger import TerminalCodes
log = logger.get_logger()
class Nettacker(ArgParser):
def __init__(self, api_arguments=None):
if not api_arguments:
self.print_logo()
self.check_dependencies()
log.info(_("scan_started"))
super().__init__(api_arguments=api_arguments)
@staticmethod
def print_logo():
"""
OWASP Nettacker Logo
"""
log.write_to_api_console(
open(Config.path.logo_file)
.read()
.format(
cyan=TerminalCodes.CYAN.value,
red=TerminalCodes.RED.value,
rst=TerminalCodes.RESET.value,
v1=version_info()[0],
v2=version_info()[1],
yellow=TerminalCodes.YELLOW.value,
)
)
log.reset_color()
def check_dependencies(self):
if sys.platform not in {"darwin", "freebsd13", "freebsd14", "freebsd15", "linux"}:
die_failure(_("error_platform"))
try:
Config.path.tmp_dir.mkdir(exist_ok=True, parents=True)
Config.path.results_dir.mkdir(exist_ok=True, parents=True)
except PermissionError:
die_failure("Cannot access the directory {0}".format(Config.path.tmp_dir))
if Config.db.engine == "sqlite":
try:
if not Config.path.new_database_file.exists():
Config.path.new_database_file.parent.mkdir(parents=True, exist_ok=True)
if Config.path.old_database_file.exists():
shutil.copy(Config.path.old_database_file, Config.path.new_database_file)
log.warn("Database files migrated from .data to .nettacker ...")
else:
sqlite_create_tables()
except PermissionError:
die_failure("cannot access the directory {0}".format(Config.path.home_dir))
elif Config.db.engine == "mysql":
try:
mysql_create_database()
mysql_create_tables()
except Exception:
die_failure(_("database_connection_failed"))
elif Config.db.engine == "postgres":
try:
postgres_create_database()
except Exception:
die_failure(_("database_connection_failed"))
else:
die_failure(_("invalid_database"))
def expand_targets(self, scan_id):
"""
determine targets.
Args:
options: all options
scan_id: unique scan identifier
Returns:
a generator
"""
targets = []
base_path = ""
for target in self.arguments.targets:
if "://" in target:
try:
if not target.split("://")[1].split("/")[1]:
base_path = ""
else:
base_path = "/".join(target.split("://")[1].split("/")[1:])
if base_path[-1] != "/":
base_path += "/"
except IndexError:
base_path = ""
# remove url proto; uri; port
target = target.split("://")[1].split("/")[0].split(":")[0]
targets.append(target)
# single IPs
elif is_single_ipv4(target) or is_single_ipv6(target):
if self.arguments.scan_ip_range:
targets += get_ip_range(target)
else:
targets.append(target)
# IP ranges
elif (
is_ipv4_range(target)
or is_ipv6_range(target)
or is_ipv4_cidr(target)
or is_ipv6_cidr(target)
):
targets += generate_ip_range(target)
# domains probably
else:
targets.append(target)
self.arguments.targets = targets
self.arguments.url_base_path = base_path
# subdomain_scan
if self.arguments.scan_subdomains:
selected_modules = self.arguments.selected_modules
self.arguments.selected_modules = ["subdomain_scan"]
self.start_scan(scan_id)
self.arguments.selected_modules = selected_modules
if "subdomain_scan" in self.arguments.selected_modules:
self.arguments.selected_modules.remove("subdomain_scan")
for target in copy.deepcopy(self.arguments.targets):
for row in find_events(target, "subdomain_scan", scan_id):
for sub_domain in json.loads(row.json_event)["response"]["conditions_results"][
"content"
]:
if sub_domain not in self.arguments.targets:
self.arguments.targets.append(sub_domain)
# icmp_scan
if self.arguments.ping_before_scan:
if os.geteuid() == 0:
selected_modules = self.arguments.selected_modules
self.arguments.selected_modules = ["icmp_scan"]
self.start_scan(scan_id)
self.arguments.selected_modules = selected_modules
if "icmp_scan" in self.arguments.selected_modules:
self.arguments.selected_modules.remove("icmp_scan")
self.arguments.targets = self.filter_target_by_event(targets, scan_id, "icmp_scan")
else:
log.warn(_("icmp_need_root_access"))
if "icmp_scan" in self.arguments.selected_modules:
self.arguments.selected_modules.remove("icmp_scan")
# port_scan
if not self.arguments.skip_service_discovery:
self.arguments.skip_service_discovery = True
selected_modules = self.arguments.selected_modules
self.arguments.selected_modules = ["port_scan"]
self.start_scan(scan_id)
self.arguments.selected_modules = selected_modules
if "port_scan" in self.arguments.selected_modules:
self.arguments.selected_modules.remove("port_scan")
self.arguments.targets = self.filter_target_by_event(targets, scan_id, "port_scan")
self.arguments.skip_service_discovery = False
return list(set(self.arguments.targets))
def filter_target_by_event(self, targets, scan_id, module_name):
for target in copy.deepcopy(targets):
if not find_events(target, module_name, scan_id):
targets.remove(target)
return targets
def run(self):
"""
preparing for attacks and managing multi-processing for host
Args:
options: all options
Returns:
True when it ends
"""
scan_id = common_utils.generate_random_token(32)
log.info("ScanID: {0}".format(scan_id))
log.info(_("regrouping_targets"))
# find total number of targets + types + expand (subdomain, IPRanges, etc)
# optimize CPU usage
self.arguments.targets = self.expand_targets(scan_id)
if not self.arguments.targets:
log.info(_("no_live_service_found"))
return True
exit_code = self.start_scan(scan_id)
create_report(self.arguments, scan_id)
if self.arguments.scan_compare_id is not None:
create_compare_report(self.arguments, scan_id)
log.info("ScanID: {0} ".format(scan_id) + _("done"))
return exit_code
def start_scan(self, scan_id):
target_groups = common_utils.generate_target_groups(
self.arguments.targets, self.arguments.set_hardware_usage
)
log.info(_("removing_old_db_records"))
for target_group in target_groups:
for target in target_group:
for module_name in self.arguments.selected_modules:
remove_old_logs(
{
"target": target,
"module_name": module_name,
"scan_id": scan_id,
"scan_compare_id": self.arguments.scan_compare_id,
}
)
for _i in range(target_groups.count([])):
target_groups.remove([])
log.info(_("start_multi_process").format(len(self.arguments.targets), len(target_groups)))
active_processes = []
for t_id, target_groups in enumerate(target_groups):
process = multiprocess.Process(
target=self.scan_target_group, args=(target_groups, scan_id, t_id)
)
process.start()
active_processes.append(process)
return wait_for_threads_to_finish(active_processes, sub_process=True)
def scan_target(
self,
target,
module_name,
scan_id,
process_number,
thread_number,
total_number_threads,
):
options = copy.deepcopy(self.arguments)
socket.socket, socket.getaddrinfo = set_socks_proxy(options.socks_proxy)
module = Module(
module_name,
options,
target,
scan_id,
process_number,
thread_number,
total_number_threads,
)
module.load()
module.generate_loops()
module.sort_loops()
module.start()
log.verbose_event_info(
_("finished_parallel_module_scan").format(
process_number, module_name, target, thread_number, total_number_threads
)
)
return os.EX_OK
def scan_target_group(self, targets, scan_id, process_number):
active_threads = []
log.verbose_event_info(_("single_process_started").format(process_number))
total_number_of_modules = len(targets) * len(self.arguments.selected_modules)
total_number_of_modules_counter = 1
for target in targets:
for module_name in self.arguments.selected_modules:
thread = Thread(
target=self.scan_target,
args=(
target,
module_name,
scan_id,
process_number,
total_number_of_modules_counter,
total_number_of_modules,
),
)
thread.name = f"{target} -> {module_name}"
thread.start()
log.verbose_event_info(
_("start_parallel_module_scan").format(
process_number,
module_name,
target,
total_number_of_modules_counter,
total_number_of_modules,
)
)
total_number_of_modules_counter += 1
active_threads.append(thread)
if not wait_for_threads_to_finish(
active_threads, self.arguments.parallel_module_scan, True
):
return False
wait_for_threads_to_finish(active_threads, maximum=None, terminable=True)
return True

View File

@ -0,0 +1,766 @@
import json
import sys
from argparse import ArgumentParser
import yaml
from nettacker import all_module_severity_and_desc
from nettacker.config import version_info, Config
from nettacker.core.die import die_failure, die_success
from nettacker.core.ip import (
is_single_ipv4,
is_single_ipv6,
is_ipv4_cidr,
is_ipv6_range,
is_ipv6_cidr,
is_ipv4_range,
generate_ip_range,
)
from nettacker.core.messages import messages as _
from nettacker.core.template import TemplateLoader
from nettacker.core.utils import common as common_utils
from nettacker.logger import TerminalCodes, get_logger
log = get_logger()
class ArgParser(ArgumentParser):
def __init__(self, api_arguments=None) -> None:
super().__init__(prog="Nettacker", add_help=False)
self.api_arguments = api_arguments
self.graphs = self.load_graphs()
self.languages = self.load_languages()
self.modules = self.load_modules(full_details=True)
log.info(_("loaded_modules").format(len(self.modules)))
self.profiles = self.load_profiles()
self.add_arguments()
self.parse_arguments()
@staticmethod
def load_graphs():
"""
load all available graphs
Returns:
an array of graph names
"""
graph_names = []
for graph_library in Config.path.graph_dir.glob("*/engine.py"):
graph_names.append(str(graph_library).split("/")[-2] + "_graph")
return list(set(graph_names))
@staticmethod
def load_languages():
"""
Get available languages
Returns:
an array of languages
"""
languages_list = []
for language in Config.path.locale_dir.glob("*.yaml"):
languages_list.append(str(language).split("/")[-1].split(".")[0])
return list(set(languages_list))
@staticmethod
def load_modules(limit=-1, full_details=False):
"""
load all available modules
limit: return limited number of modules
full: with full details
Returns:
an array of all module names
"""
# Search for Modules
module_names = {}
for module_name in sorted(Config.path.modules_dir.glob("**/*.yaml")):
library = str(module_name).split("/")[-1].split(".")[0]
category = str(module_name).split("/")[-2]
module = f"{library}_{category}"
contents = yaml.safe_load(TemplateLoader(module).open().split("payload:")[0])
module_names[module] = contents["info"] if full_details else None
info = contents.get("info", {})
all_module_severity_and_desc[module] = {
"severity": info.get("severity", 0),
"desc": info.get("description", ""),
}
if len(module_names) == limit:
module_names["..."] = {}
break
module_names = common_utils.sort_dictionary(module_names)
module_names["all"] = {}
return module_names
@staticmethod
def load_profiles(limit=-1):
"""
load all available profiles
Returns:
an array of all profile names
"""
all_modules_with_details = ArgParser.load_modules(full_details=True).copy()
profiles = {}
if "..." in all_modules_with_details:
del all_modules_with_details["..."]
del all_modules_with_details["all"]
for key in all_modules_with_details:
for tag in all_modules_with_details[key]["profiles"]:
if tag not in profiles:
profiles[tag] = []
profiles[tag].append(key)
else:
profiles[tag].append(key)
if len(profiles) == limit:
profiles = common_utils.sort_dictionary(profiles)
profiles["..."] = []
profiles["all"] = []
return profiles
profiles = common_utils.sort_dictionary(profiles)
profiles["all"] = []
return profiles
def add_arguments(self):
# Engine Options
engine_options = self.add_argument_group(_("engine"), _("engine_input"))
engine_options.add_argument(
"-L",
"--language",
action="store",
dest="language",
default=Config.settings.language,
help=_("select_language").format(self.languages),
)
engine_options.add_argument(
"-v",
"--verbose",
action="store_true",
dest="verbose_mode",
default=Config.settings.verbose_mode,
help=_("verbose_mode"),
)
engine_options.add_argument(
"--verbose-event",
action="store_true",
dest="verbose_event",
default=Config.settings.verbose_event,
help=_("verbose_event"),
)
engine_options.add_argument(
"-V",
"--version",
action="store_true",
default=Config.settings.show_version,
dest="show_version",
help=_("software_version"),
)
engine_options.add_argument(
"-o",
"--output",
action="store",
default=Config.settings.report_path_filename,
dest="report_path_filename",
help=_("save_logs"),
)
engine_options.add_argument(
"--graph",
action="store",
default=Config.settings.graph_name,
dest="graph_name",
help=_("available_graph").format(self.graphs),
)
engine_options.add_argument(
"-h",
"--help",
action="store_true",
default=Config.settings.show_help_menu,
dest="show_help_menu",
help=_("help_menu"),
)
# Target Options
target_options = self.add_argument_group(_("target"), _("target_input"))
target_options.add_argument(
"-i",
"--targets",
action="store",
dest="targets",
default=Config.settings.targets,
help=_("target_list"),
)
target_options.add_argument(
"-l",
"--targets-list",
action="store",
dest="targets_list",
default=Config.settings.targets_list,
help=_("read_target"),
)
# Exclude Module Name
exclude_modules = sorted(self.modules.keys())[:10]
exclude_modules.remove("all")
# Method Options
method_options = self.add_argument_group(_("Method"), _("scan_method_options"))
method_options.add_argument(
"-m",
"--modules",
action="store",
dest="selected_modules",
default=Config.settings.selected_modules,
help=_("choose_scan_method").format(list(self.modules.keys())[:10]),
)
method_options.add_argument(
"--modules-extra-args",
action="store",
dest="modules_extra_args",
default=Config.settings.modules_extra_args,
help=_("modules_extra_args_help"),
)
method_options.add_argument(
"--show-all-modules",
action="store_true",
dest="show_all_modules",
default=Config.settings.show_all_modules,
help=_("show_all_modules"),
)
method_options.add_argument(
"--profile",
action="store",
default=Config.settings.profiles,
dest="profiles",
help=_("select_profile").format(list(self.profiles.keys())[:10]),
)
method_options.add_argument(
"--show-all-profiles",
action="store_true",
dest="show_all_profiles",
default=Config.settings.show_all_profiles,
help=_("show_all_profiles"),
)
method_options.add_argument(
"-x",
"--exclude-modules",
action="store",
dest="excluded_modules",
default=Config.settings.excluded_modules,
help=_("exclude_scan_method").format(exclude_modules),
)
method_options.add_argument(
"-X",
"--exclude-ports",
action="store",
dest="excluded_ports",
default=Config.settings.excluded_ports,
help=_("exclude_ports"),
)
method_options.add_argument(
"-u",
"--usernames",
action="store",
dest="usernames",
default=Config.settings.usernames,
help=_("username_list"),
)
method_options.add_argument(
"-U",
"--users-list",
action="store",
dest="usernames_list",
default=Config.settings.usernames_list,
help=_("username_from_file"),
)
method_options.add_argument(
"-p",
"--passwords",
action="store",
dest="passwords",
default=Config.settings.passwords,
help=_("password_separator"),
)
method_options.add_argument(
"-P",
"--passwords-list",
action="store",
dest="passwords_list",
default=Config.settings.passwords_list,
help=_("read_passwords"),
)
method_options.add_argument(
"-g",
"--ports",
action="store",
dest="ports",
default=Config.settings.ports,
help=_("port_separator"),
)
method_options.add_argument(
"--user-agent",
action="store",
dest="user_agent",
default=Config.settings.user_agent,
help=_("select_user_agent"),
)
method_options.add_argument(
"-T",
"--timeout",
action="store",
dest="timeout",
default=Config.settings.timeout,
type=float,
help=_("read_passwords"),
)
method_options.add_argument(
"-w",
"--time-sleep-between-requests",
action="store",
dest="time_sleep_between_requests",
default=Config.settings.time_sleep_between_requests,
type=float,
help=_("time_to_sleep"),
)
method_options.add_argument(
"-r",
"--range",
action="store_true",
default=Config.settings.scan_ip_range,
dest="scan_ip_range",
help=_("range"),
)
method_options.add_argument(
"-s",
"--sub-domains",
action="store_true",
default=Config.settings.scan_subdomains,
dest="scan_subdomains",
help=_("subdomains"),
)
method_options.add_argument(
"-d",
"--skip-service-discovery",
action="store_true",
default=Config.settings.skip_service_discovery,
dest="skip_service_discovery",
help=_("skip_service_discovery"),
)
method_options.add_argument(
"-t",
"--thread-per-host",
action="store",
default=Config.settings.thread_per_host,
type=int,
dest="thread_per_host",
help=_("thread_number_connections"),
)
method_options.add_argument(
"-M",
"--parallel-module-scan",
action="store",
default=Config.settings.parallel_module_scan,
type=int,
dest="parallel_module_scan",
help=_("thread_number_modules"),
)
method_options.add_argument(
"--set-hardware-usage",
action="store",
dest="set_hardware_usage",
default=Config.settings.set_hardware_usage,
help=_("set_hardware_usage"),
)
method_options.add_argument(
"-R",
"--socks-proxy",
action="store",
dest="socks_proxy",
default=Config.settings.socks_proxy,
help=_("outgoing_proxy"),
)
method_options.add_argument(
"--retries",
action="store",
dest="retries",
type=int,
default=Config.settings.retries,
help=_("connection_retries"),
)
method_options.add_argument(
"--ping-before-scan",
action="store_true",
dest="ping_before_scan",
default=Config.settings.ping_before_scan,
help=_("ping_before_scan"),
)
method_options.add_argument(
"-K",
"--scan-compare",
action="store",
dest="scan_compare_id",
default=Config.settings.scan_compare_id,
help=_("compare_scans"),
)
method_options.add_argument(
"-J",
"--compare-report-path",
action="store",
dest="compare_report_path_filename",
default=Config.settings.compare_report_path_filename,
help=_("compare_report_path_filename"),
)
method_options.add_argument(
"-W",
"--wordlist",
action="store",
default=Config.settings.read_from_file,
dest="read_from_file",
help=_("user_wordlist"),
)
method_options.add_argument(
"-H",
"--add-http-header",
action="append",
default=Config.settings.http_header,
dest="http_header",
help=_("http_header"),
)
# API Options
api_options = self.add_argument_group(_("API"), _("API_options"))
api_options.add_argument(
"--start-api",
action="store_true",
dest="start_api_server",
default=Config.api.start_api_server,
help=_("start_api_server"),
)
api_options.add_argument(
"--api-host",
action="store",
dest="api_hostname",
default=Config.api.api_hostname,
help=_("API_host"),
)
api_options.add_argument(
"--api-port",
action="store",
dest="api_port",
default=Config.api.api_port,
help=_("API_port"),
)
api_options.add_argument(
"--api-debug-mode",
action="store_true",
dest="api_debug_mode",
default=Config.api.api_debug_mode,
help=_("API_debug"),
)
api_options.add_argument(
"--api-access-key",
action="store",
dest="api_access_key",
default=Config.api.api_access_key,
help=_("API_access_key"),
)
api_options.add_argument(
"--api-client-whitelisted-ips",
action="store",
dest="api_client_whitelisted_ips",
default=Config.api.api_client_whitelisted_ips,
help=_("define_white_list"),
)
api_options.add_argument(
"--api-access-log",
action="store",
dest="api_access_log",
default=Config.api.api_access_log,
help=_("API_access_log_file"),
)
api_options.add_argument(
"--api-cert",
action="store",
dest="api_cert",
help=_("API_cert"),
)
api_options.add_argument(
"--api-cert-key",
action="store",
dest="api_cert_key",
help=_("API_cert_key"),
)
def parse_arguments(self):
"""
check all rules and requirements for ARGS
Args:
api_forms: values from nettacker.api
Returns:
all ARGS with applied rules
"""
# Checking Requirements
options = self.api_arguments or self.parse_args()
if options.language not in self.languages:
die_failure("Please select one of these languages {0}".format(self.languages))
# Check Help Menu
if options.show_help_menu:
self.print_help()
log.write("\n\n")
log.write(_("license"))
die_success()
# Check version
if options.show_version:
log.info(
_("current_version").format(
TerminalCodes.YELLOW.value,
version_info()[0],
TerminalCodes.RESET.value,
TerminalCodes.CYAN.value,
version_info()[1],
TerminalCodes.RESET.value,
TerminalCodes.GREEN.value,
)
)
die_success()
if options.show_all_modules:
log.info(_("loading_modules"))
for module in self.modules:
log.info(
_("module_profile_full_information").format(
TerminalCodes.CYAN.value,
module,
TerminalCodes.GREEN.value,
", ".join(
[
"{key}: {value}".format(key=key, value=self.modules[module][key])
for key in self.modules[module]
]
),
)
)
die_success()
if options.show_all_profiles:
log.info(_("loading_profiles"))
for profile in self.profiles:
log.info(
_("module_profile_full_information").format(
TerminalCodes.CYAN.value,
profile,
TerminalCodes.GREEN.value,
", ".join(self.profiles[profile]),
)
)
die_success()
# API mode
if options.start_api_server:
if "--start-api" in sys.argv and self.api_arguments:
die_failure(_("cannot_run_api_server"))
from nettacker.api.engine import start_api_server
if options.api_client_whitelisted_ips:
if isinstance(options.api_client_whitelisted_ips, str):
options.api_client_whitelisted_ips = options.api_client_whitelisted_ips.split(
","
)
whitelisted_ips = []
for ip in options.api_client_whitelisted_ips:
if is_single_ipv4(ip) or is_single_ipv6(ip):
whitelisted_ips.append(ip)
elif (
is_ipv4_range(ip)
or is_ipv6_range(ip)
or is_ipv4_cidr(ip)
or is_ipv6_cidr(ip)
):
whitelisted_ips += generate_ip_range(ip)
options.api_client_whitelisted_ips = whitelisted_ips
start_api_server(options)
# Check the target(s)
if not (options.targets or options.targets_list) or (
options.targets and options.targets_list
):
# self.print_help()
# write("\n")
die_failure(_("error_target"))
if options.targets:
options.targets = list(set(options.targets.split(",")))
if options.targets_list:
try:
options.targets = list(
set(open(options.targets_list, "rb").read().decode().split())
)
except Exception:
die_failure(_("error_target_file").format(options.targets_list))
# check for modules
if not (options.selected_modules or options.profiles):
die_failure(_("scan_method_select"))
if options.selected_modules:
if options.selected_modules == "all":
options.selected_modules = list(set(self.modules.keys()))
options.selected_modules.remove("all")
else:
options.selected_modules = list(set(options.selected_modules.split(",")))
for module_name in options.selected_modules:
if module_name not in self.modules:
die_failure(_("scan_module_not_found").format(module_name))
if options.profiles:
if not options.selected_modules:
options.selected_modules = []
if options.profiles == "all":
options.selected_modules = list(set(self.modules.keys()))
options.selected_modules.remove("all")
else:
options.profiles = list(set(options.profiles.split(",")))
for profile in options.profiles:
if profile not in self.profiles:
die_failure(_("profile_404").format(profile))
for module_name in self.profiles[profile]:
if module_name not in options.selected_modules:
options.selected_modules.append(module_name)
# threading & processing
if options.set_hardware_usage not in {"low", "normal", "high", "maximum"}:
die_failure(_("wrong_hardware_usage"))
options.set_hardware_usage = common_utils.select_maximum_cpu_core(
options.set_hardware_usage
)
options.thread_per_host = int(options.thread_per_host)
if options.thread_per_host < 1:
options.thread_per_host = 1
options.parallel_module_scan = int(options.parallel_module_scan)
if options.parallel_module_scan < 1:
options.parallel_module_scan = 1
# Check for excluding modules
if options.excluded_modules:
options.excluded_modules = options.excluded_modules.split(",")
if "all" in options.excluded_modules:
die_failure(_("error_exclude_all"))
for excluded_module in options.excluded_modules:
if excluded_module in options.selected_modules:
options.selected_modules.remove(excluded_module)
# Check port(s)
if options.ports:
tmp_ports = set()
for port in options.ports.split(","):
try:
if "-" in port:
for port_number in range(
int(port.split("-")[0]), int(port.split("-")[1]) + 1
):
tmp_ports.add(port_number)
else:
tmp_ports.add(int(port))
except Exception:
die_failure(_("ports_int"))
options.ports = list(tmp_ports)
# Check for excluded ports
if options.excluded_ports:
tmp_excluded_ports = set()
for excluded_port in options.excluded_ports.split(","):
try:
if "-" in excluded_port:
for excluded_port_number in range(
int(excluded_port.split("-")[0]), int(excluded_port.split("-")[1]) + 1
):
tmp_excluded_ports.add(excluded_port_number)
else:
tmp_excluded_ports.add(int(excluded_port))
except Exception:
die_failure(_("ports_int"))
options.excluded_ports = list(tmp_excluded_ports)
if options.user_agent == "random_user_agent":
options.user_agents = open(Config.path.user_agents_file).read().split("\n")
# Check user list
if options.usernames:
options.usernames = list(set(options.usernames.split(",")))
elif options.usernames_list:
try:
options.usernames = list(set(open(options.usernames_list).read().split("\n")))
except Exception:
die_failure(_("error_username").format(options.usernames_list))
# Check password list
if options.passwords:
options.passwords = list(set(options.passwords.split(",")))
elif options.passwords_list:
try:
options.passwords = list(set(open(options.passwords_list).read().split("\n")))
except Exception:
die_failure(_("error_passwords").format(options.passwords_list))
# Check custom wordlist
if options.read_from_file:
try:
open(options.read_from_file).read().split("\n")
except Exception:
die_failure(_("error_wordlist").format(options.read_from_file))
# Check output file
try:
temp_file = open(options.report_path_filename, "w")
temp_file.close()
except Exception:
die_failure(_("file_write_error").format(options.report_path_filename))
# Check Graph
if options.graph_name:
if options.graph_name not in self.graphs:
die_failure(_("graph_module_404").format(options.graph_name))
if not (
options.report_path_filename.endswith(".html")
or options.report_path_filename.endswith(".htm")
):
log.warn(_("graph_output"))
options.graph_name = None
# check modules extra args
if options.modules_extra_args:
all_args = {}
for args in options.modules_extra_args.split("&"):
value = args.split("=")[1]
if value.lower() == "true":
value = True
elif value.lower() == "false":
value = False
elif "." in value:
try:
value = float(value)
except Exception:
pass
elif "{" in value or "[" in value:
try:
value = json.loads(value)
except Exception:
pass
else:
try:
value = int(value)
except Exception:
pass
all_args[args.split("=")[0]] = value
options.modules_extra_args = all_args
options.timeout = float(options.timeout)
options.time_sleep_between_requests = float(options.time_sleep_between_requests)
options.retries = int(options.retries)
self.arguments = options

View File

@ -1,15 +1,15 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from nettacker import logger
log = logger.get_logger()
def die_success():
"""
exit the framework with code 0
"""
from core.color import reset_color
reset_color()
log.reset_color()
sys.exit(0)
@ -20,8 +20,7 @@ def die_failure(msg):
Args:
msg: the error message
"""
from core.color import reset_color
from core.alert import error
error(msg)
reset_color()
log.error(msg)
log.reset_color()
sys.exit(1)

5
nettacker/core/fuzzer.py Normal file
View File

@ -0,0 +1,5 @@
from nettacker.config import Config
def read_from_file(file_path):
return open(Config.path.payloads_dir / file_path).read().split("\n")

403
nettacker/core/graph.py Normal file
View File

@ -0,0 +1,403 @@
import csv
import html
import importlib
import json
import os
import uuid
from datetime import datetime
from pathlib import Path
import texttable
from nettacker import logger, all_module_severity_and_desc
from nettacker.config import Config, version_info
from nettacker.core.die import die_failure
from nettacker.core.messages import messages as _
from nettacker.core.utils.common import (
merge_logs_to_list,
now,
sanitize_path,
generate_compare_filepath,
)
from nettacker.database.db import get_logs_by_scan_id, submit_report_to_db, get_options_by_scan_id
log = logger.get_logger()
nettacker_path_config = Config.path
def build_graph(graph_name, events):
"""
build a graph
Args:
graph_name: graph name
events: list of events
Returns:
graph in HTML type
"""
log.info(_("build_graph"))
try:
start = getattr(
importlib.import_module(
f"nettacker.lib.graph.{graph_name.rsplit('_graph')[0]}.engine"
),
"start",
)
except ModuleNotFoundError:
die_failure(_("graph_module_unavailable").format(graph_name))
log.info(_("finish_build_graph"))
return start(events)
def build_compare_report(compare_results):
"""
build the compare report
Args:
compare_results: Final result of the comparision(dict)
Returns:
report in html format
"""
log.info(_("build_compare_report"))
try:
build_report = getattr(
importlib.import_module("nettacker.lib.compare_report.engine"),
"build_report",
)
except ModuleNotFoundError:
die_failure(_("graph_module_unavailable").format("compare_report"))
log.info(_("finish_build_report"))
return build_report(compare_results)
def build_text_table(events):
"""
value['date'], value["target"], value['module_name'], value['scan_id'],
value['options'], value['event']
build a text table with generated event related to the scan
:param events: all events
:return:
array [text table, event_number]
"""
_table = texttable.Texttable()
table_headers = ["date", "target", "module_name", "port", "logs"]
_table.add_rows([table_headers])
for event in events:
log = merge_logs_to_list(json.loads(event["json_event"]), [])
_table.add_rows(
[
table_headers,
[
event["date"],
event["target"],
event["module_name"],
str(event["port"]),
"\n".join(log) if log else "Detected",
],
]
)
return (
_table.draw()
+ "\n\n"
+ _("nettacker_version_details").format(version_info()[0], version_info()[1], now())
+ "\n"
)
def create_compare_text_table(results):
table = texttable.Texttable()
table_headers = list(results.keys())
table.add_rows([table_headers])
table.add_rows(
[
table_headers,
[results[col] for col in table_headers],
]
)
table.set_cols_width([len(i) for i in table_headers])
return table.draw() + "\n\n"
def create_dd_specific_json(all_scan_logs):
severity_mapping = {1: "Info", 2: "Low", 3: "Medium", 4: "High", 5: "Critical"}
findings = []
for log in all_scan_logs:
module_name = log["module_name"].strip()
date = datetime.strptime(log["date"], "%Y-%m-%d %H:%M:%S.%f").strftime("%m/%d/%Y")
port = str(log.get("port", "")).strip()
impact = log.get("event", "").strip()
severity_justification = log.get("json_event", "").strip()
service = log.get("target", "").strip()
unique_id = log.get("scan_id", uuid.uuid4().hex)
metadata = all_module_severity_and_desc.get(module_name, {})
severity_raw = metadata.get("severity", 0)
description = metadata.get("desc", "")
if severity_raw >= 9:
severity = severity_mapping[5]
elif severity_raw >= 7:
severity = severity_mapping[4]
elif severity_raw >= 4:
severity = severity_mapping[3]
elif severity_raw > 0:
severity = severity_mapping[2]
else:
severity = severity_mapping[1]
findings.append(
{
"date": date,
"title": module_name,
"description": description.strip(),
"severity": severity,
"param": port,
"impact": impact,
"severity_justification": severity_justification,
"service": service,
"unique_id_from_tool": unique_id,
"static_finding": False,
"dynamic_finding": True,
}
)
return json.dumps({"findings": findings}, indent=4)
def create_sarif_report(all_scan_logs):
"""
Takes all_scan_logs and converts them to a SARIF based json
format. The schema and version used are 2.1.0 linked below.
The following conversions are made:
ruleId: name of the module
message: event value for each log in all_scan_logs
locations.physicalLocations.artifactLocation.uri: target value
webRequest.properties.json_event: json_event value for each log in all_scan_logs
properties.scan_id: scan_id unique value for each run
properties.date: date field specified in all_scan_logs
"""
sarif_structure = {
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
"version": "2.1.0",
"runs": [
{
"tool": {
"driver": {
"name": "Nettacker",
"version": "0.4.0",
"informationUri": "https://github.com/OWASP/Nettacker",
}
},
"results": [],
}
],
}
for log in all_scan_logs:
sarif_result = {
"ruleId": log["module_name"],
"message": {"text": log["event"]},
"locations": [{"physicalLocation": {"artifactLocation": {"uri": log["target"]}}}],
"properties": {
"scan_id": log["scan_id"],
"date": log["date"],
"json_event": log["json_event"],
},
}
sarif_structure["runs"][0]["results"].append(sarif_result)
return json.dumps(sarif_structure, indent=2)
def create_report(options, scan_id):
"""
sort all events, create log file in HTML/TEXT/JSON and remove old logs
Args:
options: parsing options
scan_id: scan unique id
Returns:
True if success otherwise None
"""
all_scan_logs = get_logs_by_scan_id(scan_id)
if not all_scan_logs:
log.info(_("no_events_for_report"))
return True
report_path_filename = options.report_path_filename
if (len(report_path_filename) >= 5 and report_path_filename[-5:] == ".html") or (
len(report_path_filename) >= 4 and report_path_filename[-4:] == ".htm"
):
if options.graph_name:
html_graph = build_graph(options.graph_name, all_scan_logs)
else:
html_graph = ""
from nettacker.lib.html_log import log_data
html_table_content = log_data.table_title.format(
html_graph,
log_data.css_1,
"date",
"target",
"module_name",
"port",
"logs",
"json_event",
)
index = 1
for event in all_scan_logs:
log_list = merge_logs_to_list(json.loads(event["json_event"]), [])
html_table_content += log_data.table_items.format(
event["date"],
event["target"],
event["module_name"],
event["port"],
"<br>".join(log_list) if log_list else "Detected", # event["event"], #log
index,
html.escape(event["json_event"]),
)
index += 1
html_table_content += (
log_data.table_end
+ '<div id="json_length">'
+ str(index - 1)
+ "</div>"
+ '<p class="footer">'
+ _("nettacker_version_details").format(version_info()[0], version_info()[1], now())
+ " ScanID: {0}".format(scan_id)
+ "</p>"
+ log_data.json_parse_js
)
with Path(report_path_filename).open("w", encoding="utf-8") as report_file:
report_file.write(html_table_content + "\n")
elif len(report_path_filename) >= 5 and report_path_filename[-8:].lower() == ".dd.json":
with Path(report_path_filename).open("w", encoding="utf-8") as report_file:
dd_content_json = create_dd_specific_json(all_scan_logs)
report_file.write(dd_content_json + "\n")
elif len(report_path_filename) >= 5 and report_path_filename[-5:] == ".json":
with Path(report_path_filename).open("w", encoding="utf-8") as report_file:
report_file.write(str(json.dumps(all_scan_logs)) + "\n")
elif len(report_path_filename) >= 6 and report_path_filename[-6:].lower() == ".sarif":
with Path(report_path_filename).open("w", encoding="utf-8") as report_file:
sarif_content = create_sarif_report(all_scan_logs)
report_file.write(sarif_content + "\n")
elif len(report_path_filename) >= 5 and report_path_filename[-4:] == ".csv":
keys = all_scan_logs[0].keys()
with Path(report_path_filename).open("a") as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=keys)
writer.writeheader()
for log_list in all_scan_logs:
dict_data = {key: value for key, value in log_list.items() if key in keys}
writer.writerow(dict_data)
else:
with Path(report_path_filename).open("w", encoding="utf-8") as report_file:
report_file.write(build_text_table(all_scan_logs))
log.write(build_text_table(all_scan_logs))
submit_report_to_db(
{
"date": datetime.now(),
"scan_id": scan_id,
"options": vars(options),
}
)
log.info(_("file_saved").format(report_path_filename))
return True
def create_compare_report(options, scan_id):
"""
if compare_id is given then create the report of comparision b/w scans
Args:
options: parsing options
scan_id: scan unique id
Returns:
True if success otherwise None
"""
comp_id = options["scan_compare_id"] if isinstance(options, dict) else options.scan_compare_id
scan_log_curr = get_logs_by_scan_id(scan_id)
scan_logs_comp = get_logs_by_scan_id(comp_id)
if not scan_log_curr:
log.info(_("no_events_for_report"))
return None
if not scan_logs_comp:
log.info(_("no_scan_to_compare"))
return None
scan_opts_curr = get_options_by_scan_id(scan_id)
scan_opts_comp = get_options_by_scan_id(comp_id)
def get_targets_set(item):
return tuple(json.loads(item["options"])["targets"])
curr_target_set = set(get_targets_set(item) for item in scan_opts_curr)
comp_target_set = set(get_targets_set(item) for item in scan_opts_comp)
def get_modules_ports(item):
return (item["target"], item["module_name"], item["port"])
curr_modules_ports = set(get_modules_ports(item) for item in scan_log_curr)
comp_modules_ports = set(get_modules_ports(item) for item in scan_logs_comp)
compare_results = {
"curr_scan_details": (scan_id, scan_log_curr[0]["date"]),
"comp_scan_details": (comp_id, scan_logs_comp[0]["date"]),
"curr_target_set": tuple(curr_target_set),
"comp_target_set": tuple(comp_target_set),
"curr_scan_result": tuple(curr_modules_ports),
"comp_scan_result": tuple(comp_modules_ports),
"new_targets_discovered": tuple(curr_modules_ports - comp_modules_ports),
"old_targets_not_detected": tuple(comp_modules_ports - curr_modules_ports),
}
if isinstance(options, dict):
compare_report_path_filename = options["compare_report_path_filename"]
else:
compare_report_path_filename = (
options.compare_report_path_filename
if len(options.compare_report_path_filename) != 0
else generate_compare_filepath(scan_id)
)
base_path = str(nettacker_path_config.results_dir)
compare_report_path_filename = sanitize_path(compare_report_path_filename)
fullpath = os.path.normpath(os.path.join(base_path, compare_report_path_filename))
if not fullpath.startswith(base_path):
raise PermissionError
if (len(fullpath) >= 5 and fullpath[-5:] == ".html") or (
len(fullpath) >= 4 and fullpath[-4:] == ".htm"
):
html_report = build_compare_report(compare_results)
with Path(fullpath).open("w", encoding="utf-8") as compare_report:
compare_report.write(html_report + "\n")
elif len(fullpath) >= 5 and fullpath[-5:] == ".json":
with Path(fullpath).open("w", encoding="utf-8") as compare_report:
compare_report.write(str(json.dumps(compare_results)) + "\n")
elif len(fullpath) >= 5 and fullpath[-4:] == ".csv":
keys = compare_results.keys()
with Path(fullpath).open("a") as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=keys)
if csvfile.tell() == 0:
writer.writeheader()
writer.writerow(compare_results)
else:
with Path(fullpath).open("w", encoding="utf-8") as compare_report:
compare_report.write(create_compare_text_table(compare_results))
log.write(create_compare_text_table(compare_results))
log.info(_("compare_report_saved").format(fullpath))
return True

View File

@ -1,11 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import netaddr
import requests
from netaddr import iprange_to_cidrs
from netaddr import IPNetwork
def generate_ip_range(ip_range):
@ -18,13 +14,13 @@ def generate_ip_range(ip_range):
Returns:
an array with CIDRs
"""
if '/' in ip_range:
return [
ip.format() for ip in [cidr for cidr in IPNetwork(ip_range)]
]
if "/" in ip_range:
return [ip.format() for ip in [cidr for cidr in netaddr.IPNetwork(ip_range)]]
else:
ips = []
for generator_ip_range in [cidr.iter_hosts() for cidr in iprange_to_cidrs(*ip_range.rsplit('-'))]:
for generator_ip_range in [
cidr.iter_hosts() for cidr in netaddr.iprange_to_cidrs(*ip_range.rsplit("-"))
]:
for ip in generator_ip_range:
ips.append(ip.format())
return ips
@ -44,9 +40,9 @@ def get_ip_range(ip):
return generate_ip_range(
json.loads(
requests.get(
'https://rest.db.ripe.net/search.json?query-string={ip}&flags=no-filtering'.format(ip=ip)
f"https://rest.db.ripe.net/search.json?query-string={ip}&flags=no-filtering"
).content
)['objects']['object'][0]['primary-key']['attribute'][0]['value'].replace(' ', '')
)["objects"]["object"][0]["primary-key"]["attribute"][0]["value"].replace(" ", "")
)
except Exception:
return [ip]
@ -67,14 +63,24 @@ def is_single_ipv4(ip):
def is_ipv4_range(ip_range):
try:
return '/' in ip_range and '.' in ip_range and '-' not in ip_range and netaddr.IPNetwork(ip_range)
return (
"/" in ip_range
and "." in ip_range
and "-" not in ip_range
and bool(netaddr.IPNetwork(ip_range))
)
except Exception:
return False
def is_ipv4_cidr(ip_range):
try:
return '/' not in ip_range and '.' in ip_range and '-' in ip_range and iprange_to_cidrs(*ip_range.split('-'))
return (
"/" not in ip_range
and "." in ip_range
and "-" in ip_range
and bool(netaddr.iprange_to_cidrs(*ip_range.split("-")))
)
except Exception:
return False
@ -89,18 +95,28 @@ def is_single_ipv6(ip):
Returns:
True if it's IPv6 otherwise False
"""
return netaddr.valid_ipv6(str(ip))
return netaddr.valid_ipv6(ip)
def is_ipv6_range(ip_range):
try:
return '/' not in ip_range and ':' in ip_range and '-' in ip_range and iprange_to_cidrs(*ip_range.split('-'))
return (
"/" not in ip_range
and ":" in ip_range
and "-" in ip_range
and bool(netaddr.iprange_to_cidrs(*ip_range.split("-")))
)
except Exception:
return False
def is_ipv6_cidr(ip_range):
try:
return '/' in ip_range and ':' in ip_range and '-' not in ip_range and netaddr.IPNetwork(ip_range)
return (
"/" in ip_range
and ":" in ip_range
and "-" not in ip_range
and bool(netaddr.IPNetwork(ip_range))
)
except Exception:
return False

View File

313
nettacker/core/lib/base.py Normal file
View File

@ -0,0 +1,313 @@
import copy
import json
import re
import time
from abc import ABC
from datetime import datetime
import yaml
from nettacker.config import Config
from nettacker.core.messages import messages as _
from nettacker.core.utils.common import merge_logs_to_list, remove_sensitive_header_keys
from nettacker.database.db import find_temp_events, submit_temp_logs_to_db, submit_logs_to_db
from nettacker.logger import get_logger, TerminalCodes
log = get_logger()
class BaseLibrary(ABC):
"""Nettacker library base class."""
client = None
def brute_force(self):
"""Brute force method."""
class BaseEngine(ABC):
"""Nettacker engine base class."""
library = None
def apply_extra_data(self, *args, **kwargs):
"""Add extra data into step context."""
def filter_large_content(self, content, filter_rate=150):
if len(content) <= filter_rate:
return content
else:
filter_rate -= 1
filter_index = filter_rate
for char in content[filter_rate:]:
if char == " ":
return content[0:filter_index] + _("filtered_content")
else:
filter_index += 1
return content
def get_dependent_results_from_database(self, target, module_name, scan_id, event_names):
events = []
for event_name in event_names.split(","):
while True:
event = find_temp_events(target, module_name, scan_id, event_name)
if event:
events.append(json.loads(event.event)["response"]["conditions_results"])
break
time.sleep(0.1)
return events
def find_and_replace_dependent_values(self, sub_step, dependent_on_temp_event):
if isinstance(sub_step, dict):
for key in copy.deepcopy(sub_step):
if not isinstance(sub_step[key], (str, float, int, bytes)):
sub_step[key] = self.find_and_replace_dependent_values(
copy.deepcopy(sub_step[key]), dependent_on_temp_event
)
else:
if isinstance(sub_step[key], str):
if "dependent_on_temp_event" in sub_step[key]:
globals().update(locals())
generate_new_step = copy.deepcopy(sub_step[key])
key_name = re.findall(
re.compile(
"dependent_on_temp_event\\[\\S+\\]\\['\\S+\\]\\[\\S+\\]"
),
generate_new_step,
)[0]
try:
key_value = eval(key_name)
except Exception:
key_value = "error"
sub_step[key] = sub_step[key].replace(key_name, key_value)
if isinstance(sub_step, list):
value_index = 0
for key in copy.deepcopy(sub_step):
if type(sub_step[value_index]) not in [str, float, int, bytes]:
sub_step[key] = self.find_and_replace_dependent_values(
copy.deepcopy(sub_step[value_index]), dependent_on_temp_event
)
else:
if isinstance(sub_step[value_index], str):
if "dependent_on_temp_event" in sub_step[value_index]:
globals().update(locals())
generate_new_step = copy.deepcopy(sub_step[key])
key_name = re.findall(
re.compile("dependent_on_temp_event\\['\\S+\\]\\[\\S+\\]"),
generate_new_step,
)[0]
try:
key_value = eval(key_name)
except Exception:
key_value = "error"
sub_step[value_index] = sub_step[value_index].replace(
key_name, key_value
)
value_index += 1
return sub_step
def process_conditions(
self,
event,
module_name,
target,
scan_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests,
):
# Remove sensitive keys from headers before submitting to DB
event = remove_sensitive_header_keys(event)
if "save_to_temp_events_only" in event.get("response", ""):
submit_temp_logs_to_db(
{
"date": datetime.now(),
"target": target,
"module_name": module_name,
"scan_id": scan_id,
"event_name": event["response"]["save_to_temp_events_only"],
"port": event.get("ports", ""),
"event": event,
"data": response,
}
)
if event["response"]["conditions_results"] and "save_to_temp_events_only" not in event.get(
"response", ""
):
# remove sensitive information before submitting to db
options = copy.deepcopy(options)
for key in Config.api:
try:
del options[key]
except KeyError:
continue
del event["response"]["conditions"]
del event["response"]["condition_type"]
if "log" in event["response"]:
del event["response"]["log"]
event_request_keys = copy.deepcopy(event)
del event_request_keys["response"]
submit_logs_to_db(
{
"date": datetime.now(),
"target": target,
"module_name": module_name,
"scan_id": scan_id,
"port": event.get("ports")
or event.get("port")
or (
event.get("url").split(":")[2].split("/")[0]
if isinstance(event.get("url"), str)
and len(event.get("url").split(":")) >= 3
and event.get("url").split(":")[2].split("/")[0].isdigit()
else ""
),
"event": " ".join(yaml.dump(event_request_keys).split())
+ " conditions: "
+ " ".join(yaml.dump(event["response"]["conditions_results"]).split()),
"json_event": event,
}
)
log_list = merge_logs_to_list(event["response"]["conditions_results"])
if log_list:
log.success_event_info(
_("send_success_event_from_module").format(
process_number,
module_name,
target,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests,
" ",
self.filter_large_content(
"\n".join(
[
TerminalCodes.PURPLE.value + key + TerminalCodes.RESET.value
for key in log_list
]
),
filter_rate=100000,
),
)
)
else:
log.success_event_info(
_("send_success_event_from_module").format(
process_number,
module_name,
target,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests,
" ".join(
[
TerminalCodes.YELLOW.value + key + TerminalCodes.RESET.value
if ":" in key
else TerminalCodes.GREEN.value + key + TerminalCodes.RESET.value
for key in yaml.dump(event_request_keys).split()
]
),
self.filter_large_content(
"conditions: "
+ " ".join(
[
TerminalCodes.PURPLE.value + key + TerminalCodes.RESET.value
if ":" in key
else TerminalCodes.GREEN.value
+ key
+ TerminalCodes.RESET.value
for key in yaml.dump(
event["response"]["conditions_results"]
).split()
]
),
filter_rate=150,
),
)
)
log.verbose_info(json.dumps(event))
return True
else:
del event["response"]["conditions"]
log.verbose_info(
_("send_unsuccess_event_from_module").format(
process_number,
module_name,
target,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests,
)
)
log.verbose_info(json.dumps(event))
return "save_to_temp_events_only" in event["response"]
def replace_dependent_values(self, sub_step, dependent_on_temp_event):
return self.find_and_replace_dependent_values(sub_step, dependent_on_temp_event)
def run(
self,
sub_step,
module_name,
target,
scan_id,
options,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests,
):
"""Engine entry point."""
backup_method = copy.deepcopy(sub_step["method"])
backup_response = copy.deepcopy(sub_step["response"])
del sub_step["method"]
del sub_step["response"]
for attr_name in ("ports", "usernames", "passwords"):
if attr_name in sub_step:
value = sub_step.pop(attr_name)
sub_step[attr_name.rstrip("s")] = int(value) if attr_name == "ports" else value
if "dependent_on_temp_event" in backup_response:
temp_event = self.get_dependent_results_from_database(
target, module_name, scan_id, backup_response["dependent_on_temp_event"]
)
sub_step = self.replace_dependent_values(sub_step, temp_event)
action = getattr(self.library(), backup_method)
for _i in range(options["retries"]):
try:
response = action(**sub_step)
break
except Exception:
response = []
sub_step["method"] = backup_method
sub_step["response"] = backup_response
sub_step["response"]["conditions_results"] = response
self.apply_extra_data(sub_step, response)
return self.process_conditions(
sub_step,
module_name,
target,
scan_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests,
)

24
nettacker/core/lib/ftp.py Normal file
View File

@ -0,0 +1,24 @@
import ftplib
from nettacker.core.lib.base import BaseEngine, BaseLibrary
class FtpLibrary(BaseLibrary):
client = ftplib.FTP
def brute_force(self, host, port, username, password, timeout):
connection = self.client(timeout=timeout)
connection.connect(host, port)
connection.login(username, password)
connection.close()
return {
"host": host,
"port": port,
"username": username,
"password": password,
}
class FtpEngine(BaseEngine):
library = FtpLibrary

View File

@ -0,0 +1,11 @@
import ftplib
from nettacker.core.lib.ftp import FtpEngine, FtpLibrary
class FtpsLibrary(FtpLibrary):
client = ftplib.FTP_TLS
class FtpsEngine(FtpEngine):
library = FtpsLibrary

225
nettacker/core/lib/http.py Normal file
View File

@ -0,0 +1,225 @@
#!/usr/bin/env python
import asyncio
import copy
import random
import re
import time
import aiohttp
import uvloop
from nettacker.core.lib.base import BaseEngine
from nettacker.core.utils.common import (
replace_dependent_response,
reverse_and_regex_condition,
get_http_header_key,
get_http_header_value,
)
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
async def perform_request_action(action, request_options):
start_time = time.time()
async with action(**request_options) as response:
return {
"reason": response.reason,
"url": str(response.url),
"status_code": str(response.status),
"content": await response.content.read(),
"headers": dict(response.headers),
"responsetime": time.time() - start_time,
}
async def send_request(request_options, method):
async with aiohttp.ClientSession() as session:
action = getattr(session, method, None)
response = await asyncio.gather(
*[asyncio.ensure_future(perform_request_action(action, request_options))]
)
return response[0]
def response_conditions_matched(sub_step, response):
if not response:
return {}
condition_type = sub_step["response"]["condition_type"]
conditions = sub_step["response"]["conditions"]
condition_results = {}
for condition in conditions:
if condition in ["reason", "status_code", "content", "url"]:
regex = re.findall(re.compile(conditions[condition]["regex"]), response[condition])
reverse = conditions[condition]["reverse"]
condition_results[condition] = reverse_and_regex_condition(regex, reverse)
if condition == "headers":
# convert headers to case insensitive dict
for key in response["headers"].copy():
response["headers"][key.lower()] = response["headers"][key]
condition_results["headers"] = {}
for header in conditions["headers"]:
reverse = conditions["headers"][header]["reverse"]
try:
regex = re.findall(
re.compile(conditions["headers"][header]["regex"]),
response["headers"][header.lower()]
if header.lower() in response["headers"]
else False,
)
condition_results["headers"][header] = reverse_and_regex_condition(
regex, reverse
)
except TypeError:
condition_results["headers"][header] = []
if condition == "responsetime":
if len(conditions[condition].split()) == 2 and conditions[condition].split()[0] in [
"==",
"!=",
">=",
"<=",
">",
"<",
]:
exec(
"condition_results['responsetime'] = response['responsetime'] if ("
+ "response['responsetime'] {0} float(conditions['responsetime'].split()[-1])".format(
conditions["responsetime"].split()[0]
)
+ ") else []"
)
else:
condition_results["responsetime"] = []
if condition_type.lower() == "or":
# if one of the values are matched, it will be a string or float object in the array
# we count False in the array and if it's not all []; then we know one of the conditions
# is matched.
if (
"headers" not in condition_results
and (
list(condition_results.values()).count([]) != len(list(condition_results.values()))
)
) or (
"headers" in condition_results
and (
len(list(condition_results.values()))
+ len(list(condition_results["headers"].values()))
- list(condition_results.values()).count([])
- list(condition_results["headers"].values()).count([])
- 1
!= 0
)
):
if sub_step["response"].get("log", False):
condition_results["log"] = sub_step["response"]["log"]
if "response_dependent" in condition_results["log"]:
condition_results["log"] = replace_dependent_response(
condition_results["log"], condition_results
)
return condition_results
else:
return {}
if condition_type.lower() == "and":
if [] in condition_results.values() or (
"headers" in condition_results and [] in condition_results["headers"].values()
):
return {}
else:
if sub_step["response"].get("log", False):
condition_results["log"] = sub_step["response"]["log"]
if "response_dependent" in condition_results["log"]:
condition_results["log"] = replace_dependent_response(
condition_results["log"], condition_results
)
return condition_results
return {}
class HttpEngine(BaseEngine):
def run(
self,
sub_step,
module_name,
target,
scan_id,
options,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests,
):
if options["http_header"] is not None:
for header in options["http_header"]:
key = get_http_header_key(header).strip()
value = get_http_header_value(header)
if value is not None:
sub_step["headers"][key] = value.strip()
else:
sub_step["headers"][key] = ""
backup_method = copy.deepcopy(sub_step["method"])
backup_response = copy.deepcopy(sub_step["response"])
backup_iterative_response_match = copy.deepcopy(
sub_step["response"]["conditions"].get("iterative_response_match", None)
)
if options["user_agent"] == "random_user_agent":
sub_step["headers"]["User-Agent"] = random.choice(options["user_agents"])
del sub_step["method"]
if "dependent_on_temp_event" in backup_response:
temp_event = self.get_dependent_results_from_database(
target,
module_name,
scan_id,
backup_response["dependent_on_temp_event"],
)
sub_step = self.replace_dependent_values(sub_step, temp_event)
backup_response = copy.deepcopy(sub_step["response"])
del sub_step["response"]
for _i in range(options["retries"]):
try:
response = asyncio.run(send_request(sub_step, backup_method))
response["content"] = response["content"].decode(errors="ignore")
break
except Exception:
response = []
sub_step["method"] = backup_method
sub_step["response"] = backup_response
if backup_iterative_response_match is not None:
backup_iterative_response_match = copy.deepcopy(
sub_step["response"]["conditions"].get("iterative_response_match")
)
del sub_step["response"]["conditions"]["iterative_response_match"]
sub_step["response"]["conditions_results"] = response_conditions_matched(
sub_step, response
)
if backup_iterative_response_match is not None and (
sub_step["response"]["conditions_results"]
or sub_step["response"]["condition_type"] == "or"
):
sub_step["response"]["conditions"][
"iterative_response_match"
] = backup_iterative_response_match
for key in sub_step["response"]["conditions"]["iterative_response_match"]:
result = response_conditions_matched(
sub_step["response"]["conditions"]["iterative_response_match"][key],
response,
)
if result:
sub_step["response"]["conditions_results"][key] = result
return self.process_conditions(
sub_step,
module_name,
target,
scan_id,
options,
response,
process_number,
module_thread_number,
total_module_thread_number,
request_number_counter,
total_number_of_requests,
)

View File

@ -0,0 +1,24 @@
import poplib
from nettacker.core.lib.base import BaseEngine, BaseLibrary
class Pop3Library(BaseLibrary):
client = poplib.POP3
def brute_force(self, host, port, username, password, timeout):
connection = self.client(host, port=port, timeout=timeout)
connection.user(username)
connection.pass_(password)
connection.quit()
return {
"host": host,
"port": port,
"username": username,
"password": password,
}
class Pop3Engine(BaseEngine):
library = Pop3Library

View File

@ -0,0 +1,11 @@
import poplib
from nettacker.core.lib.pop3 import Pop3Engine, Pop3Library
class Pop3sLibrary(Pop3Library):
client = poplib.POP3_SSL
class Pop3sEngine(Pop3Engine):
library = Pop3sLibrary

Some files were not shown because too many files have changed in this diff Show More