├── .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 | [![first-timers](https://img.shields.io/badge/first--timers--only-friendly-blue.svg?style=flat-square)](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: <title>" 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 "<!DOCTYPE html> 27 | <html lang='en'> 28 | <head> 29 | <meta charset='UTF-8'> 30 | <meta name='viewport' content='width=device-width, initial-scale=1.0'> 31 | <title>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 | 18 | 19 | {% endblock breadcrumb_title %} 20 | 21 | {% block main_content %} 22 |
23 |
24 |
25 |
26 |

Hi {{user.get_username}}!

27 |
28 |
29 |
30 | 31 | 32 |
33 |
34 |

Change Password

35 |
36 | {% csrf_token %} 37 |
38 |
39 | 40 | 41 | {% if form.errors.old_password %} 42 | {% for error in form.errors.old_password %} 43 |

{{error}}

44 | {% endfor %} 45 | {% endif %} 46 |
47 |
48 | 49 | 50 |
51 |
52 | 53 | 54 |
55 |
56 | {% if form.errors.new_password2 %} 57 | {% for error in form.errors.new_password2 %} 58 |

{{error}}

59 | {% endfor %} 60 | {% endif %} 61 | 62 |
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 | 14 | 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 |

Interesting Lookup

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 | 34 |

Default Keywords

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 |

Custom Keywords

44 |
45 | {% csrf_token %} 46 | 47 | {{ form.keywords }} 48 | {# hidden value #} 49 | {{ form.custom_type }} 50 | Please use a comma (,) to separate the keywords. 51 |

Lookup in

52 |
53 | {{form.url_lookup}} 54 | 55 |
56 |
57 | {{form.title_lookup}} 58 | 59 |
60 |

Lookup Conditions

61 | reNgine will lookup the keywords only when below conditions are met. 62 |
63 | Lookup only when 64 |
65 | {{form.condition_200_http_lookup}} 66 | 67 |
68 | 69 |
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 | 11 | 12 | {% endblock breadcrumb_title %} 13 | {% block page_title %} 14 | Add Tool 15 | {% endblock page_title %} 16 | {% block main_content %} 17 |
18 |
19 |
20 |
21 |
22 | {% csrf_token %} 23 |
24 | {% include "scanEngine/settings/_items/external_tool_form.html" %} 25 |
26 |
27 |
28 | 29 |
30 |
31 |
32 | 33 |
34 |
35 |
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 | 13 | 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 |

Proxy Settings

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 | 34 |
35 | {% csrf_token %} 36 |
37 | {{form.use_proxy}} 38 | 39 |
40 |

Proxy List

41 |

You can enter as many proxies as you want, reNgine will randomly pick one among them during the scan.

42 | 43 | {{form.proxies}} 44 | 45 |
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 | 10 | 11 | {% endblock breadcrumb_title %} 12 | {% block page_title %} 13 | Update Tool 14 | {% endblock page_title %} 15 | {% block main_content %} 16 |
17 |
18 |
19 |
20 |
21 | {% csrf_token %} 22 |
23 | {% include "scanEngine/settings/_items/external_tool_form.html" %} 24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
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 | 26 | 27 | {% endblock breadcrumb_title %} 28 | 29 | {% block page_title %} 30 | Update Scan Engine 31 | {% endblock page_title %} 32 | 33 | {% block main_content %} 34 |
35 |
36 |
37 |
38 |

Update Scan Engine

39 |
40 | {% csrf_token %} 41 | {% include "scanEngine/_items/form_engine.html" %} 42 | 43 |
44 |
45 |
46 |
47 |
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 | 14 | 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 |
28 | {% csrf_token %} 29 |
30 |
31 | 32 | {{ form.name }} 33 |
34 |
35 | 36 | {{ form.short_name }} 37 | {% if form.errors.short_name %} 38 |
39 | {{ form.errors.short_name|striptags }} 40 |
41 | {% endif %} 42 |

Please keep the short names without spaces, like my-wordlist or my_wordlist. The short names will be later used to reference wordlist in the YAML settings.

43 |
44 |
45 |

Select the wordlist file

46 |

Your wordlist must be a *.txt file and wordlists must be separated by a new line.

47 |
48 |
49 | 50 | {{ form.upload_file }} 51 |
52 |
53 | 54 |
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 | 18 | 19 | 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 | 17 | 18 | 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 | 19 | 20 | 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 | 18 | 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 | 17 | 18 | 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 | 15 | 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 |
30 | {% csrf_token %} 31 |
32 |
33 | 34 | {{ form.name }} 35 | {% if form.errors %} 36 |
37 | {{ form.errors.name|striptags }} 38 |
39 | {% endif %} 40 |
41 |
42 | 43 | {{ form.description }} 44 |
45 |
46 | 47 | {{form.domains}} 48 | {% if form.errors.domains %} 49 |
50 |

51 | {{ form.errors.domains|striptags }} 52 |

53 |
54 | {% endif %} 55 |
56 |
57 | 58 |
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 | 15 | 16 | {% endblock breadcrumb_title %} 17 | 18 | {% block page_title %} 19 | Update Organization 20 | {% endblock page_title %} 21 | 22 | {% block main_content %} 23 |
24 |
25 |
26 |
27 |
28 | {% csrf_token %} 29 |
30 |
31 | 32 | {{ form.name }} 33 | {% if form.errors %} 34 |
35 | {{ form.errors.name|striptags }} 36 |
37 | {% endif %} 38 |
39 |
40 | 41 | {{ form.description }} 42 |
43 |
44 | 45 | {{form.domains}} 46 | {% if form.errors.domains %} 47 |
48 |

49 | {{ form.errors.domains|striptags }} 50 |

51 |
52 | {% endif %} 53 |
54 |
55 | 56 |
57 |
58 |
59 |
60 |
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 |
18 |
19 |
20 |
21 |

Update Target

22 |
23 | {% csrf_token %} 24 |
25 |
26 |
27 | 28 | {{ form.name }} 29 | {% if form.errors %} 30 |
31 | {{ form.errors.name|striptags }} 32 |
33 | {% endif %} 34 |
35 |
36 |
37 | 38 | {{ form.description }} 39 |
40 |
41 | {% if user_preferences.bug_bounty_mode %} 42 |
43 | 47 | {{ form.h1_team_handle }} 48 |
49 | {% endif %} 50 | 51 |
52 |
53 |
54 |
55 |
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 |
2 | 3 | 4 | 5 |
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 |
2 |
3 |
4 |

Most Common CVE IDs

5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |

Most Common CWE IDs

13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |

Most Common Vulnerability Tags

21 |
22 |
23 |
24 |
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 |
2 |
3 |
4 |
5 |
6 |

Most Common Vulnerabilities

7 |
8 |
9 |
10 | 11 | 12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | -------------------------------------------------------------------------------- /web/templates/base/_items/most_vuln_target.html: -------------------------------------------------------------------------------- 1 | {% load mathfilters %} 2 |
3 |
4 |
5 |
6 |
7 |

{{most_vuln_widget_title}}

8 |
9 |
10 |
11 | 12 | 13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | -------------------------------------------------------------------------------- /web/templates/base/_items/offcanvas.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |
8 |
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 |
27 | Show All 28 |
29 |
30 |
Upcoming
31 |
32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 |
Currently Running
40 |
41 |
42 |
43 |
Recently Completed
44 |
45 |
46 |
47 | Show All 48 |
49 |
50 |
Upcoming
51 |
52 |
53 |
54 |
55 |
56 |
57 | 62 |
63 |
64 |
65 |
66 |
67 | -------------------------------------------------------------------------------- /web/templates/base/_items/subscan_modal.html: -------------------------------------------------------------------------------- 1 | 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 |

Vulnerability Breakdown by Severity

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 |
3 |
4 |

Vulnerability Highlights

5 |
6 | 7 | {% if not vulnerability_list %} 8 | 11 | {% else %} 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | {% for vulnerability in vulnerability_list %} 22 | 23 | 24 | 35 | 50 | 51 | 52 | {% endfor %} 53 | 54 | {% endif %} 55 |
TypeVulnerabilitySeverityVulnerable URL
{{vulnerability.type}} 25 | {{vulnerability.name}} 26 | {% if vulnerability.cve_ids %} 27 |
28 | {% for cve in vulnerability.cve_ids.all %} 29 | {{cve.name}} 30 | {% endfor %} 31 | {% endif %} 32 |
33 | Discovered: {{vulnerability.discovered_date|naturaltime}} 34 |
36 | {% if vulnerability.severity == 0 %} 37 | Info 38 | {% elif vulnerability.severity == 1 %} 39 | Low 40 | {% elif vulnerability.severity == 2 %} 41 | Medium 42 | {% elif vulnerability.severity == 3 %} 43 | High 44 | {% elif vulnerability.severity == 4 %} 45 | Critical 46 | {% elif vulnerability.severity == -1 %} 47 | Unknown 48 | {% endif %} 49 | {{vulnerability.http_url|truncatechars:50}}
56 |
57 |
58 |
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 |
18 |
19 |
20 |
21 |
22 |
Thank you for using reNgine.
23 |
24 |

You have been successfully logged out!

25 |

For any issues or feature request, please feel free to raise issue on github

26 |
27 |
28 |
29 |
30 |
31 |
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 --------------------------------------------------------------------------------