├── .dockerignore
├── .env
├── .gitattributes
├── .github
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.yaml
│ ├── config.yml
│ └── feature_request.yml
├── SECURITY.md
├── SPONSORS.md
├── screenshots
│ ├── banner.gif
│ └── scan_results.gif
└── workflows
│ ├── auto-comment.yml
│ ├── auto-release.yml
│ ├── build-pr.yml
│ ├── build.yml
│ ├── codeql-analysis.yml
│ └── github-pages-deploy.yml
├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTORS.md
├── LICENSE
├── Makefile
├── README.md
├── _config.yml
├── certs
├── Dockerfile
└── entrypoint.sh
├── config
└── nginx
│ └── rengine.conf
├── default_yaml_config.yaml
├── docker-compose.dev.yml
├── docker-compose.setup.yml
├── docker-compose.yml
├── install.sh
├── make.bat
├── scripts
└── uninstall.sh
├── update.sh
└── web
├── .gitignore
├── .version
├── Dockerfile
├── api
├── __init__.py
├── permissions.py
├── serializers.py
├── shared_api_tasks.py
├── urls.py
└── views.py
├── art
└── reNgine.txt
├── beat-entrypoint.sh
├── celery-entrypoint.sh
├── dashboard
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_chaosapikey_hackeroneapikey_inappnotification_userpreferences.py
│ └── __init__.py
├── models.py
├── templates
│ └── dashboard
│ │ ├── admin.html
│ │ ├── bountyhub_programs.html
│ │ ├── index.html
│ │ ├── onboarding.html
│ │ ├── profile.html
│ │ ├── projects.html
│ │ └── search.html
├── tests.py
├── urls.py
└── views.py
├── entrypoint.sh
├── fixtures
├── default_keywords.yaml
├── default_scan_engines.yaml
├── extensions.txt
└── external_tools.yaml
├── manage.py
├── reNgine
├── __init__.py
├── celery.py
├── celery_custom_task.py
├── charts.py
├── common_func.py
├── common_serializers.py
├── context_processors.py
├── database_utils.py
├── definitions.py
├── init.py
├── llm.py
├── middleware.py
├── roles.py
├── settings.py
├── tasks.py
├── urls.py
├── utilities.py
├── validators.py
├── views.py
└── wsgi.py
├── recon_note
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ ├── 0001_initial.py
│ └── __init__.py
├── models.py
├── static
│ └── note
│ │ └── js
│ │ └── todo.js
├── templates
│ └── note
│ │ └── index.html
├── tests.py
├── urls.py
└── views.py
├── requirements.txt
├── scanEngine
├── __init__.py
├── admin.py
├── apps.py
├── forms.py
├── management
│ └── commands
│ │ ├── dumpcustomengines.py
│ │ └── loadcustomengines.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_hackerone_send_report.py
│ └── __init__.py
├── models.py
├── static
│ └── scanEngine
│ │ └── js
│ │ ├── custom_scan_engine.js
│ │ ├── custom_tools.js
│ │ └── tool_arsenal.js
├── templates
│ └── scanEngine
│ │ ├── _items
│ │ └── form_engine.html
│ │ ├── add_engine.html
│ │ ├── index.html
│ │ ├── lookup.html
│ │ ├── settings
│ │ ├── _items
│ │ │ └── external_tool_form.html
│ │ ├── add_tool.html
│ │ ├── api.html
│ │ ├── hackerone.html
│ │ ├── llm_toolkit.html
│ │ ├── notification.html
│ │ ├── proxy.html
│ │ ├── rengine.html
│ │ ├── report.html
│ │ ├── tool.html
│ │ ├── tool_arsenal.html
│ │ └── update_tool.html
│ │ ├── update_engine.html
│ │ └── wordlist
│ │ ├── add.html
│ │ └── index.html
├── templatetags
│ ├── __init__.py
│ └── custom_tags.py
├── tests.py
├── urls.py
└── views.py
├── startScan
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20240911_0145.py
│ └── __init__.py
├── models.py
├── static
│ └── startScan
│ │ └── js
│ │ ├── detail_scan.js
│ │ ├── endpoint-datatables-suggestions.js
│ │ ├── schedule-scan-wizard.js
│ │ ├── start-scan-wizard-init.js
│ │ ├── subdomains-suggestions.js
│ │ └── vulnerability-datatables-suggestions.js
├── templates
│ ├── organization
│ │ ├── schedule_scan_ui.html
│ │ └── start_scan.html
│ └── startScan
│ │ ├── _items
│ │ ├── scanengine_accordion.html
│ │ ├── schedule_scan_wizard.html
│ │ └── start_scan_wizard.html
│ │ ├── detail_scan.html
│ │ ├── endpoints.html
│ │ ├── history.html
│ │ ├── index.html
│ │ ├── schedule_scan_list.html
│ │ ├── schedule_scan_ui.html
│ │ ├── start_multiple_scan_ui.html
│ │ ├── start_scan_ui.html
│ │ ├── subdomains.html
│ │ ├── subscan_history.html
│ │ └── vulnerabilities.html
├── templatetags
│ ├── __init__.py
│ └── custom_tags.py
├── tests.py
├── urls.py
└── views.py
├── static
├── assets
│ ├── css
│ │ ├── app-dark.min.css
│ │ ├── app.min.css
│ │ ├── icons.min.css
│ │ └── scrollspyNav.css
│ └── js
│ │ ├── app.min.js
│ │ ├── clipboard.min.js
│ │ └── vendor.min.js
├── bootstrap
│ ├── bootstrap-dark.min.css
│ └── bootstrap.min.css
├── custom
│ ├── bountyhub.js
│ ├── custom.css
│ ├── custom.js
│ ├── jsonob.json
│ ├── mitch.js
│ ├── notification.js
│ ├── right_sidebar.js
│ ├── subdomain.js
│ ├── subdomain_datatable.js
│ ├── timeline.css
│ ├── todo.js
│ ├── toolbox.js
│ ├── update.js
│ └── vuln_datatables.js
├── fonts
│ ├── cerebrisans-bold.eot
│ ├── cerebrisans-bold.svg
│ ├── cerebrisans-bold.ttf
│ ├── cerebrisans-bold.woff
│ ├── cerebrisans-bold.woff2
│ ├── cerebrisans-light.eot
│ ├── cerebrisans-light.svg
│ ├── cerebrisans-light.ttf
│ ├── cerebrisans-light.woff
│ ├── cerebrisans-light.woff2
│ ├── cerebrisans-medium.eot
│ ├── cerebrisans-medium.svg
│ ├── cerebrisans-medium.ttf
│ ├── cerebrisans-medium.woff
│ ├── cerebrisans-medium.woff2
│ ├── cerebrisans-regular.eot
│ ├── cerebrisans-regular.svg
│ ├── cerebrisans-regular.ttf
│ ├── cerebrisans-regular.woff
│ ├── cerebrisans-regular.woff2
│ ├── cerebrisans-semibold.eot
│ ├── cerebrisans-semibold.svg
│ ├── cerebrisans-semibold.ttf
│ ├── cerebrisans-semibold.woff
│ ├── cerebrisans-semibold.woff2
│ ├── dripicons-v2.eot
│ ├── dripicons-v2.svg
│ ├── dripicons-v2.ttf
│ ├── dripicons-v2.woff
│ ├── dropify.eot
│ ├── dropify.svg
│ ├── dropify.ttf
│ ├── dropify.woff
│ ├── fa-brands-400.eot
│ ├── fa-brands-400.svg
│ ├── fa-brands-400.ttf
│ ├── fa-brands-400.woff
│ ├── fa-brands-400.woff2
│ ├── fa-regular-400.eot
│ ├── fa-regular-400.svg
│ ├── fa-regular-400.ttf
│ ├── fa-regular-400.woff
│ ├── fa-regular-400.woff2
│ ├── fa-solid-900.eot
│ ├── fa-solid-900.svg
│ ├── fa-solid-900.ttf
│ ├── fa-solid-900.woff
│ ├── fa-solid-900.woff2
│ ├── feather.eot
│ ├── feather.svg
│ ├── feather.ttf
│ ├── feather.woff
│ ├── footable.eot
│ ├── footable.svg
│ ├── footable.ttf
│ ├── footable.woff
│ ├── materialdesignicons-webfont.eot
│ ├── materialdesignicons-webfont.ttf
│ ├── materialdesignicons-webfont.woff
│ ├── materialdesignicons-webfont.woff2
│ ├── simple-Line-Icons.eot
│ ├── simple-Line-Icons.svg
│ ├── simple-Line-Icons.ttf
│ ├── simple-Line-Icons.woff
│ ├── simple-Line-Icons.woff2
│ ├── summernote.eot
│ ├── summernote.ttf
│ ├── summernote.woff
│ ├── summernote.woff2
│ ├── themify.eot
│ ├── themify.svg
│ ├── themify.ttf
│ ├── themify.woff
│ ├── weathericons-regular-webfont.eot
│ ├── weathericons-regular-webfont.svg
│ ├── weathericons-regular-webfont.ttf
│ ├── weathericons-regular-webfont.woff
│ └── weathericons-regular-webfont.woff2
├── img
│ ├── discord.svg
│ ├── favicon.png
│ ├── firewall.png
│ ├── girl.png
│ ├── global.png
│ ├── ladybug.png
│ ├── logo-lg.png
│ ├── logo.png
│ ├── magnifying.png
│ └── slack.svg
└── plugins
│ ├── accordions
│ └── custom-accordions.css
│ ├── datatable
│ ├── custom.css
│ ├── datatables.css
│ ├── datatables.js
│ └── global.css
│ ├── flatpickr
│ ├── flatpickr.min.css
│ └── flatpickr.min.js
│ ├── gridzy
│ ├── gridzy.css
│ ├── gridzy.js
│ └── skins
│ │ └── gridzySkinBlank
│ │ └── style.css
│ ├── j-map
│ ├── jquery-jvectormap.css
│ ├── jquery-jvectormap.min.js
│ └── maps
│ │ └── jquery-jvectormap-world-mill-en.js
│ ├── jquery-step
│ ├── jquery.steps.css
│ └── jquery.steps.min.js
│ ├── lightbox
│ ├── css
│ │ └── lightbox.css
│ ├── images
│ │ ├── close.png
│ │ ├── loading.gif
│ │ ├── next.png
│ │ └── prev.png
│ └── js
│ │ └── lightbox.js
│ ├── markdown
│ ├── simplemde.min.css
│ └── simplemde.min.js
│ ├── perfect-scrollbar
│ ├── perfect-scrollbar.css
│ └── perfect-scrollbar.min.js
│ ├── select2
│ ├── select2-spinner.gif
│ ├── select2.min.css
│ ├── select2.min.js
│ ├── select2.png
│ └── select2x2.png
│ ├── selectize
│ ├── css
│ │ ├── selectize.bootstrap3.css
│ │ └── selectize.css
│ └── js
│ │ └── standalone
│ │ └── selectize.min.js
│ ├── snackbar
│ ├── snackbar.min.css
│ └── snackbar.min.js
│ ├── sweetalert2
│ ├── sweetalert2.all.min.js
│ ├── sweetalert2.min.css
│ └── sweetalert2.min.js
│ ├── switches
│ └── switches.min.css
│ └── todo
│ └── todolist.css
├── targetApp
├── __init__.py
├── admin.py
├── apps.py
├── forms.py
├── migrations
│ ├── 0001_initial.py
│ └── __init__.py
├── models.py
├── static
│ └── targetApp
│ │ └── js
│ │ ├── custom_domain.js
│ │ ├── custom_organization.js
│ │ └── target_summary.js
├── templates
│ ├── organization
│ │ ├── add.html
│ │ ├── list.html
│ │ └── update.html
│ └── target
│ │ ├── add.html
│ │ ├── index.html
│ │ ├── list.html
│ │ ├── summary.html
│ │ ├── test.html
│ │ └── update.html
├── tests.py
├── urls.py
└── views.py
├── templates
├── 404.html
├── base
│ ├── _items
│ │ ├── center_spinner.html
│ │ ├── down_arrow.html
│ │ ├── endpoint_tab_content.html
│ │ ├── footer.html
│ │ ├── green_tick.html
│ │ ├── minus_icon.html
│ │ ├── modal.html
│ │ ├── most_common_cve_cwe_tag_template.html
│ │ ├── most_common_cve_cwe_tags.js
│ │ ├── most_common_vuln.html
│ │ ├── most_vuln_target.html
│ │ ├── offcanvas.html
│ │ ├── plus_icon.html
│ │ ├── recon_note_modal.html
│ │ ├── red_cross.html
│ │ ├── right_bar.html
│ │ ├── subdomain_tab_content.html
│ │ ├── subdomain_toolbar.html
│ │ ├── subscan_modal.html
│ │ ├── top_bar.html
│ │ ├── top_nav.html
│ │ ├── up_arrow.html
│ │ ├── vulnerability_tab_content.html
│ │ ├── widgets
│ │ │ ├── vulnerability_breakdown_by_severity_chart.html
│ │ │ └── vulnerability_highlights.html
│ │ └── xl_scrollable_modal.html
│ ├── base.html
│ ├── login.html
│ └── logout.html
└── report
│ ├── default.html
│ └── modern.html
└── tests
├── __init__.py
├── test_nmap.py
└── test_scan.py
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 | .gitignore
3 | .github
4 | .gitmodules
5 | .dockerignore
6 | .sonarcloud.properties
7 | db.sqlite3
8 | Dockerfile
9 | docker-compose.yml
10 | *.md
11 | _config.yml
12 | LICENSE
13 | downloads
14 | uploads
15 | logs
16 | venv
17 | secret
18 |
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | #
2 | # General
3 | #
4 | COMPOSE_PROJECT_NAME=rengine
5 |
6 | #
7 | # SSL specific configuration
8 | #
9 | AUTHORITY_NAME=reNgine
10 | AUTHORITY_PASSWORD=nSrmNkwT
11 | COMPANY=reNgine
12 | DOMAIN_NAME=rengine.example.com
13 | COUNTRY_CODE=US
14 | STATE=Georgia
15 | CITY=Atlanta
16 |
17 | #
18 | # Database configurations
19 | #
20 | POSTGRES_DB=rengine
21 | POSTGRES_USER=rengine
22 | POSTGRES_PASSWORD=hE2a5@K&9nEY1fzgA6X
23 | POSTGRES_PORT=5432
24 | POSTGRES_HOST=db
25 |
26 | #
27 | # Celery Scaling Configurations
28 | #
29 | MAX_CONCURRENCY=80
30 | MIN_CONCURRENCY=10
31 |
32 | #
33 | # Rengine web interface super user (for non-interactive install)
34 | #
35 | DJANGO_SUPERUSER_USERNAME=rengine
36 | DJANGO_SUPERUSER_EMAIL=rengine@example.com
37 | DJANGO_SUPERUSER_PASSWORD=Sm7IJG.IfHAFw9snSKv
38 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | Dockerfile eol=lf
2 | *.sh eol=lf
3 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | nationality, personal appearance, race, religion, or sexual identity and
10 | orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at yogesh.ojha11@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at [https://contributor-covenant.org/version/1/4][version]
72 |
73 | [homepage]: https://contributor-covenant.org
74 | [version]: https://contributor-covenant.org/version/1/4/
75 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to reNgine
2 | [](https://www.firsttimersonly.com/)
3 |
4 | As an open-source project, reNgine welcomes any contributions. Your contributions could be as simple as fixing the indentations or fixing UI to as complex as bringing new modules and features.
5 | Your contributions are highly appreciated and we welcome any kind of contributions as long as you adhere to our guidelines and your PR aligns the idea behind creating the reNgine.
6 |
7 | If you are new to open source community, reNgine is beginner-friendly. Please create pull requests for any new features, bug fixes, improvements on documentation, or anything!
8 |
9 | Join our developer chat on [Discord Developer Room](https://discord.gg/JuhHdHTtwd) if you would like to contribute to reNgine.
10 |
11 | ## Bug reporting
12 |
13 | We appreciate your effort to improve reNgine by submitting a bug report. But, Before doing so, please check the following things:
14 |
15 | 1. Please **do not** use the issue tracker for personal support requests, instead use [reNgine Support Discord channel](https://discord.gg/azv6fzhNCE) for any personal support request.
16 | 2. Check whether the bug **hasn't been already reported**. Duplicate reports take us time, that we could be used to fix other bugs or make improvements.
17 | 3. If you get an error while using reNgine, please **describe what happened** and add a verbose error message. Reports like "I got an error when I started scanning some random website." are not worth anybody's time. Please be as descriptive as you can.
18 | 4. Provide easy steps to reproduce. This will help us solve your issues easily and quickly.
19 | Your contributions are again highly appreciated!
20 |
21 | Please report [bugs here on GitHub Issues section][1].
22 |
23 | [1]: https://github.com/yogeshojha/rengine/issues/new
24 |
25 |
26 | ## Feature requests
27 | We welcome feature requests. But please take a moment to find out whether your idea fits with the original idea behind reEngine. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible.
28 |
29 | ## Pull requests
30 | Pull requests with a bug fix, improvements, new features are welcome and very much appreciated.
31 |
32 | **Please ask** first before embarking on any significant pull request (e.g. implementing features, refactoring code, porting to a different language), otherwise you risk spending a lot of time working on something that the project's developers might not want to merge into the project.
33 |
34 | ### First Time Contributors
35 | If reNgine happens to be your first open-source project to contribute to, please follow the guidelines.
36 |
37 | 1. Fork this project.
38 | 2. `git clone https://github.com/yourusername/rengine.git`
39 | 3. Configure the remote as below
40 | ```
41 | cd rengine
42 | # Assign upstream
43 | git remote add upstream https://github.com/yogeshojha/rengine.git
44 | ```
45 | 4. If cloning was done a while ago, please get the latest changes from upstream
46 | ```
47 | git checkout master
48 | git pull upstream master
49 | ```
50 | 5. Commit your changes in the logical chunks
51 |
52 | ## Code of Conduct
53 |
54 | Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md).
55 | By participating in this project you agree to abide by its terms.
56 |
57 | ## Thank you!
58 |
59 | Thank you for contributing!
60 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | custom: ['https://paypal.me/yogeshojha11']
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yaml:
--------------------------------------------------------------------------------
1 | name: 🐞 Bug
2 | description: File a bug/issue
3 | title: "bug:
"
4 | labels: [bug]
5 | body:
6 | - type: checkboxes
7 | attributes:
8 | label: Is there an existing issue for this?
9 | description: Please search to see if an issue already exists for the bug you encountered.
10 | options:
11 | - label: I have searched the existing issues
12 | required: true
13 | - type: textarea
14 | attributes:
15 | label: Current Behavior
16 | description: A concise description of what you're experiencing.
17 | validations:
18 | required: true
19 | - type: textarea
20 | attributes:
21 | label: Expected Behavior
22 | description: A concise description of what you expected to happen.
23 | validations:
24 | required: true
25 | - type: textarea
26 | attributes:
27 | label: Steps To Reproduce
28 | description: Steps to reproduce the behavior.
29 | placeholder: |
30 | 1. In this environment...
31 | 2. With this config...
32 | 3. Run '...'
33 | 4. See error...
34 | validations:
35 | required: true
36 | - type: textarea
37 | attributes:
38 | label: Environment
39 | description: |
40 | examples:
41 | - **reNgine**: 1.3.6
42 | - **OS**: Ubuntu 20.04
43 | - **Python**: 3.11.0
44 | - **Docker**: 20.10.22
45 | - **Docker compose**: 2.15.1
46 | - **Browser**: Microsoft Edge 112.0.1722.58
47 | value: |
48 | - reNgine:
49 | - OS:
50 | - Python:
51 | - Docker Engine:
52 | - Docker Compose:
53 | - Browser:
54 | render: markdown
55 | validations:
56 | required: true
57 | - type: textarea
58 | attributes:
59 | label: Anything else?
60 | description: |
61 | Links? References? Anything that will give us more context about the issue you are encountering!
62 |
63 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
64 | validations:
65 | required: false
66 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: 🚀 Feature request
2 | description: File a feature request
3 | title: "feat: "
4 | labels: [feature_request]
5 | body:
6 | - type: checkboxes
7 | attributes:
8 | label: Is there an existing feature or issue for this?
9 | description: Please search to see if the feature already exists or has already being requested.
10 | options:
11 | - label: I have searched the existing issues
12 | required: true
13 | - type: textarea
14 | attributes:
15 | label: Expected feature
16 | description: A clear and concise description of what the problem is and how it could be approached.
17 | validations:
18 | required: true
19 | - type: textarea
20 | attributes:
21 | label: Alternative solutions
22 | description: A clear and concise description of any alternative solutions or features you've considered.
23 | validations:
24 | required: false
25 | - type: textarea
26 | attributes:
27 | label: Anything else?
28 | description: |
29 | Links? References? Anything that will give us more context about the issue you are encountering!
30 |
31 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
32 | validations:
33 | required: false
34 |
--------------------------------------------------------------------------------
/.github/SPONSORS.md:
--------------------------------------------------------------------------------
1 | Thank you to these individuals for sponsoring this project.
2 |
3 | * Emrah Kutuk
4 | * Fisher
5 |
--------------------------------------------------------------------------------
/.github/screenshots/banner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/.github/screenshots/banner.gif
--------------------------------------------------------------------------------
/.github/screenshots/scan_results.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/.github/screenshots/scan_results.gif
--------------------------------------------------------------------------------
/.github/workflows/auto-release.yml:
--------------------------------------------------------------------------------
1 | name: Update Version and Changelog and Readme
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | update-version-and-changelog:
9 | runs-on: ubuntu-latest
10 | permissions:
11 | contents: write
12 | steps:
13 | - name: Checkout code
14 | uses: actions/checkout@v3
15 | with:
16 | fetch-depth: 0
17 |
18 | - name: Get latest release info
19 | id: get_release
20 | uses: actions/github-script@v6
21 | with:
22 | script: |
23 | const release = await github.rest.repos.getLatestRelease({
24 | owner: context.repo.owner,
25 | repo: context.repo.repo,
26 | });
27 | core.setOutput('tag_name', release.data.tag_name);
28 | core.setOutput('body', release.data.body);
29 |
30 | - name: Update version file
31 | run: echo ${{ steps.get_release.outputs.tag_name }} > web/.version
32 |
33 | - name: Update CHANGELOG.md
34 | run: |
35 | echo "# Changelog" > CHANGELOG.md.new
36 | echo "" >> CHANGELOG.md.new
37 | echo "## ${{ steps.get_release.outputs.tag_name }}" >> CHANGELOG.md.new
38 | echo "" >> CHANGELOG.md.new
39 | echo "${{ steps.get_release.outputs.body }}" >> CHANGELOG.md.new
40 | echo "" >> CHANGELOG.md.new
41 | if [ -f CHANGELOG.md ]; then
42 | sed '1,2d' CHANGELOG.md >> CHANGELOG.md.new
43 | fi
44 | mv CHANGELOG.md.new CHANGELOG.md
45 |
46 | - name: Update README.md
47 | run: |
48 | sed -i 's|https://img.shields.io/badge/version-.*-informational|https://img.shields.io/badge/version-${{ steps.get_release.outputs.tag_name }}-informational|g' README.md
49 |
50 | - name: Commit and push changes
51 | run: |
52 | git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
53 | git config --local user.name "github-actions[bot]"
54 | git add web/.version CHANGELOG.md README.md
55 | if git diff --staged --quiet; then
56 | echo "No changes to commit"
57 | else
58 | git commit -m "reNgine release: ${{ steps.get_release.outputs.tag_name }} :rocket:"
59 | git push origin HEAD:${{ github.event.repository.default_branch }}
60 | fi
61 |
--------------------------------------------------------------------------------
/.github/workflows/build-pr.yml:
--------------------------------------------------------------------------------
1 | name: 🏗️ Build Docker image for pull request
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - master
7 | - release/*
8 |
9 | jobs:
10 | build:
11 | name: 🐳 Build Docker image
12 | runs-on: ubuntu-latest
13 | strategy:
14 | matrix:
15 | platform:
16 | - linux/amd64
17 | - linux/arm64
18 | # - linux/arm/v7
19 | steps:
20 | - name: 📥 Checkout the git repo
21 | uses: actions/checkout@v4
22 |
23 | - name: 🖥️ Set up QEMU
24 | uses: docker/setup-qemu-action@v3
25 |
26 | - name: 🏗️ Set up Docker Buildx
27 | uses: docker/setup-buildx-action@v3
28 |
29 | - name: 🏷️ Extract metadata (tags, labels) for Docker
30 | id: meta
31 | uses: docker/metadata-action@v5
32 | with:
33 | images: yogeshojha/rengine
34 | tags: |
35 | type=raw,value=pr-${{ github.event.pull_request.number }}
36 | type=sha,prefix=sha-
37 | type=ref,event=branch
38 | type=ref,event=pr
39 |
40 | - name: 🏗️ Build Docker image
41 | uses: docker/build-push-action@v5
42 | with:
43 | context: web/
44 | platforms: ${{ matrix.platform }}
45 | push: false
46 | tags: ${{ steps.meta.outputs.tags }}
47 | labels: ${{ steps.meta.outputs.labels }}
48 | cache-from: type=gha
49 | cache-to: type=gha,mode=max
50 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: 🚀 Build and Push Docker image
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | release:
7 | types: [published]
8 | schedule:
9 | - cron: '0 0 */5 * *' # Run every 5 days at midnight UTC
10 |
11 | jobs:
12 | build-and-push:
13 | name: 🐳 Build and Push Docker image
14 | runs-on: ubuntu-latest
15 | strategy:
16 | matrix:
17 | platform:
18 | - linux/amd64
19 | - linux/arm64
20 | steps:
21 | - name: 📥 Checkout the git repo
22 | uses: actions/checkout@v4
23 |
24 | - name: 🖥️ Set up QEMU
25 | uses: docker/setup-qemu-action@v3
26 |
27 | - name: 🛠️ Set up Docker Buildx
28 | uses: docker/setup-buildx-action@v3
29 |
30 | - name: 🔑 Log in to Docker Hub
31 | uses: docker/login-action@v3
32 | with:
33 | username: ${{ secrets.DOCKER_USERNAME }}
34 | password: ${{ secrets.DOCKER_PASSWORD }}
35 |
36 | - name: 🏷️ Extract metadata (tags, labels) for Docker
37 | id: meta
38 | uses: docker/metadata-action@v5
39 | with:
40 | images: yogeshojha/rengine
41 | tags: |
42 | type=raw,value=${{ matrix.platform }}-latest,enable={{is_default_branch}}
43 | type=semver,pattern=${{ matrix.platform }}-{{version}}
44 | type=semver,pattern=${{ matrix.platform }}-{{major}}.{{minor}}
45 | type=semver,pattern=${{ matrix.platform }}-{{major}}
46 | type=sha,prefix=${{ matrix.platform }}-sha-
47 | type=schedule,pattern=${{ matrix.platform }}-{{date 'YYYYMMDD'}}
48 |
49 | - name: 🏗️ Build and push Docker image
50 | uses: docker/build-push-action@v5
51 | with:
52 | context: web/
53 | platforms: ${{ matrix.platform }}
54 | push: ${{ github.event_name != 'pull_request' }}
55 | tags: ${{ steps.meta.outputs.tags }}
56 | labels: ${{ steps.meta.outputs.labels }}
57 | cache-from: type=gha
58 | cache-to: type=gha,mode=max
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | name: "Code Quality"
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 | schedule:
9 | - cron: '0 18 * * 5'
10 |
11 | jobs:
12 | analyze:
13 | name: Analyze
14 | runs-on: ubuntu-latest
15 |
16 | strategy:
17 | fail-fast: false
18 | matrix:
19 | language: [ 'javascript', 'python' ]
20 |
21 | steps:
22 | - name: Checkout repository
23 | uses: actions/checkout@v4
24 |
25 | # Initializes the CodeQL tools for scanning.
26 | - name: Initialize CodeQL
27 | uses: github/codeql-action/init@v3
28 | with:
29 | languages: ${{ matrix.language }}
30 |
31 | - name: Autobuild
32 | uses: github/codeql-action/autobuild@v3
33 |
34 | - name: Perform CodeQL Analysis
35 | uses: github/codeql-action/analyze@v3
36 |
--------------------------------------------------------------------------------
/.github/workflows/github-pages-deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy README to GitHub Pages
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | workflow_dispatch:
8 |
9 | jobs:
10 | deploy:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout repository
14 | uses: actions/checkout@v3
15 |
16 | - name: Setup Node.js
17 | uses: actions/setup-node@v3
18 | with:
19 | node-version: '14'
20 |
21 | - name: Install marked (Markdown parser)
22 | run: npm install marked
23 |
24 | - name: Convert README to HTML
25 | run: |
26 | echo "
27 |
28 |
29 |
30 |
31 | reNgine Documentation
32 |
33 |
47 |
48 |
49 | $(node -e "const marked = require('marked'); const fs = require('fs'); console.log(marked.parse(fs.readFileSync('README.md', 'utf-8')))")
50 |
51 | " > index.html
52 |
53 | - name: Deploy to GitHub Pages
54 | uses: peaceiris/actions-gh-pages@v3
55 | with:
56 | github_token: ${{ secrets.GITHUB_TOKEN }}
57 | publish_dir: .
58 | publish_branch: gh-pages
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | web/custom_engines*
2 | Pipfile*
3 | resume.cfg
4 | *.txt
5 | *.log
6 | *.pot
7 | *.pyc
8 | __pycache__/
9 | local_settings.py
10 | db.sqlite3
11 | db.sqlite3-journal
12 | media
13 |
14 | ### Django.Python Stack ###
15 | # Byte-compiled / optimized / DLL files
16 | *.py[cod]
17 | *$py.class
18 |
19 | # C extensions
20 | *.so
21 |
22 | # Distribution / packaging
23 | .Python
24 | build/
25 | develop-eggs/
26 | dist/
27 | downloads/
28 | eggs/
29 | .eggs/
30 | parts/
31 | sdist/
32 | var/
33 | wheels/
34 | pip-wheel-metadata/
35 | share/python-wheels/
36 | *.egg-info/
37 | .installed.cfg
38 | *.egg
39 | MANIFEST
40 |
41 | *.manifest
42 | *.spec
43 |
44 | # Installer logs
45 | pip-log.txt
46 | pip-delete-this-directory.txt
47 |
48 |
49 | # Sphinx documentation
50 | docs/_build/
51 |
52 | # pyenv
53 | .python-version
54 |
55 | **/.DS_Store
56 | staticfiles/
57 |
58 | secret
59 | /secrets
60 |
61 | get-docker.sh
62 |
63 | # Environment variables
64 | .env
65 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | ## Contributors
2 |
3 | Thanks to these individuals for making reNgine awesome by fixing bugs, resolving issues and by creating PR!
4 |
5 | * [Aju100](https://github.com/Aju100)
6 | * [d1pakda5](https://github.com/d1pakda5)
7 | * [subha7595](https://github.com/subha7595)
8 | * [Suprita-25](https://github.com/Suprita-25)
9 | * [TheBinitGhimire](https://github.com/TheBinitGhimire)
10 | * [Vinay Leo](https://github.com/vinaynm)
11 | * [Erdem Ozgen](https://github.com/ErdemOzgen)
12 |
13 | *If you have created a Pull request, feel free to add your name here, because we know you are awesome and deserve thanks from the community!*
14 |
15 |
16 | Also, Thanks to these individuals for making reNgine awesome by providing continuous suggestions and support!
17 |
18 | * [bhavsec](https://twitter.com/bhavsec)
19 | * [Cor3min3r](https://linkedin.com/in/cor3min3r)
20 | * [Ganesh Pandey](https://github.com/GaneshPandey)
21 | * [Prial Islam](https://github.com/prial261)
22 | * [SecArmy](https://twitter.com/secarmyofficial)
23 | * pulsar: [FooBallZ](https://github.com/FooBallZ/pulsar)
24 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | include .env
2 | .DEFAULT_GOAL:=help
3 |
4 | # Credits: https://github.com/sherifabdlnaby/elastdocker/
5 |
6 | # This for future release of Compose that will use Docker Buildkit, which is much efficient.
7 | COMPOSE_PREFIX_CMD := COMPOSE_DOCKER_CLI_BUILD=1
8 |
9 | COMPOSE_ALL_FILES := -f docker-compose.yml
10 | SERVICES := db web proxy redis celery celery-beat ollama
11 |
12 | # Check if 'docker compose' command is available, otherwise use 'docker-compose'
13 | DOCKER_COMPOSE := $(shell if command -v docker > /dev/null && docker compose version > /dev/null 2>&1; then echo "docker compose"; else echo "docker-compose"; fi)
14 | $(info Using: $(shell echo "$(DOCKER_COMPOSE)"))
15 |
16 | # --------------------------
17 |
18 | .PHONY: setup certs up build username pull down stop restart rm logs
19 |
20 | certs: ## Generate certificates.
21 | @${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} -f docker-compose.setup.yml run --rm certs
22 |
23 | setup: ## Generate certificates.
24 | @make certs
25 |
26 | up: ## Build and start all services.
27 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} up -d --build ${SERVICES}
28 |
29 | build: ## Build all services.
30 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} build ${SERVICES}
31 |
32 | username: ## Generate Username (Use only after make up).
33 | ifeq ($(isNonInteractive), true)
34 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} exec web python3 manage.py createsuperuser --username ${DJANGO_SUPERUSER_USERNAME} --email ${DJANGO_SUPERUSER_EMAIL} --noinput
35 | else
36 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} exec web python3 manage.py createsuperuser
37 | endif
38 |
39 | changepassword: ## Change password for user
40 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} exec web python3 manage.py changepassword
41 |
42 | migrate: ## Apply migrations
43 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} exec web python3 manage.py migrate
44 |
45 | pull: ## Pull Docker images.
46 | docker login docker.pkg.github.com
47 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} pull
48 |
49 | down: ## Down all services.
50 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} down
51 |
52 | stop: ## Stop all services.
53 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} stop ${SERVICES}
54 |
55 | restart: ## Restart all services.
56 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} ${COMPOSE_ALL_FILES} restart ${SERVICES}
57 |
58 | rm: ## Remove all services containers.
59 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} $(COMPOSE_ALL_FILES) rm -f ${SERVICES}
60 |
61 | test:
62 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} $(COMPOSE_ALL_FILES) exec celery python3 -m unittest tests/test_scan.py
63 |
64 | logs: ## Tail all logs with -n 1000.
65 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} $(COMPOSE_ALL_FILES) logs --follow --tail=1000 ${SERVICES}
66 |
67 | images: ## Show all Docker images.
68 | ${COMPOSE_PREFIX_CMD} ${DOCKER_COMPOSE} $(COMPOSE_ALL_FILES) images ${SERVICES}
69 |
70 | prune: ## Remove containers and delete volume data.
71 | @make stop && make rm && docker volume prune -f
72 |
73 | help: ## Show this help.
74 | @echo "Make application Docker images and manage containers using Docker Compose files."
75 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m (default: help)\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-12s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
76 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
2 |
--------------------------------------------------------------------------------
/certs/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine:latest
2 |
3 | RUN apk update && \
4 | apk add --no-cache openssl && \
5 | rm -rf /var/cache/apk/*
6 |
7 | RUN echo "[ v3_ca ]" >>/etc/ssl/openssl.cnf && \
8 | echo "basicConstraints = critical, CA:TRUE" >>/etc/ssl/openssl.cnf && \
9 | echo "subjectKeyIdentifier = hash" >>/etc/ssl/openssl.cnf && \
10 | echo "authorityKeyIdentifier = keyid:always,issuer:always" >>/etc/ssl/openssl.cnf && \
11 | echo "keyUsage = critical, digitalSignature, cRLSign, keyCertSign" >>/etc/ssl/openssl.cnf
12 |
13 | COPY entrypoint.sh /
14 | RUN chmod +x /entrypoint.sh
15 |
16 | ENTRYPOINT ["/entrypoint.sh"]
17 |
--------------------------------------------------------------------------------
/certs/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cert() {
4 | COMMON_NAME=${1}
5 | FILENAME=${2:-app}
6 |
7 | echo "Creating new certificate for ${COMMON_NAME}"
8 |
9 | # Generate a new RSA key pair if does not exist
10 | if ! test -f ${CERT}_rsa.key; then
11 | openssl genrsa -out ${FILENAME}.key 4096
12 | else
13 | mv ${CERT}_rsa.key ${FILENAME}.key
14 | fi
15 |
16 | # Request a new certificate for the generated key pair
17 | openssl req -new -sha256 \
18 | -key ${FILENAME}.key \
19 | -out ${FILENAME}.csr \
20 | -subj "/C=${COUNTRY_CODE}/ST=${STATE}/L=${CITY}/O=${COMPANY}/CN=${COMMON_NAME}"
21 |
22 | # Creating SAN extension which is needed by modern browsers
23 | echo "subjectAltName=DNS:${COMMON_NAME}" > client-ext.cnf
24 |
25 | # Create a new certificate using our own CA
26 | openssl x509 -req -sha256 -passin pass:${AUTHORITY_PASSWORD} -days 3650 \
27 | -in ${FILENAME}.csr -CA ca.crt -CAkey ca.key \
28 | -out ${FILENAME}.crt \
29 | -extfile client-ext.cnf
30 |
31 | # Rename files and remove useless ones
32 | mv ${FILENAME}.crt ${FILENAME}.pem
33 | cp ca.crt ${FILENAME}_chain.pem
34 | mv ${FILENAME}.key ${FILENAME}_rsa.key
35 | rm ${FILENAME}.csr
36 | rm client-ext.cnf
37 | }
38 |
39 | # Create /certs folder if it does not exist
40 | [[ -d /certs ]] || mkdir /certs
41 | cd /certs
42 |
43 | # Create a new CA if it does not exist
44 | if (! test -f ca.key) || (! test -f ca.crt); then
45 | echo "Creating new CA..."
46 | openssl genrsa -out ca.key 4096
47 | openssl req -new -x509 -sha256 \
48 | -passin pass:${AUTHORITY_PASSWORD} \
49 | -passout pass:${AUTHORITY_PASSWORD} \
50 | -extensions v3_ca -key ca.key -out ca.crt -days 3650 \
51 | -subj "/C=${COUNTRY_CODE}/O=${COMPANY}/CN=${AUTHORITY_NAME}"
52 |
53 | echo "01" > ca.srl
54 | fi
55 |
56 | # Create a new certificate for the DOMAIN_NAME
57 | cert ${DOMAIN_NAME} rengine
58 |
59 | # Print all cert files
60 | ls -l /certs
61 |
62 |
--------------------------------------------------------------------------------
/config/nginx/rengine.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 8082 default;
3 | listen [::]:8082 default;
4 | server_name rengine recon;
5 | return 301 https://$host$request_uri;
6 | }
7 |
8 |
9 | server {
10 | listen 443 ssl http2;
11 | listen [::]:443 ssl http2;
12 | server_name rengine recon;
13 |
14 | charset utf-8;
15 | keepalive_timeout 70;
16 |
17 | client_max_body_size 800M;
18 |
19 | location / {
20 | proxy_read_timeout 300;
21 | proxy_connect_timeout 300;
22 | proxy_redirect off;
23 |
24 | proxy_set_header Host $host;
25 | proxy_set_header X-Real-IP $remote_addr;
26 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
27 | proxy_set_header X-Forwarded-Proto $scheme;
28 | proxy_pass http://rengine:8000/;
29 | }
30 |
31 | location /staticfiles/ {
32 | alias /usr/src/app/staticfiles/;
33 | }
34 |
35 | location /protected_media/ {
36 | internal;
37 | alias /usr/src/scan_results/;
38 | autoindex off;
39 | }
40 |
41 | ssl_protocols TLSv1.2;
42 |
43 | ssl_certificate /etc/nginx/certs/rengine.pem; # RSA certificate in PEM format.
44 | ssl_certificate_key /etc/nginx/certs/rengine_rsa.key; # Secret key in PEM format.
45 | ssl_trusted_certificate /etc/nginx/certs/rengine_chain.pem; # Certificate chain.
46 |
47 | ssl_ciphers '!EDH:!EXP:!SHA:!DSS:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256'; # Cipher suite (see https://tls.imirhil.fr/suite/ and `openssl ciphers | sed -r -e 's/:/\n/g'`).
48 | ssl_prefer_server_ciphers on; # Specifies that server ciphers should be preferred over client ciphers.
49 |
50 | # ssl_dhparam /etc/ssl/private/private/dh4096.pem; # Diffie-Hellman server params with 4096 bits (generated using `openssl dhparam 4096 -out /etc/ssl/private/private/dh4096.pem`).
51 | ssl_ecdh_curve secp384r1:X25519:prime256v1; # Elliptic Curve Diffie-Hellman server params.
52 |
53 | ssl_session_cache shared:SSL:10m; # Create a shared cache able to store about 80000 sessions (about 4000 for 1MB storage).
54 | ssl_session_timeout 5m; # Timeout before session to be dropped.
55 | ssl_session_tickets off; # Disable TLS session tickets.
56 | }
57 |
--------------------------------------------------------------------------------
/docker-compose.setup.yml:
--------------------------------------------------------------------------------
1 | services:
2 | certs:
3 | build: ./certs
4 | environment:
5 | - AUTHORITY_NAME=${AUTHORITY_NAME:-CA}
6 | - AUTHORITY_PASSWORD=${AUTHORITY_PASSWORD:-CHANGE_IT}
7 | - COMPANY=${COMPANY:-Company}
8 | - DOMAIN_NAME=${DOMAIN_NAME:-example.com}
9 | - COUNTRY_CODE=${COUNTRY_CODE:-CC}
10 | - STATE=${STATE:-State}
11 | - CITY=${CITY:-City}
12 | volumes:
13 | - ./secrets/certs:/certs:rw
14 |
--------------------------------------------------------------------------------
/make.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | :: Credits: https://github.com/ninjhacks
4 |
5 | set COMPOSE_ALL_FILES = -f docker-compose.yml
6 | set SERVICES = db web proxy redis celery celery-beat ollama
7 |
8 | :: Check if 'docker compose' command is available
9 | docker compose version >nul 2>&1
10 | if %errorlevel% == 0 (
11 | set DOCKER_COMPOSE=docker compose
12 | ) else (
13 | set DOCKER_COMPOSE=docker-compose
14 | )
15 |
16 |
17 | :: Generate certificates.
18 | if "%1" == "certs" %DOCKER_COMPOSE% -f docker-compose.setup.yml run --rm certs
19 | :: Generate certificates.
20 | if "%1" == "setup" %DOCKER_COMPOSE% -f docker-compose.setup.yml run --rm certs
21 | :: Build and start all services.
22 | if "%1" == "up" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% up -d --build %SERVICES%
23 | :: Build all services.
24 | if "%1" == "build" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% build %SERVICES%
25 | :: Generate Username (Use only after make up).
26 | if "%1" == "username" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% exec web python3 manage.py createsuperuser
27 | :: Apply migrations
28 | if "%1" == "migrate" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% exec web python3 manage.py migrate
29 | :: Pull Docker images.
30 | if "%1" == "pull" %DOCKER_COMPOSE% docker.pkg.github.com & docker-compose %COMPOSE_ALL_FILES% pull
31 | :: Down all services.
32 | if "%1" == "down" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% down
33 | :: Stop all services.
34 | if "%1" == "stop" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% stop %SERVICES%
35 | :: Restart all services.
36 | if "%1" == "restart" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% restart %SERVICES%
37 | :: Remove all services containers.
38 | if "%1" == "rm" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% rm -f %SERVICES%
39 | :: Tail all logs with -n 1000.
40 | if "%1" == "logs" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% logs --follow --tail=1000 %SERVICES%
41 | :: Show all Docker images.
42 | if "%1" == "images" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% images %SERVICES%
43 | :: Remove containers and delete volume data.
44 | if "%1" == "prune" %DOCKER_COMPOSE% %COMPOSE_ALL_FILES% stop %SERVICES% & docker-compose %COMPOSE_ALL_FILES% rm -f %SERVICES% & docker volume prune -f
45 | :: Show this help.
46 | if "%1" == "help" @echo Make application Docker images and manage containers using Docker Compose files only for windows.
47 |
--------------------------------------------------------------------------------
/scripts/uninstall.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cat ../web/art/reNgine.txt
4 | echo "Uninstalling reNgine"
5 |
6 | if [ "$EUID" -ne 0 ]
7 | then
8 | echo -e "\e[31mError uninstalling reNgine, Please run this script as root!\e[0m"
9 | echo -e "\e[31mExample: sudo ./uninstall.sh\e[0m"
10 | exit
11 | fi
12 |
13 | DANGER='\e[31m'
14 | SUCCESS='\e[32m'
15 | WARNING='\e[33m'
16 | INFO='\e[34m'
17 | RESET='\e[0m'
18 |
19 | print_status() {
20 | echo -e "${INFO}--------------------------------------------------${RESET}"
21 | echo -e "${INFO}$1${RESET}"
22 | echo -e "${INFO}--------------------------------------------------${RESET}"
23 | }
24 |
25 | print_status "WARNING: You are about to uninstall rengine"
26 | echo -e "${DANGER}This action is not reversible. All containers, volumes, networks, and scan results will be removed.${RESET}"
27 | echo -e "${DANGER}There is no going back after this point.${RESET}"
28 | read -p "$(echo -e ${WARNING}"Are you sure you want to proceed? (y/Y/yes/YES to confirm): "${RESET})" -r CONFIRM
29 |
30 | # change answer to lowecase for comparison
31 | ANSWER_LC=$(echo "$CONFIRM" | tr '[:upper:]' '[:lower:]')
32 |
33 | if [ -z "$CONFIRM" ] || { [ "$CONFIRM" != "y" ] && [ "$CONFIRM" != "Y" ] && [ "$CONFIRM" != "yes" ] && [ "$CONFIRM" != "Yes" ] && [ "$CONFIRM" != "YES" ]; }; then
34 | print_status "${WARNING}Uninstall aborted by user.${RESET}"
35 | exit 0
36 | fi
37 |
38 | print_status "${INFO}Proceeding with uninstalling reNgine${RESET}"
39 |
40 | print_status "Stopping all containers related to reNgine..."
41 | docker stop $(docker ps -a -q --filter name=rengine) 2>/dev/null
42 |
43 | print_status "Removing all containers related to reNgine..."
44 | docker rm $(docker ps -a -q --filter name=rengine) 2>/dev/null
45 |
46 | print_status "Removing all volumes related to reNgine..."
47 | docker volume rm $(docker volume ls -q --filter name=rengine) 2>/dev/null
48 |
49 | print_status "Removing all networks related to reNgine..."
50 | docker network rm $(docker network ls -q --filter name=rengine) 2>/dev/null
51 |
52 | print_status "Removing all images related to reNgine..."
53 | docker rmi $(docker images -q --filter reference=rengine) 2>/dev/null
54 |
55 | print_status "Performing final cleanup"
56 | docker system prune -f --volumes --filter "label=com.docker.compose.project=rengine"
57 |
58 | print_status "${SUCCESS}reNgine uninstall process has been completed.${RESET}"
59 |
--------------------------------------------------------------------------------
/update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "Do you want to apply your local changes after updating? (y/n)"
4 | read answer
5 | answer=$(echo $answer | tr '[:upper:]' '[:lower:]')
6 |
7 | if [[ $answer == "y" ]]; then
8 | make down && git stash save && git pull && git stash apply && make build && make up
9 | elif [[ $answer == "n" ]]; then
10 | make down && git stash && git stash drop && git pull && make build && make up
11 | else
12 | echo "Invalid input. Please enter 'y' or 'n'."
13 | fi
14 |
--------------------------------------------------------------------------------
/web/.gitignore:
--------------------------------------------------------------------------------
1 | secret
2 | /secrets
3 |
--------------------------------------------------------------------------------
/web/.version:
--------------------------------------------------------------------------------
1 | v2.2.0
2 |
--------------------------------------------------------------------------------
/web/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/api/__init__.py
--------------------------------------------------------------------------------
/web/api/permissions.py:
--------------------------------------------------------------------------------
1 | from rest_framework.permissions import BasePermission
2 | from rest_framework.exceptions import PermissionDenied
3 | from rolepermissions.checkers import has_permission
4 |
5 | class HasPermission(BasePermission):
6 | """
7 | This is a custom permission class for DRF that checks if the user
8 | has the required permission.
9 | Usage in drf views:
10 | permission_classes = [HasPermission]
11 | permission_required = PERM_MODIFY_SCAN_CONFIGURATIONS
12 | """
13 |
14 | def has_permission(self, request, view):
15 | permission_code = getattr(view, 'permission_required', None)
16 | if not permission_code:
17 | raise PermissionDenied(detail="Permission is not specified for this view.")
18 |
19 | if not has_permission(request.user, permission_code):
20 | raise PermissionDenied(detail="This user does not have enough permissions")
21 | return True
--------------------------------------------------------------------------------
/web/art/reNgine.txt:
--------------------------------------------------------------------------------
1 | _ _ _
2 | | \ | | (_)
3 | _ __ ___| \| | __ _ _ _ __ ___
4 | | '__/ _ \ . ` |/ _` | | '_ \ / _ \
5 | | | | __/ |\ | (_| | | | | | __/
6 | |_| \___|_| \_|\__, |_|_| |_|\___|
7 | __/ |
8 | |___/
9 |
--------------------------------------------------------------------------------
/web/beat-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | python3 manage.py migrate
4 |
5 | exec "$@"
6 |
--------------------------------------------------------------------------------
/web/dashboard/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/dashboard/__init__.py
--------------------------------------------------------------------------------
/web/dashboard/admin.py:
--------------------------------------------------------------------------------
1 | from dashboard.models import *
2 | from django.contrib import admin
3 |
4 | admin.site.register(SearchHistory)
5 | admin.site.register(Project)
6 | admin.site.register(OpenAiAPIKey)
7 | admin.site.register(NetlasAPIKey)
8 | admin.site.register(ChaosAPIKey)
9 | admin.site.register(HackerOneAPIKey)
10 | admin.site.register(InAppNotification)
11 | admin.site.register(UserPreferences)
--------------------------------------------------------------------------------
/web/dashboard/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class DashboardConfig(AppConfig):
5 | name = 'dashboard'
6 |
--------------------------------------------------------------------------------
/web/dashboard/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.23 on 2024-06-19 02:43
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | initial = True
9 |
10 | dependencies = [
11 | ]
12 |
13 | operations = [
14 | migrations.CreateModel(
15 | name='NetlasAPIKey',
16 | fields=[
17 | ('id', models.AutoField(primary_key=True, serialize=False)),
18 | ('key', models.CharField(max_length=500)),
19 | ],
20 | ),
21 | migrations.CreateModel(
22 | name='OllamaSettings',
23 | fields=[
24 | ('id', models.AutoField(primary_key=True, serialize=False)),
25 | ('selected_model', models.CharField(max_length=500)),
26 | ('use_ollama', models.BooleanField(default=True)),
27 | ],
28 | ),
29 | migrations.CreateModel(
30 | name='OpenAiAPIKey',
31 | fields=[
32 | ('id', models.AutoField(primary_key=True, serialize=False)),
33 | ('key', models.CharField(max_length=500)),
34 | ],
35 | ),
36 | migrations.CreateModel(
37 | name='Project',
38 | fields=[
39 | ('id', models.AutoField(primary_key=True, serialize=False)),
40 | ('name', models.CharField(max_length=500)),
41 | ('slug', models.SlugField(unique=True)),
42 | ('insert_date', models.DateTimeField()),
43 | ],
44 | ),
45 | migrations.CreateModel(
46 | name='SearchHistory',
47 | fields=[
48 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
49 | ('query', models.CharField(max_length=1000)),
50 | ],
51 | ),
52 | ]
53 |
--------------------------------------------------------------------------------
/web/dashboard/migrations/0002_chaosapikey_hackeroneapikey_inappnotification_userpreferences.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.23 on 2024-09-11 01:46
2 |
3 | from django.conf import settings
4 | from django.db import migrations, models
5 | import django.db.models.deletion
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12 | ('dashboard', '0001_initial'),
13 | ]
14 |
15 | operations = [
16 | migrations.CreateModel(
17 | name='ChaosAPIKey',
18 | fields=[
19 | ('id', models.AutoField(primary_key=True, serialize=False)),
20 | ('key', models.CharField(max_length=500)),
21 | ],
22 | ),
23 | migrations.CreateModel(
24 | name='HackerOneAPIKey',
25 | fields=[
26 | ('id', models.AutoField(primary_key=True, serialize=False)),
27 | ('username', models.CharField(max_length=500)),
28 | ('key', models.CharField(max_length=500)),
29 | ],
30 | ),
31 | migrations.CreateModel(
32 | name='UserPreferences',
33 | fields=[
34 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
35 | ('bug_bounty_mode', models.BooleanField(default=True)),
36 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
37 | ],
38 | ),
39 | migrations.CreateModel(
40 | name='InAppNotification',
41 | fields=[
42 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
43 | ('notification_type', models.CharField(choices=[('system', 'system'), ('project', 'project')], default='system', max_length=10)),
44 | ('status', models.CharField(choices=[('success', 'Success'), ('info', 'Informational'), ('warning', 'Warning'), ('error', 'Error')], default='info', max_length=10)),
45 | ('title', models.CharField(max_length=255)),
46 | ('description', models.TextField()),
47 | ('icon', models.CharField(max_length=50)),
48 | ('is_read', models.BooleanField(default=False)),
49 | ('created_at', models.DateTimeField(auto_now_add=True)),
50 | ('redirect_link', models.URLField(blank=True, max_length=255, null=True)),
51 | ('open_in_new_tab', models.BooleanField(default=False)),
52 | ('project', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dashboard.project')),
53 | ],
54 | options={
55 | 'ordering': ['-created_at'],
56 | },
57 | ),
58 | ]
59 |
--------------------------------------------------------------------------------
/web/dashboard/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/dashboard/migrations/__init__.py
--------------------------------------------------------------------------------
/web/dashboard/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from reNgine.definitions import *
3 | from django.contrib.auth.models import User
4 |
5 |
6 | class SearchHistory(models.Model):
7 | query = models.CharField(max_length=1000)
8 |
9 | def __str__(self):
10 | return self.query
11 |
12 |
13 | class Project(models.Model):
14 | id = models.AutoField(primary_key=True)
15 | name = models.CharField(max_length=500)
16 | slug = models.SlugField(unique=True)
17 | insert_date = models.DateTimeField()
18 |
19 | def __str__(self):
20 | return self.slug
21 |
22 |
23 | class OpenAiAPIKey(models.Model):
24 | id = models.AutoField(primary_key=True)
25 | key = models.CharField(max_length=500)
26 |
27 | def __str__(self):
28 | return self.key
29 |
30 |
31 | class OllamaSettings(models.Model):
32 | id = models.AutoField(primary_key=True)
33 | selected_model = models.CharField(max_length=500)
34 | use_ollama = models.BooleanField(default=True)
35 |
36 | def __str__(self):
37 | return self.selected_model
38 |
39 |
40 | class NetlasAPIKey(models.Model):
41 | id = models.AutoField(primary_key=True)
42 | key = models.CharField(max_length=500)
43 |
44 | def __str__(self):
45 | return self.key
46 |
47 |
48 | class ChaosAPIKey(models.Model):
49 | id = models.AutoField(primary_key=True)
50 | key = models.CharField(max_length=500)
51 |
52 | def __str__(self):
53 | return self.key
54 |
55 |
56 | class HackerOneAPIKey(models.Model):
57 | id = models.AutoField(primary_key=True)
58 | username = models.CharField(max_length=500)
59 | key = models.CharField(max_length=500)
60 |
61 | def __str__(self):
62 | return self.username
63 |
64 |
65 | class InAppNotification(models.Model):
66 | project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True)
67 | notification_type = models.CharField(max_length=10, choices=NOTIFICATION_TYPES, default='system')
68 | status = models.CharField(max_length=10, choices=NOTIFICATION_STATUS_TYPES, default='info')
69 | title = models.CharField(max_length=255)
70 | description = models.TextField()
71 | icon = models.CharField(max_length=50) # mdi icon class name
72 | is_read = models.BooleanField(default=False)
73 | created_at = models.DateTimeField(auto_now_add=True)
74 | redirect_link = models.URLField(max_length=255, blank=True, null=True)
75 | open_in_new_tab = models.BooleanField(default=False)
76 |
77 | class Meta:
78 | ordering = ['-created_at']
79 |
80 | def __str__(self):
81 | if self.notification_type == 'system':
82 | return f"System wide notif: {self.title}"
83 | else:
84 | return f"Project wide notif: {self.project.name}: {self.title}"
85 |
86 | @property
87 | def is_system_wide(self):
88 | # property to determine if the notification is system wide or project specific
89 | return self.notification_type == 'system'
90 |
91 |
92 | class UserPreferences(models.Model):
93 | user = models.OneToOneField(User, on_delete=models.CASCADE)
94 | bug_bounty_mode = models.BooleanField(default=True)
95 |
96 | def __str__(self):
97 | return f"{self.user.username}'s preferences"
--------------------------------------------------------------------------------
/web/dashboard/templates/dashboard/profile.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load humanize %}
3 | {% load static %}
4 |
5 | {% block title %}
6 | Profile
7 | {% endblock title %}
8 |
9 | {% block custom_js_css_link %}
10 | {% endblock custom_js_css_link %}
11 |
12 | {% block page_title %}
13 | My Profile
14 | {% endblock page_title %}
15 |
16 | {% block breadcrumb_title %}
17 | Dashboard
18 | My Profile
19 | {% endblock breadcrumb_title %}
20 |
21 | {% block main_content %}
22 |
23 |
24 |
25 |
26 |
Hi {{user.get_username}}!
27 |
28 |
29 |
30 | Username
31 |
32 |
33 |
34 |
Change Password
35 |
63 |
64 |
65 |
66 |
67 |
68 | {% endblock main_content %}
69 |
70 |
71 | {% block page_level_script %}
72 | {% endblock page_level_script %}
73 |
--------------------------------------------------------------------------------
/web/dashboard/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/web/dashboard/urls.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.urls import include, path
3 |
4 | from . import views
5 |
6 | urlpatterns = [
7 | path(
8 | '',
9 | views.onboarding,
10 | name='onboarding'),
11 | path(
12 | '/dashboard/',
13 | views.index,
14 | name='dashboardIndex'),
15 | path(
16 | '/profile/',
17 | views.profile,
18 | name='profile'),
19 | path(
20 | '/admin_interface/',
21 | views.admin_interface,
22 | name='admin_interface'),
23 | path(
24 | '/admin_interface/update',
25 | views.admin_interface_update,
26 | name='admin_interface_update'),
27 | path(
28 | '/search',
29 | views.search,
30 | name='search'),
31 | path(
32 | '404/',
33 | views.four_oh_four,
34 | name='four_oh_four'),
35 | path(
36 | '/projects/',
37 | views.projects,
38 | name='list_projects'),
39 | path(
40 | 'delete/project/',
41 | views.delete_project,
42 | name='delete_project'),
43 | path(
44 | '/bountyhub/list/programs',
45 | views.list_bountyhub_programs,
46 | name='list_bountyhub_programs'),
47 | ]
48 |
--------------------------------------------------------------------------------
/web/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | python3 manage.py migrate
4 | python3 manage.py runserver 0.0.0.0:8000
5 |
6 | exec "$@"
7 |
--------------------------------------------------------------------------------
/web/fixtures/default_keywords.yaml:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "model": "scanEngine.interestinglookupmodel",
4 | "pk": 1,
5 | "fields": {
6 | "keywords": "admin, ftp, cpanel, dashboard",
7 | "custom_type": false,
8 | "title_lookup": true,
9 | "url_lookup": true,
10 | "condition_200_http_lookup": false
11 | }
12 | }
13 | ]
14 |
--------------------------------------------------------------------------------
/web/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Django's command-line utility for administrative tasks."""
3 | import os
4 | import sys
5 |
6 |
7 | def main():
8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'reNgine.settings')
9 | # show rengine artwork
10 | f = open('art/reNgine.txt', 'r')
11 | file_contents = f.read()
12 | print (file_contents)
13 | f.close()
14 | try:
15 | from django.core.management import execute_from_command_line
16 | except ImportError as exc:
17 | raise ImportError(
18 | "Couldn't import Django. Are you sure it's installed and "
19 | "available on your PYTHONPATH environment variable? Did you "
20 | "forget to activate a virtual environment?"
21 | ) from exc
22 | execute_from_command_line(sys.argv)
23 |
24 |
25 | if __name__ == '__main__':
26 | main()
27 |
--------------------------------------------------------------------------------
/web/reNgine/__init__.py:
--------------------------------------------------------------------------------
1 | from .celery import app as celery_app
2 |
3 | __all__ = ('celery_app',)
4 |
--------------------------------------------------------------------------------
/web/reNgine/celery.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import django
4 | from celery import Celery
5 | from celery.signals import setup_logging
6 |
7 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'reNgine.settings')
8 | django.setup()
9 |
10 | # Celery app
11 | app = Celery('reNgine')
12 | app.config_from_object('django.conf:settings', namespace='CELERY')
13 | app.autodiscover_tasks()
14 |
15 |
16 | @setup_logging.connect()
17 | def config_loggers(*args, **kwargs):
18 | from logging.config import dictConfig
19 | dictConfig(app.conf['LOGGING'])
20 |
--------------------------------------------------------------------------------
/web/reNgine/common_serializers.py:
--------------------------------------------------------------------------------
1 | from rest_framework import serializers
2 | from targetApp.models import *
3 |
4 |
5 | class HistoricalIPSerializer(serializers.ModelSerializer):
6 | class Meta:
7 | model = HistoricalIP
8 | fields = ['ip', 'location', 'owner', 'last_seen']
9 |
10 |
11 | class RelatedDomainSerializer(serializers.ModelSerializer):
12 | class Meta:
13 | model = RelatedDomain
14 | fields = '__all__'
15 |
16 |
17 | class NameServersSerializer(serializers.ModelSerializer):
18 | class Meta:
19 | model = NameServer
20 | fields = ['name']
21 |
22 |
23 | class DomainRegistrarSerializer(serializers.ModelSerializer):
24 | class Meta:
25 | model = Registrar
26 | fields = ['name', 'phone', 'email', 'url']
27 |
28 |
29 | class DomainRegistrationSerializer(serializers.ModelSerializer):
30 | class Meta:
31 | model = DomainRegistration
32 | fields = [
33 | 'name',
34 | 'organization',
35 | 'address',
36 | 'city',
37 | 'state',
38 | 'zip_code',
39 | 'country',
40 | 'email',
41 | 'phone',
42 | 'fax'
43 | ]
44 |
45 | class DomainWhoisStatusSerializer(serializers.ModelSerializer):
46 | class Meta:
47 | model = WhoisStatus
48 | fields = ['name']
49 |
50 |
51 | class DomainDNSRecordSerializer(serializers.ModelSerializer):
52 | class Meta:
53 | model = DNSRecord
54 | fields = ['name', 'type']
55 |
--------------------------------------------------------------------------------
/web/reNgine/context_processors.py:
--------------------------------------------------------------------------------
1 | from dashboard.models import *
2 | from django.conf import settings
3 |
4 |
5 | def projects(request):
6 | projects = Project.objects.all()
7 | try:
8 | slug = request.resolver_match.kwargs.get('slug')
9 | project = Project.objects.get(slug=slug)
10 | except Exception:
11 | project = None
12 | return {
13 | 'projects': projects,
14 | 'current_project': project
15 | }
16 |
17 | def version_context(request):
18 | return {
19 | 'RENGINE_CURRENT_VERSION': settings.RENGINE_CURRENT_VERSION
20 | }
21 |
22 | def user_preferences(request):
23 | if hasattr(request, 'user_preferences'):
24 | return {'user_preferences': request.user_preferences}
25 | return {}
--------------------------------------------------------------------------------
/web/reNgine/init.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import secrets
3 | import os
4 |
5 | logger = logging.getLogger(__name__)
6 |
7 |
8 | '''
9 | Based on
10 | https://github.com/MobSF/Mobile-Security-Framework-MobSF/blob/master/MobSF/init.py
11 | '''
12 |
13 |
14 | def first_run(secret_file, base_dir):
15 | if 'RENGINE_SECRET_KEY' in os.environ:
16 | secret_key = os.environ['RENGINE_SECRET_KEY']
17 | elif os.path.isfile(secret_file):
18 | secret_key = open(secret_file).read().strip()
19 | else:
20 | try:
21 | secret_key = get_random()
22 | secret = open(secret_file, 'w')
23 | secret.write(secret_key)
24 | secret.close()
25 | except OSError:
26 | raise Exception(f'Secret file generation failed. Path: {secret_file}')
27 | return secret_key
28 |
29 |
30 | def get_random():
31 | charlist = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
32 | return ''.join(secrets.choice(charlist) for _ in range(64))
33 |
--------------------------------------------------------------------------------
/web/reNgine/middleware.py:
--------------------------------------------------------------------------------
1 | from dashboard.models import UserPreferences
2 |
3 | class UserPreferencesMiddleware:
4 | def __init__(self, get_response):
5 | self.get_response = get_response
6 |
7 | def __call__(self, request):
8 | if request.user.is_authenticated:
9 | request.user_preferences, created = UserPreferences.objects.get_or_create(user=request.user)
10 | return self.get_response(request)
11 |
--------------------------------------------------------------------------------
/web/reNgine/roles.py:
--------------------------------------------------------------------------------
1 | from rolepermissions.roles import AbstractUserRole
2 | from reNgine.definitions import *
3 |
4 | class SysAdmin(AbstractUserRole):
5 | available_permissions = {
6 | PERM_MODIFY_SYSTEM_CONFIGURATIONS: True,
7 | PERM_MODIFY_SCAN_CONFIGURATIONS: True,
8 | PERM_MODIFY_SCAN_RESULTS: True,
9 | PERM_MODIFY_WORDLISTS: True,
10 | PERM_MODIFY_INTERESTING_LOOKUP: True,
11 | PERM_MODIFY_SCAN_REPORT: True,
12 | PERM_INITATE_SCANS_SUBSCANS: True,
13 | PERM_MODIFY_TARGETS: True,
14 | }
15 |
16 |
17 | class PenetrationTester(AbstractUserRole):
18 | available_permissions = {
19 | PERM_MODIFY_SYSTEM_CONFIGURATIONS: False,
20 | PERM_MODIFY_SCAN_CONFIGURATIONS: True,
21 | PERM_MODIFY_SCAN_RESULTS: True,
22 | PERM_MODIFY_WORDLISTS: True,
23 | PERM_MODIFY_INTERESTING_LOOKUP: True,
24 | PERM_MODIFY_SCAN_REPORT: True,
25 | PERM_INITATE_SCANS_SUBSCANS: True,
26 | PERM_MODIFY_TARGETS: True,
27 | }
28 |
29 |
30 | class Auditor(AbstractUserRole):
31 | available_permissions = {
32 | PERM_MODIFY_SYSTEM_CONFIGURATIONS: False,
33 | PERM_MODIFY_SCAN_CONFIGURATIONS: False,
34 | PERM_MODIFY_SCAN_RESULTS: True,
35 | PERM_MODIFY_WORDLISTS: False,
36 | PERM_MODIFY_INTERESTING_LOOKUP: True,
37 | PERM_MODIFY_SCAN_REPORT: True,
38 | PERM_INITATE_SCANS_SUBSCANS: False,
39 | PERM_MODIFY_TARGETS: False,
40 | }
41 |
--------------------------------------------------------------------------------
/web/reNgine/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from django.conf.urls import url
3 | from django.conf.urls.static import static
4 | from django.contrib import admin
5 | from django.contrib.auth import views as auth_views
6 | from django.urls import include, path
7 | from drf_yasg import openapi
8 | from drf_yasg.views import get_schema_view
9 | from rest_framework import permissions
10 |
11 | from reNgine.views import serve_protected_media
12 |
13 | schema_view = get_schema_view(
14 | openapi.Info(
15 | title="reNgine API",
16 | default_version='v1',
17 | description="reNgine: An Automated reconnaissance framework.",
18 | contact=openapi.Contact(email="yogesh.ojha11@gmail.com"),
19 | ),
20 | public=True,
21 | permission_classes=[permissions.AllowAny],
22 | )
23 |
24 | urlpatterns = [
25 | url(r'^swagger(?P\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
26 | url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
27 | path(
28 | 'admin/',
29 | admin.site.urls),
30 | path(
31 | '',
32 | include('dashboard.urls')),
33 | path(
34 | 'target/',
35 | include('targetApp.urls')),
36 | path(
37 | 'scanEngine/',
38 | include('scanEngine.urls')),
39 | path(
40 | 'scan/',
41 | include('startScan.urls')),
42 | path(
43 | 'recon_note/',
44 | include('recon_note.urls')),
45 | path(
46 | 'login/',
47 | auth_views.LoginView.as_view(template_name='base/login.html'),
48 | name='login'),
49 | path(
50 | 'logout/',
51 | auth_views.LogoutView.as_view(template_name='base/logout.html'),
52 | name='logout'),
53 | path(
54 | 'api/',
55 | include(
56 | 'api.urls',
57 | 'api')),
58 | path(
59 | 'media/',
60 | serve_protected_media,
61 | name='serve_protected_media'
62 | ),
63 | ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
64 | # ] + static(settings.MEDIA_URL, document_root=settings.RENGINE_RESULTS) + \
65 |
66 |
--------------------------------------------------------------------------------
/web/reNgine/validators.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | import validators
4 | from django.core.exceptions import ValidationError
5 | from django.utils.translation import gettext_lazy as _
6 |
7 |
8 | def validate_domain(value):
9 | if not validators.domain(value):
10 | raise ValidationError(_('%(value)s is not a valid domain Name'
11 | ), params={'value': value})
12 |
13 |
14 | def validate_url(value):
15 | if not validators.url(value):
16 | raise ValidationError(_('%(value)s is not a valid URL Name'),
17 | params={'value': value})
18 |
19 |
20 | def validate_short_name(value):
21 | regex = re.compile(r'[@!#$%^&*()<>?/\|}{~:]')
22 | if regex.search(value):
23 | raise ValidationError(_('%(value)s is not a valid short name,'
24 | + ' can only contain - and _'),
25 | params={'value': value})
26 |
--------------------------------------------------------------------------------
/web/reNgine/views.py:
--------------------------------------------------------------------------------
1 | import os
2 | import mimetypes
3 | from django.contrib.auth.decorators import login_required
4 | from django.http import HttpResponse, Http404
5 | from django.conf import settings
6 |
7 | @login_required
8 | def serve_protected_media(request, path):
9 | file_path = os.path.join(settings.MEDIA_ROOT, path)
10 | if os.path.isdir(file_path):
11 | raise Http404("File not found")
12 | if os.path.exists(file_path):
13 | content_type, _ = mimetypes.guess_type(file_path)
14 | response = HttpResponse()
15 | # response['Content-Disposition'] = f'attachment; filename={os.path.basename(file_path)}'
16 | response['Content-Type'] = content_type
17 | response['X-Accel-Redirect'] = f'/protected_media/{path}'
18 | return response
19 | else:
20 | raise Http404("File not found")
21 |
22 |
--------------------------------------------------------------------------------
/web/reNgine/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for reNgine project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'reNgine.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/web/recon_note/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/recon_note/__init__.py
--------------------------------------------------------------------------------
/web/recon_note/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from recon_note.models import *
3 |
4 | admin.site.register(TodoNote)
5 |
--------------------------------------------------------------------------------
/web/recon_note/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ReconNoteConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'recon_note'
7 |
--------------------------------------------------------------------------------
/web/recon_note/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.23 on 2024-06-19 02:43
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | initial = True
10 |
11 | dependencies = [
12 | ('startScan', '0001_initial'),
13 | ('dashboard', '0001_initial'),
14 | ]
15 |
16 | operations = [
17 | migrations.CreateModel(
18 | name='TodoNote',
19 | fields=[
20 | ('id', models.AutoField(primary_key=True, serialize=False)),
21 | ('title', models.CharField(blank=True, max_length=1000, null=True)),
22 | ('description', models.TextField(blank=True, null=True)),
23 | ('is_done', models.BooleanField(default=False)),
24 | ('is_important', models.BooleanField(default=False)),
25 | ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='dashboard.project')),
26 | ('scan_history', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='startScan.scanhistory')),
27 | ('subdomain', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='startScan.subdomain')),
28 | ],
29 | ),
30 | ]
31 |
--------------------------------------------------------------------------------
/web/recon_note/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/recon_note/migrations/__init__.py
--------------------------------------------------------------------------------
/web/recon_note/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from startScan.models import *
3 | from dashboard.models import Project
4 |
5 |
6 | class TodoNote(models.Model):
7 | id = models.AutoField(primary_key=True)
8 | title = models.CharField(max_length=1000, null=True, blank=True)
9 | description = models.TextField(null=True, blank=True)
10 | scan_history = models.ForeignKey(
11 | ScanHistory,
12 | on_delete=models.CASCADE,
13 | null=True,
14 | blank=True
15 | )
16 | subdomain = models.ForeignKey(
17 | Subdomain,
18 | on_delete=models.CASCADE,
19 | null=True,
20 | blank=True
21 | )
22 | is_done = models.BooleanField(default=False)
23 | is_important = models.BooleanField(default=False)
24 | project = models.ForeignKey(Project, on_delete=models.CASCADE)
25 |
--------------------------------------------------------------------------------
/web/recon_note/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/web/recon_note/urls.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.urls import include, path
3 |
4 | from . import views
5 |
6 | urlpatterns = [
7 | path(
8 | '/list_note',
9 | views.list_note,
10 | name='list_note'),
11 | path(
12 | 'flip_todo_status',
13 | views.flip_todo_status,
14 | name='flip_todo_status'),
15 | path(
16 | 'flip_important_status',
17 | views.flip_important_status,
18 | name='flip_important_status'),
19 | path(
20 | 'delete_note',
21 | views.delete_note,
22 | name='delete_note'),
23 | ]
24 |
--------------------------------------------------------------------------------
/web/recon_note/views.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | from django.http import JsonResponse
4 | from django.shortcuts import render
5 |
6 | from recon_note.models import *
7 | from startScan.models import *
8 |
9 |
10 | def list_note(request, slug):
11 | context = {}
12 | context['recon_note_active'] = 'active'
13 | return render(request, 'note/index.html', context)
14 |
15 | def flip_todo_status(request):
16 | if request.method == "POST":
17 | body_unicode = request.body.decode('utf-8')
18 | body = json.loads(body_unicode)
19 |
20 | note = TodoNote.objects.get(id=body['id'])
21 | note.is_done = not note.is_done
22 | note.save()
23 |
24 | return JsonResponse({'status': True})
25 |
26 | def flip_important_status(request):
27 | if request.method == "POST":
28 | body_unicode = request.body.decode('utf-8')
29 | body = json.loads(body_unicode)
30 |
31 | note = TodoNote.objects.get(id=body['id'])
32 | note.is_important = not note.is_important
33 | note.save()
34 |
35 | return JsonResponse({'status': True})
36 |
37 | def delete_note(request):
38 | if request.method == "POST":
39 | body_unicode = request.body.decode('utf-8')
40 | body = json.loads(body_unicode)
41 |
42 | TodoNote.objects.filter(id=body['id']).delete()
43 |
44 | return JsonResponse({'status': True})
45 |
--------------------------------------------------------------------------------
/web/requirements.txt:
--------------------------------------------------------------------------------
1 | aiodns==3.0.0
2 | argh==0.26.2
3 | beautifulsoup4==4.9.3
4 | celery==5.4.0
5 | discord-webhook==1.3.0
6 | Django==3.2.23
7 | django-ace==1.0.11
8 | django-celery-beat==2.6.0
9 | django-login-required-middleware==0.6.1
10 | django-role-permissions==3.2.0
11 | django-mathfilters==1.0.0
12 | django-timezone-field==6.1.0
13 | djangorestframework==3.12.4
14 | djangorestframework-datatables==0.6.0
15 | dotted-dict==1.1.3
16 | drf-yasg==1.21.3
17 | gunicorn==22.0.0
18 | gevent==24.2.1
19 | humanize==4.3.0
20 | langchain-community==0.2.7
21 | Markdown==3.3.4
22 | metafinder==1.2
23 | netaddr==0.8.0
24 | netlas==0.5.1
25 | openai==0.28.0
26 | PyYAML==6.0.1
27 | PySocks==1.7.1
28 | psycopg2==2.9.7
29 | pycvesearch==1.0
30 | redis==5.0.3
31 | requests==2.31.0
32 | scapy==2.4.3
33 | sqlalchemy==1.4.52
34 | tldextract==3.5.0
35 | uro==1.0.0
36 | validators==0.18.2
37 | watchdog==4.0.0
38 | whatportis
39 | weasyprint==53.3
40 | wafw00f==2.2.0
41 | xmltodict==0.13.0
42 | django-environ==0.11.2
43 | plotly==5.23.0
44 | kaleido
--------------------------------------------------------------------------------
/web/scanEngine/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/scanEngine/__init__.py
--------------------------------------------------------------------------------
/web/scanEngine/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from scanEngine.models import *
3 |
4 | # Register your models here.
5 | admin.site.register(EngineType)
6 | admin.site.register(Wordlist)
7 | admin.site.register(Configuration)
8 | admin.site.register(InterestingLookupModel)
9 | admin.site.register(Notification)
10 | admin.site.register(VulnerabilityReportSetting)
11 | admin.site.register(InstalledExternalTool)
12 | admin.site.register(Hackerone)
--------------------------------------------------------------------------------
/web/scanEngine/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ScanengineConfig(AppConfig):
5 | name = 'scanEngine'
6 |
--------------------------------------------------------------------------------
/web/scanEngine/management/commands/dumpcustomengines.py:
--------------------------------------------------------------------------------
1 | from django.core.management.base import BaseCommand
2 | from reNgine.common_func import dump_custom_scan_engines
3 |
4 |
5 | class Command(BaseCommand):
6 | help = 'Dumps custom engines into YAMLs in custom_engines/ folder'
7 |
8 | def handle(self, *args, **kwargs):
9 | return dump_custom_scan_engines('/usr/src/app/custom_engines')
--------------------------------------------------------------------------------
/web/scanEngine/management/commands/loadcustomengines.py:
--------------------------------------------------------------------------------
1 | from django.core.management.base import BaseCommand
2 | from reNgine.common_func import load_custom_scan_engines
3 |
4 |
5 | class Command(BaseCommand):
6 | help = 'Loads custom engines from YAMLs in custom_engines/ folder into database'
7 |
8 | def handle(self, *args, **kwargs):
9 | return load_custom_scan_engines('/usr/src/app/custom_engines')
10 |
11 |
12 |
--------------------------------------------------------------------------------
/web/scanEngine/migrations/0002_hackerone_send_report.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.23 on 2024-09-11 01:46
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('scanEngine', '0001_initial'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='hackerone',
15 | name='send_report',
16 | field=models.BooleanField(blank=True, default=False, null=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/web/scanEngine/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/scanEngine/migrations/__init__.py
--------------------------------------------------------------------------------
/web/scanEngine/static/scanEngine/js/custom_scan_engine.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | var table = $('#show-hide-col').DataTable( {
3 | "searching": false,
4 | "scrollY": "280px",
5 | "paging": false,
6 | "info": false,
7 | "ordering": false,
8 | "stripeClasses": [],
9 | "lengthMenu": [7, 10, 20, 50],
10 | "pageLength": 7
11 | } );
12 | $('a.toggle-vis').on( 'click', function (e) {
13 | e.preventDefault();
14 | // Get the column API object
15 | var column = table.column( $(this).attr('data-column') );
16 | // Toggle the visibility
17 | column.visible( ! column.visible() );
18 | } );
19 |
20 | } );
21 |
22 |
23 | function delete_api(id, item)
24 | {
25 | var delAPI = 'delete/'+id;
26 | swal.queue([{
27 | title: 'Are you sure you want to delete this scan engine?',
28 | text: "You won't be able to revert this!",
29 | type: 'warning',
30 | showCancelButton: true,
31 | confirmButtonText: 'Delete',
32 | padding: '2em',
33 | showLoaderOnConfirm: true,
34 | preConfirm: function() {
35 | return fetch(delAPI, {
36 | method: 'POST',
37 | credentials: "same-origin",
38 | headers: {
39 | "X-CSRFToken": getCookie("csrftoken")
40 | }
41 | })
42 | .then(function (response) {
43 | return response.json();
44 | })
45 | .then(function(data) {
46 | // TODO Look for better way
47 | return location.reload();
48 | })
49 | .catch(function() {
50 | swal.insertQueueStep({
51 | type: 'error',
52 | title: 'Oops! Unable to delete'
53 | })
54 | })
55 | }
56 | }])
57 | }
58 |
--------------------------------------------------------------------------------
/web/scanEngine/templates/scanEngine/lookup.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 | {% load custom_tags %}
4 | {% block title %}
5 | Interesting entries Lookup
6 | {% endblock title %}
7 |
8 |
9 | {% block custom_js_css_link %}
10 | {% endblock custom_js_css_link %}
11 |
12 | {% block breadcrumb_title %}
13 | Engines
14 | Interesting Lookup
15 | {% endblock breadcrumb_title %}
16 |
17 | {% block page_title %}
18 | Interesting Lookup
19 | {% endblock page_title %}
20 |
21 | {% block main_content %}
22 |
23 |
24 |
25 |
26 |
27 |
28 | reNgine supports lookup for interesting keyword in recon data. This could be either looking up in subdomains, URLs or in page title.
29 | You can enter the keywords to lookup and reNgine will highlight the matched entries.
30 |
31 |
32 | Keywords are case insensitive.
33 |
34 |
35 |
reNgine will use these default keywords to find the interesting subdomains or URLs from recon data.
36 |
37 | {% for keyword in default_lookup %}
38 | {% for key in keyword.keywords|split:"," %}
39 | {{key}}
40 | {% endfor %}
41 | {% endfor %}
42 |
43 |
44 |
70 |
71 |
72 |
73 |
74 | {% endblock main_content %}
75 |
76 | {% block page_level_script %}
77 | {% endblock page_level_script %}
78 |
--------------------------------------------------------------------------------
/web/scanEngine/templates/scanEngine/settings/add_tool.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 | {% block title %}
4 | Add Tool
5 | {% endblock title %}
6 | {% block custom_js_css_link %}
7 |
8 | {% endblock custom_js_css_link %}
9 | {% block breadcrumb_title %}
10 | Tool Arsenal
11 | Add Tool
12 | {% endblock breadcrumb_title %}
13 | {% block page_title %}
14 | Add Tool
15 | {% endblock page_title %}
16 | {% block main_content %}
17 |
36 | {% endblock main_content %}
37 | {% block page_level_script %}
38 |
39 |
66 | {% endblock page_level_script %}
67 |
--------------------------------------------------------------------------------
/web/scanEngine/templates/scanEngine/settings/proxy.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 | {% load custom_tags %}
4 | {% block title %}
5 | Proxy Settings
6 | {% endblock title %}
7 |
8 | {% block custom_js_css_link %}
9 | {% endblock custom_js_css_link %}
10 |
11 | {% block breadcrumb_title %}
12 | Settings
13 | Proxy Settings
14 | {% endblock breadcrumb_title %}
15 |
16 | {% block page_title %}
17 | Proxy Settings
18 | {% endblock page_title %}
19 |
20 | {% block main_content %}
21 |
22 |
23 |
24 |
25 |
26 |
Every website has a limit to certain number of requests allowed for a certain period of time from an particular IP Address, exceeding the limit will block any incoming requests from that particular IP Address for a specific period of time.
27 | This results in unreliable recon results. Suppose if you were to run Nuclei on a particular target with all the templates, your IP is likely to get banned because of the number of requests made by Nuclei.
28 |
29 | And this is especially true for dorking and other OSINT reNgine does. After certain dorking attempts Google is likely to ban your IP for certain period of time.
30 |
31 |
32 | Using proxies is recommended.
33 |
34 |
46 |
47 |
48 |
49 |
50 | {% endblock main_content %}
51 |
52 |
53 | {% block page_level_script %}
54 |
67 | {% endblock page_level_script %}
68 |
--------------------------------------------------------------------------------
/web/scanEngine/templates/scanEngine/settings/update_tool.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 | {% block title %}
4 | Update Tool
5 | {% endblock title %}
6 | {% block custom_js_css_link %}
7 | {% endblock custom_js_css_link %}
8 | {% block breadcrumb_title %}
9 | Tool Arsenal
10 | Update Tool
11 | {% endblock breadcrumb_title %}
12 | {% block page_title %}
13 | Update Tool
14 | {% endblock page_title %}
15 | {% block main_content %}
16 |
35 | {% endblock main_content %}
36 | {% block page_level_script %}
37 |
38 | {% endblock page_level_script %}
39 |
--------------------------------------------------------------------------------
/web/scanEngine/templates/scanEngine/update_engine.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}
5 | Update Scan Engine
6 | {% endblock title %}
7 |
8 |
9 | {% block custom_js_css_link %}
10 |
11 | {{ form.media }}
12 |
22 | {% endblock custom_js_css_link %}
23 |
24 | {% block breadcrumb_title %}
25 | Engines
26 | Update Scan Engine
27 | {% endblock breadcrumb_title %}
28 |
29 | {% block page_title %}
30 | Update Scan Engine
31 | {% endblock page_title %}
32 |
33 | {% block main_content %}
34 |
48 |
49 | {% endblock main_content %}
50 |
51 | {% block page_level_script %}
52 |
54 | {% endblock page_level_script %}
55 |
--------------------------------------------------------------------------------
/web/scanEngine/templates/scanEngine/wordlist/add.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}
5 | Add New Wordlist
6 | {% endblock title %}
7 |
8 |
9 | {% block custom_js_css_link %}
10 | {% endblock custom_js_css_link %}
11 |
12 | {% block breadcrumb_title %}
13 | Wordlist
14 | Add Worldlist
15 | {% endblock breadcrumb_title %}
16 |
17 | {% block page_title %}
18 | Add New Wordlist for Bruteforce
19 | {% endblock page_title %}
20 |
21 | {% block main_content %}
22 |
23 |
24 |
25 |
26 |
Wordlist can be used for directory bruteforce or subdomain bruteforce. Instructions on how to use the wordlist are found here
27 |
55 |
56 |
57 |
58 |
59 | {% endblock main_content %}
60 |
61 |
62 | {% block page_level_script %}
63 |
84 | {% endblock page_level_script %}
85 |
--------------------------------------------------------------------------------
/web/scanEngine/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/scanEngine/templatetags/__init__.py
--------------------------------------------------------------------------------
/web/scanEngine/templatetags/custom_tags.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from urllib.parse import urlparse
3 |
4 | register = template.Library()
5 |
6 |
7 | @register.filter(name='split')
8 | def split(value, key):
9 | return value.split(key)
10 |
--------------------------------------------------------------------------------
/web/scanEngine/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/web/scanEngine/urls.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.urls import include, path
3 |
4 | from . import views
5 |
6 | urlpatterns = [
7 | path(
8 | '/',
9 | views.index,
10 | name='scan_engine_index'),
11 | path(
12 | '/add/',
13 | views.add_engine,
14 | name='add_engine'),
15 | path(
16 | '/delete/',
17 | views.delete_engine,
18 | name='delete_engine_url'),
19 | path(
20 | '/update/',
21 | views.update_engine,
22 | name='update_engine'),
23 | path(
24 | '/tool_arsenal/update/',
25 | views.modify_tool_in_arsenal,
26 | name='update_tool_in_arsenal'),
27 | path(
28 | '/wordlist/',
29 | views.wordlist_list,
30 | name='wordlist_list'),
31 | path(
32 | '/wordlist/add/',
33 | views.add_wordlist,
34 | name='add_wordlist'),
35 | path(
36 | '/tool_arsenal/add/',
37 | views.add_tool,
38 | name='add_tool'),
39 | path(
40 | '/wordlist/delete/',
41 | views.delete_wordlist,
42 | name='delete_wordlist'),
43 | path(
44 | '/interesting/lookup/',
45 | views.interesting_lookup,
46 | name='interesting_lookup'),
47 | path(
48 | '/tool_settings',
49 | views.tool_specific_settings,
50 | name='tool_settings'),
51 | path(
52 | '/api_vault',
53 | views.api_vault,
54 | name='api_vault'),
55 | path(
56 | '/tool_arsenal',
57 | views.tool_arsenal_section,
58 | name='tool_arsenal'),
59 | path(
60 | '/llm_toolkit',
61 | views.llm_toolkit_section,
62 | name='llm_toolkit'),
63 | path(
64 | '/rengine_settings',
65 | views.rengine_settings,
66 | name='rengine_settings'),
67 | path(
68 | '/notification_settings',
69 | views.notification_settings,
70 | name='notification_settings'),
71 | path(
72 | '/proxy_settings',
73 | views.proxy_settings,
74 | name='proxy_settings'),
75 | path(
76 | '/hackerone_settings',
77 | views.hackerone_settings,
78 | name='hackerone_settings'),
79 | path(
80 | '/report_settings',
81 | views.report_settings,
82 | name='report_settings'),
83 | path(
84 | '/testHackerone/',
85 | views.test_hackerone,
86 | name='testHackerone'
87 | ),
88 | ]
89 |
--------------------------------------------------------------------------------
/web/startScan/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/startScan/__init__.py
--------------------------------------------------------------------------------
/web/startScan/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from startScan.models import *
3 |
4 | admin.site.register(ScanHistory)
5 | admin.site.register(SubScan)
6 | admin.site.register(Subdomain)
7 | admin.site.register(ScanActivity)
8 | admin.site.register(EndPoint)
9 | admin.site.register(Vulnerability)
10 | admin.site.register(CweId)
11 | admin.site.register(CveId)
12 | admin.site.register(VulnerabilityReference)
13 | admin.site.register(VulnerabilityTags)
14 | admin.site.register(Port)
15 | admin.site.register(IpAddress)
16 | admin.site.register(DirectoryFile)
17 | admin.site.register(DirectoryScan)
18 | admin.site.register(Technology)
19 | admin.site.register(MetaFinderDocument)
20 | admin.site.register(Email)
21 | admin.site.register(Employee)
22 | admin.site.register(Dork)
23 | admin.site.register(Waf)
24 | admin.site.register(CountryISO)
25 | admin.site.register(Command)
26 | admin.site.register(GPTVulnerabilityReport)
27 | admin.site.register(S3Bucket)
28 |
--------------------------------------------------------------------------------
/web/startScan/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 | from reNgine.definitions import logger
3 |
4 |
5 | class StartscanConfig(AppConfig):
6 | name = 'startScan'
7 |
8 | def ready(self):
9 | '''
10 | Any Scans that were incomplete in the last scan, we will mark them failed after
11 | server restarted
12 | This does not include pending_scans, pending_scans are taken care by celery
13 | '''
14 | pass
15 | # logger.info('Cancelling all the ongoing scans')
16 | # ScanHistory = self.get_model('ScanHistory')
17 | # ScanHistory.objects.filter(scan_status=1).update(scan_status=0)
18 |
--------------------------------------------------------------------------------
/web/startScan/migrations/0002_auto_20240911_0145.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.23 on 2024-09-11 01:45
2 |
3 | import django.contrib.postgres.fields
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('startScan', '0001_initial'),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name='scanhistory',
16 | name='cfg_excluded_paths',
17 | field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, default=list, null=True, size=None),
18 | ),
19 | migrations.AddField(
20 | model_name='scanhistory',
21 | name='cfg_imported_subdomains',
22 | field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, default=list, null=True, size=None),
23 | ),
24 | migrations.AddField(
25 | model_name='scanhistory',
26 | name='cfg_out_of_scope_subdomains',
27 | field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), blank=True, default=list, null=True, size=None),
28 | ),
29 | migrations.AddField(
30 | model_name='scanhistory',
31 | name='cfg_starting_point_path',
32 | field=models.CharField(blank=True, max_length=200, null=True),
33 | ),
34 | ]
35 |
--------------------------------------------------------------------------------
/web/startScan/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/startScan/migrations/__init__.py
--------------------------------------------------------------------------------
/web/startScan/static/startScan/js/schedule-scan-wizard.js:
--------------------------------------------------------------------------------
1 | function schedulerChanged(selectObject) {
2 | selectedValue = selectObject.value;
3 | if (selectedValue == "periodic") {
4 | var clockedDiv = document.getElementById("clocked-div");
5 | clockedDiv.classList.remove("show");
6 | clockedDiv.classList.remove("active");
7 | var periodicDiv = document.getElementById("periodic-div");
8 | periodicDiv.classList.add("show");
9 | periodicDiv.classList.add("active");
10 | } else if (selectedValue == "clocked") {
11 | var periodicDiv = document.getElementById("periodic-div");
12 | periodicDiv.classList.remove("show");
13 | periodicDiv.classList.remove("active");
14 | var clockedDiv = document.getElementById("clocked-div");
15 | clockedDiv.classList.add("show");
16 | clockedDiv.classList.add("active");
17 | }
18 | }
19 |
20 | var buttonEnabled = true;
21 | var globalTimeout = 0;
22 |
23 | function disableNext() {
24 | var nextButton = $(".actions ul li:nth-child(2) a");
25 | nextButton.attr("href", "#");
26 | buttonEnabled = $(".actions ul li:nth-child(2)")
27 | .addClass("disabled")
28 | .attr("aria-disabled", "true");
29 | }
30 |
31 | function enableNext() {
32 | var nextButton = $(".actions ul li:nth-child(2) a");
33 | nextButton.attr("href", "#next");
34 | buttonEnabled = $(".actions ul li:nth-child(2)")
35 | .removeClass("disabled")
36 | .attr("aria-disabled", "false");
37 | }
38 |
39 | function updateButton() {
40 | var text = $("input[type=radio][name=scan_mode]").val();
41 | if (text === "") {
42 | disableNext();
43 | return false;
44 | } else {
45 | enableNext();
46 | return true;
47 | }
48 | }
49 |
50 | function initTimer() {
51 | if (globalTimeout) clearTimeout(globalTimeout);
52 | globalTimeout = setTimeout(updateButton, 400);
53 | }
54 |
55 | $("#schedule_scan_steps").steps({
56 | headerTag: "h3",
57 | bodyTag: "div",
58 | transitionEffect: "slide",
59 | cssClass: "pill wizard",
60 | enableKeyNavigation: false,
61 | onStepChanging: updateButton,
62 | labels: { finish: "Schedule Scan" },
63 | onInit: function (event, current) {
64 | $('a[role="menuitem"]').addClass("text-white");
65 | $(".actions ul li:nth-child(3) a").attr(
66 | "onclick",
67 | `$(this).closest('form').submit()`
68 | );
69 | flatpickr(document.getElementById("clockedTime"), {
70 | enableTime: true,
71 | dateFormat: "Y-m-d H:i",
72 | });
73 | // $(".basic").select2({
74 | // minimumResultsForSearch: -1
75 | // });
76 | },
77 | onStepChanged: function (event, currentIndex, priorIndex) {
78 | if (currentIndex == 1) {
79 | $("input[type=radio][name=scan_mode]").change(initTimer).keyup(initTimer);
80 | disableNext();
81 | }
82 | },
83 | });
84 |
85 | $("#excludedPaths").selectize({
86 | persist: false,
87 | createOnBlur: true,
88 | create: true,
89 | });
90 |
--------------------------------------------------------------------------------
/web/startScan/static/startScan/js/start-scan-wizard-init.js:
--------------------------------------------------------------------------------
1 | var buttonEnabled = true;
2 | var globalTimeout = 0;
3 |
4 | $("#select_engine").steps({
5 | headerTag: "h4",
6 | bodyTag: "div",
7 | transitionEffect: "slide",
8 | cssClass: "pill wizard",
9 | enableKeyNavigation: false,
10 | onStepChanging: updateButton,
11 | labels: { finish: "Start Scan" },
12 | onInit: function (event, current) {
13 | $(".actions ul li:nth-child(3) a")
14 | .attr("onclick", `$(this).closest('form').submit()`)
15 | .addClass("text-white");
16 | $(".actions ul li:nth-child(1) a[href='#previous']").removeClass(
17 | "btn btn-primary waves-effect waves-light"
18 | );
19 | disableNext();
20 | updateButton();
21 | updatePreviousButton();
22 | },
23 | });
24 |
25 | $("input[type=radio][name=scan_mode]").change(initTimer).keyup(initTimer);
26 | // $('a[role="menuitem"]').addClass("text-white");
27 |
28 | function initTimer() {
29 | if (globalTimeout) clearTimeout(globalTimeout);
30 | globalTimeout = setTimeout(updateButton, 400);
31 | }
32 |
33 | function disableNext() {
34 | var nextButton = $(".actions ul li:nth-child(2) a");
35 | nextButton.attr("href", "#");
36 | nextButton.removeClass("btn btn-primary waves-effect waves-light text-white");
37 | buttonEnabled = false;
38 | $(".actions ul li:nth-child(2)")
39 | .addClass("disabled")
40 | .attr("aria-disabled", "true");
41 | }
42 |
43 | function enableNext() {
44 | var nextButton = $(".actions ul li:nth-child(2) a");
45 | nextButton.attr("href", "#next");
46 | buttonEnabled = true;
47 | nextButton.addClass("btn btn-primary waves-effect waves-light text-white");
48 | $(".actions ul li:nth-child(2)")
49 | .removeClass("disabled")
50 | .attr("aria-disabled", "false");
51 | }
52 |
53 | function updateButton() {
54 | var selectedEngine = $("input[type=radio][name=scan_mode]:checked").val();
55 | if (selectedEngine) {
56 | enableNext();
57 | } else {
58 | disableNext();
59 | }
60 | updatePreviousButton();
61 | return buttonEnabled;
62 | }
63 |
64 | function updatePreviousButton() {
65 | var previousButton = $("a[href='#previous']");
66 | if (previousButton.parent().hasClass("disabled")) {
67 | previousButton.removeClass("text-white");
68 | } else {
69 | previousButton.addClass("text-white");
70 | }
71 | }
72 |
73 | $("#select_engine").on("steps.change", function (e, currentIndex, newIndex) {
74 | setTimeout(updatePreviousButton, 0);
75 | });
76 |
77 | $("#excludedPaths").selectize({
78 | persist: false,
79 | createOnBlur: true,
80 | create: true,
81 | });
82 |
--------------------------------------------------------------------------------
/web/startScan/templates/organization/schedule_scan_ui.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}
5 | Schedule Scan for Organization
6 | {% endblock title %}
7 |
8 |
9 | {% block custom_js_css_link %}
10 |
11 |
12 |
13 |
14 | {% endblock custom_js_css_link %}
15 |
16 | {% block breadcrumb_title %}
17 | Organization
18 | Schedule Scan
19 | {{organization.name}}
20 | {% endblock breadcrumb_title %}
21 |
22 | {% block page_title %}
23 | Scheduling scan for {{organization.name}}
24 | {% endblock page_title %}
25 |
26 | {% block main_content %}
27 | {% include "startScan/_items/schedule_scan_wizard.html" %}
28 | {% endblock main_content %}
29 |
30 |
31 | {% block page_level_script %}
32 |
33 |
34 |
35 |
36 | {% endblock page_level_script %}
37 |
--------------------------------------------------------------------------------
/web/startScan/templates/organization/start_scan.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}
5 | Initiating Scan for Organization
6 | {% endblock title %}
7 |
8 |
9 | {% block custom_js_css_link %}
10 |
11 |
12 |
13 | {% endblock custom_js_css_link %}
14 |
15 | {% block breadcrumb_title %}
16 | Organization
17 | Initiate Scan
18 | {{organization.name}}
19 | {% endblock breadcrumb_title %}
20 |
21 | {% block page_title %}
22 | Initiating scan for {{organization.name}}
23 | {% endblock page_title %}
24 |
25 | {% block main_content %}
26 | {% include "startScan/_items/start_scan_wizard.html" %}
27 | {% endblock main_content %}
28 |
29 |
30 | {% block page_level_script %}
31 |
32 |
33 |
34 | {% endblock page_level_script %}
35 |
--------------------------------------------------------------------------------
/web/startScan/templates/startScan/endpoints.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 | {% load humanize %}
4 | {% load custom_tags %}
5 | {% block title %}
6 | All Endpoints
7 | {% endblock title %}
8 |
9 | {% block custom_js_css_link %}
10 |
11 | {% endblock custom_js_css_link %}
12 |
13 | {% block main_content %}
14 |
15 | {% include 'base/_items/endpoint_tab_content.html' with all_endpoints=True%}
16 |
17 | {% endblock main_content %}
18 |
19 |
20 | {% block page_level_script %}
21 |
22 |
23 |
24 |
25 |
45 | {% endblock page_level_script %}
46 |
--------------------------------------------------------------------------------
/web/startScan/templates/startScan/index.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}
5 | Scan Engine
6 | {% endblock title %}
7 |
8 | {% block custom_js_css_link %}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | {% endblock custom_js_css_link %}
20 |
21 | {% block main_content %}
22 | {% endblock main_content %}
23 |
24 |
25 | {% block page_level_script %}
26 |
27 |
28 |
29 |
30 | {% endblock page_level_script %}
31 |
--------------------------------------------------------------------------------
/web/startScan/templates/startScan/schedule_scan_ui.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 | {% load permission_tags %}
4 |
5 | {% block title %}
6 | Schedule Scan
7 | {% endblock title %}
8 |
9 |
10 | {% block custom_js_css_link %}
11 |
12 |
13 |
14 |
15 | {% endblock custom_js_css_link %}
16 |
17 | {% block breadcrumb_title %}
18 | Target
19 | Schedule Scan
20 | {{domain.name}}
21 | {% endblock breadcrumb_title %}
22 |
23 | {% block page_title %}
24 | Scheduling scan for {{domain.name}}
25 | {% endblock page_title %}
26 |
27 | {% block main_content %}
28 | {% include "startScan/_items/schedule_scan_wizard.html" %}
29 | {% endblock main_content %}
30 |
31 |
32 | {% block page_level_script %}
33 |
34 |
35 |
36 |
37 | {% endblock page_level_script %}
38 |
--------------------------------------------------------------------------------
/web/startScan/templates/startScan/start_multiple_scan_ui.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}
5 | Start Scan for Multiple Targets
6 | {% endblock title %}
7 |
8 |
9 |
10 | {% block custom_js_css_link %}
11 |
12 |
13 |
14 | {% endblock custom_js_css_link %}
15 |
16 | {% block breadcrumb_title %}
17 | Target
18 | Initiate Multiple Scans
19 | {% endblock breadcrumb_title %}
20 |
21 | {% block page_title %}
22 | Initiate Scan for Multiple Targets
23 | {% endblock page_title %}
24 |
25 | {% block main_content %}
26 | {% include "startScan/_items/start_scan_wizard.html" %}
27 | {% endblock main_content %}
28 |
29 |
30 | {% block page_level_script %}
31 |
32 |
33 |
34 | {% endblock page_level_script %}
35 |
--------------------------------------------------------------------------------
/web/startScan/templates/startScan/start_scan_ui.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}
5 | Start Scan
6 | {% endblock title %}
7 |
8 |
9 | {% block custom_js_css_link %}
10 |
11 |
12 |
13 | {% endblock custom_js_css_link %}
14 |
15 | {% block breadcrumb_title %}
16 | Target
17 | Initiate Scan
18 | {{domain.name}}
19 | {% endblock breadcrumb_title %}
20 |
21 | {% block page_title %}
22 | Initiating scan for {{domain.name}}
23 | {% endblock page_title %}
24 |
25 | {% block main_content %}
26 | {% include "startScan/_items/start_scan_wizard.html" %}
27 | {% endblock main_content %}
28 |
29 |
30 | {% block page_level_script %}
31 |
32 |
33 |
34 | {% endblock page_level_script %}
35 |
--------------------------------------------------------------------------------
/web/startScan/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/startScan/templatetags/__init__.py
--------------------------------------------------------------------------------
/web/startScan/templatetags/custom_tags.py:
--------------------------------------------------------------------------------
1 | from urllib.parse import urlparse
2 |
3 | from django import template
4 |
5 | register = template.Library()
6 |
7 |
8 | @register.filter(name='split')
9 | def split(value, key):
10 | return [x.strip() for x in value.split(key)]
11 |
12 |
13 | @register.filter(name='count')
14 | def count(value):
15 | return len(value.split(','))
16 |
17 |
18 | @register.filter(name='getpath')
19 | def getpath(value):
20 | parsed_url = urlparse(value)
21 | if parsed_url.query:
22 | return parsed_url.path + '?' + parsed_url.query
23 | else:
24 | return parsed_url.path
25 |
26 |
27 | @register.filter(name='none_or_never')
28 | def none_or_never(value):
29 | return 'Never' if value is None else value
30 |
31 |
32 | # https://stackoverflow.com/a/32801096
33 | @register.filter
34 | def next(some_list, current_index):
35 | """
36 | Returns the next element of the list using the current index if it exists.
37 | Otherwise returns an empty string.
38 | """
39 | try:
40 | return some_list[int(current_index) + 1] # access the next element
41 | except:
42 | return '' # return empty string in case of exception
43 |
44 | @register.filter
45 | def previous(some_list, current_index):
46 | """
47 | Returns the previous element of the list using the current index if it exists.
48 | Otherwise returns an empty string.
49 | """
50 | try:
51 | return some_list[int(current_index) - 1] # access the previous element
52 | except:
53 | return '' # return empty string in case of exception
54 |
--------------------------------------------------------------------------------
/web/startScan/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/web/startScan/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 | from . import views
3 |
4 | urlpatterns = [
5 | path(
6 | '/history/scan',
7 | views.scan_history,
8 | name="scan_history"),
9 | path(
10 | '/history/subscan',
11 | views.subscan_history,
12 | name="subscan_history"),
13 | path(
14 | '/scheduled/',
15 | views.scheduled_scan_view,
16 | name="scheduled_scan_view"),
17 | path(
18 | '/detail/',
19 | views.detail_scan,
20 | name='detail_scan'),
21 | path(
22 | 'create_report/',
23 | views.create_report,
24 | name='create_report'),
25 | path(
26 | '/all/subdomains',
27 | views.all_subdomains,
28 | name='all_subdomains'),
29 | path(
30 | 'detail/vuln/',
31 | views.detail_vuln_scan,
32 | name='detail_vuln_scan'),
33 | path(
34 | '/detail/vuln',
35 | views.detail_vuln_scan,
36 | name='all_vulns'),
37 | path(
38 | 'visualise/',
39 | views.visualise,
40 | name='visualise'),
41 | path(
42 | '/detail/all/endpoint',
43 | views.all_endpoints,
44 | name='all_endpoints'),
45 | path(
46 | '/start/',
47 | views.start_scan_ui,
48 | name='start_scan'),
49 | path(
50 | '/schedule/target/',
51 | views.schedule_scan,
52 | name='schedule_scan'),
53 | path(
54 | '/schedule/organization/',
55 | views.schedule_organization_scan,
56 | name='schedule_organization_scan'),
57 | path(
58 | 'export/subdomains/',
59 | views.export_subdomains,
60 | name='export_subdomains'),
61 | path(
62 | 'export/endpoints/',
63 | views.export_endpoints,
64 | name='export_endpoints'),
65 | path(
66 | 'export/urls/',
67 | views.export_urls,
68 | name='export_http_urls'),
69 | path(
70 | 'delete/scan/',
71 | views.delete_scan,
72 | name='delete_scan'),
73 | path(
74 | 'stop/scan/',
75 | views.stop_scan,
76 | name='stop_scan'),
77 | path(
78 | 'delete/scheduled_task/',
79 | views.delete_scheduled_task,
80 | name='delete_scheduled_task'),
81 | path(
82 | 'toggle/scheduled_task/',
83 | views.change_scheduled_task_status,
84 | name='change_scheduled_task_status'),
85 | path(
86 | 'toggle/vuln_status/',
87 | views.change_vuln_status,
88 | name='change_vuln_status'),
89 | path(
90 | '/start/multiple/',
91 | views.start_multiple_scan,
92 | name='start_multiple_scan'),
93 | path(
94 | '/start/organization/',
95 | views.start_organization_scan,
96 | name='start_organization_scan'),
97 | path(
98 | 'delete/scan_results/',
99 | views.delete_all_scan_results,
100 | name='delete_all_scan_results'),
101 | path(
102 | 'delete/screenshots/',
103 | views.delete_all_screenshots,
104 | name='delete_all_screenshots'),
105 | path(
106 | '/delete/multiple',
107 | views.delete_scans,
108 | name='delete_multiple_scans'),
109 | path(
110 | '/delete/multiple/scheduled',
111 | views.delete_scheduled_scans,
112 | name='delete_multiple_scheduled_scans'),
113 | path(
114 | '/stop/multiple',
115 | views.stop_scans,
116 | name='stop_multiple_scans'),
117 | ]
118 |
--------------------------------------------------------------------------------
/web/static/assets/css/scrollspyNav.css:
--------------------------------------------------------------------------------
1 | .sidenav {
2 | position: fixed;
3 | right: -30px;
4 | width: 236px;
5 | border-left: 1px solid #e0e6ed; }
6 | .sidenav .sidenav-header:after {
7 | display: none; }
8 | .sidenav .sidenav-header p {
9 | font-weight: 600;
10 | font-size: 18px;
11 | color: #fff;
12 | margin-bottom: 20px;
13 | background: #4361ee;
14 | text-align: center;
15 | border-radius: 5px;
16 | padding: 4px;
17 | letter-spacing: 1px;
18 | background-image: linear-gradient(to right, #4361ee 0%, #805dca 100%); }
19 | .sidenav .sidenav-content {
20 | background-color: transparent;
21 | display: block;
22 | border: none; }
23 | .sidenav .sidenav-content a {
24 | display: block;
25 | padding: 3px 0px;
26 | color: #3b3f5c;
27 | font-size: 12px;
28 | padding: 3px 25px; }
29 | .sidenav .sidenav-content a.active {
30 | color: #805dca;
31 | font-weight: 700;
32 | border-left: 1px solid #805dca; }
33 | .sidenav .sidenav-content a:hover {
34 | color: #4361ee;
35 | font-weight: 700;
36 | border-left: 1px solid #805dca; }
37 |
38 | #content > .container {
39 | display: flex;
40 | max-width: 58.333333% !important;
41 | margin-left: 80px;
42 | padding: 0 16px !important; }
43 | #content > .container > .container {
44 | padding: 0;
45 | margin: 0; }
46 |
47 | @media (max-width: 575px) {
48 | .sidenav .sidenav-content a {
49 | padding: 4px 7px;
50 | margin-right: 0;
51 | margin-bottom: 10px; } }
52 |
53 | @media (max-width: 1199px) {
54 | .sidenav {
55 | display: none; }
56 | #content > .container {
57 | max-width: 100% !important;
58 | margin-left: auto; }
59 | #content > .container > .container {
60 | max-width: 100%; } }
61 |
--------------------------------------------------------------------------------
/web/static/custom/subdomain.js:
--------------------------------------------------------------------------------
1 | function checkedCount() {
2 | // this function will count the number of boxes checked
3 | item = document.getElementsByClassName("subdomain_checkbox");
4 | count = 0;
5 | for (var i = 0; i < item.length; i++) {
6 | if (item[i].checked) {
7 | count++;
8 | }
9 | }
10 | return count;
11 | }
12 |
13 | function mainCheckBoxSelected(checkbox) {
14 | if (checkbox.checked) {
15 | $("[data-button=subdomain_btns]").removeClass("disabled");
16 | $(".subdomain_checkbox").prop('checked', true);
17 | $('#subdomain_selected_count').text(checkedCount() + ' Subdomains Selected x');
18 | } else {
19 | uncheckSubdomains();
20 | }
21 | }
22 |
23 | function toggleMultipleSubdomainButton() {
24 | var checked_count = checkedCount();
25 | if (checked_count > 0) {
26 | $("[data-button=subdomain_btns]").removeClass("disabled");
27 | $('#subdomain_selected_count').text(checked_count + ' Subdomains Selected x');
28 | } else {
29 | $("[data-button=subdomain_btns]").addClass("disabled");
30 | $('#subdomain_selected_count').empty();
31 | }
32 | }
33 |
34 | function uncheckSubdomains(){
35 | $("[data-button=subdomain_btns]").addClass("disabled");
36 | $(".subdomain_checkbox").prop('checked', false);
37 | $("#head_checkbox").prop('checked', false);
38 | $('#subdomain_selected_count').empty();
39 | }
40 |
--------------------------------------------------------------------------------
/web/static/custom/subdomain_datatable.js:
--------------------------------------------------------------------------------
1 | const subdomain_datatable_columns = [
2 | {'data': 'id'},
3 | {'data': 'name'},
4 | {'data': 'endpoint_count'},
5 | {'data': 'endpoint_count'},
6 | {'data': 'http_status'},
7 | {'data': 'page_title'},
8 | {'data': 'ip_addresses'},
9 | {'data': 'ip_addresses'},
10 | {'data': 'content_length', 'searchable': false},
11 | {'data': 'screenshot_path', 'searchable': false},
12 | {'data': 'response_time'},
13 | {'data': 'technologies'},
14 | {'data': 'http_url'},
15 | {'data': 'cname'},
16 | {'data': 'is_interesting'},
17 | {'data': 'info_count'},
18 | {'data': 'low_count'},
19 | {'data': 'medium_count'},
20 | {'data': 'high_count'},
21 | {'data': 'critical_count'},
22 | {'data': 'todos_count'},
23 | {'data': 'is_important'},
24 | {'data': 'webserver'},
25 | {'data': 'content_type'},
26 | {'data': 'id'},
27 | {'data': 'directories_count'},
28 | {'data': 'subscan_count'},
29 | {'data': 'waf'},
30 | {'data': 'attack_surface'},
31 | ];
32 |
33 | const subdomain_datatable_page_length = 50;
34 | const subdomain_datatable_length_menu = [[50, 100, 500, 1000, -1], [50, 100, 500, 1000, 'All']];
35 |
36 | const subdomain_oLanguage = {
37 | "oPaginate": { "sPrevious": ' ', "sNext": ' ' },
38 | "sInfo": "Showing page _PAGE_ of _PAGES_",
39 | "sSearch": ' ',
40 | "sSearchPlaceholder": "Search...",
41 | "sLengthMenu": "Results : _MENU_",
42 | "sProcessing": "Fetching Subdomains... Please wait..."
43 | };
44 |
45 | function subdomain_datatable_col_visibility(subdomain_datatables){
46 | if(!$('#sub_http_status_filter_checkbox').is(":checked")){
47 | subdomain_datatables.column(get_datatable_col_index('http_status', subdomain_datatable_columns)).visible(false);
48 | }
49 | if(!$('#sub_page_title_filter_checkbox').is(":checked")){
50 | subdomain_datatables.column(get_datatable_col_index('page_title', subdomain_datatable_columns)).visible(false);
51 | }
52 | if(!$('#sub_ip_filter_checkbox').is(":checked")){
53 | subdomain_datatables.column(get_datatable_col_index('ip_addresses', subdomain_datatable_columns)).visible(false);
54 | }
55 | if(!$('#sub_ports_filter_checkbox').is(":checked")){
56 | subdomain_datatables.column(get_datatable_col_index('ip_addresses', subdomain_datatable_columns)).visible(false);
57 | }
58 | if(!$('#sub_content_length_filter_checkbox').is(":checked")){
59 | subdomain_datatables.column(get_datatable_col_index('content_length', subdomain_datatable_columns)).visible(false);
60 | }
61 | if(!$('#sub_http_status_filter_checkbox').is(":checked")){
62 | subdomain_datatables.column(get_datatable_col_index('http_status', subdomain_datatable_columns)).visible(false);
63 | }
64 | if(!$('#sub_response_time_filter_checkbox').is(":checked")){
65 | subdomain_datatables.column(get_datatable_col_index('response_time', subdomain_datatable_columns)).visible(false);
66 | }
67 | if(!$('#sub_screenshot_filter_checkbox').is(":checked")){
68 | subdomain_datatables.column(get_datatable_col_index('screenshot_path', subdomain_datatable_columns)).visible(false);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/web/static/custom/timeline.css:
--------------------------------------------------------------------------------
1 | /* Source: https://www.bootdey.com/snippets/view/simple-horizontal-timeline#preview */
2 | .hori-timeline .events {
3 | border-top: 3px solid #e9ecef;
4 | }
5 | .hori-timeline .events .event-list {
6 | display: block;
7 | position: relative;
8 | text-align: center;
9 | padding-top: 70px;
10 | margin-right: 0;
11 | }
12 | .hori-timeline .events .event-list:before {
13 | content: "";
14 | position: absolute;
15 | height: 36px;
16 | border-right: 2px dashed #dee2e6;
17 | top: 0;
18 | }
19 | .hori-timeline .events .event-list .event-date {
20 | position: absolute;
21 | top: 38px;
22 | left: 0;
23 | right: 0;
24 | width: max-content;
25 | margin: 0 auto;
26 | border-radius: 4px;
27 | padding: 2px 10px;
28 | font-size: 13px;
29 | }
30 | @media (min-width: 1140px) {
31 | .hori-timeline .events .event-list {
32 | display: inline-block;
33 | width: 24%;
34 | padding-top: 45px;
35 | }
36 | .hori-timeline .events .event-list .event-date {
37 | top: -30px;
38 | }
39 | }
40 | .bg-soft-primary {
41 | background-color: rgba(64,144,203,.3)!important;
42 | }
43 | .bg-soft-success {
44 | background-color: rgba(71,189,154,.3)!important;
45 | }
46 | .bg-soft-danger {
47 | background-color: rgba(231,76,94,.3)!important;
48 | }
49 | .bg-soft-warning {
50 | background-color: rgba(249,213,112,.3)!important;
51 | }
52 |
--------------------------------------------------------------------------------
/web/static/custom/vuln_datatables.js:
--------------------------------------------------------------------------------
1 | const vuln_datatable_columns = [
2 | {'data': 'id'},
3 | {'data': 'source'},
4 | {'data': 'type'},
5 |
6 | {'data': 'name'},
7 | {'data': 'cvss_metrics'},
8 | {'data': 'tags'},
9 | {'data': 'hackerone_report_id'},
10 |
11 | {'data': 'severity'},
12 | {'data': 'cvss_score'},
13 | {'data': 'cve_ids'},
14 | {'data': 'cwe_ids'},
15 | {'data': 'http_url'},
16 |
17 | {'data': 'description'},
18 | {'data': 'references'},
19 |
20 | {'data': 'discovered_date'},
21 |
22 | {'data': 'open_status'},
23 |
24 | {'data': 'hackerone_report_id'},
25 |
26 | {'data': 'extracted_results'},
27 | {'data': 'curl_command'},
28 | {'data': 'matcher_name'},
29 | {'data': 'request'},
30 | {'data': 'response'},
31 | {'data': 'template'},
32 | {'data': 'template_url'},
33 | {'data': 'template_id'},
34 | {'data': 'impact'},
35 | {'data': 'remediation'},
36 | {'data': 'is_gpt_used'},
37 | ];
38 |
39 | const vuln_datatable_page_length = 50;
40 | const vuln_datatable_length_menu = [[50, 100, 500, 1000, -1], [50, 100, 500, 1000, 'All']];
41 |
42 |
43 | function vulnerability_datatable_col_visibility(table){
44 | if(!$('#vuln_source_checkbox').is(":checked")){
45 | table.column(get_datatable_col_index('vuln_source_checkbox', vuln_datatable_columns)).visible(false);
46 | }
47 | if(!$('#vuln_severity_checkbox').is(":checked")){
48 | table.column(get_datatable_col_index('severity', vuln_datatable_columns)).visible(false);
49 | }
50 | if(!$('#vuln_vulnerable_url_checkbox').is(":checked")){
51 | table.column(get_datatable_col_index('http_url', vuln_datatable_columns)).visible(false);
52 | }
53 | if(!$('#vuln_status_checkbox').is(":checked")){
54 | table.column(get_datatable_col_index('status', vuln_datatable_columns)).visible(false);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-bold.eot
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-bold.ttf
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-bold.woff
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-bold.woff2
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-light.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-light.eot
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-light.ttf
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-light.woff
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-light.woff2
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-medium.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-medium.eot
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-medium.ttf
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-medium.woff
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-medium.woff2
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-regular.eot
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-regular.ttf
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-regular.woff
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-regular.woff2
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-semibold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-semibold.eot
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-semibold.ttf
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-semibold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-semibold.woff
--------------------------------------------------------------------------------
/web/static/fonts/cerebrisans-semibold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/cerebrisans-semibold.woff2
--------------------------------------------------------------------------------
/web/static/fonts/dripicons-v2.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/dripicons-v2.eot
--------------------------------------------------------------------------------
/web/static/fonts/dripicons-v2.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/dripicons-v2.ttf
--------------------------------------------------------------------------------
/web/static/fonts/dripicons-v2.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/dripicons-v2.woff
--------------------------------------------------------------------------------
/web/static/fonts/dropify.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/dropify.eot
--------------------------------------------------------------------------------
/web/static/fonts/dropify.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Copyright (C) 2015 by original authors @ fontello.com
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/web/static/fonts/dropify.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/dropify.ttf
--------------------------------------------------------------------------------
/web/static/fonts/dropify.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/dropify.woff
--------------------------------------------------------------------------------
/web/static/fonts/fa-brands-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-brands-400.eot
--------------------------------------------------------------------------------
/web/static/fonts/fa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-brands-400.ttf
--------------------------------------------------------------------------------
/web/static/fonts/fa-brands-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-brands-400.woff
--------------------------------------------------------------------------------
/web/static/fonts/fa-brands-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-brands-400.woff2
--------------------------------------------------------------------------------
/web/static/fonts/fa-regular-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-regular-400.eot
--------------------------------------------------------------------------------
/web/static/fonts/fa-regular-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-regular-400.ttf
--------------------------------------------------------------------------------
/web/static/fonts/fa-regular-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-regular-400.woff
--------------------------------------------------------------------------------
/web/static/fonts/fa-regular-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-regular-400.woff2
--------------------------------------------------------------------------------
/web/static/fonts/fa-solid-900.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-solid-900.eot
--------------------------------------------------------------------------------
/web/static/fonts/fa-solid-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-solid-900.ttf
--------------------------------------------------------------------------------
/web/static/fonts/fa-solid-900.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-solid-900.woff
--------------------------------------------------------------------------------
/web/static/fonts/fa-solid-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/fa-solid-900.woff2
--------------------------------------------------------------------------------
/web/static/fonts/feather.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/feather.eot
--------------------------------------------------------------------------------
/web/static/fonts/feather.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/feather.ttf
--------------------------------------------------------------------------------
/web/static/fonts/feather.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/feather.woff
--------------------------------------------------------------------------------
/web/static/fonts/footable.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/footable.eot
--------------------------------------------------------------------------------
/web/static/fonts/footable.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/footable.ttf
--------------------------------------------------------------------------------
/web/static/fonts/footable.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/footable.woff
--------------------------------------------------------------------------------
/web/static/fonts/materialdesignicons-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/materialdesignicons-webfont.eot
--------------------------------------------------------------------------------
/web/static/fonts/materialdesignicons-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/materialdesignicons-webfont.ttf
--------------------------------------------------------------------------------
/web/static/fonts/materialdesignicons-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/materialdesignicons-webfont.woff
--------------------------------------------------------------------------------
/web/static/fonts/materialdesignicons-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/materialdesignicons-webfont.woff2
--------------------------------------------------------------------------------
/web/static/fonts/simple-Line-Icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/simple-Line-Icons.eot
--------------------------------------------------------------------------------
/web/static/fonts/simple-Line-Icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/simple-Line-Icons.ttf
--------------------------------------------------------------------------------
/web/static/fonts/simple-Line-Icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/simple-Line-Icons.woff
--------------------------------------------------------------------------------
/web/static/fonts/simple-Line-Icons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/simple-Line-Icons.woff2
--------------------------------------------------------------------------------
/web/static/fonts/summernote.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/summernote.eot
--------------------------------------------------------------------------------
/web/static/fonts/summernote.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/summernote.ttf
--------------------------------------------------------------------------------
/web/static/fonts/summernote.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/summernote.woff
--------------------------------------------------------------------------------
/web/static/fonts/summernote.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/summernote.woff2
--------------------------------------------------------------------------------
/web/static/fonts/themify.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/themify.eot
--------------------------------------------------------------------------------
/web/static/fonts/themify.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/themify.ttf
--------------------------------------------------------------------------------
/web/static/fonts/themify.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/themify.woff
--------------------------------------------------------------------------------
/web/static/fonts/weathericons-regular-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/weathericons-regular-webfont.eot
--------------------------------------------------------------------------------
/web/static/fonts/weathericons-regular-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/weathericons-regular-webfont.ttf
--------------------------------------------------------------------------------
/web/static/fonts/weathericons-regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/weathericons-regular-webfont.woff
--------------------------------------------------------------------------------
/web/static/fonts/weathericons-regular-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/fonts/weathericons-regular-webfont.woff2
--------------------------------------------------------------------------------
/web/static/img/discord.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/static/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/img/favicon.png
--------------------------------------------------------------------------------
/web/static/img/firewall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/img/firewall.png
--------------------------------------------------------------------------------
/web/static/img/girl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/img/girl.png
--------------------------------------------------------------------------------
/web/static/img/global.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/img/global.png
--------------------------------------------------------------------------------
/web/static/img/ladybug.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/img/ladybug.png
--------------------------------------------------------------------------------
/web/static/img/logo-lg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/img/logo-lg.png
--------------------------------------------------------------------------------
/web/static/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/img/logo.png
--------------------------------------------------------------------------------
/web/static/img/magnifying.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/img/magnifying.png
--------------------------------------------------------------------------------
/web/static/img/slack.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/web/static/plugins/accordions/custom-accordions.css:
--------------------------------------------------------------------------------
1 | .card {
2 | border: 1px solid #d3d3d3;
3 | border-radius: 6px;
4 | margin-bottom: 4px; }
5 |
6 | .card-header {
7 | background-color: transparent;
8 | color: #f8538d;
9 | border-color: transparent;
10 | border-radius: 4px;
11 | padding: 0;
12 | position: relative; }
13 | .card-header section > div {
14 | padding: 13px 19px;
15 | cursor: pointer;
16 | display: block;
17 | font-size: 14px;
18 | letter-spacing: 1px; }
19 | .card-header section > div.collapsed {
20 | color: #888ea8; }
21 | .card-header section > div:not(.collapsed) {
22 | color: #4361ee;
23 | border-bottom: 1px solid #d3d3d3;
24 | font-weight: 600; }
25 | .card-header section > div .icons {
26 | position: absolute;
27 | right: 0;
28 | top: 0;
29 | bottom: 0;
30 | padding: 9px; }
31 | .card-header section > div .icons svg {
32 | width: 18px; }
33 |
34 | .card .card-body p {
35 | color: #888ea8;
36 | letter-spacing: 1px;
37 | font-size: 13px; }
38 | .card .card-body p:not(:last-child) {
39 | margin-bottom: 10px; }
40 |
41 | .card .card-body ul {
42 | margin-bottom: 0; }
43 | .card .card-body ul li {
44 | font-size: 12px;
45 | letter-spacing: 1px; }
46 | .card .card-body ul li:not(:last-child) {
47 | margin-bottom: 5px; }
48 | .card .card-body ul li a {
49 | color: #3b3f5c;
50 | font-size: 13px;
51 | font-weight: 600; }
52 | .card .card-body ul li a:hover {
53 | color: #4361ee; }
54 |
55 | /*
56 | No Outer Spacing
57 | */
58 | .no-outer-spacing {
59 | border: 1px solid #d3d3d3;
60 | border-radius: 6px; }
61 | .no-outer-spacing .card {
62 | margin-bottom: 0;
63 | border: none;
64 | border-radius: 0; }
65 | .no-outer-spacing .card:first-child {
66 | border-top-left-radius: 6px;
67 | border-top-right-radius: 6px; }
68 | .no-outer-spacing .card:last-child {
69 | border-bottom-left-radius: 6px;
70 | border-bottom-right-radius: 6px; }
71 | .no-outer-spacing .card:not(:last-child) {
72 | border-bottom: 1px solid #d3d3d3; }
73 | .no-outer-spacing .card-header section > div:not(.collapsed) {
74 | border-bottom: none; }
75 |
76 | /*
77 | Accordin with Icons
78 | */
79 | .accordion-icons .accordion-icon {
80 | display: inline-block;
81 | margin-right: 10px; }
82 | .accordion-icons .accordion-icon svg {
83 | color: #888ea8;
84 | margin-right: 6px;
85 | vertical-align: middle;
86 | width: 20px;
87 | height: 20px;
88 | fill: rgba(0, 23, 55, 0.08); }
89 |
90 | .accordion-icons div:not(.collapsed) .accordion-icon svg {
91 | color: #4361ee;
92 | fill: rgba(27, 85, 226, 0.239216); }
93 |
--------------------------------------------------------------------------------
/web/static/plugins/datatable/custom.css:
--------------------------------------------------------------------------------
1 | /*
2 | ===============================
3 | @Import Function
4 | ===============================
5 | */
6 | /*
7 | ===============================
8 | @Import Mixins
9 | ===============================
10 | */
11 | .widget-content-area {
12 | box-shadow: none !important;
13 | border: none;
14 | border-radius: 6px; }
15 |
16 | .table-hover:not(.table-dark) tbody tr td:first-child {
17 | border-left: none !important;
18 | border-left: none !important; }
19 |
20 | .table-hover:not(.table-dark) tbody tr:hover .new-control.new-checkbox .new-control-indicator {
21 | border: 1px solid #4361ee; }
22 |
23 | /*Style. 1*/
24 | .style-1 .user-name {
25 | font-size: 15px;
26 | color: #805dca; }
27 |
28 | .style-1 .profile-img img {
29 | border-radius: 6px;
30 | background-color: #ebedf2;
31 | padding: 2px;
32 | width: 35px;
33 | height: 35px; }
34 |
35 | /*Style. 2*/
36 | .style-2 .new-control.new-checkbox .new-control-indicator {
37 | top: 1px; }
38 |
39 | .style-2 .user-name {
40 | font-size: 15px;
41 | font-weight: 600;
42 | color: #e2a03f; }
43 |
44 | .style-2 img.profile-img {
45 | background-color: #ebedf2;
46 | padding: 2px;
47 | width: 35px;
48 | height: 35px; }
49 |
50 | /*Style. 3*/
51 | .style-3 .new-control.new-checkbox .new-control-indicator {
52 | top: 1px; }
53 |
54 | .style-3 .user-name {
55 | font-size: 15px;
56 | font-weight: 600;
57 | color: #e2a03f; }
58 |
59 | .style-3 img.profile-img {
60 | border-radius: 6px;
61 | background-color: #ebedf2;
62 | padding: 2px;
63 | width: 35px;
64 | height: 35px; }
65 |
66 | .style-3 .table-controls {
67 | padding: 0;
68 | margin-bottom: 0; }
69 | .style-3 .table-controls li {
70 | list-style: none;
71 | display: inline; }
72 | .style-3 .table-controls li svg {
73 | /* color: $m-color_6;
74 | vertical-align: middle;
75 | width: 28px;
76 | height: 28px;
77 | fill: rgba(0, 23, 55, 0.08);
78 | cursor: pointer; */
79 | /* color: $dark;
80 | margin-right: 6px;
81 | vertical-align: middle;
82 | fill: $m-color_1; */
83 | cursor: pointer;
84 | /* stroke-width: 1; */
85 | margin: 0;
86 | vertical-align: middle;
87 | cursor: pointer;
88 | color: #515365;
89 | stroke-width: 1.5;
90 | width: 28px;
91 | height: 28px; }
92 |
93 | .style-3.table-hover:not(.table-dark) tbody tr:hover .table-controls li svg {
94 | color: #191e3a;
95 | /* fill: rgba(231, 81, 90, 0.2196078431372549); */ }
96 |
97 | .style-3.table-hover:not(.table-dark) tbody tr:hover td:first-child {
98 | color: #4361ee !important; }
99 |
--------------------------------------------------------------------------------
/web/static/plugins/gridzy/skins/gridzySkinBlank/style.css:
--------------------------------------------------------------------------------
1 | /** SKIN Blank **/
2 |
3 | /* all gallery items (children of the main container element) */
4 | .gridzySkinBlank > .gridzyItem {
5 | overflow: hidden;
6 | }
7 |
8 | /* all gallery images (already predefined in Gridzy's main css file and you can override it here) */
9 | .gridzySkinBlank .gridzyImage {
10 | }
11 |
12 | /* all gallery captions (just create your own style) */
13 | .gridzySkinBlank .gridzyCaption {
14 | margin: 0;
15 | padding: .5em;
16 | position: absolute;
17 | z-index: 1;
18 | bottom: 0;
19 | left: 0;
20 | text-align: left;
21 | width: 100%;
22 | height: auto;
23 | color: #ffffff;
24 | font-weight: 200;
25 | background: rgba(0, 0, 0, .9);
26 | }
27 |
28 | .gridzySkinBlank .gridzyCaption a{
29 | color: #2196f3;
30 | }
31 |
32 | /* the mouseover status of all captions */
33 | .gridzySkinBlank > .gridzyItem:hover .gridzyCaption {
34 | opacity: 1;
35 | }
36 |
--------------------------------------------------------------------------------
/web/static/plugins/lightbox/images/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/plugins/lightbox/images/close.png
--------------------------------------------------------------------------------
/web/static/plugins/lightbox/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/plugins/lightbox/images/loading.gif
--------------------------------------------------------------------------------
/web/static/plugins/lightbox/images/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/plugins/lightbox/images/next.png
--------------------------------------------------------------------------------
/web/static/plugins/lightbox/images/prev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/plugins/lightbox/images/prev.png
--------------------------------------------------------------------------------
/web/static/plugins/perfect-scrollbar/perfect-scrollbar.css:
--------------------------------------------------------------------------------
1 | /*
2 | ===============================
3 | @Import Function
4 | ===============================
5 | */
6 | /*
7 | ===============================
8 | @Import Mixins
9 | ===============================
10 | */
11 | /*
12 | * Container style
13 | */
14 | .ps {
15 | overflow: hidden !important;
16 | overflow-anchor: none;
17 | -ms-overflow-style: none;
18 | touch-action: auto;
19 | -ms-touch-action: auto; }
20 |
21 | /*
22 | * Scrollbar rail styles
23 | */
24 | .ps__rail-x {
25 | display: none;
26 | opacity: 0;
27 | transition: background-color .2s linear, opacity .2s linear;
28 | -webkit-transition: background-color .2s linear, opacity .2s linear;
29 | height: 10px;
30 | /* there must be 'bottom' or 'top' for ps__rail-x */
31 | bottom: 0px;
32 | /* please don't change 'position' */
33 | position: absolute; }
34 |
35 | .ps__rail-y {
36 | display: none;
37 | opacity: 0;
38 | transition: background-color .2s linear, opacity .2s linear;
39 | -webkit-transition: background-color .2s linear, opacity .2s linear;
40 | width: 10px;
41 | /* there must be 'right' or 'left' for ps__rail-y */
42 | right: 0;
43 | /* please don't change 'position' */
44 | position: absolute; }
45 |
46 | .ps--active-x > .ps__rail-x, .ps--active-y > .ps__rail-y {
47 | display: block;
48 | background-color: transparent; }
49 |
50 | .ps:hover > .ps__rail-x, .ps:hover > .ps__rail-y {
51 | opacity: 0.6; }
52 |
53 | .ps--focus > .ps__rail-x, .ps--focus > .ps__rail-y {
54 | opacity: 0.6; }
55 |
56 | .ps--scrolling-x > .ps__rail-x, .ps--scrolling-y > .ps__rail-y {
57 | opacity: 0.6; }
58 |
59 | .ps .ps__rail-x:hover, .ps .ps__rail-y:hover, .ps .ps__rail-x:focus, .ps .ps__rail-y:focus, .ps .ps__rail-x.ps--clicking, .ps .ps__rail-y.ps--clicking {
60 | background-color: #eee;
61 | opacity: 0.9; }
62 |
63 | /*
64 | * Scrollbar thumb styles
65 | */
66 | .ps__thumb-x {
67 | background-color: #d3d3d3;
68 | border-radius: 6px;
69 | transition: background-color .2s linear, height .2s ease-in-out;
70 | -webkit-transition: background-color .2s linear, height .2s ease-in-out;
71 | height: 4px;
72 | /* there must be 'bottom' for ps__thumb-x */
73 | bottom: 2px;
74 | /* please don't change 'position' */
75 | position: absolute; }
76 |
77 | .ps__thumb-y {
78 | background-color: #d3d3d3;
79 | border-radius: 6px;
80 | transition: background-color .2s linear, width .2s ease-in-out;
81 | -webkit-transition: background-color .2s linear, width .2s ease-in-out;
82 | width: 4px;
83 | /* there must be 'right' for ps__thumb-y */
84 | right: 2px;
85 | /* please don't change 'position' */
86 | position: absolute; }
87 |
88 | .ps__rail-x:hover > .ps__thumb-x, .ps__rail-x:focus > .ps__thumb-x, .ps__rail-x.ps--clicking .ps__thumb-x {
89 | background-color: #e3e4eb;
90 | height: 6px; }
91 |
92 | .ps__rail-y:hover > .ps__thumb-y, .ps__rail-y:focus > .ps__thumb-y, .ps__rail-y.ps--clicking .ps__thumb-y {
93 | background-color: #e3e4eb;
94 | width: 6px; }
95 |
96 | /* MS supports */
97 | @supports (-ms-overflow-style: none) {
98 | .ps {
99 | overflow: auto !important; } }
100 |
101 | @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
102 | .ps {
103 | overflow: auto !important; } }
104 |
--------------------------------------------------------------------------------
/web/static/plugins/select2/select2-spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/plugins/select2/select2-spinner.gif
--------------------------------------------------------------------------------
/web/static/plugins/select2/select2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/plugins/select2/select2.png
--------------------------------------------------------------------------------
/web/static/plugins/select2/select2x2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/static/plugins/select2/select2x2.png
--------------------------------------------------------------------------------
/web/static/plugins/snackbar/snackbar.min.css:
--------------------------------------------------------------------------------
1 | .snackbar-container{transition:all .5s ease;transition-property:top,right,bottom,left,opacity;font-family:Roboto,sans-serif;font-size:14px;min-height:14px;background-color:#070b0e;position:fixed;display:flex;justify-content:space-between;align-items:center;color:#fff;line-height:22px;padding:18px 24px;bottom:-100px;top:-100px;opacity:0;z-index:9999}.snackbar-container .action{background:inherit;display:inline-block;border:none;font-size:inherit;text-transform:uppercase;color:#4caf50;margin:0 0 0 24px;padding:0;min-width:min-content;cursor:pointer}@media (min-width:640px){.snackbar-container{min-width:288px;max-width:568px;display:inline-flex;border-radius:2px;margin:24px}}@media (max-width:640px){.snackbar-container{left:0;right:0;width:100%}}.snackbar-pos.bottom-center{top:auto!important;bottom:0;left:50%;transform:translate(-50%,0)}.snackbar-pos.bottom-left{top:auto!important;bottom:0;left:0}.snackbar-pos.bottom-right{top:auto!important;bottom:0;right:0}.snackbar-pos.top-left{bottom:auto!important;top:0;left:0}.snackbar-pos.top-center{bottom:auto!important;top:0;left:50%;transform:translate(-50%,0)}.snackbar-pos.top-right{bottom:auto!important;top:0;right:0}@media (max-width:640px){.snackbar-pos.bottom-center,.snackbar-pos.top-center{left:0;transform:none}}
--------------------------------------------------------------------------------
/web/static/plugins/snackbar/snackbar.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Snackbar v0.1.14
3 | * http://polonel.com/Snackbar
4 | *
5 | * Copyright 2018 Chris Brame and other contributors
6 | * Released under the MIT license
7 | * https://github.com/polonel/Snackbar/blob/master/LICENSE
8 | */
9 | !function(a,b){"use strict";"function"==typeof define&&define.amd?define([],function(){return a.Snackbar=b()}):"object"==typeof module&&module.exports?module.exports=a.Snackbar=b():a.Snackbar=b()}(this,function(){var a={};a.current=null;var b={text:"Default Text",textColor:"#FFFFFF",width:"auto",showAction:!0,actionText:"Dismiss",actionTextAria:"Dismiss, Description for Screen Readers",alertScreenReader:!1,actionTextColor:"#4CAF50",showSecondButton:!1,secondButtonText:"",secondButtonAria:"Description for Screen Readers",secondButtonTextColor:"#4CAF50",backgroundColor:"#323232",pos:"bottom-left",duration:5e3,customClass:"",onActionClick:function(a){a.style.opacity=0},onSecondButtonClick:function(a){},onClose:function(a){}};a.show=function(d){var e=c(!0,b,d);a.current&&(a.current.style.opacity=0,setTimeout(function(){var a=this.parentElement;a&&
10 | // possible null if too many/fast Snackbars
11 | a.removeChild(this)}.bind(a.current),500)),a.snackbar=document.createElement("div"),a.snackbar.className="snackbar-container "+e.customClass,a.snackbar.style.width=e.width;var f=document.createElement("p");if(f.style.margin=0,f.style.padding=0,f.style.color=e.textColor,f.style.fontSize="14px",f.style.fontWeight=300,f.style.lineHeight="1em",f.innerHTML=e.text,a.snackbar.appendChild(f),a.snackbar.style.background=e.backgroundColor,e.showSecondButton){var g=document.createElement("button");g.className="action",g.innerHTML=e.secondButtonText,g.setAttribute("aria-label",e.secondButtonAria),g.style.color=e.secondButtonTextColor,g.addEventListener("click",function(){e.onSecondButtonClick(a.snackbar)}),a.snackbar.appendChild(g)}if(e.showAction){var h=document.createElement("button");h.className="action",h.innerHTML=e.actionText,h.setAttribute("aria-label",e.actionTextAria),h.style.color=e.actionTextColor,h.addEventListener("click",function(){e.onActionClick(a.snackbar)}),a.snackbar.appendChild(h)}e.duration&&setTimeout(function(){a.current===this&&(a.current.style.opacity=0,
12 | // When natural remove event occurs let's move the snackbar to its origins
13 | a.current.style.top="-100px",a.current.style.bottom="-100px")}.bind(a.snackbar),e.duration),e.alertScreenReader&&a.snackbar.setAttribute("role","alert"),a.snackbar.addEventListener("transitionend",function(b,c){"opacity"===b.propertyName&&"0"===this.style.opacity&&("function"==typeof e.onClose&&e.onClose(this),this.parentElement.removeChild(this),a.current===this&&(a.current=null))}.bind(a.snackbar)),a.current=a.snackbar,document.body.appendChild(a.snackbar);getComputedStyle(a.snackbar).bottom,getComputedStyle(a.snackbar).top;a.snackbar.style.opacity=1,a.snackbar.className="snackbar-container "+e.customClass+" snackbar-pos "+e.pos},a.close=function(){a.current&&(a.current.style.opacity=0)};
14 | // Pure JS Extend
15 | // http://gomakethings.com/vanilla-javascript-version-of-jquery-extend/
16 | var c=function(){var a={},b=!1,d=0,e=arguments.length;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(b=arguments[0],d++);for(var f=function(d){for(var e in d)Object.prototype.hasOwnProperty.call(d,e)&&(b&&"[object Object]"===Object.prototype.toString.call(d[e])?a[e]=c(!0,a[e],d[e]):a[e]=d[e])};d
11 | {% endblock custom_js_css_link %}
12 |
13 | {% block breadcrumb_title %}
14 | Organization
15 | Add Organization
16 | {% endblock breadcrumb_title %}
17 |
18 | {% block page_title %}
19 | Add Organization
20 | {% endblock page_title %}
21 |
22 |
23 | {% block main_content %}
24 |
25 |
26 |
27 |
28 |
Organizations can be used to bundle the targets, an organization can have multiple targets. You will be able to scan the organizations just like the targets, but scanning the organization will allow you to scan all the targets within the organization together.
29 |
59 |
60 |
61 |
62 |
63 | {% endblock main_content %}
64 |
65 |
66 | {% block page_level_script %}
67 |
68 |
84 | {% endblock page_level_script %}
85 |
--------------------------------------------------------------------------------
/web/targetApp/templates/organization/update.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}
5 | Update Organization
6 | {% endblock title %}
7 |
8 |
9 | {% block custom_js_css_link %}
10 |
11 | {% endblock custom_js_css_link %}
12 |
13 | {% block breadcrumb_title %}
14 | Organization
15 | Update Organization
16 | {% endblock breadcrumb_title %}
17 |
18 | {% block page_title %}
19 | Update Organization
20 | {% endblock page_title %}
21 |
22 | {% block main_content %}
23 |
61 | {% endblock main_content %}
62 |
63 |
64 | {% block page_level_script %}
65 |
66 |
74 | {% endblock page_level_script %}
75 |
--------------------------------------------------------------------------------
/web/targetApp/templates/target/index.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/targetApp/templates/target/index.html
--------------------------------------------------------------------------------
/web/targetApp/templates/target/update.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}
5 | Update Target
6 | {% endblock title %}
7 |
8 |
9 | {% block custom_js_css_link %}
10 | {% endblock custom_js_css_link %}
11 |
12 | {% block page_title %}
13 | Update Target {{ form.name.value }}
14 | {% endblock page_title %}
15 |
16 | {% block main_content %}
17 |
56 | {% endblock main_content %}
57 |
58 |
59 | {% block page_level_script %}
60 | {% endblock page_level_script %}
61 |
--------------------------------------------------------------------------------
/web/targetApp/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/web/targetApp/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import include, path
2 |
3 | from . import views
4 |
5 | urlpatterns = [
6 | path(
7 | '',
8 | views.index,
9 | name='targetIndex'),
10 | path(
11 | '/add/target',
12 | views.add_target,
13 | name='add_target'),
14 | path(
15 | '/add/organization',
16 | views.add_organization,
17 | name='add_organization'),
18 | path(
19 | '/update/target/',
20 | views.update_target,
21 | name='update_target'),
22 | path(
23 | '/update/organization/',
24 | views.update_organization,
25 | name='update_organization'),
26 | path(
27 | '/list/target',
28 | views.list_target,
29 | name='list_target'),
30 | path(
31 | '/list/organization',
32 | views.list_organization,
33 | name='list_organization'),
34 | path(
35 | 'delete/target/',
36 | views.delete_target,
37 | name='delete_target'),
38 | path(
39 | 'delete/organization/',
40 | views.delete_organization,
41 | name='delete_organization'),
42 | path(
43 | '/delete/multiple',
44 | views.delete_targets,
45 | name='delete_multiple_targets'),
46 | path(
47 | '/summary/',
48 | views.target_summary,
49 | name='target_summary'),
50 | ]
51 |
--------------------------------------------------------------------------------
/web/templates/404.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 | {% load humanize %}
3 | {% load static %}
4 |
5 | {% block title %}
6 | {% endblock title %}
7 |
8 | {% block custom_js_css_link %}
9 | {% endblock custom_js_css_link %}
10 |
11 | {% block page_title %}
12 | {% endblock page_title %}
13 |
14 | {% block breadcrumb_title %}
15 | {% endblock breadcrumb_title %}
16 |
17 | {% block main_content %}
18 |
19 |
20 |
21 |
22 |
23 | 404!
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
Oops-a-Daisy! You've Found Our Top-Secret Interdimensional Rabbit Hole!
34 |
Back to Dashboard
35 |
36 |
37 |
38 |
39 |
40 | {% endblock main_content %}
41 |
42 |
43 | {% block page_level_script %}
44 | {% endblock page_level_script %}
45 |
--------------------------------------------------------------------------------
/web/templates/base/_items/center_spinner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Loading...
4 |
5 |
6 |
--------------------------------------------------------------------------------
/web/templates/base/_items/down_arrow.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/web/templates/base/_items/footer.html:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/web/templates/base/_items/green_tick.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/web/templates/base/_items/minus_icon.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/web/templates/base/_items/modal.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/web/templates/base/_items/most_common_cve_cwe_tag_template.html:
--------------------------------------------------------------------------------
1 |
9 |
17 |
25 |
--------------------------------------------------------------------------------
/web/templates/base/_items/most_common_cve_cwe_tags.js:
--------------------------------------------------------------------------------
1 | var colors = [
2 | {% for cve in most_common_cve %}
3 | '#7E57C2',
4 | {% endfor %}
5 | ];
6 |
7 | // http_status chart
8 | var options = {
9 | series: [{
10 | name: 'CVE IDs',
11 | data: [{% for cve in most_common_cve %}
12 | {{cve.nused}},
13 | {% endfor %}]
14 | }],
15 | chart: {
16 | height: 350,
17 | type: 'bar',
18 | events: {
19 | click: function(chart, w, e) {
20 | // console.log(chart, w, e)
21 | }
22 | }
23 | },
24 | colors: colors,
25 | plotOptions: {
26 | bar: {
27 | columnWidth: '45%',
28 | distributed: true,
29 | }
30 | },
31 | dataLabels: {
32 | enabled: false
33 | },
34 | legend: {
35 | show: false
36 | },
37 | xaxis: {
38 | categories: [
39 | {% for cve in most_common_cve %}
40 | '{{cve.name}}',
41 | {% endfor %}
42 | ],
43 | labels: {
44 | style: {
45 | colors: colors,
46 | fontSize: '12px'
47 | }
48 | }
49 | }
50 | };
51 |
52 | var chart = new ApexCharts(document.querySelector("#most_common_cve"), options);
53 | chart.render();
54 |
55 | var colors = [
56 | {% for cwe in most_common_cwe %}
57 | '#5C6BC0',
58 | {% endfor %}
59 | ];
60 |
61 | // http_status chart
62 | var options = {
63 | series: [{
64 | name: 'CWE IDs',
65 | data: [{% for cwe in most_common_cwe %}
66 | {{cwe.nused}},
67 | {% endfor %}]
68 | }],
69 | chart: {
70 | height: 350,
71 | type: 'bar',
72 | events: {
73 | click: function(chart, w, e) {
74 | // console.log(chart, w, e)
75 | }
76 | }
77 | },
78 | colors: colors,
79 | plotOptions: {
80 | bar: {
81 | columnWidth: '45%',
82 | distributed: true,
83 | }
84 | },
85 | dataLabels: {
86 | enabled: false
87 | },
88 | legend: {
89 | show: false
90 | },
91 | xaxis: {
92 | categories: [
93 | {% for cwe in most_common_cwe %}
94 | '{{cwe.name}}',
95 | {% endfor %}
96 | ],
97 | labels: {
98 | style: {
99 | colors: colors,
100 | fontSize: '12px'
101 | }
102 | }
103 | }
104 | };
105 |
106 | var chart = new ApexCharts(document.querySelector("#most_common_cwe"), options);
107 | chart.render();
108 |
109 |
110 | var colors = [
111 | {% for tag in most_common_tags %}
112 | '#EF5350',
113 | {% endfor %}
114 | ];
115 |
116 | // http_status chart
117 | var options = {
118 | series: [{
119 | name: 'CWE IDs',
120 | data: [{% for tag in most_common_tags %}
121 | {{tag.nused}},
122 | {% endfor %}]
123 | }],
124 | chart: {
125 | height: 350,
126 | type: 'bar',
127 | events: {
128 | click: function(chart, w, e) {
129 | // console.log(chart, w, e)
130 | }
131 | }
132 | },
133 | colors: colors,
134 | plotOptions: {
135 | bar: {
136 | columnWidth: '45%',
137 | distributed: true,
138 | }
139 | },
140 | dataLabels: {
141 | enabled: false
142 | },
143 | legend: {
144 | show: false
145 | },
146 | xaxis: {
147 | categories: [
148 | {% for tag in most_common_tags %}
149 | '{{tag.name}}',
150 | {% endfor %}
151 | ],
152 | labels: {
153 | style: {
154 | colors: colors,
155 | fontSize: '12px'
156 | }
157 | }
158 | }
159 | };
160 |
161 | var chart = new ApexCharts(document.querySelector("#most_common_tags"), options);
162 | chart.render();
163 |
--------------------------------------------------------------------------------
/web/templates/base/_items/most_common_vuln.html:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/web/templates/base/_items/most_vuln_target.html:
--------------------------------------------------------------------------------
1 | {% load mathfilters %}
2 |
28 |
--------------------------------------------------------------------------------
/web/templates/base/_items/offcanvas.html:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/web/templates/base/_items/plus_icon.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/web/templates/base/_items/recon_note_modal.html:
--------------------------------------------------------------------------------
1 |
39 |
--------------------------------------------------------------------------------
/web/templates/base/_items/red_cross.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/web/templates/base/_items/right_bar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
19 |
Currently Scanning
20 |
21 |
22 |
23 |
Recently Completed
24 |
25 |
26 |
29 |
30 |
Upcoming
31 |
36 |
37 |
38 |
39 |
Currently Running
40 |
41 |
42 |
43 |
Recently Completed
44 |
45 |
46 |
49 |
50 |
Upcoming
51 |
56 |
57 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/web/templates/base/_items/subscan_modal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
Select the scan engine (default engine Selected)
11 |
12 | {% for engine in scan_engines %}
13 | {% if engine.engine_name == history.scan_type.engine_name %}
14 | {{engine}}
15 | {% else %}
16 | {{engine}}
17 | {% endif %}
18 | {% endfor %}
19 |
20 |
21 |
Select the engine's subtasks to perform
22 |
23 |
24 |
25 |
26 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/web/templates/base/_items/up_arrow.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/web/templates/base/_items/widgets/vulnerability_breakdown_by_severity_chart.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Critical
8 |
{{critical_count}}
9 |
10 |
11 |
High
12 |
{{high_count}}
13 |
14 |
15 |
Medium
16 |
{{medium_count}}
17 |
18 |
19 |
Low
20 |
{{low_count}}
21 |
22 |
23 |
Info
24 |
{{info_count}}
25 |
26 |
27 |
Unknown
28 |
{{unknown_count}}
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/web/templates/base/_items/widgets/vulnerability_highlights.html:
--------------------------------------------------------------------------------
1 | {% load humanize %}
2 |
59 |
--------------------------------------------------------------------------------
/web/templates/base/_items/xl_scrollable_modal.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/web/templates/base/logout.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 |
3 |
4 |
5 |
6 |
7 |
8 | Login
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/web/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yogeshojha/rengine/f2f40582e84edf4130b2ddc4ab892c5950458b65/web/tests/__init__.py
--------------------------------------------------------------------------------
/web/tests/test_nmap.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import os
3 | import unittest
4 |
5 | os.environ['RENGINE_SECRET_KEY'] = 'secret'
6 | os.environ['CELERY_ALWAYS_EAGER'] = 'True'
7 |
8 | from celery.utils.log import get_task_logger
9 | from reNgine.settings import DEBUG
10 | from reNgine.tasks import parse_nmap_results, parse_nmap_vuln_output, parse_nmap_vulscan_output
11 | import pathlib
12 |
13 | logger = get_task_logger(__name__)
14 | DOMAIN_NAME = os.environ['DOMAIN_NAME']
15 | FIXTURES_DIR = pathlib.Path().absolute() / 'fixtures' / 'nmap_xml'
16 |
17 | if not DEBUG:
18 | logging.disable(logging.CRITICAL)
19 |
20 |
21 | class TestNmapParsing(unittest.TestCase):
22 | def setUp(self):
23 | self.nmap_vuln_single_xml = FIXTURES_DIR / 'nmap_vuln_single.xml'
24 | self.nmap_vuln_multiple_xml = FIXTURES_DIR / 'nmap_vuln_multiple.xml'
25 | self.nmap_vulscan_single_xml = FIXTURES_DIR / 'nmap_vulscan_single.xml'
26 | self.nmap_vulscan_multiple_xml = FIXTURES_DIR / 'nmap_vulscan_multiple.xml'
27 | self.all_xml = [
28 | self.nmap_vuln_single_xml,
29 | self.nmap_vuln_multiple_xml,
30 | self.nmap_vulscan_single_xml,
31 | self.nmap_vulscan_multiple_xml
32 | ]
33 |
34 | def test_nmap_parse(self):
35 | for xml_file in self.all_xml:
36 | vulns = parse_nmap_results(self.nmap_vuln_single_xml)
37 | self.assertGreater(self.vulns, 0)
38 |
39 | def test_nmap_vuln_single(self):
40 | pass
41 |
42 | def test_nmap_vuln_multiple(self):
43 | pass
44 |
45 | def test_nmap_vulscan_single(self):
46 | pass
47 |
48 | def test_nmap_vulscan_multiple(self):
49 | pass
--------------------------------------------------------------------------------