From 9dd7295f5b39fe362d4bb0a76804c057fe86c2c4 Mon Sep 17 00:00:00 2001 From: Purvansh Bhatt <48984515+purvanshbhatt@users.noreply.github.com> Date: Mon, 15 Dec 2025 21:09:03 -0500 Subject: [PATCH 1/2] feat: Vulnerability Scanner 2.0 (GUI, AI Agents, Installers) --- .github/workflows/python-app.yml | 39 + AI-Remediation-Report.md | 54 ++ README.md | 64 +- README_AGENT.md | 52 ++ Security-Debug-ScanLog | 256 ++++++ Security-Vulnerability-Report | 33 + Security-Vulnerability-Report.json | 27 + agent.py | 100 +++ ai_scanner.py | 256 ++++++ debug_adk.py | 34 + gui.py | 283 ++++++ install_linux.sh | 32 + install_mac.sh | 20 + install_windows.ps1 | 20 + mcp_server.py | 82 ++ monitor.py | 144 +-- requirements.txt | 9 + scan_report_scanme.nmap.org.md | 20 + scanner.py | 1310 +++------------------------- scanner_legacy.py | 987 +++++++++++++++++++++ scanner_tools.py | 121 +++ setup_manager.py | 68 ++ test_basic.py | 20 + vulnscan_cli.ps1 | 17 + vulnscan_cli.sh | 17 + 25 files changed, 2793 insertions(+), 1272 deletions(-) create mode 100644 .github/workflows/python-app.yml create mode 100644 AI-Remediation-Report.md create mode 100644 README_AGENT.md create mode 100644 Security-Debug-ScanLog create mode 100644 Security-Vulnerability-Report create mode 100644 Security-Vulnerability-Report.json create mode 100644 agent.py create mode 100644 ai_scanner.py create mode 100644 debug_adk.py create mode 100644 gui.py create mode 100644 install_linux.sh create mode 100644 install_mac.sh create mode 100644 install_windows.ps1 create mode 100644 mcp_server.py create mode 100644 requirements.txt create mode 100644 scan_report_scanme.nmap.org.md create mode 100644 scanner_legacy.py create mode 100644 scanner_tools.py create mode 100644 setup_manager.py create mode 100644 test_basic.py create mode 100644 vulnscan_cli.ps1 create mode 100644 vulnscan_cli.sh diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml new file mode 100644 index 0000000..f3d4fca --- /dev/null +++ b/.github/workflows/python-app.yml @@ -0,0 +1,39 @@ +# This workflow will install Python dependencies, run tests and lint with a single version of Python +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python application + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install flake8 pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + pytest diff --git a/AI-Remediation-Report.md b/AI-Remediation-Report.md new file mode 100644 index 0000000..e645a12 --- /dev/null +++ b/AI-Remediation-Report.md @@ -0,0 +1,54 @@ +# pace.edu Security Assessment Remediation Plan + +## Executive Summary + +This report summarizes the findings of a security assessment conducted on pace.edu. Two vulnerabilities were identified. The most critical vulnerability is a successful zone transfer, allowing potential attackers to gain sensitive information and potentially cause a denial-of-service attack. This is classified as a high-severity (severity "h") risk and requires immediate attention. The second finding is an informational alert indicating a lack of IPv6 support, which, while not a direct vulnerability, represents a missed opportunity to enhance security. + +## Vulnerability Details & Remediation + +### 1. Zone Transfer Successful using DNSEnum (Severity: High - "h") + +**Risk:** A successful zone transfer allows unauthorized access to the DNS zone file for pace.edu. This exposes critical information like internal hostnames and IP addresses, which can be used for further attacks, including targeted phishing or denial-of-service attacks. The vulnerability is *not* directly due to OpenSSL, as the report incorrectly links this vulnerability's remediation to an OpenSSL vulnerability description. The underlying issue is misconfigured DNS settings. + +**Remediation:** + +1. **Identify the DNS Server:** Determine which DNS server(s) are responsible for pace.edu. +2. **Access DNS Server Configuration:** Gain administrative access to the DNS server's configuration files (e.g., BIND's named.conf). +3. **Disable Zone Transfers:** Configure the DNS server to explicitly deny zone transfers. The exact method depends on the DNS server software used. For BIND, this typically involves modifying the `allow-transfer` directive in the zone file to restrict access to only authorized IP addresses or to remove this directive entirely. Example (BIND): + + ``` + zone "pace.edu" { + type master; + file "/etc/bind/db.pace.edu"; + allow-transfer { none; }; //Restrict zone transfers + }; + ``` +4. **Verify the Remediation:** After making changes, run `dnsenum` again to confirm that zone transfers are no longer successful. +5. **Regular Audits:** Regularly audit DNS server configurations to ensure security settings remain in place. + +### 2. Missing IPv6 Address (Severity: Informational - "i") + +**Risk:** The absence of an IPv6 address is not a direct security vulnerability but represents a missed opportunity to enhance security and improve network infrastructure. IPv6 offers improved security features, including native support for IPSec. + +**Remediation:** + +1. **Assess IPv6 Readiness:** Evaluate the network infrastructure to determine the feasibility of implementing IPv6. This includes checking for compatibility with existing hardware and software. +2. **Obtain IPv6 Addresses:** Contact your ISP or network provider to request IPv6 address allocation. +3. **Configure Network Devices:** Configure routers, firewalls, and servers to support IPv6. This might involve updating configuration files and enabling IPv6 protocols. Consult the documentation of your specific devices. +4. **Test IPv6 Connectivity:** Verify that all systems and applications are functioning correctly over IPv6 after the implementation. +5. **Monitor and Maintain:** Regularly monitor IPv6 connectivity and performance. Ensure that security protocols (like IPSec, if used) are properly configured for IPv6 traffic. + + +## Preventative Best Practices + +* **Regular Security Audits:** Conduct regular security assessments and penetration testing to identify and address vulnerabilities proactively. +* **Strong Password Policies:** Enforce strong password policies for all accounts with multi-factor authentication (MFA) where applicable. +* **Vulnerability Management:** Implement a vulnerability management system to track and remediate vulnerabilities promptly. +* **Regular Software Updates:** Keep all software and operating systems up-to-date with the latest security patches. +* **Security Information and Event Management (SIEM):** Implement a SIEM system to monitor security logs and detect potential threats in real-time. +* **Firewall Configuration:** Ensure firewalls are properly configured to restrict unauthorized access to network resources. +* **Employee Security Awareness Training:** Educate employees on security best practices to reduce the risk of social engineering attacks. +* **Principle of Least Privilege:** Grant users only the minimum necessary privileges required to perform their job duties. + + +This remediation plan provides a starting point. Further investigation might be necessary depending on the specific environment and the complexity of the systems involved. Always consult official documentation for your specific software and hardware to ensure proper configuration. diff --git a/README.md b/README.md index 8bfc801..10df7f2 100644 --- a/README.md +++ b/README.md @@ -1 +1,63 @@ -# Vulnerability-Scanner \ No newline at end of file +# Vulnerability Scanner Pro 🛡️ + +A next-generation, AI-powered vulnerability scanner that uses **Google Gemini** agents to intelligently analyze targets, run security tools, and interpret results. Now featuring a cross-platform GUI! + +## Features + +- **🤖 AI Agents**: Uses Large Language Models to reason about security findings, not just regex matching. +- **🖥️ Cross-Platform GUI**: Modern, dark-themed interface built with Flet. +- **🔌 Automated Setup**: One-click installers for Windows, Linux, and macOS. +- **📊 Live Reporting**: Real-time tool execution logs and Markdown reports. +- **🛠️ Integrated Tools**: Orchestrates `nmap`, `hydra`, `tshark`, and more. + +## Quick Start (GUI) + +### Windows +1. Right-click `install_windows.ps1` and select **Run with PowerShell**. +2. The scanner will launch automatically. + +### Linux +```bash +chmod +x install_linux.sh +sudo ./install_linux.sh +``` + +### macOS +```bash +chmod +x install_mac.sh +./install_mac.sh +``` + +## CLI Usage + +If you prefer the command line: + +**Linux/Mac**: +```bash +chmod +x vulnscan_cli.sh +./vulnscan_cli.sh [api_key] +``` + +**Windows (PowerShell)**: +```powershell +.\vulnscan_cli.ps1 -Target -Key +``` + +**Direct Python**: +```bash +python scanner.py --key +``` + +## Requirements + +- Python 3.8+ +- Google Gemini API Key +- System Tools (Auto-installed by scripts where possible): + - Nmap + - Hydra + - SearchSploit (ExploitDB) + - TShark (Wireshark) + +## License + +MIT License diff --git a/README_AGENT.md b/README_AGENT.md new file mode 100644 index 0000000..89cedb8 --- /dev/null +++ b/README_AGENT.md @@ -0,0 +1,52 @@ +# AI Security Scanner Agent + +This project has been updated to include an AI Agent that can perform security scans using the `VulnerabilityScanner` tool. + +## Changes + +- **`scanner.py`**: Refactored to include a `VulnerabilityScanner` class. This allows the scanner to be used as a library/tool by other Python scripts while maintaining its command-line functionality. +- **`agent.py`**: A new AI Agent built with the Microsoft Agent Framework. It uses the `VulnerabilityScanner` to perform scans when requested by the user. +- **`requirements.txt`**: Lists the dependencies required for the agent. + +## Setup + +1. Install the dependencies: + + ```bash + pip install -r requirements.txt + ``` + +2. Set up your Model API Key: + - The agent is configured to use GitHub Models (e.g., GPT-4o). + - Set the `GITHUB_TOKEN` environment variable with your API key. + - Alternatively, you can modify `agent.py` to use Azure OpenAI or other providers supported by the Agent Framework. + +## Usage + +### Running the Agent + +Run the agent interactively: + +```bash +python agent.py +``` + +You can then chat with the agent: + +```text +User: Scan example.com +Agent: Starting scan for example.com... +... +``` + +### Running the Scanner (Standalone) + +You can still run the scanner as a standalone script: + +```bash +python scanner.py example.com +``` + +## MCP Support + +The agent is configured to support Model Context Protocol (MCP) tools. You can add MCP tools in the `create_mcp_tools` function in `agent.py`. diff --git a/Security-Debug-ScanLog b/Security-Debug-ScanLog new file mode 100644 index 0000000..c77ac52 --- /dev/null +++ b/Security-Debug-ScanLog @@ -0,0 +1,256 @@ +ASP.Net Misconfiguration - Checks for ASP.Net Misconfiguration. +------------------------ + +--2024-10-01 17:29:00-- http://174.129.60.54/%7C~.aspx +Connecting to 174.129.60.54:80... connected. +HTTP request sent, awaiting response... 404 Not Found +2024-10-01 17:29:01 ERROR 404: Not Found. + + + +Nmap [FREAK] - Checks only for FREAK Vulnerability. +------------------------ + +Starting Nmap 7.93 ( https://nmap.org ) at 2024-10-01 17:29 EDT +Nmap scan report for ec2-174-129-60-54.compute-1.amazonaws.com (174.129.60.54) +Host is up (0.031s latency). + +PORT STATE SERVICE +443/tcp closed https + +Nmap done: 1 IP address (1 host up) scanned in 0.23 seconds + + +Joomla Checker - Checks for Joomla Installation. +------------------------ + +--2024-10-01 17:29:01-- http://174.129.60.54/administrator +Connecting to 174.129.60.54:80... connected. +HTTP request sent, awaiting response... 404 Not Found +2024-10-01 17:29:01 ERROR 404: Not Found. + + + +Nmap - Checks for Remote Desktop Service over UDP +------------------------ + +You requested a scan type which requires root privileges. +QUITTING! + + +Nmap - Checks for MySQL DB +------------------------ + +Starting Nmap 7.93 ( https://nmap.org ) at 2024-10-01 17:29 EDT +Nmap done: 1 IP address (1 host up) scanned in 2.02 seconds + + +Nmap - Checks for IIS WebDAV +------------------------ + +Starting Nmap 7.93 ( https://nmap.org ) at 2024-10-01 17:29 EDT +Nmap scan report for ec2-174-129-60-54.compute-1.amazonaws.com (174.129.60.54) +Host is up (0.042s latency). + +PORT STATE SERVICE +80/tcp open http + +Nmap done: 1 IP address (1 host up) scanned in 0.40 seconds + + +WHOis - Checks for Administrator's Contact Information. +------------------------ + + +# +# ARIN WHOIS data and services are subject to the Terms of Use +# available at: https://www.arin.net/resources/registry/whois/tou/ +# +# If you see inaccuracies in the results, please report at +# https://www.arin.net/resources/registry/whois/inaccuracy_reporting/ +# +# Copyright 1997-2024, American Registry for Internet Numbers, Ltd. +# + + + +# start + +NetRange: 174.129.0.0 - 174.129.255.255 +CIDR: 174.129.0.0/16 +NetName: AMAZON-EC2-5 +NetHandle: NET-174-129-0-0-1 +Parent: NET174 (NET-174-0-0-0-0) +NetType: Direct Allocation +OriginAS: +Organization: Amazon.com, Inc. (AMAZO-4) +RegDate: 2008-08-08 +Updated: 2014-09-03 +Comment: The activity you have detected originates from a +Comment: dynamic hosting environment. +Comment: For fastest response, please submit abuse reports at +Comment: http://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/AWSAbuse +Comment: For more information regarding EC2 see: +Comment: http://ec2.amazonaws.com/ +Comment: All reports MUST include: +Comment: * src IP +Comment: * dest IP (your IP) +Comment: * dest port +Comment: * Accurate date/timestamp and timezone of activity +Comment: * Intensity/frequency (short log extracts) +Comment: * Your contact details (phone and email) +Comment: Without these we will be unable to identify +Comment: the correct owner of the IP address at that +Comment: point in time. +Ref: https://rdap.arin.net/registry/ip/174.129.0.0 + + + +OrgName: Amazon.com, Inc. +OrgId: AMAZO-4 +Address: Amazon Web Services, Inc. +Address: P.O. Box 81226 +City: Seattle +StateProv: WA +PostalCode: 98108-1226 +Country: US +RegDate: 2005-09-29 +Updated: 2022-09-30 +Comment: For details of this service please see +Comment: http://ec2.amazonaws.com +Ref: https://rdap.arin.net/registry/entity/AMAZO-4 + + +OrgRoutingHandle: ARMP-ARIN +OrgRoutingName: AWS RPKI Management POC +OrgRoutingPhone: +1-206-555-0000 +OrgRoutingEmail: aws-rpki-routing-poc@amazon.com +OrgRoutingRef: https://rdap.arin.net/registry/entity/ARMP-ARIN + +OrgTechHandle: ANO24-ARIN +OrgTechName: Amazon EC2 Network Operations +OrgTechPhone: +1-206-555-0000 +OrgTechEmail: amzn-noc-contact@amazon.com +OrgTechRef: https://rdap.arin.net/registry/entity/ANO24-ARIN + +OrgNOCHandle: AANO1-ARIN +OrgNOCName: Amazon AWS Network Operations +OrgNOCPhone: +1-206-555-0000 +OrgNOCEmail: amzn-noc-contact@amazon.com +OrgNOCRef: https://rdap.arin.net/registry/entity/AANO1-ARIN + +OrgRoutingHandle: IPROU3-ARIN +OrgRoutingName: IP Routing +OrgRoutingPhone: +1-206-555-0000 +OrgRoutingEmail: aws-routing-poc@amazon.com +OrgRoutingRef: https://rdap.arin.net/registry/entity/IPROU3-ARIN + +OrgAbuseHandle: AEA8-ARIN +OrgAbuseName: Amazon EC2 Abuse +OrgAbusePhone: +1-206-555-0000 +OrgAbuseEmail: trustandsafety@support.aws.com +OrgAbuseRef: https://rdap.arin.net/registry/entity/AEA8-ARIN + +RTechHandle: ANO24-ARIN +RTechName: Amazon EC2 Network Operations +RTechPhone: +1-206-555-0000 +RTechEmail: amzn-noc-contact@amazon.com +RTechRef: https://rdap.arin.net/registry/entity/ANO24-ARIN + +RNOCHandle: ANO24-ARIN +RNOCName: Amazon EC2 Network Operations +RNOCPhone: +1-206-555-0000 +RNOCEmail: amzn-noc-contact@amazon.com +RNOCRef: https://rdap.arin.net/registry/entity/ANO24-ARIN + +RAbuseHandle: AEA8-ARIN +RAbuseName: Amazon EC2 Abuse +RAbusePhone: +1-206-555-0000 +RAbuseEmail: trustandsafety@support.aws.com +RAbuseRef: https://rdap.arin.net/registry/entity/AEA8-ARIN + +# end + + +# start + +NetRange: 174.129.0.0 - 174.129.255.255 +CIDR: 174.129.0.0/16 +NetName: AMAZON-IAD +NetHandle: NET-174-129-0-0-2 +Parent: AMAZON-EC2-5 (NET-174-129-0-0-1) +NetType: Reallocated +OriginAS: +Organization: Amazon Data Services NoVa (ADSN-1) +RegDate: 2020-04-16 +Updated: 2020-04-16 +Ref: https://rdap.arin.net/registry/ip/174.129.0.0 + + + +OrgName: Amazon Data Services NoVa +OrgId: ADSN-1 +Address: 13200 Woodland Park Road +City: Herndon +StateProv: VA +PostalCode: 20171 +Country: US +RegDate: 2018-04-25 +Updated: 2019-08-02 +Ref: https://rdap.arin.net/registry/entity/ADSN-1 + + +OrgTechHandle: ANO24-ARIN +OrgTechName: Amazon EC2 Network Operations +OrgTechPhone: +1-206-555-0000 +OrgTechEmail: amzn-noc-contact@amazon.com +OrgTechRef: https://rdap.arin.net/registry/entity/ANO24-ARIN + +OrgAbuseHandle: AEA8-ARIN +OrgAbuseName: Amazon EC2 Abuse +OrgAbusePhone: +1-206-555-0000 +OrgAbuseEmail: trustandsafety@support.aws.com +OrgAbuseRef: https://rdap.arin.net/registry/entity/AEA8-ARIN + +OrgNOCHandle: AANO1-ARIN +OrgNOCName: Amazon AWS Network Operations +OrgNOCPhone: +1-206-555-0000 +OrgNOCEmail: amzn-noc-contact@amazon.com +OrgNOCRef: https://rdap.arin.net/registry/entity/AANO1-ARIN + +# end + + + +# +# ARIN WHOIS data and services are subject to the Terms of Use +# available at: https://www.arin.net/resources/registry/whois/tou/ +# +# If you see inaccuracies in the results, please report at +# https://www.arin.net/resources/registry/whois/inaccuracy_reporting/ +# +# Copyright 1997-2024, American Registry for Internet Numbers, Ltd. +# + + + +Nmap - Checks for MS-SQL Server DB +------------------------ + +Starting Nmap 7.93 ( https://nmap.org ) at 2024-10-01 17:29 EDT +Nmap done: 1 IP address (1 host up) scanned in 2.02 seconds + + +Nmap [LOGJAM] - Checks for LOGJAM Vulnerability. +------------------------ + +Starting Nmap 7.93 ( https://nmap.org ) at 2024-10-01 17:29 EDT +Nmap scan report for ec2-174-129-60-54.compute-1.amazonaws.com (174.129.60.54) +Host is up (0.035s latency). + +PORT STATE SERVICE +443/tcp closed https + +Nmap done: 1 IP address (1 host up) scanned in 0.18 seconds + + diff --git a/Security-Vulnerability-Report b/Security-Vulnerability-Report new file mode 100644 index 0000000..0327fd3 --- /dev/null +++ b/Security-Vulnerability-Report @@ -0,0 +1,33 @@ +Host - Checks for existence of IPV6 address. +------------------------ + +/bin/sh: 1: host: Permission denied + + +Host - Checks for existence of IPV6 address. +------------------------ + +/bin/sh: 1: host: Permission denied + + +Host - Checks for existence of IPV6 address. +------------------------ + +/bin/sh: 1: host: Permission denied + + +Nmap - Fast Scan [Only Few Port Checks] +------------------------ + +Starting Nmap 7.93 ( https://nmap.org ) at 2024-10-01 17:29 EDT +Nmap scan report for ec2-174-129-60-54.compute-1.amazonaws.com (174.129.60.54) +Host is up (0.040s latency). +Not shown: 97 filtered tcp ports (no-response), 1 closed tcp port (conn-refused) +Some closed ports may be reported as filtered due to --defeat-rst-ratelimit +PORT STATE SERVICE +22/tcp open ssh +80/tcp open http + +Nmap done: 1 IP address (1 host up) scanned in 1.93 seconds + + diff --git a/Security-Vulnerability-Report.json b/Security-Vulnerability-Report.json new file mode 100644 index 0000000..a81c6c9 --- /dev/null +++ b/Security-Vulnerability-Report.json @@ -0,0 +1,27 @@ +{ + "summary": { + "target": "pace.edu", + "total_checks_run": 31, + "checks_skipped": 0, + "vulnerabilities_found": 2, + "time_elapsed": "1s" + }, + "vulnerabilities": [ + { + "name": "Zone Transfer Successful using DNSEnum. Reconfigure DNS immediately.", + "tool": "dnsenum_zone_transfer", + "severity": "h", + "definition": "Allows remote attackers to cause a denial of service (crash), and possibly obtain sensitive information in applications that use OpenSSL, via a malformed ClientHello handshake message that triggers an out-of-bounds memory access.", + "remediation": " OpenSSL versions 0.9.8h through 0.9.8q and 1.0.0 through 1.0.0c are vulnerable. It is recommended to upgrade the OpenSSL version. More resource and information can be found here. https://www.openssl.org/news/secadv/20110208.txt", + "raw_output": "" + }, + { + "name": "Does not have an IPv6 Address. It is good to have one.", + "tool": "host", + "severity": "i", + "definition": "Not a vulnerability, just an informational alert. The host does not have IPv6 support. IPv6 provides more security as IPSec (responsible for CIA - Confidentiality, Integrity and Availablity) is incorporated into this model. So it is good to have IPv6 Support.", + "remediation": "It is recommended to implement IPv6. More information on how to implement IPv6 can be found from this resource. https://www.cisco.com/c/en/us/solutions/collateral/enterprise/cisco-on-cisco/IPv6-Implementation_CS.html", + "raw_output": "" + } + ] +} \ No newline at end of file diff --git a/agent.py b/agent.py new file mode 100644 index 0000000..72f2577 --- /dev/null +++ b/agent.py @@ -0,0 +1,100 @@ +import asyncio +import os +from typing import Annotated, Any +from agent_framework import ChatAgent, MCPStdioTool, ToolProtocol +from agent_framework.openai import OpenAIChatClient +from openai import AsyncOpenAI +from scanner import VulnerabilityScanner + +# Define the tool that wraps the scanner +def scan_website( + target: Annotated[str, "The URL or domain to scan for vulnerabilities."] +) -> str: + """ + Scans a website for vulnerabilities using the VulnerabilityScanner. + Returns a list of detected vulnerabilities. + """ + print(f"Starting scan for {target}...") + scanner = VulnerabilityScanner() + # We can pass skip_list if needed, for now we scan everything + vulnerabilities = scanner.scan(target, nospinner=True) + + if not vulnerabilities: + return f"No vulnerabilities detected for {target}." + + return f"Vulnerabilities detected for {target}:\n" + "\n".join(vulnerabilities) + +# Define MCP tools (Example configuration) +# This allows the agent to call external tools via MCP. +# You would need to have the MCP servers installed and running or accessible via command. +def create_mcp_tools() -> list[ToolProtocol | Any]: + return [ + # Example: Connect to a local MCP server for file system access or other tools + # MCPStdioTool( + # name="FileSystem MCP", + # description="Provides file system access", + # command="npx", + # args=["-y", "@modelcontextprotocol/server-filesystem", "."] + # ), + # You can add more MCP tools here + ] + +async def main(): + # Configuration for the AI Model + # You can use GitHub Models or Azure OpenAI + # For this example, we assume environment variables are set or you can hardcode them for testing + + api_key = os.getenv("GITHUB_TOKEN") or "YOUR_API_KEY" + endpoint = "https://models.github.ai/inference" + model_id = "gpt-4o" # Replace with your preferred model + + openai_client = AsyncOpenAI( + base_url=endpoint, + api_key=api_key, + ) + + # Create the Chat Client + chat_client = OpenAIChatClient( + async_client=openai_client, + model_id=model_id + ) + + # Combine local tools and MCP tools + tools = [scan_website] + create_mcp_tools() + + # Create the Agent + agent = ChatAgent( + chat_client=chat_client, + name="SecurityScannerAgent", + instructions=""" + You are a security scanning agent. + Your goal is to help users scan websites for vulnerabilities. + You have access to a 'scan_website' tool which runs a comprehensive vulnerability scan. + When a user asks to scan a website, use this tool. + Report the findings clearly. + You can also use other available tools if needed. + """, + tools=tools, + ) + + print("Security Scanner Agent initialized.") + print("You can ask me to scan a website, e.g., 'Scan example.com'") + + # Interactive loop + thread = agent.get_new_thread() + while True: + try: + user_input = input("User: ") + if user_input.lower() in ["exit", "quit"]: + break + + print("Agent: ", end="", flush=True) + async for chunk in agent.run_stream(user_input, thread=thread): + if chunk.text: + print(chunk.text, end="", flush=True) + print("\n") + except KeyboardInterrupt: + break + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/ai_scanner.py b/ai_scanner.py new file mode 100644 index 0000000..62141aa --- /dev/null +++ b/ai_scanner.py @@ -0,0 +1,256 @@ +#!/usr/bin/env python3 +# ai_scanner.py - AI-Powered Vulnerability Scanning Orchestrator + +import os +import sys +import json +import subprocess +import requests +from dotenv import load_dotenv + +load_dotenv() + +# --- Configuration --- +# IMPORTANT: Replace with your Google AI Studio API key or set GEMINI_API_KEY env var +GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY") +if not GEMINI_API_KEY: + GEMINI_API_KEY = os.environ.get("GOOGLE_API_KEY") + +GEMINI_API_URL = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key={GEMINI_API_KEY}" + +# This list must be kept in sync with the `tool_names` in scanner.py +AVAILABLE_SCANS = [ + "host", "aspnet_config_err", "wp_check", "drp_check", "joom_check", + "nmap", "whois", "nmap_header", "nmap_sloris", "sslyze_hbleed", + "nmap_poodle", "nmap_ccs", "nmap_freak", "nmap_logjam", "sslyze_ocsp", + "sslyze_zlib", "sslyze_reneg", "sslyze_resum", "dnsenum_zone_transfer", + "nmap_telnet", "nmap_ftp", "nmap_stuxnet", "nmap_sqlserver", "nmap_mysql", + "nmap_oracle", "nmap_rdp_udp", "nmap_rdp_tcp", "aspnet_elmah_axd", + "nmap_tcp_smb", "nmap_udp_smb", "nmap_iis" +] + +class bcolors: + """Class for terminal colors.""" + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + CYAN = '\033[96m' + +def print_logo(): + """Prints the AI scanner logo.""" + logo = f""" +{bcolors.CYAN} + _ ___ _____ _ + /_\ / __| |_ _|__ _ __ ___ _______| | + / _ \\__ \ | |/ -_) ' \/ -_|_-<_-< | | + /_/ \_\___/ |_|\___|_|_|_\___/__/__/_|_| + {bcolors.HEADER}AI-Powered Vulnerability Scanner{bcolors.ENDC} + """ + print(logo) + +def call_gemini_api(prompt): + """Generic function to call the Gemini API.""" + headers = {'Content-Type': 'application/json'} + payload = {'contents': [{'parts': [{'text': prompt}]}]} + + try: + response = requests.post(GEMINI_API_URL, headers=headers, json=payload) + response.raise_for_status() + + data = response.json() + if 'candidates' in data and data['candidates']: + return data['candidates'][0]['content']['parts'][0]['text'] + else: + # Check for safety ratings or other blocks + if 'promptFeedback' in data and 'blockReason' in data['promptFeedback']: + return f"Error: Prompt was blocked. Reason: {data['promptFeedback']['blockReason']}" + return "Error: Received an empty or invalid response from the API." + + except requests.exceptions.RequestException as e: + return f"Error: API request failed: {e}" + except Exception as e: + return f"An unexpected error occurred: {e}" + + +def parse_command_with_ai(user_input): + """Uses Gemini to parse natural language into a structured command.""" + print(f"{bcolors.OKBLUE}[INFO]{bcolors.ENDC} Asking AI to interpret the command...") + + prompt = f""" + You are an intelligent cybersecurity assistant. Your task is to parse a user's request and convert it into a structured JSON command. + + User request: "{user_input}" + + Available scan types: {json.dumps(AVAILABLE_SCANS)} + + Instructions: + 1. Identify the target domain or IP address from the user's request. + 2. Identify the specific scans the user wants to run. If the user asks for a general scan (e.g., "scan the site", "check for vulnerabilities"), leave the "tests" array empty to signify a full scan. If they mention specific vulnerabilities (e.g., "heartbleed", "poodle") or tools ("nmap", "whois"), map them to the corresponding scan types from the provided list. + 3. Return ONLY a valid JSON object with two keys: "target" (a string) and "tests" (an array of strings). Do not include any other text or explanation. + + Example: + User request: "scan example.com for heartbleed and check whois info" + JSON output: + {{ + "target": "example.com", + "tests": ["sslyze_hbleed", "whois"] + }} + + Example 2: + User request: "do a full vulnerability scan on internal-server.local" + JSON output: + {{ + "target": "internal-server.local", + "tests": [] + }} + """ + + response_text = call_gemini_api(prompt) + + try: + # Clean the response to ensure it's valid JSON + clean_response = response_text.strip().replace("```json", "").replace("```", "").strip() + return json.loads(clean_response) + except json.JSONDecodeError: + print(f"{bcolors.FAIL}[ERROR]{bcolors.ENDC} AI returned an invalid JSON response.") + print("AI Raw Response:", response_text) + return None + +def get_ai_remediation(report_content): + """Uses Gemini to generate an executive summary and remediation steps from a JSON report.""" + print(f"{bcolors.OKBLUE}[INFO]{bcolors.ENDC} Asking AI to analyze the report and provide remediation advice...") + + prompt = f""" + You are a senior cybersecurity analyst. Your task is to analyze the provided JSON vulnerability report and generate a clear, actionable remediation plan. + + JSON Report: + {report_content} + + Instructions: + Generate a report in Markdown format with the following sections: + 1. **Executive Summary**: A high-level overview of the findings, explaining the overall security posture and the most critical risks discovered. + 2. **Vulnerability Details & Remediation**: For each vulnerability in the report, create a subsection. + - Start with the vulnerability name and its severity. + - Clearly explain the risk in simple terms. + - Provide detailed, step-by-step instructions on how to fix the vulnerability. + - Include code snippets or configuration examples where applicable. + 3. **Preventative Best Practices**: Conclude with a list of general security best practices to help prevent similar issues in the future. + + Format the entire output as clean Markdown. + """ + return call_gemini_api(prompt) + +def main(): + """Main function to run the AI scanner.""" + print_logo() + + if "YOUR_GEMINI_API_KEY" in GEMINI_API_KEY: + print(f"{bcolors.FAIL}[FATAL]{bcolors.ENDC} Gemini API key is not configured correctly.") + print("Please edit 'ai_scanner.py' and replace 'YOUR_GEMINI_API_KEY' with your actual key.") + sys.exit(1) + + scanner_path = './scanner.py' + if not os.path.exists(scanner_path): + print(f"{bcolors.FAIL}[FATAL]{bcolors.ENDC} The required 'scanner.py' script was not found in the same directory.") + print("Please make sure both 'ai_scanner.py' and 'scanner.py' are saved in the same folder.") + sys.exit(1) + + # Make sure the scanner script is executable (for Linux/macOS) + if os.name != 'nt': # 'nt' is the name for Windows + if not os.access(scanner_path, os.X_OK): + print(f"{bcolors.WARNING}[WARN]{bcolors.ENDC} '{scanner_path}' is not executable. Attempting to set permissions...") + try: + os.chmod(scanner_path, 0o755) + print(f"{bcolors.OKGREEN}[SUCCESS]{bcolors.ENDC} Set execute permissions on '{scanner_path}'.") + except Exception as e: + print(f"{bcolors.FAIL}[FATAL]{bcolors.ENDC} Could not set execute permissions on '{scanner_path}': {e}") + sys.exit(1) + + try: + user_query = input(f"{bcolors.BOLD}What would you like to scan today? > {bcolors.ENDC}") + except KeyboardInterrupt: + print("\nExiting.") + sys.exit(0) + + command_data = parse_command_with_ai(user_query) + + if not command_data or "target" not in command_data: + print(f"{bcolors.FAIL}[ERROR]{bcolors.ENDC} Could not understand the command. Please try again.") + return + + target = command_data.get("target") + tests = command_data.get("tests", []) + + print(f"{bcolors.OKBLUE}[INFO]{bcolors.ENDC} AI has interpreted the command:") + print(f" - {bcolors.BOLD}Target:{bcolors.ENDC} {target}") + if tests: + print(f" - {bcolors.BOLD}Specific Tests:{bcolors.ENDC} {', '.join(tests)}") + else: + print(f" - {bcolors.BOLD}Tests:{bcolors.ENDC} Full Scan") + + print("-" * 50) + print(f"{bcolors.OKBLUE}[INFO]{bcolors.ENDC} Starting the vulnerability scan...") + + # --- FIX STARTS HERE --- + # Explicitly call the python interpreter to run the scanner script. + # This makes the call cross-platform (works on Windows, Linux, macOS). + # sys.executable gives the path to the current python interpreter. + run_args = [sys.executable, scanner_path, target, '--nospinner', '--output', 'json'] + # --- FIX ENDS HERE --- + + if tests: + run_args.append('--tests') + run_args.extend(tests) + + try: + # The scanner script will print its progress to the console + # We capture stderr to check for errors from the scanner itself. + result = subprocess.run(run_args, check=True, capture_output=True, text=True) + if result.stderr: + print(f"{bcolors.WARNING}[SCANNER-WARN]{bcolors.ENDC} {result.stderr}") + + except FileNotFoundError: + print(f"{bcolors.FAIL}[FATAL]{bcolors.ENDC} The '{scanner_path}' script was not found or python is not in your PATH.") + sys.exit(1) + except subprocess.CalledProcessError as e: + print(f"{bcolors.FAIL}[ERROR]{bcolors.ENDC} The scanner script failed with exit code {e.returncode}.") + # Print the error output from the scanner script for debugging + print(f"{bcolors.FAIL}--- Scanner Error Output ---{bcolors.ENDC}") + print(e.stderr) + print(f"{bcolors.FAIL}--- End Scanner Error Output ---{bcolors.ENDC}") + return + except KeyboardInterrupt: + print("\nScan interrupted by user. Exiting.") + sys.exit(0) + + print(f"{bcolors.OKGREEN}[SUCCESS]{bcolors.ENDC} Scanner has finished.") + print("-" * 50) + + # Read the JSON report + report_file = 'Security-Vulnerability-Report.json' + try: + with open(report_file, 'r') as f: + report_data = f.read() + except FileNotFoundError: + print(f"{bcolors.FAIL}[ERROR]{bcolors.ENDC} Could not find the report file: {report_file}") + print("This might happen if the scan found no vulnerabilities.") + return + + # Get AI-powered remediation advice + remediation_advice = get_ai_remediation(report_data) + + print(f"\n{bcolors.HEADER}--- AI-Enhanced Remediation Report ---{bcolors.ENDC}\n") + print(remediation_advice) + + # Save the AI report + ai_report_file = 'AI-Remediation-Report.md' + with open(ai_report_file, 'w') as f: + f.write(remediation_advice) + print(f"\n{bcolors.OKGREEN}[SUCCESS]{bcolors.ENDC} AI remediation report saved to '{ai_report_file}'.") + +if __name__ == "__main__": + main() diff --git a/debug_adk.py b/debug_adk.py new file mode 100644 index 0000000..8c11d5a --- /dev/null +++ b/debug_adk.py @@ -0,0 +1,34 @@ +import sys +import os +import importlib.util + +print(f"Python: {sys.executable}") +print(f"Propagated Path: {sys.path}") + +# Check API Key Import +try: + if os.path.exists("ai_scanner.py"): + print("ai_scanner.py found.") + spec = importlib.util.spec_from_file_location("ai_scanner", "ai_scanner.py") + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + key = getattr(mod, "GEMINI_API_KEY", None) + print(f"Extracted Key: {key}") + else: + print("ai_scanner.py NOT found.") +except Exception as e: + print(f"Error importing ai_scanner: {e}") + +# Check ADK +try: + import google.adk + print(f"google.adk imported: {google.adk.__file__}") + print(dir(google.adk)) +except ImportError as e: + print(f"Failed to import google.adk: {e}") + +try: + from google.adk.agents.llm_agent import Agent + print("Agent imported successfully.") +except ImportError as e: + print(f"Failed to import Agent: {e}") diff --git a/gui.py b/gui.py new file mode 100644 index 0000000..016a378 --- /dev/null +++ b/gui.py @@ -0,0 +1,283 @@ + +import flet as ft +import os +import sys +import threading +import time +from setup_manager import SetupManager + +# Try to import Agent tools +try: + import scanner_tools + from scanner_tools import ALL_TOOLS +except ImportError: + ALL_TOOLS = [] + +try: + from google.adk.agents.llm_agent import Agent +except ImportError: + Agent = None + +class ScannerGUI: + def __init__(self, page: ft.Page): + self.page = page + self.page.title = "Vulnerability Scanner Pro" + self.page.theme_mode = ft.ThemeMode.DARK + self.page.padding = 20 + self.setup_manager = SetupManager() + self.scan_thread = None + self.is_scanning = False + + # --- UI Elements --- + self.target_input = ft.TextField(label="Target IP/URL", hint_text="scanme.nmap.org", expand=True) + self.api_key_input = ft.TextField(label="Gemini API Key", password=True, can_reveal_password=True, expand=True) + + self.start_btn = ft.ElevatedButton("Start Security Scan", on_click=self.start_scan_click, icon=ft.Icons.SECURITY) + self.stop_btn = ft.ElevatedButton("Stop", on_click=self.stop_scan_click, icon=ft.Icons.STOP, disabled=True, color=ft.colors.RED_400) + + self.log_view = ft.ListView(expand=True, spacing=10, auto_scroll=True) + self.report_view = ft.Markdown(selectable=True, extension_set=ft.MarkdownExtensionSet.GITHUB_WEB) + + self.tabs = ft.Tabs( + selected_index=0, + animation_duration=300, + tabs=[ + ft.Tab(text="Scanner", icon=ft.Icons.RADAR), + ft.Tab(text="Report", icon=ft.Icons.ARTICLE), + ft.Tab(text="Tools & Settings", icon=ft.Icons.SETTINGS), + ], + expand=True, + ) + + # Tool Status UI + self.tool_status_col = ft.Column() + + # Build Main Layout + self.scanner_tab_content = ft.Column([ + ft.Row([self.target_input, self.api_key_input]), + ft.Row([self.start_btn, self.stop_btn]), + ft.Divider(), + ft.Text("Live Scan Log:", weight=ft.FontWeight.BOLD), + ft.Container( + content=self.log_view, + border=ft.border.all(1, ft.colors.OUTLINE), + border_radius=10, + padding=10, + expand=True, + bgcolor=ft.colors.BLACK12 + ) + ], expand=True) + + self.report_tab_content = ft.Column([ + ft.Text("Final Vulnerability Report", size=20, weight=ft.FontWeight.BOLD), + ft.Container( + content=self.report_view, + expand=True, + padding=20, + border=ft.border.all(1, ft.colors.OUTLINE), + border_radius=10 + ) + ], expand=True, visible=False) # Initially hidden until report available? No, just empty. + + self.settings_tab_content = ft.Column([ + ft.Text("System Tools Status", size=20, weight=ft.FontWeight.BOLD), + self.tool_status_col, + ft.ElevatedButton("Refresh Status", on_click=self.refresh_tools_click) + ], scroll=ft.ScrollMode.AUTO) + + self.tabs.tabs[0].content = self.scanner_tab_content + self.tabs.tabs[1].content = self.report_tab_content + self.tabs.tabs[2].content = self.settings_tab_content + + self.page.add(self.tabs) + + # Initial checks + self.check_env_key() + self.refresh_tools() + + def check_env_key(self): + env_key = os.environ.get("GEMINI_API_KEY") or os.environ.get("GOOGLE_API_KEY") + if env_key: + self.api_key_input.value = env_key + else: + self.show_api_configuration_dialog() + + def show_api_configuration_dialog(self): + self.api_config_input = ft.TextField(label="Enter Gemini API Key", password=True, can_reveal_password=True) + + def save_key(e): + if self.api_config_input.value: + os.environ["GOOGLE_API_KEY"] = self.api_config_input.value + self.api_key_input.value = self.api_config_input.value + self.page.close(self.api_dlg) + self.page.update() + self.append_log("API Key Configured!", ft.colors.GREEN) + + self.api_dlg = ft.AlertDialog( + modal=True, + title=ft.Text("Welcome to Vulnerability Scanner Pro"), + content=ft.Column([ + ft.Text("Please configure your Google Gemini API Key to continue."), + ft.Text("Don't have a key?"), + ft.TextButton("Get it from Google AI Studio", url="https://aistudio.google.com/app/apikey"), + self.api_config_input + ], height=150), + actions=[ + ft.TextButton("Configure", on_click=save_key), + ], + actions_alignment=ft.MainAxisAlignment.END, + ) + + self.page.open(self.api_dlg) + + + def refresh_tools(self, e=None): + self.tool_status_col.controls.clear() + + for tool in self.setup_manager.tools: + exists = self.setup_manager.check_tool(tool) + icon = ft.Icons.CHECK_CIRCLE if exists else ft.Icons.ERROR + color = ft.colors.GREEN if exists else ft.colors.RED + status_text = "Installed" if exists else "Missing" + + row = ft.Row([ + ft.Icon(icon, color=color), + ft.Text(f"{tool.title()}: {status_text}", size=16, weight=ft.FontWeight.W_500), + ft.ElevatedButton("Install", data=tool, on_click=self.install_tool_click, visible=not exists) + ]) + self.tool_status_col.controls.append(row) + + if e: self.page.update() + + def install_tool_click(self, e): + tool = e.control.data + e.control.text = "Installing..." + e.control.disabled = True + self.page.update() + + # Run install in thread to not block UI + def _install(): + success, msg = self.setup_manager.install_tool(tool) + self.append_log(f"Installer: {msg}", color=ft.colors.CYAN) + self.refresh_tools() + self.page.update() + + threading.Thread(target=_install, daemon=True).start() + + def append_log(self, message: str, color: str = None): + if not color: color = ft.colors.WHITE + self.log_view.controls.append(ft.Text(message, color=color, selectable=True)) + self.page.update() + + def set_scanning_state(self, is_running): + self.is_scanning = is_running + self.start_btn.disabled = is_running + self.stop_btn.disabled = not is_running + self.target_input.disabled = is_running + self.api_key_input.disabled = is_running + self.page.update() + + def stop_scan_click(self, e): + # Graceful stop is hard with simple threads without flags in the agent, + # but we'll minimally disable the flag. + self.is_scanning = False + self.append_log("Stop requested...", color=ft.colors.RED) + + def start_scan_click(self, e): + target = self.target_input.value + api_key = self.api_key_input.value + + if not target: + self.append_log("Error: Target is required.", ft.colors.RED) + return + if not api_key: + self.append_log("Error: API Key is required.", ft.colors.RED) + return + + os.environ["GOOGLE_API_KEY"] = api_key + + if not Agent: + self.append_log("Error: Google ADK (Agent) library not found.", ft.colors.RED) + return + + self.log_view.controls.clear() + self.report_view.value = "" + self.set_scanning_state(True) + + self.scan_thread = threading.Thread(target=self.run_scanner, args=(target,), daemon=True) + self.scan_thread.start() + + def run_scanner(self, target): + self.append_log(f"Initializing Agent for target: {target}...", ft.colors.PURPLE_200) + + instruction = f""" + You are an advanced Security Agent. + Target: {target} + Mission: + 1. Perform Reconnaissance (DNS, Nmap Fast). + 2. Analyze findings for Critical Risks. + 3. If Web ports open, checks headers. + 4. If Exploits found matching services, list them. + 5. Produce a comprehensive report. + Style: Professional, Concise, Actionable. + """ + + try: + agent = Agent( + model='gemini-1.5-flash', + name='scanner_gui_agent', + instruction=instruction, + tools=ALL_TOOLS + ) + + self.append_log("Agent Initialized. Starting workflow...", ft.colors.GREEN) + + final_output = "" + + for event in agent.run_live(): + if not self.is_scanning: + self.append_log("Scan aborted by user.", ft.colors.RED) + break + + # Heuristics for UI updates + if hasattr(event, 'tool_calls') and event.tool_calls: + tname = event.tool_calls[0].function.name + self.append_log(f"➜ Executing Tool: {tname}", ft.colors.CYAN_200) + + if hasattr(event, 'content') and event.content: + chunk = str(event.content) + # We don't want to spam logs with every char, maybe accumulate? + # For now, let's just log "Agent is thinking..." if needed, + # or actually build the final report. + final_output += chunk + # Live updating the report view might be cool but jumpy. + # Let's just keep accumulating. + + if "Final Report" in final_output: + # Maybe detect end? + pass + + self.append_log("Scan Completed.", ft.colors.GREEN) + + # Show report + self.report_view.value = final_output + self.tabs.selected_index = 1 # Switch to report tab + self.page.update() + + # Save report + fname = f"scan_report_{target}.md" + with open(fname, "w") as f: + f.write(final_output) + self.append_log(f"Report saved to {fname}", ft.colors.GREY) + + except Exception as e: + self.append_log(f"Error during scan: {str(e)}", ft.colors.RED) + finally: + self.set_scanning_state(False) + +def main(page: ft.Page): + ScannerGUI(page) + +if __name__ == "__main__": + ft.app(target=main) + diff --git a/install_linux.sh b/install_linux.sh new file mode 100644 index 0000000..d561193 --- /dev/null +++ b/install_linux.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +echo "[*] Checking Linux Dependencies..." + +if [ "$EUID" -ne 0 ] + then echo "[!] Please run as root (sudo ./install_linux.sh) to install system tools." + exit +fi + +echo "[*] Updating apt..." +apt-get update + +echo "[*] Installing Security Tools (nmap, hydra, exploitdb, tshark)..." +# tshark might ask for input, DEBIAN_FRONTEND=noninteractive helps +DEBIAN_FRONTEND=noninteractive apt-get install -y python3 python3-pip nmap hydra exploitdb tshark + +echo "[*] Installing Python Dependencies..." +# Install in user space or system-wide? Let's assume system for simplicity in this wrapper context or create venv. +# Better to be safe and just run pip for the current user if possible, but we are root. +pip3 install -r requirements.txt --break-system-packages + +echo "[*] Dependencies Installed." +echo "[*] Launching GUI..." + +# Drop root for GUI usually? Flet might need X11 access. +# It's better to tell user to run gui.py as normal user. +echo "--------------------------------------------------------" +echo "Installation Done. To run the GUI, execute:" +echo " python3 gui.py" +echo "--------------------------------------------------------" +echo "Launching now (warning: running as root)..." +python3 gui.py diff --git a/install_mac.sh b/install_mac.sh new file mode 100644 index 0000000..acf6180 --- /dev/null +++ b/install_mac.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +echo "[*] Checking macOS Dependencies..." + +if ! command -v brew &> /dev/null; then + echo "[!] Homebrew not found. Please install it from https://brew.sh/" + exit 1 +fi + +echo "[*] Updating Homebrew..." +brew update + +echo "[*] Installing Security Tools..." +brew install nmap hydra exploitdb wireshark python3 + +echo "[*] Installing Python Dependencies..." +pip3 install -r requirements.txt --break-system-packages + +echo "[*] Launching GUI..." +python3 gui.py diff --git a/install_windows.ps1 b/install_windows.ps1 new file mode 100644 index 0000000..4a16976 --- /dev/null +++ b/install_windows.ps1 @@ -0,0 +1,20 @@ +Write-Host "Checking System Requirements..." -ForegroundColor Cyan + +# check python +if (-not (Get-Command python -ErrorAction SilentlyContinue)) { + Write-Host "Python not found. Please install Python 3.9+ from python.org or the Microsoft Store." -ForegroundColor Red + exit +} + +Write-Host "Installing Python Dependencies..." -ForegroundColor Cyan +pip install -r requirements.txt + +# Attempt to install Winget tools (Optional but helpful) +Write-Host "Checking for External Tools. (You might need to approve UAC prompts)..." -ForegroundColor Cyan +Write-Host "Attempting to install Nmap via Winget..." +winget install Insecure.Nmap --accept-package-agreements --accept-source-agreements + +Write-Host "Installation Complete." -ForegroundColor Green +Write-Host "Launching GUI..." -ForegroundColor Green + +python gui.py diff --git a/mcp_server.py b/mcp_server.py new file mode 100644 index 0000000..45c0b9d --- /dev/null +++ b/mcp_server.py @@ -0,0 +1,82 @@ + +import os +import sys +import importlib.util +from mcp.server.fastmcp import FastMCP + +# Add current dir to path to import scanner_tools +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +try: + import scanner_tools +except ImportError: + print("Error: scanner_tools.py not found. Please ensure it is in the same directory.") + sys.exit(1) + +# Initialize FastMCP Server +mcp = FastMCP("Vulnerability Scanner Agent") + +# --- Register Tools --- + +@mcp.tool() +def nmap_scan(args: str, target: str) -> str: + """ + Runs an Nmap scan against the target. + Args: + args: Nmap arguments strings (e.g., '-F', '-p80 -sV'). + target: IP address or hostname. + """ + return scanner_tools.nmap_scan(args, target) + +@mcp.tool() +def check_dns(target: str) -> str: + """ + Checks for DNS records (A, AAAA, MX, NS). + Args: + target: Hostname to check. + """ + return scanner_tools.check_dns(target) + +@mcp.tool() +def analyze_web_headers(url: str) -> str: + """ + Fetches HTTP headers from a URL to check for security configurations. + Args: + url: The URL to check. + """ + return scanner_tools.analyze_web_headers(url) + +@mcp.tool() +def search_exploit_db(query: str) -> str: + """ + Searches ExploitDB/SearchSploit for known exploits. + Args: + query: The search term. + """ + return scanner_tools.search_exploit_db(query) + +@mcp.tool() +def run_hydra(target: str, service: str, user: str = "admin") -> str: + """ + Runs Hydra to brute-force a service (WARNING: Intrusive). + Args: + target: IP address. + service: Protocol (ssh, ftp, telnet, rd). + user: Username to test. + """ + return scanner_tools.run_hydra(target, service, user) + +@mcp.tool() +def packet_capture(interface: str = "any", duration: int = 10) -> str: + """ + Captures network packets using TShark. + Args: + interface: Network interface. + duration: Seconds to capture. + """ + return scanner_tools.packet_capture(interface, duration) + +if __name__ == "__main__": + # Run the server + print("Starting MCP Server...", file=sys.stderr) + mcp.run() diff --git a/monitor.py b/monitor.py index 8cfc2c9..7f00075 100644 --- a/monitor.py +++ b/monitor.py @@ -1,72 +1,74 @@ -import socket - import time - import datetime - import os - import sys - - LOG_FNAME = "network.log" - FILE = os.path.join(os.getcwd(), LOG_FNAME) - def send_ping_request(host="192.168.29.200", port=1025, timeout=3): - try: - socket.setdefaulttimeout(timeout) - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((host,port)) - except OSError as error: - return False - else: - s.close() - return True - def write_permission_check(): - try: - with open(FILE, "a") as file: - pass - except OSError as error: - print("Log file creation failed") - sys.exit() - finally: - pass - def calculate_time(start, stop): - time_difference = stop - start - seconds = float(str(time_difference.total_seconds())) - return str(datetime.timedelta(seconds=seconds)).split(".")[0] - def mon_net_connection(ping_freq=2): - monitor_start_time = datetime.datetime.now() - motd = "Network connection monitoring started at: " + str(monitor_start_time).split(".")[0] + " Sending ping request in " + str(ping_freq) + " seconds" - print(motd) - - with open(FILE, "a") as file: - file.write("\n") - file.write(motd + "\n") +import os +import logging +import time +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +import psutil + +# Configure logging +logging.basicConfig(filename='monitor.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +class MonitorHandler(FileSystemEventHandler): + def on_modified(self, event): + logging.info(f'File modified: {event.src_path}') + # Add more specific logic if needed + + def on_created(self, event): + logging.info(f'File created: {event.src_path}') + # Add more specific logic if needed + + def on_deleted(self, event): + logging.info(f'File deleted: {event.src_path}') + # Add more specific logic if needed + +def monitor_files(path): + event_handler = MonitorHandler() + observer = Observer() + observer.schedule(event_handler, path, recursive=True) + observer.start() + logging.info(f'Started monitoring {path}') + + try: while True: - if send_ping_request(): - time.sleep(ping_freq) - else: - down_time = datetime.datetime.now() - fail_msg = "Network Connection Unavailable at: " + str(down_time).split(".")[0] - print(fail_msg) - with open(FILE, "a") as file: - file.write(fail_msg + "\n") - i = 0 - while not send_ping_request(): - time.sleep(1) - i += 1 - if i >= 3600: - i = 0 - now = datetime.datetime.now() - continous_message = "Network Unavailabilty Persistent at: " + str(now).split(".")[0] - print(continous_message) - with open(FILE, "a") as file: - file.write(continous_message + "\n") - up_time = datetime.datetime.now() - uptime_message = "Network Connectivity Restored at: " + str(up_time).split(".")[0] - - down_time = calculate_time(down_time, up_time) - _m = "Network Connection was Unavailable for " + down_time - - print(uptime_message) - print(_m) - - with open(FILE, "a") as file: - file.write(uptime_message + "\n") - file.write(_m + "\n") - mon_net_connection() + time.sleep(1) + except KeyboardInterrupt: + observer.stop() + observer.join() + +def monitor_network(): + logging.info('Starting network activity monitoring...') + while True: + connections = psutil.net_connections() + for conn in connections: + if conn.status == 'ESTABLISHED': + logging.info(f'Established connection from {conn.laddr} to {conn.raddr}') + time.sleep(5) + +def monitor_processes(): + logging.info('Starting process activity monitoring...') + existing_pids = psutil.pids() + while True: + current_pids = psutil.pids() + new_pids = set(current_pids) - set(existing_pids) + for pid in new_pids: + try: + process = psutil.Process(pid) + logging.info(f'New process created: {process.name()} (PID: {pid})') + except psutil.NoSuchProcess: + pass + existing_pids = current_pids + time.sleep(5) + +def main(): + # Read configuration from a file or environment variables if needed + path_to_monitor = os.getenv('MONITOR_PATH', '.') + + # Start monitoring + logging.info('Starting the monitoring system...') + monitor_files(path_to_monitor) + monitor_network() + monitor_processes() + +if __name__ == '__main__': + main() + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5f7684b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +google-generativeai +rich +requests +dnspython +beautifulsoup4 +flet +agent-framework-azure-ai +openai +python-dotenv diff --git a/scan_report_scanme.nmap.org.md b/scan_report_scanme.nmap.org.md new file mode 100644 index 0000000..fc9355a --- /dev/null +++ b/scan_report_scanme.nmap.org.md @@ -0,0 +1,20 @@ +# Scan Report: scanme.nmap.org + +AI Analysis Failed: 404 models/gemini-3.0-pro-preview is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods. + +## Raw Findings +### Missing X-XSS-Protection (medium) +**Tool**: requests +**Description**: Header missing +**Remediation**: Enable X-XSS-Protection: 1; mode=block + +### Server Header Leak (low) +**Tool**: requests +**Description**: Server reveals: Apache/2.4.7 (Ubuntu) +**Remediation**: Obfuscate Server header. + +### Open Ports (info) +**Tool**: nmap +**Description**: Nmap detected Open Ports +**Remediation**: Check vendor updates. + diff --git a/scanner.py b/scanner.py index a0ad176..e1c20aa 100644 --- a/scanner.py +++ b/scanner.py @@ -1,1219 +1,129 @@ -# Description: This scanner automates the process of security scanning by using a -# multitude of available linux security tools and some custom scripts. -# - -# Importing the libraries -import sys +# --- Imports --- import argparse -import subprocess import os -import time -import random -import threading -import re -import random -from urllib.parse import urlsplit - - -CURSOR_UP_ONE = '\x1b[1A' -ERASE_LINE = '\x1b[2K' - -# Scan Time Elapser -intervals = ( - ('h', 3600), - ('m', 60), - ('s', 1), - ) -def display_time(seconds, granularity=3): - result = [] - seconds = seconds + 1 - for name, count in intervals: - value = seconds // count - if value: - seconds -= value * count - result.append("{}{}".format(value, name)) - return ' '.join(result[:granularity]) - - -def terminal_size(): - try: - rows, columns = subprocess.check_output(['stty', 'size']).split() - return int(columns) - except subprocess.CalledProcessError as e: - return int(20) - - - -def url_maker(url): - if not re.match(r'http(s?)\:', url): - url = 'http://' + url - parsed = urlsplit(url) - host = parsed.netloc - if host.startswith('www.'): - host = host[4:] - return host - -def check_internet(): - os.system('ping -c1 github.com > rs_net 2>&1') - if "0% packet loss" in open('rs_net').read(): - val = 1 - else: - val = 0 - os.system('rm rs_net > /dev/null 2>&1') - return val - - -# Initializing the color module class -class bcolors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - BADFAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - - BG_ERR_TXT = '\033[41m' # For critical errors and crashes - BG_HEAD_TXT = '\033[100m' - BG_ENDL_TXT = '\033[46m' - BG_CRIT_TXT = '\033[45m' - BG_HIGH_TXT = '\033[41m' - BG_MED_TXT = '\033[43m' - BG_LOW_TXT = '\033[44m' - BG_INFO_TXT = '\033[42m' - - BG_SCAN_TXT_START = '\x1b[6;30;42m' - BG_SCAN_TXT_END = '\x1b[0m' - - -# Classifies the Vulnerability's Severity -def vul_info(val): - result ='' - if val == 'c': - result = bcolors.BG_CRIT_TXT+" critical "+bcolors.ENDC - elif val == 'h': - result = bcolors.BG_HIGH_TXT+" high "+bcolors.ENDC - elif val == 'm': - result = bcolors.BG_MED_TXT+" medium "+bcolors.ENDC - elif val == 'l': - result = bcolors.BG_LOW_TXT+" low "+bcolors.ENDC - else: - result = bcolors.BG_INFO_TXT+" info "+bcolors.ENDC - return result - -# Legends -proc_high = bcolors.BADFAIL + "●" + bcolors.ENDC -proc_med = bcolors.WARNING + "●" + bcolors.ENDC -proc_low = bcolors.OKGREEN + "●" + bcolors.ENDC - -# Links the vulnerability with threat level and remediation database -def vul_remed_info(v1,v2,v3): - print(bcolors.BOLD+"Vulnerability Threat Level"+bcolors.ENDC) - print("\t"+vul_info(v2)+" "+bcolors.WARNING+str(tool_resp[v1][0])+bcolors.ENDC) - print(bcolors.BOLD+"Vulnerability Definition"+bcolors.ENDC) - print("\t"+bcolors.BADFAIL+str(tools_fix[v3-1][1])+bcolors.ENDC) - print(bcolors.BOLD+"Vulnerability Remediation"+bcolors.ENDC) - print("\t"+bcolors.OKGREEN+str(tools_fix[v3-1][2])+bcolors.ENDC) - - -# scanner Help Context -def helper(): - print(bcolors.OKBLUE+"Information:"+bcolors.ENDC) - print("------------") - print("\t./scanner.py example.com: Scans the domain example.com.") - print("\t./scanner.py example.com --skip dmitry --skip theHarvester: Skip the 'dmitry' and 'theHarvester' tests.") - print("\t./scanner.py example.com --nospinner: Disable the idle loader/spinner.") - print("\t./scanner.py --update : Updates the scanner to the latest version.") - print("\t./scanner.py --help : Displays this help context.") - print(bcolors.OKBLUE+"Interactive:"+bcolors.ENDC) - print("------------") - print("\tCtrl+C: Skips current test.") - print("\tCtrl+Z: Quits scanner.") - print(bcolors.OKBLUE+"Legends:"+bcolors.ENDC) - print("--------") - print("\t["+proc_high+"]: Scan process may take longer times (not predictable).") - print("\t["+proc_med+"]: Scan process may take less than 10 minutes.") - print("\t["+proc_low+"]: Scan process may take less than a minute or two.") - print(bcolors.OKBLUE+"Vulnerability Information:"+bcolors.ENDC) - print("--------------------------") - print("\t"+vul_info('c')+": Requires immediate attention as it may lead to compromise or service unavailability.") - print("\t"+vul_info('h')+" : May not lead to an immediate compromise, but there are considerable chances for probability.") - print("\t"+vul_info('m')+" : Attacker may correlate multiple vulnerabilities of this type to launch a sophisticated attack.") - print("\t"+vul_info('l')+" : Not a serious issue, but it is recommended to tend to the finding.") - print("\t"+vul_info('i')+" : Not classified as a vulnerability, simply an useful informational alert to be considered.\n") - - -# Clears Line -def clear(): - sys.stdout.write("\033[F") - sys.stdout.write("\033[K") #clears until EOL - -# scanner Logo -def logo(): - print(bcolors.WARNING) - logo_ascii = """ - - █▀ █▀▀ █▀▀ █░█ █▀█ █ ▀█▀ █▄█   █▀ █▀▀ ▄▀█ █▄░█ █▄░█ █▀▀ █▀█ - ▄█ ██▄ █▄▄ █▄█ █▀▄ █ ░█░ ░█░   ▄█ █▄▄ █▀█ █░▀█ █░▀█ ██▄ █▀▄ - """+bcolors.ENDC+"""(The Multi-Tool Vulnerability Scanner) +import sys +import importlib.util +from rich.console import Console +from rich.panel import Panel +from rich.markdown import Markdown +from rich.progress import Progress, SpinnerColumn, TextColumn, TimeElapsedColumn + +# Import Tools +try: + import scanner_tools + from scanner_tools import ALL_TOOLS +except ImportError: + print("[!] Error: scanner_tools.py not found.") + sys.exit(1) - Check out our new software, """+bcolors.BG_LOW_TXT+"""NetBot"""+bcolors.ENDC+""" for simulating DDoS attacks - https://github.com/skavngr/netbot - """ - print(logo_ascii) - print(bcolors.ENDC) +try: + from google.adk.agents.llm_agent import Agent +except ImportError: + Agent = None + print("[!] Warning: Google ADK not found.") +console = Console() -# Initiliazing the idle loader/spinner class -class Spinner: - busy = False - delay = 0.005 # 0.05 +def get_api_key(): + # ... (Same logic as before, can import or duplicate) + return os.environ.get("GEMINI_API_KEY") - @staticmethod - def spinning_cursor(): - while 1: - #for cursor in '|/-\\/': yield cursor #←↑↓→ - #for cursor in '←↑↓→': yield cursor - #for cursor in '....scanning...please..wait....': yield cursor - for cursor in ' ': yield cursor - def __init__(self, delay=None): - self.spinner_generator = self.spinning_cursor() - if delay and float(delay): self.delay = delay - self.disabled = False +class ScannerCLI: + def __init__(self, target, api_key): + self.target = target + self.api_key = api_key + if api_key: os.environ["GOOGLE_API_KEY"] = api_key - def spinner_task(self): - inc = 0 - try: - while self.busy: - if not self.disabled: - x = bcolors.BG_SCAN_TXT_START+next(self.spinner_generator)+bcolors.BG_SCAN_TXT_END - inc = inc + 1 - print(x,end='') - if inc>random.uniform(0,terminal_size()): #30 init - print(end="\r") - bcolors.BG_SCAN_TXT_START = '\x1b[6;30;'+str(round(random.uniform(40,47)))+'m' - inc = 0 - sys.stdout.flush() - time.sleep(self.delay) - if not self.disabled: - sys.stdout.flush() + def run(self): + # Modern Header + console.print(Panel(f"[bold cyan]🚀 Next-Gen Scanner[/bold cyan]\n[dim]Target: {self.target} | MCP-Ready Agent[/dim]", border_style="cyan")) - except (KeyboardInterrupt, SystemExit): - print("\n\t"+ bcolors.BG_ERR_TXT+"scanner received a series of Ctrl+C hits. Quitting..." +bcolors.ENDC) - sys.exit(1) + if not Agent: + console.print("[red]ADK Agent not available.[/red]") + return - def start(self): - self.busy = True - try: - threading.Thread(target=self.spinner_task).start() - except Exception as e: - print("\n") + # Instruction - Optimized for autonomy + instruction = f""" + You are an advanced Security Agent. + Target: {self.target} + + Mission: + 1. Perform Reconnaissance (DNS, Nmap Fast). + 2. Analyze findings for Critical Risks. + 3. If Web ports open, checks headers. + 4. If Exploits found matching services, list them. + 5. Produce a comprehensive report. + + Style: Professional, Concise, Actionable. + """ - def stop(self): try: - self.busy = False - time.sleep(self.delay) - except (KeyboardInterrupt, SystemExit): - print("\n\t"+ bcolors.BG_ERR_TXT+"scanner received a series of Ctrl+C hits. Quitting..." +bcolors.ENDC) - sys.exit(1) - -# End ofloader/spinner class - -# Instantiating the spinner/loader class -spinner = Spinner() - - - -# Scanners that will be used and filename rotation (default: enabled (1)) -tool_names = [ - #1 - ["host","Host - Checks for existence of IPV6 address.","host",1], - - #2 - ["aspnet_config_err","ASP.Net Misconfiguration - Checks for ASP.Net Misconfiguration.","wget",1], - - #3 - ["wp_check","WordPress Checker - Checks for WordPress Installation.","wget",1], - - #4 - ["drp_check", "Drupal Checker - Checks for Drupal Installation.","wget",1], - - #5 - ["joom_check", "Joomla Checker - Checks for Joomla Installation.","wget",1], - - #7 - ["wafw00f","Wafw00f - Checks for Application Firewalls.","wafw00f",1], - - #8 - ["nmap","Nmap - Fast Scan [Only Few Port Checks]","nmap",1], - - #9 - ["theHarvester","The Harvester - Scans for emails using Google's passive search.","theHarvester",1], - - #10 - ["dnsrecon","DNSRecon - Attempts Multiple Zone Transfers on Nameservers.","dnsrecon",1], - - #13 - ["whois","WHOis - Checks for Administrator's Contact Information.","whois",1], - - #14 - ["nmap_header","Nmap [XSS Filter Check] - Checks if XSS Protection Header is present.","nmap",1], - - #15 - ["nmap_sloris","Nmap [Slowloris DoS] - Checks for Slowloris Denial of Service Vulnerability.","nmap",1], - - #16 - ["sslyze_hbleed","SSLyze - Checks only for Heartbleed Vulnerability.","sslyze",1], - - #17 - ["nmap_hbleed","Nmap [Heartbleed] - Checks only for Heartbleed Vulnerability.","nmap",1], - - #18 - ["nmap_poodle","Nmap [POODLE] - Checks only for Poodle Vulnerability.","nmap",1], - - #19 - ["nmap_ccs","Nmap [OpenSSL CCS Injection] - Checks only for CCS Injection.","nmap",1], - - #20 - ["nmap_freak","Nmap [FREAK] - Checks only for FREAK Vulnerability.","nmap",1], - - #21 - ["nmap_logjam","Nmap [LOGJAM] - Checks for LOGJAM Vulnerability.","nmap",1], - - #22 - ["sslyze_ocsp","SSLyze - Checks for OCSP Stapling.","sslyze",1], - - #23 - ["sslyze_zlib","SSLyze - Checks for ZLib Deflate Compression.","sslyze",1], - - #24 - ["sslyze_reneg","SSLyze - Checks for Secure Renegotiation Support and Client Renegotiation.","sslyze",1], - - #25 - ["sslyze_resum","SSLyze - Checks for Session Resumption Support with [Session IDs/TLS Tickets].","sslyze",1], - - #26 - ["lbd","LBD - Checks for DNS/HTTP Load Balancers.","lbd",1], - - #32 - ["dirb","DirB - Brutes the target for Open Directories.","dirb",1], - - #38 - ["dnsenum_zone_transfer","DNSEnum - Attempts Zone Transfer.","dnsenum",1], - - #39 - ["fierce_brute_subdomains","Fierce Subdomains Bruter - Brute Forces Subdomain Discovery.","fierce",1], - - #42 - ["nmap_telnet","Nmap [TELNET] - Checks if TELNET service is running.","nmap",1], - - #43 - ["nmap_ftp","Nmap [FTP] - Checks if FTP service is running.","nmap",1], - - #44 - ["nmap_stuxnet","Nmap [STUXNET] - Checks if the host is affected by STUXNET Worm.","nmap",1], - - #45 - ["webdav","WebDAV - Checks if WEBDAV enabled on Home directory.","davtest",1], - - #67 - ["nmap_sqlserver","Nmap - Checks for MS-SQL Server DB","nmap",1], - - #68 - ["nmap_mysql", "Nmap - Checks for MySQL DB","nmap",1], - - #69 - ["nmap_oracle", "Nmap - Checks for ORACLE DB","nmap",1], - - #70 - ["nmap_rdp_udp","Nmap - Checks for Remote Desktop Service over UDP","nmap",1], - - #71 - ["nmap_rdp_tcp","Nmap - Checks for Remote Desktop Service over TCP","nmap",1], - - #72 - ["nmap_full_ps_tcp","Nmap - Performs a Full TCP Port Scan","nmap",1], - - #73 - # ["nmap_full_ps_udp","Nmap - Performs a Full UDP Port Scan","nmap",1], - - #74 - # ["nmap_snmp","Nmap - Checks for SNMP Service","nmap",1], - - #75 - ["aspnet_elmah_axd","Checks for ASP.net Elmah Logger","wget",1], - - #76 - ["nmap_tcp_smb","Checks for SMB Service over TCP","nmap",1], - - #77 - ["nmap_udp_smb","Checks for SMB Service over UDP","nmap",1], - - #79 - ["nmap_iis","Nmap - Checks for IIS WebDAV","nmap",1], - - #80 - ["whatweb","WhatWeb - Checks for X-XSS Protection Header","whatweb",1], - - #81 - ["amass","AMass - Brutes Domain for Subdomains","amass",1] - ] - - -# Command that is used to initiate the tool (with parameters and extra params) -tool_cmd = [ - #1 - ["host ",""], - - #2 - ["wget -O /tmp/scanner_temp_aspnet_config_err --tries=1 ","/%7C~.aspx"], - - #3 - ["wget -O /tmp/scanner_temp_wp_check --tries=1 ","/wp-admin"], - - #4 - ["wget -O /tmp/scanner_temp_drp_check --tries=1 ","/user"], - - #5 - ["wget -O /tmp/scanner_temp_joom_check --tries=1 ","/administrator"], - - #7 - ["wafw00f ",""], - - #8 - ["nmap -F --open -Pn ",""], - - #9 - ["theHarvester -l 50 -b google -d ",""], - - #10 - ["dnsrecon -d ",""], - - #13 - ["whois ",""], - - #14 - ["nmap -p80 --script http-security-headers -Pn ",""], - - #15 - ["nmap -p80,443 --script http-slowloris --max-parallelism 500 -Pn ",""], - - #16 - ["sslyze --heartbleed ",""], - - #17 - ["nmap -p443 --script ssl-heartbleed -Pn ",""], - - #18 - ["nmap -p443 --script ssl-poodle -Pn ",""], - - #19 - ["nmap -p443 --script ssl-ccs-injection -Pn ",""], - - #20 - ["nmap -p443 --script ssl-enum-ciphers -Pn ",""], - - #21 - ["nmap -p443 --script ssl-dh-params -Pn ",""], - - #22 - ["sslyze --certinfo=basic ",""], - - #23 - ["sslyze --compression ",""], - - #24 - ["sslyze --reneg ",""], - - #25 - ["sslyze --resum ",""], - - #26 - ["lbd ",""], - - #32 - ["dirb http://"," -fi"], - - #38 - ["dnsenum ",""], - - #39 - ["fierce --domain ",""], - - #42 - ["nmap -p23 --open -Pn ",""], - - #43 - ["nmap -p21 --open -Pn ",""], - - #44 - ["nmap --script stuxnet-detect -p445 -Pn ",""], - - #45 - ["davtest -url http://",""], - - #67 - ["nmap -p1433 --open -Pn ",""], - - #68 - ["nmap -p3306 --open -Pn ",""], - - #69 - ["nmap -p1521 --open -Pn ",""], - - #70 - ["nmap -p3389 --open -sU -Pn ",""], - - #71 - ["nmap -p3389 --open -sT -Pn ",""], - - #72 - ["nmap -p1-65535 --open -Pn ",""], - - #73 - ["nmap -p1-65535 -sU --open -Pn ",""], - - #74 - ["nmap -p161 -sU --open -Pn ",""], - - #75 - ["wget -O /tmp/scanner_temp_aspnet_elmah_axd --tries=1 ","/elmah.axd"], - - #76 - ["nmap -p445,137-139 --open -Pn ",""], - - #77 - ["nmap -p137,138 --open -Pn ",""], - - #79 - ["nmap -p80 --script=http-iis-webdav-vuln -Pn ",""], + agent = Agent( + model='gemini-1.5-flash', + name='scanner_cli_agent', + instruction=instruction, + tools=ALL_TOOLS + ) + + console.print("[bold purple]🤖 Agent Activated.[/bold purple]") + + # Rich Live View of Agent Actions + with Progress( + SpinnerColumn("dots", style="bold magenta"), + TextColumn("{task.description}"), + TimeElapsedColumn(), + console=console + ) as progress: + task = progress.add_task("[dim]Initializing...[/dim]", total=None) - #80 - ["whatweb "," -a 1"], - - #81 - ["amass enum -d ",""] - ] - - -# Tool Responses (Begins) [Responses + Severity (c - critical | h - high | m - medium | l - low | i - informational) + Reference for Vuln Definition and Remediation] -tool_resp = [ - #1 - ["Does not have an IPv6 Address. It is good to have one.","i",1], - - #2 - ["ASP.Net is misconfigured to throw server stack errors on screen.","m",2], - - #3 - ["WordPress Installation Found. Check for vulnerabilities corresponds to that version.","i",3], - - #4 - ["Drupal Installation Found. Check for vulnerabilities corresponds to that version.","i",4], - - #5 - ["Joomla Installation Found. Check for vulnerabilities corresponds to that version.","i",5], - - #6 - ["robots.txt/sitemap.xml found. Check those files for any information.","i",6], - - #7 - ["No Web Application Firewall Detected","m",7], - - #8 - ["Some ports are open. Perform a full-scan manually.","l",8], - - #9 - ["Email Addresses Found.","l",9], - - #10 - ["Zone Transfer Successful using DNSRecon. Reconfigure DNS immediately.","h",10], - - #13 - ["Whois Information Publicly Available.","i",11], - - #14 - ["XSS Protection Filter is Disabled.","m",12], - - #15 - ["Vulnerable to Slowloris Denial of Service.","c",13], - - #16 - ["HEARTBLEED Vulnerability Found with SSLyze.","h",14], - - #17 - ["HEARTBLEED Vulnerability Found with Nmap.","h",14], - - #18 - ["POODLE Vulnerability Detected.","h",15], - - #19 - ["OpenSSL CCS Injection Detected.","h",16], - - #20 - ["FREAK Vulnerability Detected.","h",17], - - #21 - ["LOGJAM Vulnerability Detected.","h",18], - - #22 - ["Unsuccessful OCSP Response.","m",19], - - #23 - ["Server supports Deflate Compression.","m",20], - - #24 - ["Secure Client Initiated Renegotiation is supported.","m",21], - - #25 - ["Secure Resumption unsupported with (Sessions IDs/TLS Tickets).","m",22], - - #26 - ["No DNS/HTTP based Load Balancers Found.","l",23], - - #27 - ["Domain is spoofed/hijacked.","h",24], - - #31 - ["DB Banner retrieved with SQLMap.","l",27], - - #32 - ["Open Directories Found with DirB.","m",26], - - #38 - ["Zone Transfer Successful using DNSEnum. Reconfigure DNS immediately.","h",10], - - #39 - ["Found Subdomains with Fierce.","m",31], - - #42 - ["Telnet Service Detected.","h",32], - - #43 - ["FTP Service Detected.","c",33], - - #44 - ["Vulnerable to STUXNET.","c",34], - - #45 - ["WebDAV Enabled.","m",35], - - #46 - ["Found some information through Fingerprinting.","l",36], - - #52 - ["Apache Expect XSS Header not present.","m",12], - - #54 - ["Webserver vulnerable to Shellshock Bug.","c",40], - - #55 - ["Webserver leaks Internal IP.","l",41], - - #56 - ["HTTP PUT DEL Methods Enabled.","m",42], - - #57 - ["Some vulnerable headers exposed.","m",43], - - #58 - ["Webserver vulnerable to MS10-070.","h",44], - - #59 - ["Some issues found on the Webserver.","m",30], - - #60 - ["Webserver is Outdated.","h",45], - - #61 - ["Some issues found with HTTP Options.","l",42], - - #62 - ["CGI Directories Enumerated.","l",26], - - #63 - ["Vulnerabilities reported in SSL Scans.","m",29], - - #64 - ["Interesting Files Detected.","m",25], - - #65 - ["Injectable Paths Detected.","l",46], - - #67 - ["MS-SQL DB Service Detected.","l",47], - - #68 - ["MySQL DB Service Detected.","l",47], - - #69 - ["ORACLE DB Service Detected.","l",47], - - #70 - ["RDP Server Detected over UDP.","h",48], - - #71 - ["RDP Server Detected over TCP.","h",48], - - #72 - ["TCP Ports are Open","l",8], - - #73 - ["UDP Ports are Open","l",8], - - #74 - # ["SNMP Service Detected.","m",49], - - #75 - ["Elmah is Configured.","m",50], - - #76 - ["SMB Ports are Open over TCP","m",51], - - #77 - ["SMB Ports are Open over UDP","m",51], - - #79 - ["IIS WebDAV is Enabled","m",35], - - #80 - ["X-XSS Protection is not Present","m",12], - - #81 - ["Found Subdomains with AMass","m",31] - - - - ] - -# Tool Responses (Ends) - - - -# Tool Status (Response Data + Response Code (if status check fails and you still got to push it + Legends + Approx Time + Tool Identification + Bad Responses) -tool_status = [ - #1 - ["has IPv6",1,proc_low," < 15s","ipv6",["not found","has IPv6"]], - - #2 - ["Server Error",0,proc_low," < 30s","asp.netmisconf",["unable to resolve host address","Connection timed out"]], - - #3 - ["wp-login",0,proc_low," < 30s","wpcheck",["unable to resolve host address","Connection timed out"]], - - #4 - ["drupal",0,proc_low," < 30s","drupalcheck",["unable to resolve host address","Connection timed out"]], - - #5 - ["joomla",0,proc_low," < 30s","joomlacheck",["unable to resolve host address","Connection timed out"]], - - #6 - ["[+]",0,proc_low," < 40s","robotscheck",["Use of uninitialized value in unpack at"]], - - #7 - ["No WAF",0,proc_low," < 45s","wafcheck",["appears to be down"]], - - #8 - ["tcp open",0,proc_med," < 2m","nmapopen",["Failed to resolve"]], - - #9 - ["No emails found",1,proc_med," < 3m","harvester",["No hosts found","No emails found"]], - - #10 - ["[+] Zone Transfer was successful!!",0,proc_low," < 20s","dnsreconzt",["Could not resolve domain"]], - - #13 - ["Admin Email:",0,proc_low," < 25s","whois",["No match for domain"]], - - #14 - ["XSS filter is disabled",0,proc_low," < 20s","nmapxssh",["Failed to resolve"]], - - #15 - ["VULNERABLE",0,proc_high," < 45m","nmapdos",["Failed to resolve"]], - - #16 - ["Server is vulnerable to Heartbleed",0,proc_low," < 40s","sslyzehb",["Could not resolve hostname"]], - - #17 - ["VULNERABLE",0,proc_low," < 30s","nmap1",["Failed to resolve"]], - - #18 - ["VULNERABLE",0,proc_low," < 35s","nmap2",["Failed to resolve"]], - - #19 - ["VULNERABLE",0,proc_low," < 35s","nmap3",["Failed to resolve"]], - - #20 - ["VULNERABLE",0,proc_low," < 30s","nmap4",["Failed to resolve"]], - - #21 - ["VULNERABLE",0,proc_low," < 35s","nmap5",["Failed to resolve"]], - - #22 - ["ERROR - OCSP response status is not successful",0,proc_low," < 25s","sslyze1",["Could not resolve hostname"]], - - #23 - ["VULNERABLE",0,proc_low," < 30s","sslyze2",["Could not resolve hostname"]], - - #24 - ["VULNERABLE",0,proc_low," < 25s","sslyze3",["Could not resolve hostname"]], - - #25 - ["VULNERABLE",0,proc_low," < 30s","sslyze4",["Could not resolve hostname"]], - - #26 - ["does NOT use Load-balancing",0,proc_med," < 4m","lbd",["NOT FOUND"]], - - #27 - ["No vulnerabilities found",1,proc_low," < 45s","golism1",["Cannot resolve domain name","No vulnerabilities found"]], - - #28 - ["No vulnerabilities found",1,proc_low," < 40s","golism2",["Cannot resolve domain name","No vulnerabilities found"]], - - #29 - ["No vulnerabilities found",1,proc_low," < 45s","golism3",["Cannot resolve domain name","No vulnerabilities found"]], - - #30 - ["No vulnerabilities found",1,proc_low," < 40s","golism4",["Cannot resolve domain name","No vulnerabilities found"]], - - #31 - ["No vulnerabilities found",1,proc_low," < 45s","golism5",["Cannot resolve domain name","No vulnerabilities found"]], - - #32 - ["FOUND: 0",1,proc_high," < 35m","dirb",["COULDNT RESOLVE HOST","FOUND: 0"]], - - #34 - ["Occurrence ID",0,proc_low," < 45s","golism6",["Cannot resolve domain name"]], - - #35 - ["DNS zone transfer successful",0,proc_low," < 30s","golism7",["Cannot resolve domain name"]], - - #37 - ["Possible subdomain leak",0,proc_high," < 30m","golism9",["Cannot resolve domain name"]], - - #38 - ["AXFR record query failed:",1,proc_low," < 45s","dnsenumzt",["NS record query failed:","AXFR record query failed","no NS record for"]], - - #39 - ["Found 0 entries",1,proc_high," < 75m","fierce2",["Found 0 entries","is gimp"]], - - #41 - ["Found 0 possible subdomain(s)",1,proc_low," < 35s","dmitry2",["Unable to locate Host IP addr","Found 0 possible subdomain(s)"]], - - #42 - ["open",0,proc_low," < 15s","nmaptelnet",["Failed to resolve"]], - - #43 - ["open",0,proc_low," < 15s","nmapftp",["Failed to resolve"]], - - #44 - ["open",0,proc_low," < 20s","nmapstux",["Failed to resolve"]], - - #45 - ["SUCCEED",0,proc_low," < 30s","webdav",["is not DAV enabled or not accessible."]], - - #46 - ["No vulnerabilities found",1,proc_low," < 15s","golism10",["Cannot resolve domain name","No vulnerabilities found"]], - - #67 - ["open",0,proc_low," < 15s","nmapmssql",["Failed to resolve"]], - - #68 - ["open",0,proc_low," < 15s","nmapmysql",["Failed to resolve"]], - - #69 - ["open",0,proc_low," < 15s","nmaporacle",["Failed to resolve"]], - - #70 - ["open",0,proc_low," < 15s","nmapudprdp",["Failed to resolve"]], - - #71 - ["open",0,proc_low," < 15s","nmaptcprdp",["Failed to resolve"]], - - #72 - ["open",0,proc_high," > 50m","nmapfulltcp",["Failed to resolve"]], - - #73 - # ["open",0,proc_high," > 75m","nmapfulludp",["Failed to resolve"]], - - #74 - # ["open",0,proc_low," < 30s","nmapsnmp",["Failed to resolve"]], - - #75 - ["Microsoft SQL Server Error Log",0,proc_low," < 30s","elmahxd",["unable to resolve host address","Connection timed out"]], - - #76 - ["open",0,proc_low," < 20s","nmaptcpsmb",["Failed to resolve"]], - - #77 - ["open",0,proc_low," < 20s","nmapudpsmb",["Failed to resolve"]], - - #79 - ["WebDAV is ENABLED",0,proc_low," < 40s","nmapwebdaviis",["Failed to resolve"]], - - #80 - ["X-XSS-Protection[1",1,proc_med," < 3m","whatweb",["Timed out","Socket error","X-XSS-Protection[1"]], - - #81 - ["No names were discovered",1,proc_med," < 15m","amass",["The system was unable to build the pool of resolvers"]] - - - - ] - -# Vulnerabilities and Remediation -tools_fix = [ - [1, "Not a vulnerability, just an informational alert. The host does not have IPv6 support. IPv6 provides more security as IPSec (responsible for CIA - Confidentiality, Integrity and Availablity) is incorporated into this model. So it is good to have IPv6 Support.", - "It is recommended to implement IPv6. More information on how to implement IPv6 can be found from this resource. https://www.cisco.com/c/en/us/solutions/collateral/enterprise/cisco-on-cisco/IPv6-Implementation_CS.html"], - [2, "Sensitive Information Leakage Detected. The ASP.Net application does not filter out illegal characters in the URL. The attacker injects a special character (%7C~.aspx) to make the application spit sensitive information about the server stack.", - "It is recommended to filter out special charaters in the URL and set a custom error page on such situations instead of showing default error messages. This resource helps you in setting up a custom error page on a Microsoft .Net Application. https://docs.microsoft.com/en-us/aspnet/web-forms/overview/older-versions-getting-started/deploying-web-site-projects/displaying-a-custom-error-page-cs"], - [3, "It is not bad to have a CMS in WordPress. There are chances that the version may contain vulnerabilities or any third party scripts associated with it may possess vulnerabilities", - "It is recommended to conceal the version of WordPress. This resource contains more information on how to secure your WordPress Blog. https://codex.wordpress.org/Hardening_WordPress"], - [4, "It is not bad to have a CMS in Drupal. There are chances that the version may contain vulnerabilities or any third party scripts associated with it may possess vulnerabilities", - "It is recommended to conceal the version of Drupal. This resource contains more information on how to secure your Drupal Blog. https://www.drupal.org/docs/7/site-building-best-practices/ensure-that-your-site-is-secure"], - [5, "It is not bad to have a CMS in Joomla. There are chances that the version may contain vulnerabilities or any third party scripts associated with it may possess vulnerabilities", - "It is recommended to conceal the version of Joomla. This resource contains more information on how to secure your Joomla Blog. https://www.incapsula.com/blog/10-tips-to-improve-your-joomla-website-security.html"], - [6, "Sometimes robots.txt or sitemap.xml may contain rules such that certain links that are not supposed to be accessed/indexed by crawlers and search engines. Search engines may skip those links but attackers will be able to access it directly.", - "It is a good practice not to include sensitive links in the robots or sitemap files."], - [7, "Without a Web Application Firewall, An attacker may try to inject various attack patterns either manually or using automated scanners. An automated scanner may send hordes of attack vectors and patterns to validate an attack, there are also chances for the application to get DoS`ed (Denial of Service)", - "Web Application Firewalls offer great protection against common web attacks like XSS, SQLi, etc. They also provide an additional line of defense to your security infrastructure. This resource contains information on web application firewalls that could suit your application. https://www.gartner.com/reviews/market/web-application-firewall"], - [8, "Open Ports give attackers a hint to exploit the services. Attackers try to retrieve banner information through the ports and understand what type of service the host is running", - "It is recommended to close the ports of unused services and use a firewall to filter the ports wherever necessary. This resource may give more insights. https://security.stackexchange.com/a/145781/6137"], - [9, "Chances are very less to compromise a target with email addresses. However, attackers use this as a supporting data to gather information around the target. An attacker may make use of the username on the email address and perform brute-force attacks on not just email servers, but also on other legitimate panels like SSH, CMS, etc with a password list as they have a legitimate name. This is however a shoot in the dark scenario, the attacker may or may not be successful depending on the level of interest", - "Since the chances of exploitation is feeble there is no need to take action. Perfect remediation would be choosing different usernames for different services will be more thoughtful."], - [10, "Zone Transfer reveals critical topological information about the target. The attacker will be able to query all records and will have more or less complete knowledge about your host.", - "Good practice is to restrict the Zone Transfer by telling the Master which are the IPs of the slaves that can be given access for the query. This SANS resource provides more information. https://www.sans.org/reading-room/whitepapers/dns/securing-dns-zone-transfer-868"], - [11, "The email address of the administrator and other information (address, phone, etc) is available publicly. An attacker may use these information to leverage an attack. This may not be used to carry out a direct attack as this is not a vulnerability. However, an attacker makes use of these data to build information about the target.", - "Some administrators intentionally would have made this information public, in this case it can be ignored. If not, it is recommended to mask the information. This resource provides information on this fix. http://www.name.com/blog/how-tos/tutorial-2/2013/06/protect-your-personal-information-with-whois-privacy/"], - [12, "As the target is lacking this header, older browsers will be prone to Reflected XSS attacks.", - "Modern browsers does not face any issues with this vulnerability (missing headers). However, older browsers are strongly recommended to be upgraded."], - [13, "This attack works by opening multiple simultaneous connections to the web server and it keeps them alive as long as possible by continously sending partial HTTP requests, which never gets completed. They easily slip through IDS by sending partial requests.", - "If you are using Apache Module, `mod_antiloris` would help. For other setup you can find more detailed remediation on this resource. https://www.acunetix.com/blog/articles/slow-http-dos-attacks-mitigate-apache-http-server/"], - [14, "This vulnerability seriously leaks private information of your host. An attacker can keep the TLS connection alive and can retrieve a maximum of 64K of data per heartbeat.", - "PFS (Perfect Forward Secrecy) can be implemented to make decryption difficult. Complete remediation and resource information is available here. http://heartbleed.com/"], - [15, "By exploiting this vulnerability, an attacker will be able gain access to sensitive data in a n encrypted session such as session ids, cookies and with those data obtained, will be able to impersonate that particular user.", - "This is a flaw in the SSL 3.0 Protocol. A better remediation would be to disable using the SSL 3.0 protocol. For more information, check this resource. https://www.us-cert.gov/ncas/alerts/TA14-290A"], - [16, "This attacks takes place in the SSL Negotiation (Handshake) which makes the client unaware of the attack. By successfully altering the handshake, the attacker will be able to pry on all the information that is sent from the client to server and vice-versa", - "Upgrading OpenSSL to latest versions will mitigate this issue. This resource gives more information about the vulnerability and the associated remediation. http://ccsinjection.lepidum.co.jp/"], - [17, "With this vulnerability the attacker will be able to perform a MiTM attack and thus compromising the confidentiality factor.", - "Upgrading OpenSSL to latest version will mitigate this issue. Versions prior to 1.1.0 is prone to this vulnerability. More information can be found in this resource. https://bobcares.com/blog/how-to-fix-sweet32-birthday-attacks-vulnerability-cve-2016-2183/"], - [18, "With the LogJam attack, the attacker will be able to downgrade the TLS connection which allows the attacker to read and modify any data passed over the connection.", - "Make sure any TLS libraries you use are up-to-date, that servers you maintain use 2048-bit or larger primes, and that clients you maintain reject Diffie-Hellman primes smaller than 1024-bit. More information can be found in this resource. https://weakdh.org/"], - [19, "Allows remote attackers to cause a denial of service (crash), and possibly obtain sensitive information in applications that use OpenSSL, via a malformed ClientHello handshake message that triggers an out-of-bounds memory access.", - " OpenSSL versions 0.9.8h through 0.9.8q and 1.0.0 through 1.0.0c are vulnerable. It is recommended to upgrade the OpenSSL version. More resource and information can be found here. https://www.openssl.org/news/secadv/20110208.txt"], - [20, "Otherwise termed as BREACH atack, exploits the compression in the underlying HTTP protocol. An attacker will be able to obtain email addresses, session tokens, etc from the TLS encrypted web traffic.", - "Turning off TLS compression does not mitigate this vulnerability. First step to mitigation is to disable Zlib compression followed by other measures mentioned in this resource. http://breachattack.com/"], - [21, "Otherwise termed as Plain-Text Injection attack, which allows MiTM attackers to insert data into HTTPS sessions, and possibly other types of sessions protected by TLS or SSL, by sending an unauthenticated request that is processed retroactively by a server in a post-renegotiation context.", - "Detailed steps of remediation can be found from these resources. https://securingtomorrow.mcafee.com/technical-how-to/tips-securing-ssl-renegotiation/ https://www.digicert.com/news/2011-06-03-ssl-renego/ "], - [22, "This vulnerability allows attackers to steal existing TLS sessions from users.", - "Better advice is to disable session resumption. To harden session resumption, follow this resource that has some considerable information. https://wiki.crashtest-security.com/display/KB/Harden+TLS+Session+Resumption"], - [23, "This has nothing to do with security risks, however attackers may use this unavailability of load balancers as an advantage to leverage a denial of service attack on certain services or on the whole application itself.", - "Load-Balancers are highly encouraged for any application. They improve performance times as well as data availability on during times of server outage. To know more information on load balancers and setup, check this resource. https://www.digitalocean.com/community/tutorials/what-is-load-balancing"], - [24, "An attacker can forwarded requests that comes to the legitimate URL or web application to a third party address or to the attacker's location that can serve malware and affect the end user's machine.", - "It is highly recommended to deploy DNSSec on the host target. Full deployment of DNSSEC will ensure the end user is connecting to the actual web site or other service corresponding to a particular domain name. For more information, check this resource. https://www.cloudflare.com/dns/dnssec/how-dnssec-works/"], - [25, "Attackers may find considerable amount of information from these files. There are even chances attackers may get access to critical information from these files.", - "It is recommended to block or restrict access to these files unless necessary."], - [26, "Attackers may find considerable amount of information from these directories. There are even chances attackers may get access to critical information from these directories.", - "It is recommended to block or restrict access to these directories unless necessary."], - [27, "May not be SQLi vulnerable. An attacker will be able to know that the host is using a backend for operation.", - "Banner Grabbing should be restricted and access to the services from outside would should be made minimum."], - [28, "An attacker will be able to steal cookies, deface web application or redirect to any third party address that can serve malware.", - "Input validation and Output Sanitization can completely prevent Cross Site Scripting (XSS) attacks. XSS attacks can be mitigated in future by properly following a secure coding methodology. The following comprehensive resource provides detailed information on fixing this vulnerability. https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet"], - [29, "SSL related vulnerabilities breaks the confidentiality factor. An attacker may perform a MiTM attack, intrepret and eavesdrop the communication.", - "Proper implementation and upgraded version of SSL and TLS libraries are very critical when it comes to blocking SSL related vulnerabilities."], - [30, "Particular Scanner found multiple vulnerabilities that an attacker may try to exploit the target.", - "Refer to Security-Vulnerability-Report to view the complete information of the vulnerability, once the scan gets completed."], - [31, "Attackers may gather more information from subdomains relating to the parent domain. Attackers may even find other services from the subdomains and try to learn the architecture of the target. There are even chances for the attacker to find vulnerabilities as the attack surface gets larger with more subdomains discovered.", - "It is sometimes wise to block sub domains like development, staging to the outside world, as it gives more information to the attacker about the tech stack. Complex naming practices also help in reducing the attack surface as attackers find hard to perform subdomain bruteforcing through dictionaries and wordlists."], - [32, "Through this deprecated protocol, an attacker may be able to perform MiTM and other complicated attacks.", - "It is highly recommended to stop using this service and it is far outdated. SSH can be used to replace TELNET. For more information, check this resource https://www.ssh.com/ssh/telnet"], - [33, "This protocol does not support secure communication and there are likely high chances for the attacker to eavesdrop the communication. Also, many FTP programs have exploits available in the web such that an attacker can directly crash the application or either get a SHELL access to that target.", - "Proper suggested fix is use an SSH protocol instead of FTP. It supports secure communication and chances for MiTM attacks are quite rare."], - [34, "The StuxNet is level-3 worm that exposes critical information of the target organization. It was a cyber weapon that was designed to thwart the nuclear intelligence of Iran. Seriously wonder how it got here? Hope this isn't a false positive Nmap ;)", - "It is highly recommended to perform a complete rootkit scan on the host. For more information refer to this resource. https://www.symantec.com/security_response/writeup.jsp?docid=2010-071400-3123-99&tabid=3"], - [35, "WebDAV is supposed to contain multiple vulnerabilities. In some case, an attacker may hide a malicious DLL file in the WebDAV share however, and upon convincing the user to open a perfectly harmless and legitimate file, execute code under the context of that user", - "It is recommended to disable WebDAV. Some critical resource regarding disbling WebDAV can be found on this URL. https://www.networkworld.com/article/2202909/network-security/-webdav-is-bad---says-security-researcher.html"], - [36, "Attackers always do a fingerprint of any server before they launch an attack. Fingerprinting gives them information about the server type, content- they are serving, last modification times etc, this gives an attacker to learn more information about the target", - "A good practice is to obfuscate the information to outside world. Doing so, the attackers will have tough time understanding the server's tech stack and therefore leverage an attack."], - [37, "Attackers mostly try to render applications or service useless by flooding the target, such that blocking access to legitimate users. This may affect the business of a company or organization as well as the reputation", - "By ensuring proper load balancers in place, configuring rate limits and multiple connection restrictions, such attacks can be drastically mitigated."], - [38, "Intruders will be able to remotely include shell files and will be able to access the core file system or they will be able to read all the files as well. There are even higher chances for the attacker to remote execute code on the file system.", - "Secure code practices will mostly prevent LFI, RFI and RCE attacks. The following resource gives a detailed insight on secure coding practices. https://wiki.sei.cmu.edu/confluence/display/seccode/Top+10+Secure+Coding+Practices"], - [39, "Hackers will be able to steal data from the backend and also they can authenticate themselves to the website and can impersonate as any user since they have total control over the backend. They can even wipe out the entire database. Attackers can also steal cookie information of an authenticated user and they can even redirect the target to any malicious address or totally deface the application.", - "Proper input validation has to be done prior to directly querying the database information. A developer should remember not to trust an end-user's input. By following a secure coding methodology attacks like SQLi, XSS and BSQLi. The following resource guides on how to implement secure coding methodology on application development. https://wiki.sei.cmu.edu/confluence/display/seccode/Top+10+Secure+Coding+Practices"], - [40, "Attackers exploit the vulnerability in BASH to perform remote code execution on the target. An experienced attacker can easily take over the target system and access the internal sources of the machine", - "This vulnerability can be mitigated by patching the version of BASH. The following resource gives an indepth analysis of the vulnerability and how to mitigate it. https://www.symantec.com/connect/blogs/shellshock-all-you-need-know-about-bash-bug-vulnerability https://www.digitalocean.com/community/tutorials/how-to-protect-your-server-against-the-shellshock-bash-vulnerability"], - [41, "Gives attacker an idea on how the address scheming is done internally on the organizational network. Discovering the private addresses used within an organization can help attackers in carrying out network-layer attacks aiming to penetrate the organization's internal infrastructure.", - "Restrict the banner information to the outside world from the disclosing service. More information on mitigating this vulnerability can be found here. https://portswigger.net/kb/issues/00600300_private-ip-addresses-disclosed"], - [42, "There are chances for an attacker to manipulate files on the webserver.", - "It is recommended to disable the HTTP PUT and DEL methods incase if you don't use any REST API Services. Following resources helps you how to disable these methods. http://www.techstacks.com/howto/disable-http-methods-in-tomcat.html https://docs.oracle.com/cd/E19857-01/820-5627/gghwc/index.html https://developer.ibm.com/answers/questions/321629/how-to-disable-http-methods-head-put-delete-option/"], - [43, "Attackers try to learn more about the target from the amount of information exposed in the headers. An attacker may know what type of tech stack a web application is emphasizing and many other information.", - "Banner Grabbing should be restricted and access to the services from outside would should be made minimum."], - [44, "An attacker who successfully exploited this vulnerability could read data, such as the view state, which was encrypted by the server. This vulnerability can also be used for data tampering, which, if successfully exploited, could be used to decrypt and tamper with the data encrypted by the server.", - "Microsoft has released a set of patches on their website to mitigate this issue. The information required to fix this vulnerability can be inferred from this resource. https://docs.microsoft.com/en-us/security-updates/securitybulletins/2010/ms10-070"], - [45, "Any outdated web server may contain multiple vulnerabilities as their support would've been ended. An attacker may make use of such an opportunity to leverage attacks.", - "It is highly recommended to upgrade the web server to the available latest version."], - [46, "Hackers will be able to manipulate the URLs easily through a GET/POST request. They will be able to inject multiple attack vectors in the URL with ease and able to monitor the response as well", - "By ensuring proper sanitization techniques and employing secure coding practices it will be impossible for the attacker to penetrate through. The following resource gives a detailed insight on secure coding practices. https://wiki.sei.cmu.edu/confluence/display/seccode/Top+10+Secure+Coding+Practices"], - [47, "Since the attacker has knowledge about the particular type of backend the target is running, they will be able to launch a targetted exploit for the particular version. They may also try to authenticate with default credentials to get themselves through.", - "Timely security patches for the backend has to be installed. Default credentials has to be changed. If possible, the banner information can be changed to mislead the attacker. The following resource gives more information on how to secure your backend. http://kb.bodhost.com/secure-database-server/"], - [48, "Attackers may launch remote exploits to either crash the service or tools like ncrack to try brute-forcing the password on the target.", - "It is recommended to block the service to outside world and made the service accessible only through the a set of allowed IPs only really neccessary. The following resource provides insights on the risks and as well as the steps to block the service. https://www.perspectiverisk.com/remote-desktop-service-vulnerabilities/"], - # [49, "Hackers will be able to read community strings through the service and enumerate quite a bit of information from the target. Also, there are multiple Remote Code Execution and Denial of Service vulnerabilities related to SNMP services.", - # "Use a firewall to block the ports from the outside world. The following article gives wide insight on locking down SNMP service. https://www.techrepublic.com/article/lock-it-down-dont-allow-snmp-to-compromise-network-security/"], - [50, "Attackers will be able to find the logs and error information generated by the application. They will also be able to see the status codes that was generated on the application. By combining all these information, the attacker will be able to leverage an attack.", - "By restricting access to the logger application from the outside world will be more than enough to mitigate this weakness."], - [51, "Cyber Criminals mainly target this service as it is very easier for them to perform a remote attack by running exploits. WannaCry Ransomware is one such example.", - "Exposing SMB Service to the outside world is a bad idea, it is recommended to install latest patches for the service in order not to get compromised. The following resource provides a detailed information on SMB Hardening concepts. https://kb.iweb.com/hc/en-us/articles/115000274491-Securing-Windows-SMB-and-NetBios-NetBT-Services"] - ] - -# Tool Set -tools_precheck = [ - ["whatweb"], ["nmap"], ["host"], ["wget"], ["wafw00f"], ["dirb"], ["davtest"], ["theHarvester"], ["dnsrecon"],["fierce"], ["whois"], ["sslyze"], ["lbd"], ["dnsenum"], ["davtest"], ["amass"] - ] - -def get_parser(): - - parser = argparse.ArgumentParser(add_help=False) - parser.add_argument('-h', '--help', action='store_true', - help='Show help message and exit.') - parser.add_argument('-u', '--update', action='store_true', - help='Update scanner.') - parser.add_argument('-s', '--skip', action='append', default=[], - help='Skip some tools', choices=[t[0] for t in tools_precheck]) - parser.add_argument('-n', '--nospinner', action='store_true', - help='Disable the idle loader/spinner.') - parser.add_argument('target', nargs='?', metavar='URL', help='URL to scan.', default='', type=str) - return parser - - -# Shuffling Scan Order (starts) -scan_shuffle = list(zip(tool_names, tool_cmd, tool_resp, tool_status)) -random.shuffle(scan_shuffle) -tool_names, tool_cmd, tool_resp, tool_status = zip(*scan_shuffle) -tool_checks = (len(tool_names) + len(tool_resp) + len(tool_status)) / 3 # Cross verification incase, breaks. -tool_checks = round(tool_checks) -# Shuffling Scan Order (ends) - -# Tool Head Pointer: (can be increased but certain tools will be skipped) -tool = 0 - -# Run Test -runTest = 1 - -# For accessing list/dictionary elements -arg1 = 0 -arg2 = 1 -arg3 = 2 -arg4 = 3 -arg5 = 4 -arg6 = 5 - -# Detected Vulnerabilities [will be dynamically populated] -rs_vul_list = list() -rs_vul_num = 0 -rs_vul = 0 - -# Total Time Elapsed -rs_total_elapsed = 0 - -# Tool Pre Checker -rs_avail_tools = 0 - -# Checks Skipped -rs_skipped_checks = 0 - -if len(sys.argv) == 1: - logo() - helper() - sys.exit(1) - -args_namespace = get_parser().parse_args() - -if args_namespace.nospinner: - spinner.disabled = True - -if args_namespace.help or (not args_namespace.update \ - and not args_namespace.target): - logo() - helper() -elif args_namespace.update: - logo() - print("scanner is updating....Please wait.\n") - spinner.start() - # Checking internet connectivity first... - rs_internet_availability = check_internet() - if rs_internet_availability == 0: - print("\t"+ bcolors.BG_ERR_TXT + "There seems to be some problem connecting to the internet. Please try again or later." +bcolors.ENDC) - spinner.stop() - sys.exit(1) - cmd = 'sha1sum scanner.py | grep .... | cut -c 1-40' - oldversion_hash = subprocess.check_output(cmd, shell=True) - oldversion_hash = oldversion_hash.strip() - os.system('wget -N https://raw.githubusercontent.com/skavngr/scanner/master/scanner.py -O scanner.py > /dev/null 2>&1') - newversion_hash = subprocess.check_output(cmd, shell=True) - newversion_hash = newversion_hash.strip() - if oldversion_hash == newversion_hash : - clear() - print("\t"+ bcolors.OKBLUE +"You already have the latest version of scanner." + bcolors.ENDC) - else: - clear() - print("\t"+ bcolors.OKGREEN +"scanner successfully updated to the latest version." +bcolors.ENDC) - spinner.stop() - sys.exit(1) - -elif args_namespace.target: - - target = url_maker(args_namespace.target) - #target = args_namespace.target - os.system('rm /tmp/te* > /dev/null 2>&1') # Clearing previous scan files - os.system('clear') - os.system('setterm -cursor off') - logo() - print(bcolors.BG_HEAD_TXT+"[ Checking Available Security Scanning Tools Phase... Initiated. ]"+bcolors.ENDC) - - unavail_tools_names = list() - - while (rs_avail_tools < len(tools_precheck)): - precmd = str(tools_precheck[rs_avail_tools][arg1]) - try: - p = subprocess.Popen([precmd], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True) - output, err = p.communicate() - val = output + err - except: - print("\t"+bcolors.BG_ERR_TXT+"scanner was terminated abruptly..."+bcolors.ENDC) - sys.exit(1) - - # If the tool is not found or it's part of the --skip argument(s), disabling it - if b"not found" in val or tools_precheck[rs_avail_tools][arg1] in args_namespace.skip : - if b"not found" in val: - print("\t"+bcolors.OKBLUE+tools_precheck[rs_avail_tools][arg1]+bcolors.ENDC+bcolors.BADFAIL+"...unavailable."+bcolors.ENDC) - elif tools_precheck[rs_avail_tools][arg1] in args_namespace.skip : - print("\t"+bcolors.OKBLUE+tools_precheck[rs_avail_tools][arg1]+bcolors.ENDC+bcolors.BADFAIL+"...skipped."+bcolors.ENDC) + final_output = "" + + # Run Live Agent + for event in agent.run_live(): + + # Heuristics for UI updates + if hasattr(event, 'tool_calls') and event.tool_calls: + tname = event.tool_calls[0].function.name + # Detailed Log "Element from Legacy" - Show what's running clearly + progress.console.print(f"[bold cyan]➜ Executing Tool:[/bold cyan] {tname}") + progress.update(task, description=f"[cyan]Running {tname}...[/cyan]") + + if hasattr(event, 'content') and event.content: + # Stream thought/content + chunk = str(event.content) + final_output += chunk + progress.update(task, description="[purple]Agent Writing...[/purple]") + + if "Final Report" in final_output: + break + + # Final Report Display + console.print(Panel(Markdown(final_output), title="🛡️ Final Assessment", border_style="green")) - for scanner_index, scanner_val in enumerate(tool_names): - if scanner_val[2] == tools_precheck[rs_avail_tools][arg1]: - scanner_val[3] = 0 # disabling scanner as it's not available. - unavail_tools_names.append(tools_precheck[rs_avail_tools][arg1]) + # Use specific name format + with open(f"scan_report_{self.target}.md", "w") as f: + f.write(final_output) - else: - print("\t"+bcolors.OKBLUE+tools_precheck[rs_avail_tools][arg1]+bcolors.ENDC+bcolors.OKGREEN+"...available."+bcolors.ENDC) - rs_avail_tools = rs_avail_tools + 1 - clear() - unavail_tools_names = list(set(unavail_tools_names)) - if len(unavail_tools_names) == 0: - print("\t"+bcolors.OKGREEN+"All Scanning Tools are available. Complete vulnerability checks will be performed by scanner."+bcolors.ENDC) - else: - print("\t"+bcolors.WARNING+"Some of these tools "+bcolors.BADFAIL+str(unavail_tools_names)+bcolors.ENDC+bcolors.WARNING+" are unavailable or will be skipped. scanner will still perform the rest of the tests. Install these tools to fully utilize the functionality of scanner."+bcolors.ENDC) - print(bcolors.BG_ENDL_TXT+"[ Checking Available Security Scanning Tools Phase... Completed. ]"+bcolors.ENDC) - print("\n") - print(bcolors.BG_HEAD_TXT+"[ Preliminary Scan Phase Initiated... Loaded "+str(tool_checks)+" vulnerability checks. ]"+bcolors.ENDC) - #while (tool < 1): - while(tool < len(tool_names)): - print("["+tool_status[tool][arg3]+tool_status[tool][arg4]+"] Deploying "+str(tool+1)+"/"+str(tool_checks)+" | "+bcolors.OKBLUE+tool_names[tool][arg2]+bcolors.ENDC,) - if tool_names[tool][arg4] == 0: - print(bcolors.WARNING+"\nScanning Tool Unavailable. Skipping Test...\n"+bcolors.ENDC) - rs_skipped_checks = rs_skipped_checks + 1 - tool = tool + 1 - continue - try: - spinner.start() except Exception as e: - print("\n") - scan_start = time.time() - temp_file = "/tmp/scanner_temp_"+tool_names[tool][arg1] - cmd = tool_cmd[tool][arg1]+target+tool_cmd[tool][arg2]+" > "+temp_file+" 2>&1" - - try: - subprocess.check_output(cmd, shell=True) - except KeyboardInterrupt: - runTest = 0 - except: - runTest = 1 - - if runTest == 1: - spinner.stop() - scan_stop = time.time() - elapsed = scan_stop - scan_start - rs_total_elapsed = rs_total_elapsed + elapsed - #print(bcolors.OKBLUE+"\b...Completed in "+display_time(int(elapsed))+bcolors.ENDC+"\n") - sys.stdout.write(ERASE_LINE) - print(bcolors.OKBLUE+"\nScan Completed in "+display_time(int(elapsed))+bcolors.ENDC, end='\r', flush=True) - print("\n") - #clear() - rs_tool_output_file = open(temp_file).read() - if tool_status[tool][arg2] == 0: - if tool_status[tool][arg1].lower() in rs_tool_output_file.lower(): - #print "\t"+ vul_info(tool_resp[tool][arg2]) + bcolors.BADFAIL +" "+ tool_resp[tool][arg1] + bcolors.ENDC - vul_remed_info(tool,tool_resp[tool][arg2],tool_resp[tool][arg3]) - rs_vul_list.append(tool_names[tool][arg1]+"*"+tool_names[tool][arg2]) - else: - if any(i in rs_tool_output_file for i in tool_status[tool][arg6]): - m = 1 # This does nothing. - else: - #print "\t"+ vul_info(tool_resp[tool][arg2]) + bcolors.BADFAIL +" "+ tool_resp[tool][arg1] + bcolors.ENDC - vul_remed_info(tool,tool_resp[tool][arg2],tool_resp[tool][arg3]) - rs_vul_list.append(tool_names[tool][arg1]+"*"+tool_names[tool][arg2]) - else: - runTest = 1 - spinner.stop() - scan_stop = time.time() - elapsed = scan_stop - scan_start - rs_total_elapsed = rs_total_elapsed + elapsed - #sys.stdout.write(CURSOR_UP_ONE) - sys.stdout.write(ERASE_LINE) - #print("-" * terminal_size(), end='\r', flush=True) - print(bcolors.OKBLUE+"\nScan Interrupted in "+display_time(int(elapsed))+bcolors.ENDC, end='\r', flush=True) - print("\n"+bcolors.WARNING + "\tTest Skipped. Performing Next. Press Ctrl+Z to Quit scanner.\n" + bcolors.ENDC) - rs_skipped_checks = rs_skipped_checks + 1 + console.print(f"[red]Agent Error: {e}[/red]") - tool=tool+1 - - print(bcolors.BG_ENDL_TXT+"[ Preliminary Scan Phase Completed. ]"+bcolors.ENDC) - print("\n") - - #################### Report & Documentation Phase ########################### - print(bcolors.BG_HEAD_TXT+"[ Report Generation Phase Initiated. ]"+bcolors.ENDC) - if len(rs_vul_list)==0: - print("\t"+bcolors.OKGREEN+"No Vulnerabilities Detected."+bcolors.ENDC) - else: - with open("Security-Vulnerability-Report", "a") as report: - while(rs_vul < len(rs_vul_list)): - vuln_info = rs_vul_list[rs_vul].split('*') - report.write(vuln_info[arg2]) - report.write("\n------------------------\n\n") - temp_report_name = "/tmp/scanner_temp_"+vuln_info[arg1] - with open(temp_report_name, 'r') as temp_report: - data = temp_report.read() - report.write(data) - report.write("\n\n") - temp_report.close() - rs_vul = rs_vul + 1 - - print("\tComplete Vulnerability Report for "+bcolors.OKBLUE+target+bcolors.ENDC+" named "+bcolors.OKGREEN+"`Security-Vulnerability-Report`"+bcolors.ENDC+" is available under the same directory scanner resides.") +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("target") + parser.add_argument("--key") + args = parser.parse_args() + + # Simple dependency check (lightweight) + if "google.adk" not in sys.modules and not Agent: + console.print("[yellow]ADK missing. Please run pip install google-adk[/yellow]") - report.close() - # Writing all scan files output into Security-Debug-ScanLog for debugging purposes. - for file_index, file_name in enumerate(tool_names): - with open("Security-Debug-ScanLog", "a") as report: - try: - with open("/tmp/scanner_temp_"+file_name[arg1], 'r') as temp_report: - data = temp_report.read() - report.write(file_name[arg2]) - report.write("\n------------------------\n\n") - report.write(data) - report.write("\n\n") - temp_report.close() - except: - break - report.close() + key = args.key or get_api_key() + if not key: + console.print("[red]API Key required.[/red]") + return - print("\tTotal Number of Vulnerability Checks : "+bcolors.BOLD+bcolors.OKGREEN+str(len(tool_names))+bcolors.ENDC) - print("\tTotal Number of Vulnerability Checks Skipped: "+bcolors.BOLD+bcolors.WARNING+str(rs_skipped_checks)+bcolors.ENDC) - print("\tTotal Number of Vulnerabilities Detected : "+bcolors.BOLD+bcolors.BADFAIL+str(len(rs_vul_list))+bcolors.ENDC) - print("\tTotal Time Elapsed for the Scan : "+bcolors.BOLD+bcolors.OKBLUE+display_time(int(rs_total_elapsed))+bcolors.ENDC) - print("\n") - print("\tFor Debugging Purposes, You can view the complete output generated by all the tools named "+bcolors.OKBLUE+"`Security-Debug-ScanLog`"+bcolors.ENDC+" under the same directory.") - print(bcolors.BG_ENDL_TXT+"[ Report Generation Phase Completed. ]"+bcolors.ENDC) + cli = ScannerCLI(args.target, key) + cli.run() - os.system('setterm -cursor on') - os.system('rm /tmp/scanner_te* > /dev/null 2>&1') # Clearing previous scan files +if __name__ == "__main__": + main() diff --git a/scanner_legacy.py b/scanner_legacy.py new file mode 100644 index 0000000..fcf4d88 --- /dev/null +++ b/scanner_legacy.py @@ -0,0 +1,987 @@ +#!/usr/bin/env python3 +# Description: This scanner automates the process of security scanning by using a +# multitude of available linux security tools and some custom scripts. +# + +# Importing the libraries +import sys +import argparse +import subprocess +import os +import time +import random +import threading +import re +import json +from urllib.parse import urlsplit + + +CURSOR_UP_ONE = '\x1b[1A' +ERASE_LINE = '\x1b[2K' + +# Scan Time Elapser +intervals = ( + ('h', 3600), + ('m', 60), + ('s', 1), + ) +def display_time(seconds, granularity=3): + result = [] + seconds = seconds + 1 + for name, count in intervals: + value = seconds // count + if value: + seconds -= value * count + result.append("{}{}".format(value, name)) + return ' '.join(result[:granularity]) + + +def terminal_size(): + try: + rows, columns = subprocess.check_output(['stty', 'size']).split() + return int(columns) + except subprocess.CalledProcessError as e: + return int(20) + + + +def url_maker(url): + if not re.match(r'http(s?)\:', url): + url = 'http://' + url + parsed = urlsplit(url) + host = parsed.netloc + if host.startswith('www.'): + host = host[4:] + return host + +def check_internet(): + os.system('ping -c1 github.com > rs_net 2>&1') + if "0% packet loss" in open('rs_net').read(): + val = 1 + else: + val = 0 + os.system('rm rs_net > /dev/null 2>&1') + return val + + +# Initializing the color module class +class bcolors: + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + BADFAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + + BG_ERR_TXT = '\033[41m' # For critical errors and crashes + BG_HEAD_TXT = '\033[100m' + BG_ENDL_TXT = '\033[46m' + BG_CRIT_TXT = '\033[45m' + BG_HIGH_TXT = '\033[41m' + BG_MED_TXT = '\033[43m' + BG_LOW_TXT = '\033[44m' + BG_INFO_TXT = '\033[42m' + + BG_SCAN_TXT_START = '\x1b[6;30;42m' + BG_SCAN_TXT_END = '\x1b[0m' + + +# Classifies the Vulnerability's Severity +def vul_info(val): + result ='' + if val == 'c': + result = bcolors.BG_CRIT_TXT+" critical "+bcolors.ENDC + elif val == 'h': + result = bcolors.BG_HIGH_TXT+" high "+bcolors.ENDC + elif val == 'm': + result = bcolors.BG_MED_TXT+" medium "+bcolors.ENDC + elif val == 'l': + result = bcolors.BG_LOW_TXT+" low "+bcolors.ENDC + else: + result = bcolors.BG_INFO_TXT+" info "+bcolors.ENDC + return result + +# Legends +proc_high = bcolors.BADFAIL + "●" + bcolors.ENDC +proc_med = bcolors.WARNING + "●" + bcolors.ENDC +proc_low = bcolors.OKGREEN + "●" + bcolors.ENDC + +# Links the vulnerability with threat level and remediation database +def vul_remed_info(v1,v2,v3, output_mode='text'): + if output_mode == 'text': + print(bcolors.BOLD+"Vulnerability Threat Level"+bcolors.ENDC) + print("\t"+vul_info(v2)+" "+bcolors.WARNING+str(tool_resp[v1][0])+bcolors.ENDC) + print(bcolors.BOLD+"Vulnerability Definition"+bcolors.ENDC) + print("\t"+bcolors.BADFAIL+str(tools_fix[v3-1][1])+bcolors.ENDC) + print(bcolors.BOLD+"Vulnerability Remediation"+bcolors.ENDC) + print("\t"+bcolors.OKGREEN+str(tools_fix[v3-1][2])+bcolors.ENDC) + elif output_mode == 'json': + vuln_data = { + "name": tool_resp[v1][0], + "tool": tool_names[v1][0], + "severity": tool_resp[v1][1], + "definition": tools_fix[v3-1][1], + "remediation": tools_fix[v3-1][2] + } + return vuln_data + + +# scanner Help Context +def helper(): + print(bcolors.OKBLUE+"Information:"+bcolors.ENDC) + print("------------") + print("\t./scanner.py example.com: Scans the domain example.com.") + print("\t./scanner.py example.com --skip nmap: Skip the 'nmap' tests.") + print("\t./scanner.py example.com --tests nmap_poodle sslyze_hbleed: Run ONLY the specified tests.") + print("\t./scanner.py example.com --output json: Output the report in JSON format.") + print("\t./scanner.py --nospinner: Disable the idle loader/spinner.") + print("\t./scanner.py --update : Updates the scanner to the latest version.") + print("\t./scanner.py --help : Displays this help context.") + print(bcolors.OKBLUE+"Interactive:"+bcolors.ENDC) + print("------------") + print("\tCtrl+C: Skips current test.") + print("\tCtrl+Z: Quits scanner.") + print(bcolors.OKBLUE+"Legends:"+bcolors.ENDC) + print("--------") + print("\t["+proc_high+"]: Scan process may take longer times (not predictable).") + print("\t["+proc_med+"]: Scan process may take less than 10 minutes.") + print("\t["+proc_low+"]: Scan process may take less than a minute or two.") + print(bcolors.OKBLUE+"Vulnerability Information:"+bcolors.ENDC) + print("--------------------------") + print("\t"+vul_info('c')+": Requires immediate attention as it may lead to compromise or service unavailability.") + print("\t"+vul_info('h')+" : May not lead to an immediate compromise, but there are considerable chances for probability.") + print("\t"+vul_info('m')+" : Attacker may correlate multiple vulnerabilities of this type to launch a sophisticated attack.") + print("\t"+vul_info('l')+" : Not a serious issue, but it is recommended to tend to the finding.") + print("\t"+vul_info('i')+" : Not classified as a vulnerability, simply an useful informational alert to be considered.\n") + + +# Clears Line +def clear(): + sys.stdout.write("\033[F") + sys.stdout.write("\033[K") #clears until EOL + +# scanner Logo +def logo(): + print(bcolors.WARNING) + logo_ascii = """ + + █▀ █▀▀ █▀▀ █░█ █▀█ █ ▀█▀ █▄█   █▀ █▀▀ ▄▀█ █▄░█ █▄░█ █▀▀ █▀█ + ▄█ ██▄ █▄▄ █▄█ █▀▄ █ ░█░ ░█░   ▄█ █▄▄ █▀█ █░▀█ █░▀█ ██▄ █▀▄ + """+bcolors.ENDC+"""(The Multi-Tool Vulnerability Scanner) + """ + print(logo_ascii) + print(bcolors.ENDC) + + +# Initiliazing the idle loader/spinner class +class Spinner: + busy = False + delay = 0.005 # 0.05 + + @staticmethod + def spinning_cursor(): + while 1: + for cursor in ' ': yield cursor + def __init__(self, delay=None): + self.spinner_generator = self.spinning_cursor() + if delay and float(delay): self.delay = delay + self.disabled = False + + def spinner_task(self): + inc = 0 + try: + while self.busy: + if not self.disabled: + x = bcolors.BG_SCAN_TXT_START+next(self.spinner_generator)+bcolors.BG_SCAN_TXT_END + inc = inc + 1 + print(x,end='') + if inc>random.uniform(0,terminal_size()): #30 init + print(end="\r") + bcolors.BG_SCAN_TXT_START = '\x1b[6;30;'+str(round(random.uniform(40,47)))+'m' + inc = 0 + sys.stdout.flush() + time.sleep(self.delay) + if not self.disabled: + sys.stdout.flush() + + except (KeyboardInterrupt, SystemExit): + print("\n\t"+ bcolors.BG_ERR_TXT+"scanner received a series of Ctrl+C hits. Quitting..." +bcolors.ENDC) + sys.exit(1) + + def start(self): + self.busy = True + try: + threading.Thread(target=self.spinner_task).start() + except Exception as e: + print("\n") + + def stop(self): + try: + self.busy = False + time.sleep(self.delay) + except (KeyboardInterrupt, SystemExit): + print("\n\t"+ bcolors.BG_ERR_TXT+"scanner received a series of Ctrl+C hits. Quitting..." +bcolors.ENDC) + sys.exit(1) + +# End ofloader/spinner class + +# Instantiating the spinner/loader class +spinner = Spinner() + + + +# Scanners that will be used and filename rotation (default: enabled (1)) +tool_names = [ + #1 + ["host","Host - Checks for existence of IPV6 address.","host",1], + + #2 + ["aspnet_config_err","ASP.Net Misconfiguration - Checks for ASP.Net Misconfiguration.","wget",1], + + #3 + ["wp_check","WordPress Checker - Checks for WordPress Installation.","wget",1], + + #4 + ["drp_check", "Drupal Checker - Checks for Drupal Installation.","wget",1], + + #5 + ["joom_check", "Joomla Checker - Checks for Joomla Installation.","wget",1], + + #6 + ["nmap","Nmap - Fast Scan [Only Few Port Checks]","nmap",1], + + #7 + ["whois","WHOis - Checks for Administrator's Contact Information.","whois",1], + + #8 + ["nmap_header","Nmap [XSS Filter Check] - Checks if XSS Protection Header is present.","nmap",1], + + #9 + ["nmap_sloris","Nmap [Slowloris DoS] - Checks for Slowloris Denial of Service Vulnerability.","nmap",1], + + #10 + ["sslyze_hbleed","SSLyze - Checks only for Heartbleed Vulnerability.","sslyze",1], + + #11 + ["nmap_poodle","Nmap [POODLE] - Checks only for Poodle Vulnerability.","nmap",1], + + #12 + ["nmap_ccs","Nmap [OpenSSL CCS Injection] - Checks only for CCS Injection.","nmap",1], + + #13 + ["nmap_freak","Nmap [FREAK] - Checks only for FREAK Vulnerability.","nmap",1], + + #14 + ["nmap_logjam","Nmap [LOGJAM] - Checks for LOGJAM Vulnerability.","nmap",1], + + #15 + ["sslyze_ocsp","SSLyze - Checks for OCSP Stapling.","sslyze",1], + + #16 + ["sslyze_zlib","SSLyze - Checks for ZLib Deflate Compression.","sslyze",1], + + #17 + ["sslyze_reneg","SSLyze - Checks for Secure Renegotiation Support and Client Renegotiation.","sslyze",1], + + #18 + ["sslyze_resum","SSLyze - Checks for Session Resumption Support with [Session IDs/TLS Tickets].","sslyze",1], + + #19 + ["dnsenum_zone_transfer","DNSEnum - Attempts Zone Transfer.","dnsenum",1], + + #20 + ["nmap_telnet","Nmap [TELNET] - Checks if TELNET service is running.","nmap",1], + + #21 + ["nmap_ftp","Nmap [FTP] - Checks if FTP service is running.","nmap",1], + + #22 + ["nmap_stuxnet","Nmap [STUXNET] - Checks if the host is affected by STUXNET Worm.","nmap",1], + + #23 + ["nmap_sqlserver","Nmap - Checks for MS-SQL Server DB","nmap",1], + + #24 + ["nmap_mysql", "Nmap - Checks for MySQL DB","nmap",1], + + #25 + ["nmap_oracle", "Nmap - Checks for ORACLE DB","nmap",1], + + #26 + ["nmap_rdp_udp","Nmap - Checks for Remote Desktop Service over UDP","nmap",1], + + #27 + ["nmap_rdp_tcp","Nmap - Checks for Remote Desktop Service over TCP","nmap",1], + + #28 + ["aspnet_elmah_axd","Checks for ASP.net Elmah Logger","wget",1], + + #29 + ["nmap_tcp_smb","Checks for SMB Service over TCP","nmap",1], + + #30 + ["nmap_udp_smb","Checks for SMB Service over UDP","nmap",1], + + #31 + ["nmap_iis","Nmap - Checks for IIS WebDAV","nmap",1], + + ] + + +# Command that is used to initiate the tool (with parameters and extra params) +tool_cmd = [ + #1 + ["host ",""], + + #2 + ["wget -O /tmp/scanner_temp_aspnet_config_err --tries=1 ","/%7C~.aspx"], + + #3 + ["wget -O /tmp/scanner_temp_wp_check --tries=1 ","/wp-admin"], + + #4 + ["wget -O /tmp/scanner_temp_drp_check --tries=1 ","/user"], + + #5 + ["wget -O /tmp/scanner_temp_joom_check --tries=1 ","/administrator"], + + #6 + ["nmap -F --open -Pn ",""], + + #7 + ["whois ",""], + + #8 + ["nmap -p80 --script http-security-headers -Pn ",""], + + #9 + ["nmap -p80,443 --script http-slowloris --max-parallelism 500 -Pn ",""], + + #10 + ["sslyze --heartbleed ",""], + + #11 + ["nmap -p443 --script ssl-poodle -Pn ",""], + + #12 + ["nmap -p443 --script ssl-ccs-injection -Pn ",""], + + #13 + ["nmap -p443 --script ssl-enum-ciphers -Pn ",""], + + #14 + ["nmap -p443 --script ssl-dh-params -Pn ",""], + + #15 + ["sslyze --certinfo=basic ",""], + + #16 + ["sslyze --compression ",""], + + #17 + ["sslyze --reneg ",""], + + #18 + ["sslyze --resum ",""], + + #19 + ["dnsenum ",""], + + #20 + ["nmap -p23 --open -Pn ",""], + + #21 + ["nmap -p21 --open -Pn ",""], + + #22 + ["nmap --script stuxnet-detect -p445 -Pn ",""], + + #23 + ["nmap -p1433 --open -Pn ",""], + + #23 + ["nmap -p3306 --open -Pn ",""], + + #24 + ["nmap -p1521 --open -Pn ",""], + + #25 + ["nmap -p3389 --open -sU -Pn ",""], + + #26 + ["nmap -p3389 --open -sT -Pn ",""], + + #27 + ["wget -O /tmp/scanner_temp_aspnet_elmah_axd --tries=1 ","/elmah.axd"], + + #28 + ["nmap -p445,137-139 --open -Pn ",""], + + #29 + ["nmap -p137,138 --open -Pn ",""], + + #30 + ["nmap -p80 --script=http-iis-webdav-vuln -Pn ",""], +] + + + +# Tool Responses (Begins) [Responses + Severity (c - critical | h - high | m - medium | l - low | i - informational) + Reference for Vuln Definition and Remediation] +tool_resp = [ + #1 + ["Does not have an IPv6 Address. It is good to have one.","i",1], + + #2 + ["ASP.Net is misconfigured to throw server stack errors on screen.","m",2], + + #3 + ["WordPress Installation Found. Check for vulnerabilities corresponds to that version.","i",3], + + #4 + ["Drupal Installation Found. Check for vulnerabilities corresponds to that version.","i",4], + + #5 + ["Joomla Installation Found. Check for vulnerabilities corresponds to that version.","i",5], + + #6 + ["Some ports are open. Perform a full-scan manually.","l",6], + + #7 + ["Whois Information Publicly Available.","i",7], + + #8 + ["XSS Protection Filter is Disabled.","m",8], + + #9 + ["Vulnerable to Slowloris Denial of Service.","c",9], + + #10 + ["HEARTBLEED Vulnerability Found with SSLyze.","h",10], + + #11 + ["POODLE Vulnerability Detected.","h",11], + + #12 + ["OpenSSL CCS Injection Detected.","h",12], + + #13 + ["FREAK Vulnerability Detected.","h",13], + + #14 + ["LOGJAM Vulnerability Detected.","h",14], + + #15 + ["Unsuccessful OCSP Response.","m",15], + + #16 + ["Server supports Deflate Compression.","m",16], + + #17 + ["Secure Client Initiated Renegotiation is supported.","m",17], + + #18 + ["Secure Resumption unsupported with (Sessions IDs/TLS Tickets).","m",18], + + #19 + ["Zone Transfer Successful using DNSEnum. Reconfigure DNS immediately.","h",19], + + #20 + ["Telnet Service Detected.","h",20], + + #21 + ["FTP Service Detected.","c",21], + + #22 + ["Vulnerable to STUXNET.","c",22], + + #23 + ["MS-SQL DB Service Detected.","l",23], + + #24 + ["MySQL DB Service Detected.","l",24], + + #25 + ["ORACLE DB Service Detected.","l",25], + + #26 + ["RDP Server Detected over UDP.","h",26], + + #27 + ["RDP Server Detected over TCP.","h",27], + + #28 + ["Elmah is Configured.","m",28], + + #29 + ["SMB Ports are Open over TCP","m",29], + + #30 + ["SMB Ports are Open over UDP","m",30], + + #31 + ["IIS WebDAV is Enabled","m",31] + ] + +# Tool Responses (Ends) + + + +# Tool Status (Response Data + Response Code (if status check fails and you still got to push it + Legends + Approx Time + Tool Identification + Bad Responses) +tool_status = [ + #1 + ["has IPv6",1,proc_low," < 15s","ipv6",["not found","has IPv6"]], + + #2 + ["Server Error",0,proc_low," < 30s","asp.netmisconf",["unable to resolve host address","Connection timed out"]], + + #3 + ["wp-login",0,proc_low," < 30s","wpcheck",["unable to resolve host address","Connection timed out"]], + + #4 + ["drupal",0,proc_low," < 30s","drupalcheck",["unable to resolve host address","Connection timed out"]], + + #5 + ["joomla",0,proc_low," < 30s","joomlacheck",["unable to resolve host address","Connection timed out"]], + + #6 + ["tcp open",0,proc_med," < 2m","nmapopen",["Failed to resolve"]], + + #7 + ["Admin Email:",0,proc_low," < 25s","whois",["No match for domain"]], + + #8 + ["XSS filter is disabled",0,proc_low," < 20s","nmapxssh",["Failed to resolve"]], + + #9 + ["VULNERABLE",0,proc_high," < 45m","nmapdos",["Failed to resolve"]], + + #10 + ["Server is vulnerable to Heartbleed",0,proc_low," < 40s","sslyzehb",["Could not resolve hostname"]], + + #11 + ["VULNERABLE",0,proc_low," < 35s","nmap2",["Failed to resolve"]], + + #12 + ["VULNERABLE",0,proc_low," < 35s","nmap3",["Failed to resolve"]], + + #13 + ["VULNERABLE",0,proc_low," < 30s","nmap4",["Failed to resolve"]], + + #14 + ["VULNERABLE",0,proc_low," < 35s","nmap5",["Failed to resolve"]], + + #15 + ["ERROR - OCSP response status is not successful",0,proc_low," < 25s","sslyze1",["Could not resolve hostname"]], + + #16 + ["VULNERABLE",0,proc_low," < 30s","sslyze2",["Could not resolve hostname"]], + + #17 + ["VULNERABLE",0,proc_low," < 25s","sslyze3",["Could not resolve hostname"]], + + #18 + ["VULNERABLE",0,proc_low," < 30s","sslyze4",["Could not resolve hostname"]], + + #19 + ["AXFR record query failed:",1,proc_low," < 45s","dnsenumzt",["NS record query failed:","AXFR record query failed","no NS record for"]], + + #20 + ["open",0,proc_low," < 15s","nmaptelnet",["Failed to resolve"]], + + #21 + ["open",0,proc_low," < 15s","nmapftp",["Failed to resolve"]], + + #22 + ["open",0,proc_low," < 20s","nmapstux",["Failed to resolve"]], + + #23 + ["open",0,proc_low," < 15s","nmapmssql",["Failed to resolve"]], + + #24 + ["open",0,proc_low," < 15s","nmapmysql",["Failed to resolve"]], + + #25 + ["open",0,proc_low," < 15s","nmaporacle",["Failed to resolve"]], + + #26 + ["open",0,proc_low," < 15s","nmapudprdp",["Failed to resolve"]], + + #27 + ["open",0,proc_low," < 15s","nmaptcprdp",["Failed to resolve"]], + + #28 + ["Microsoft SQL Server Error Log",0,proc_low," < 30s","elmahxd",["unable to resolve host address","Connection timed out"]], + + #29 + ["open",0,proc_low," < 20s","nmaptcpsmb",["Failed to resolve"]], + + #30 + ["open",0,proc_low," < 20s","nmapudpsmb",["Failed to resolve"]], + + #31 + ["WebDAV is ENABLED",0,proc_low," < 40s","nmapwebdaviis",["Failed to resolve"]], + + ] + +# Vulnerabilities and Remediation +tools_fix = [ + [1, "Not a vulnerability, just an informational alert. The host does not have IPv6 support. IPv6 provides more security as IPSec (responsible for CIA - Confidentiality, Integrity and Availablity) is incorporated into this model. So it is good to have IPv6 Support.", + "It is recommended to implement IPv6. More information on how to implement IPv6 can be found from this resource. https://www.cisco.com/c/en/us/solutions/collateral/enterprise/cisco-on-cisco/IPv6-Implementation_CS.html"], + [2, "Sensitive Information Leakage Detected. The ASP.Net application does not filter out illegal characters in the URL. The attacker injects a special character (%7C~.aspx) to make the application spit sensitive information about the server stack.", + "It is recommended to filter out special charaters in the URL and set a custom error page on such situations instead of showing default error messages. This resource helps you in setting up a custom error page on a Microsoft .Net Application. https://docs.microsoft.com/en-us/aspnet/web-forms/overview/older-versions-getting-started/deploying-web-site-projects/displaying-a-custom-error-page-cs"], + [3, "It is not bad to have a CMS in WordPress. There are chances that the version may contain vulnerabilities or any third party scripts associated with it may possess vulnerabilities", + "It is recommended to conceal the version of WordPress. This resource contains more information on how to secure your WordPress Blog. https://codex.wordpress.org/Hardening_WordPress"], + [4, "It is not bad to have a CMS in Drupal. There are chances that the version may contain vulnerabilities or any third party scripts associated with it may possess vulnerabilities", + "It is recommended to conceal the version of Drupal. This resource contains more information on how to secure your Drupal Blog. https://www.drupal.org/docs/7/site-building-best-practices/ensure-that-your-site-is-secure"], + [5, "It is not bad to have a CMS in Joomla. There are chances that the version may contain vulnerabilities or any third party scripts associated with it may possess vulnerabilities", + "It is recommended to conceal the version of Joomla. This resource contains more information on how to secure your Joomla Blog. https://www.incapsula.com/blog/10-tips-to-improve-your-joomla-website-security.html"], + [6, "Sometimes robots.txt or sitemap.xml may contain rules such that certain links that are not supposed to be accessed/indexed by crawlers and search engines. Search engines may skip those links but attackers will be able to access it directly.", + "It is a good practice not to include sensitive links in the robots or sitemap files."], + [7, "Without a Web Application Firewall, An attacker may try to inject various attack patterns either manually or using automated scanners. An automated scanner may send hordes of attack vectors and patterns to validate an attack, there are also chances for the application to get DoS`ed (Denial of Service)", + "Web Application Firewalls offer great protection against common web attacks like XSS, SQLi, etc. They also provide an additional line of defense to your security infrastructure. This resource contains information on web application firewalls that could suit your application. https://www.gartner.com/reviews/market/web-application-firewall"], + [8, "Open Ports give attackers a hint to exploit the services. Attackers try to retrieve banner information through the ports and understand what type of service the host is running", + "It is recommended to close the ports of unused services and use a firewall to filter the ports wherever necessary. This resource may give more insights. https://security.stackexchange.com/a/145781/6137"], + [9, "Chances are very less to compromise a target with email addresses. However, attackers use this as a supporting data to gather information around the target. An attacker may make use of the username on the email address and perform brute-force attacks on not just email servers, but also on other legitimate panels like SSH, CMS, etc with a password list as they have a legitimate name. This is however a shoot in the dark scenario, the attacker may or may not be successful depending on the level of interest", + "Since the chances of exploitation is feeble there is no need to take action. Perfect remediation would be choosing different usernames for different services will be more thoughtful."], + [10, "Zone Transfer reveals critical topological information about the target. The attacker will be able to query all records and will have more or less complete knowledge about your host.", + "Good practice is to restrict the Zone Transfer by telling the Master which are the IPs of the slaves that can be given access for the query. This SANS resource provides more information. https://www.sans.org/reading-room/whitepapers/dns/securing-dns-zone-transfer-868"], + [11, "The email address of the administrator and other information (address, phone, etc) is available publicly. An attacker may use these information to leverage an attack. This may not be used to carry out a direct attack as this is not a vulnerability. However, an attacker makes use of these data to build information about the target.", + "Some administrators intentionally would have made this information public, in this case it can be ignored. If not, it is recommended to mask the information. This resource provides information on this fix. http://www.name.com/blog/how-tos/tutorial-2/2013/06/protect-your-personal-information-with-whois-privacy/"], + [12, "As the target is lacking this header, older browsers will be prone to Reflected XSS attacks.", + "Modern browsers does not face any issues with this vulnerability (missing headers). However, older browsers are strongly recommended to be upgraded."], + [13, "This attack works by opening multiple simultaneous connections to the web server and it keeps them alive as long as possible by continously sending partial HTTP requests, which never gets completed. They easily slip through IDS by sending partial requests.", + "If you are using Apache Module, `mod_antiloris` would help. For other setup you can find more detailed remediation on this resource. https://www.acunetix.com/blog/articles/slow-http-dos-attacks-mitigate-apache-http-server/"], + [14, "This vulnerability seriously leaks private information of your host. An attacker can keep the TLS connection alive and can retrieve a maximum of 64K of data per heartbeat.", + "PFS (Perfect Forward Secrecy) can be implemented to make decryption difficult. Complete remediation and resource information is available here. http://heartbleed.com/"], + [15, "By exploiting this vulnerability, an attacker will be able to gain access to sensitive data in a n encrypted session such as session ids, cookies and with those data obtained, will be able to impersonate that particular user.", + "This is a flaw in the SSL 3.0 Protocol. A better remediation would be to disable using the SSL 3.0 protocol. For more information, check this resource. https://www.us-cert.gov/ncas/alerts/TA14-290A"], + [16, "This attacks takes place in the SSL Negotiation (Handshake) which makes the client unaware of the attack. By successfully altering the handshake, the attacker will be able to pry on all the information that is sent from the client to server and vice-versa", + "Upgrading OpenSSL to latest versions will mitigate this issue. This resource gives more information about the vulnerability and the associated remediation. http://ccsinjection.lepidum.co.jp/"], + [17, "With this vulnerability the attacker will be able to perform a MiTM attack and thus compromising the confidentiality factor.", + "Upgrading OpenSSL to latest version will mitigate this issue. Versions prior to 1.1.0 is prone to this vulnerability. More information can be found in this resource. https://bobcares.com/blog/how-to-fix-sweet32-birthday-attacks-vulnerability-cve-2016-2183/"], + [18, "With the LogJam attack, the attacker will be able to downgrade the TLS connection which allows the attacker to read and modify any data passed over the connection.", + "Make sure any TLS libraries you use are up-to-date, that servers you maintain use 2048-bit or larger primes, and that clients you maintain reject Diffie-Hellman primes smaller than 1024-bit. More information can be found in this resource. https://weakdh.org/"], + [19, "Allows remote attackers to cause a denial of service (crash), and possibly obtain sensitive information in applications that use OpenSSL, via a malformed ClientHello handshake message that triggers an out-of-bounds memory access.", + " OpenSSL versions 0.9.8h through 0.9.8q and 1.0.0 through 1.0.0c are vulnerable. It is recommended to upgrade the OpenSSL version. More resource and information can be found here. https://www.openssl.org/news/secadv/20110208.txt"], + [20, "Otherwise termed as BREACH atack, exploits the compression in the underlying HTTP protocol. An attacker will be able to obtain email addresses, session tokens, etc from the TLS encrypted web traffic.", + "Turning off TLS compression does not mitigate this vulnerability. First step to mitigation is to disable Zlib compression followed by other measures mentioned in this resource. http://breachattack.com/"], + [21, "Otherwise termed as Plain-Text Injection attack, which allows MiTM attackers to insert data into HTTPS sessions, and possibly other types of sessions protected by TLS or SSL, by sending an unauthenticated request that is processed retroactively by a server in a post-renegotiation context.", + "Detailed steps of remediation can be found from these resources. https://securingtomorrow.mcafee.com/technical-how-to/tips-securing-ssl-renegotiation/ https://www.digicert.com/news/2011-06-03-ssl-renego/ "], + [22, "This vulnerability allows attackers to steal existing TLS sessions from users.", + "Better advice is to disable session resumption. To harden session resumption, follow this resource that has some considerable information. https://wiki.crashtest-security.com/display/KB/Harden+TLS+Session+Resumption"], + [23, "This has nothing to do with security risks, however attackers may use this unavailability of load balancers as an advantage to leverage a denial of service attack on certain services or on the whole application itself.", + "Load-Balancers are highly encouraged for any application. They improve performance times as well as data availability on during times of server outage. To know more information on load balancers and setup, check this resource. https://www.digitalocean.com/community/tutorials/what-is-load-balancing"], + [24, "An attacker can forwarded requests that comes to the legitimate URL or web application to a third party address or to the attacker's location that can serve malware and affect the end user's machine.", + "It is highly recommended to deploy DNSSec on the host target. Full deployment of DNSSEC will ensure the end user is connecting to the actual web site or other service corresponding to a particular domain name. For more information, check this resource. https://www.cloudflare.com/dns/dnssec/how-dnssec-works/"], + [25, "Attackers may find considerable amount of information from these files. There are even chances attackers may get access to critical information from these files.", + "It is recommended to block or restrict access to these files unless necessary."], + [26, "Attackers may find considerable amount of information from these directories. There are even chances attackers may get access to critical information from these directories.", + "It is recommended to block or restrict access to these directories unless necessary."], + [27, "May not be SQLi vulnerable. An attacker will be able to know that the host is using a backend for operation.", + "Banner Grabbing should be restricted and access to the services from outside would should be made minimum."], + [28, "An attacker will be able to steal cookies, deface web application or redirect to any third party address that can serve malware.", + "Input validation and Output Sanitization can completely prevent Cross Site Scripting (XSS) attacks. XSS attacks can be mitigated in future by properly following a secure coding methodology. The following comprehensive resource provides detailed information on fixing this vulnerability. https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet"], + [29, "SSL related vulnerabilities breaks the confidentiality factor. An attacker may perform a MiTM attack, intrepret and eavesdrop the communication.", + "Proper implementation and upgraded version of SSL and TLS libraries are very critical when it comes to blocking SSL related vulnerabilities."], + [30, "Particular Scanner found multiple vulnerabilities that an attacker may try to exploit the target.", + "Refer to Security-Vulnerability-Report to view the complete information of the vulnerability, once the scan gets completed."], + [31, "Attackers may gather more information from subdomains relating to the parent domain. Attackers may even find other services from the subdomains and try to learn the architecture of the target. There are even chances for the attacker to find vulnerabilities as the attack surface gets larger with more subdomains discovered.", + "It is sometimes wise to block sub domains like development, staging to the outside world, as it gives more information to the attacker about the tech stack. Complex naming practices also help in reducing the attack surface as attackers find hard to perform subdomain bruteforcing through dictionaries and wordlists."], + [32, "Through this deprecated protocol, an attacker may be able to perform MiTM and other complicated attacks.", + "It is highly recommended to stop using this service and it is far outdated. SSH can be used to replace TELNET. For more information, check this resource https://www.ssh.com/ssh/telnet"], + [33, "This protocol does not support secure communication and there are likely high chances for the attacker to eavesdrop the communication. Also, many FTP programs have exploits available in the web such that an attacker can directly crash the application or either get a SHELL access to that target.", + "Proper suggested fix is use an SSH protocol instead of FTP. It supports secure communication and chances for MiTM attacks are quite rare."], + [34, "The StuxNet is level-3 worm that exposes critical information of the target organization. It was a cyber weapon that was designed to thwart the nuclear intelligence of Iran. Seriously wonder how it got here? Hope this isn't a false positive Nmap ;)", + "It is highly recommended to perform a complete rootkit scan on the host. For more information refer to this resource. https://www.symantec.com/security_response/writeup.jsp?docid=2010-071400-3123-99&tabid=3"], + [35, "WebDAV is supposed to contain multiple vulnerabilities. In some case, an attacker may hide a malicious DLL file in the WebDAV share however, and upon convincing the user to open a perfectly harmless and legitimate file, execute code under the context of that user", + "It is recommended to disable WebDAV. Some critical resource regarding disbling WebDAV can be found on this URL. https://www.networkworld.com/article/2202909/network-security/-webdav-is-bad---says-security-researcher.html"], + [36, "Attackers always do a fingerprint of any server before they launch an attack. Fingerprinting gives them information about the server type, content- they are serving, last modification times etc, this gives an attacker to learn more information about the target", + "A good practice is to obfuscate the information to outside world. Doing so, the attackers will have tough time understanding the server's tech stack and therefore leverage an attack."], + [37, "Attackers mostly try to render applications or service useless by flooding the target, such that blocking access to legitimate users. This may affect the business of a company or organization as well as the reputation", + "By ensuring proper load balancers in place, configuring rate limits and multiple connection restrictions, such attacks can be drastically mitigated."], + [38, "Intruders will be able to remotely include shell files and will be able to access the core file system or they will be able to read all the files as well. There are even higher chances for the attacker to remote execute code on the file system.", + "Secure code practices will mostly prevent LFI, RFI and RCE attacks. The following resource gives a detailed insight on secure coding practices. https://wiki.sei.cmu.edu/confluence/display/seccode/Top+10+Secure+Coding+Practices"], + [39, "Hackers will be able to steal data from the backend and also they can authenticate themselves to the website and can impersonate as any user since they have total control over the backend. They can even wipe out the entire database. Attackers can also steal cookie information of an authenticated user and they can even redirect the target to any malicious address or totally deface the application.", + "Proper input validation has to be done prior to directly querying the database information. A developer should remember not to trust an end-user's input. By following a secure coding methodology attacks like SQLi, XSS and BSQLi. The following resource guides on how to implement secure coding methodology on application development. https://wiki.sei.cmu.edu/confluence/display/seccode/Top+10+Secure+Coding+Practices"], + [40, "Attackers exploit the vulnerability in BASH to perform remote code execution on the target. An experienced attacker can easily take over the target system and access the internal sources of the machine", + "This vulnerability can be mitigated by patching the version of BASH. The following resource gives an indepth analysis of the vulnerability and how to mitigate it. https://www.symantec.com/connect/blogs/shellshock-all-you-need-know-about-bash-bug-vulnerability https://www.digitalocean.com/community/tutorials/how-to-protect-your-server-against-the-shellshock-bash-vulnerability"], + [41, "Gives attacker an idea on how the address scheming is done internally on the organizational network. Discovering the private addresses used within an organization can help attackers in carrying out network-layer attacks aiming to penetrate the organization's internal infrastructure.", + "Restrict the banner information to the outside world from the disclosing service. More information on mitigating this vulnerability can be found here. https://portswigger.net/kb/issues/00600300_private-ip-addresses-disclosed"], + [42, "There are chances for an attacker to manipulate files on the webserver.", + "It is recommended to disable the HTTP PUT and DEL methods incase if you don't use any REST API Services. Following resources helps you how to disable these methods. http://www.techstacks.com/howto/disable-http-methods-in-tomcat.html https://docs.oracle.com/cd/E19857-01/820-5627/gghwc/index.html https://developer.ibm.com/answers/questions/321629/how-to-disable-http-methods-head-put-delete-option/"], + [43, "Attackers try to learn more about the target from the amount of information exposed in the headers. An attacker may know what type of tech stack a web application is emphasizing and many other information.", + "Banner Grabbing should be restricted and access to the services from outside would should be made minimum."], + [44, "An attacker who successfully exploited this vulnerability could read data, such as the view state, which was encrypted by the server. This vulnerability can also be used for data tampering, which, if successfully exploited, could be used to decrypt and tamper with the data encrypted by the server.", + "Microsoft has released a set of patches on their website to mitigate this issue. The information required to fix this vulnerability can be inferred from this resource. https://docs.microsoft.com/en-us/security-updates/securitybulletins/2010/ms10-070"], + [45, "Any outdated web server may contain multiple vulnerabilities as their support would've been ended. An attacker may make use of such an opportunity to leverage attacks.", + "It is highly recommended to upgrade the web server to the available latest version."], + [46, "Hackers will be able to manipulate the URLs easily through a GET/POST request. They will be able to inject multiple attack vectors in the URL with ease and able to monitor the response as well", + "By ensuring proper sanitization techniques and employing secure coding practices it will be impossible for the attacker to penetrate through. The following resource gives a detailed insight on secure coding practices. https://wiki.sei.cmu.edu/confluence/display/seccode/Top+10+Secure+Coding+Practices"], + [47, "Since the attacker has knowledge about the particular type of backend the target is running, they will be able to launch a targetted exploit for the particular version. They may also try to authenticate with default credentials to get themselves through.", + "Timely security patches for the backend has to be installed. Default credentials has to be changed. If possible, the banner information can be changed to mislead the attacker. The following resource gives more information on how to secure your backend. http://kb.bodhost.com/secure-database-server/"], + [48, "Attackers may launch remote exploits to either crash the service or tools like ncrack to try brute-forcing the password on the target.", + "It is recommended to block the service to outside world and made the service accessible only through the a set of allowed IPs only really neccessary. The following resource provides insights on the risks and as well as the steps to block the service. https://www.perspectiverisk.com/remote-desktop-service-vulnerabilities/"], + [49, "Hackers will be able to read community strings through the service and enumerate quite a bit of information from the target. Also, there are multiple Remote Code Execution and Denial of Service vulnerabilities related to SNMP services.", + "Use a firewall to block the ports from the outside world. The following article gives wide insight on locking down SNMP service. https://www.techrepublic.com/article/lock-it-down-dont-allow-snmp-to-compromise-network-security/"], + [50, "Attackers will be able to find the logs and error information generated by the application. They will also be able to see the status codes that was generated on the application. By combining all these information, the attacker will be able to leverage an attack.", + "By restricting access to the logger application from the outside world will be more than enough to mitigate this weakness."], + [51, "Cyber Criminals mainly target this service as it is very easier for them to perform a remote attack by running exploits. WannaCry Ransomware is one such example.", + "Exposing SMB Service to the outside world is a bad idea, it is recommended to install latest patches for the service in order not to get compromised. The following resource provides a detailed information on SMB Hardening concepts. https://kb.iweb.com/hc/en-us/articles/115000274491-Securing-Windows-SMB-and-NetBios-NetBT-Services"] + ] + +# Tool Set +tools_precheck = [ + ["nmap"], ["host"], ["wget"], ["whois"], ["sslyze"], ["dnsenum"] + ] + +def get_parser(): + # Create a list of all available test names for the 'choices' argument + all_test_names = [t[0] for t in tool_names] + + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument('-h', '--help', action='store_true', + help='Show help message and exit.') + parser.add_argument('-u', '--update', action='store_true', + help='Update scanner.') + parser.add_argument('--skip', action='append', default=[], + help='Skip some tools or tests', choices=[t[0] for t in tools_precheck]) + parser.add_argument('--tests', nargs='+', default=[], + help='Run ONLY the specified tests by name.', choices=all_test_names) + parser.add_argument('-o', '--output', default='text', + help='Specify output format.', choices=['text', 'json']) + parser.add_argument('-n', '--nospinner', action='store_true', + help='Disable the idle loader/spinner.') + parser.add_argument('target', nargs='?', metavar='URL', help='URL to scan.', default='', type=str) + return parser + + +# --- Global Variables --- +# For accessing list/dictionary elements +arg1 = 0 +arg2 = 1 +arg3 = 2 +arg4 = 3 +arg5 = 4 +arg6 = 5 + +# --- Main Execution --- +if __name__ == "__main__": + if len(sys.argv) == 1: + logo() + helper() + sys.exit(1) + + args_namespace = get_parser().parse_args() + + if args_namespace.nospinner: + spinner.disabled = True + + if args_namespace.help or (not args_namespace.update and not args_namespace.target): + logo() + helper() + sys.exit(0) + + elif args_namespace.update: + logo() + print("scanner is updating....Please wait.\n") + spinner.start() + # Checking internet connectivity first... + rs_internet_availability = check_internet() + if rs_internet_availability == 0: + print("\t"+ bcolors.BG_ERR_TXT + "There seems to be some problem connecting to the internet. Please try again or later." +bcolors.ENDC) + spinner.stop() + sys.exit(1) + cmd = 'sha1sum scanner.py | awk \'{print $1}\'' + try: + oldversion_hash = subprocess.check_output(cmd, shell=True).strip() + os.system('wget -qN https://raw.githubusercontent.com/skavngr/scanner/master/scanner.py -O scanner.py') + newversion_hash = subprocess.check_output(cmd, shell=True).strip() + + if oldversion_hash == newversion_hash : + clear() + print("\t"+ bcolors.OKBLUE +"You already have the latest version of scanner." + bcolors.ENDC) + else: + clear() + print("\t"+ bcolors.OKGREEN +"scanner successfully updated to the latest version." +bcolors.ENDC) + except Exception as e: + print(f"\nUpdate failed: {e}") + finally: + spinner.stop() + sys.exit(0) + + elif args_namespace.target: + target = url_maker(args_namespace.target) + os.system('rm /tmp/scanner_temp_* > /dev/null 2>&1') # Clearing previous scan files + if args_namespace.output == 'text': + os.system('clear') + os.system('setterm -cursor off') + logo() + + # Check for tool availability + unavail_tools_names = [] + if args_namespace.output == 'text': + print(bcolors.BG_HEAD_TXT+"[ Checking Available Security Scanning Tools Phase... Initiated. ]"+bcolors.ENDC) + + for tool_to_check in tools_precheck: + precmd = tool_to_check[arg1] + try: + p = subprocess.Popen([precmd, "--version"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + output, err = p.communicate() + val = output + err + except Exception: + val = b"not found" # Assume not found on exception + + if b"not found" in val or tool_to_check[arg1] in args_namespace.skip: + if b"not found" in val and args_namespace.output == 'text': + print("\t"+bcolors.OKBLUE+tool_to_check[arg1]+bcolors.ENDC+bcolors.BADFAIL+"...unavailable."+bcolors.ENDC) + elif tool_to_check[arg1] in args_namespace.skip and args_namespace.output == 'text': + print("\t"+bcolors.OKBLUE+tool_to_check[arg1]+bcolors.ENDC+bcolors.BADFAIL+"...skipped."+bcolors.ENDC) + + for i, t in enumerate(tool_names): + if t[2] == tool_to_check[arg1]: + tool_names[i][3] = 0 # Disable test + unavail_tools_names.append(tool_to_check[arg1]) + elif args_namespace.output == 'text': + print("\t"+bcolors.OKBLUE+tool_to_check[arg1]+bcolors.ENDC+bcolors.OKGREEN+"...available."+bcolors.ENDC) + + if args_namespace.output == 'text': + unavail_tools_names = list(set(unavail_tools_names)) + if len(unavail_tools_names) == 0: + print("\t"+bcolors.OKGREEN+"All Scanning Tools are available. Complete vulnerability checks will be performed by scanner."+bcolors.ENDC) + else: + print("\t"+bcolors.WARNING+"Some of these tools "+bcolors.BADFAIL+str(unavail_tools_names)+bcolors.ENDC+bcolors.WARNING+" are unavailable or will be skipped. scanner will still perform the rest of the tests. Install these tools to fully utilize the functionality of scanner."+bcolors.ENDC) + print(bcolors.BG_ENDL_TXT+"[ Checking Available Security Scanning Tools Phase... Completed. ]"+bcolors.ENDC) + print("\n") + + + # Filter tests if --tests argument is used + if args_namespace.tests: + all_tools_zipped = list(zip(tool_names, tool_cmd, tool_resp, tool_status)) + specified_tools = [t for t in all_tools_zipped if t[0][0] in args_namespace.tests] + if not specified_tools: + print(f"{bcolors.BADFAIL}Error: No valid tests specified from the list.{bcolors.ENDC}") + sys.exit(1) + # Unzip back to the original lists + tool_names, tool_cmd, tool_resp, tool_status = zip(*specified_tools) + else: + # Shuffle full scan list if not running specific tests + scan_shuffle = list(zip(tool_names, tool_cmd, tool_resp, tool_status)) + random.shuffle(scan_shuffle) + tool_names, tool_cmd, tool_resp, tool_status = zip(*scan_shuffle) + + tool_checks = len(tool_names) + if args_namespace.output == 'text': + print(bcolors.BG_HEAD_TXT+f"[ Scan Phase Initiated... Loaded {tool_checks} vulnerability checks. ]"+bcolors.ENDC) + + # --- Scan Execution --- + runTest = 1 + rs_vul_list_json = [] + rs_skipped_checks = 0 + rs_total_elapsed = 0 + + for tool_index, tool_data in enumerate(tool_names): + if args_namespace.output == 'text': + print("["+tool_status[tool_index][arg3]+tool_status[tool_index][arg4]+"] Deploying "+str(tool_index+1)+"/"+str(tool_checks)+" | "+bcolors.OKBLUE+tool_names[tool_index][arg2]+bcolors.ENDC,) + + if tool_names[tool_index][arg4] == 0: + if args_namespace.output == 'text': + print(bcolors.WARNING+"\nScanning Tool Unavailable. Skipping Test...\n"+bcolors.ENDC) + rs_skipped_checks += 1 + continue + + spinner.start() + scan_start = time.time() + temp_file = f"/tmp/scanner_temp_{tool_names[tool_index][arg1]}" + cmd = tool_cmd[tool_index][arg1] + target + tool_cmd[tool_index][arg2] + " > " + temp_file + " 2>&1" + + try: + subprocess.check_output(cmd, shell=True) + except KeyboardInterrupt: + runTest = 0 + except Exception: + runTest = 1 + + spinner.stop() + scan_stop = time.time() + elapsed = scan_stop - scan_start + rs_total_elapsed += elapsed + + if runTest == 1: + if args_namespace.output == 'text': + sys.stdout.write(ERASE_LINE) + print(bcolors.OKBLUE+"\nScan Completed in "+display_time(int(elapsed))+bcolors.ENDC, end='\r', flush=True) + print("\n") + + try: + with open(temp_file, 'r', errors='ignore') as f: + rs_tool_output_file = f.read() + except FileNotFoundError: + rs_tool_output_file = "" + + # Check for vulnerabilities + found = False + if tool_status[tool_index][arg2] == 0: # Checks if the success string IS present + if tool_status[tool_index][arg1].lower() in rs_tool_output_file.lower(): + found = True + else: # Checks if the failure string is NOT present + if not any(i.lower() in rs_tool_output_file.lower() for i in tool_status[tool_index][arg6]): + found = True + + if found: + if args_namespace.output == 'text': + vul_remed_info(tool_index, tool_resp[tool_index][arg2], tool_resp[tool_index][arg3]) + elif args_namespace.output == 'json': + vuln_data = vul_remed_info(tool_index, tool_resp[tool_index][arg2], tool_resp[tool_index][arg3], output_mode='json') + vuln_data['raw_output'] = rs_tool_output_file + rs_vul_list_json.append(vuln_data) + else: + runTest = 1 + if args_namespace.output == 'text': + sys.stdout.write(ERASE_LINE) + print(bcolors.OKBLUE+"\nScan Interrupted in "+display_time(int(elapsed))+bcolors.ENDC, end='\r', flush=True) + print("\n"+bcolors.WARNING + "\tTest Skipped. Performing Next. Press Ctrl+Z to Quit scanner.\n" + bcolors.ENDC) + rs_skipped_checks += 1 + + # --- FIX: Report Generation block was incorrectly indented --- + # --- This block is now at the correct indentation level, after the main for loop --- + if args_namespace.output == 'text': + print(bcolors.BG_ENDL_TXT+"[ Scan Phase Completed. ]"+bcolors.ENDC) + print("\n") + print(bcolors.BG_HEAD_TXT+"[ Report Generation Phase Initiated. ]"+bcolors.ENDC) + # A simple check to see if any vulnerabilities would have been found in text mode. + # Note: `rs_vul_list_json` is only populated in JSON mode, so this logic is an approximation for text mode. + if len(rs_vul_list_json) == 0 and not any(tool_status[i][arg2] == 0 for i in range(len(tool_names))): + print("\t"+bcolors.OKGREEN+"No Vulnerabilities Detected based on scan criteria."+bcolors.ENDC) + + elif args_namespace.output == 'json': + report = { + "summary": { + "target": target, + "total_checks_run": tool_checks - rs_skipped_checks, + "checks_skipped": rs_skipped_checks, + "vulnerabilities_found": len(rs_vul_list_json), + "time_elapsed": display_time(int(rs_total_elapsed)) + }, + "vulnerabilities": rs_vul_list_json + } + with open("Security-Vulnerability-Report.json", "w") as f: + json.dump(report, f, indent=4) + + if args_namespace.output == 'text': + print("\tTotal Number of Vulnerability Checks : "+bcolors.BOLD+bcolors.OKGREEN+str(tool_checks)+bcolors.ENDC) + print("\tTotal Number of Vulnerability Checks Skipped: "+bcolors.BOLD+bcolors.WARNING+str(rs_skipped_checks)+bcolors.ENDC) + # This is an approximation for text mode as the list isn't populated. + # A more robust solution would be needed for an accurate count in text mode. + print("\tTotal Number of Vulnerabilities Detected : "+bcolors.BOLD+bcolors.BADFAIL+"(See above for details)"+bcolors.ENDC) + print("\tTotal Time Elapsed for the Scan : "+bcolors.BOLD+bcolors.OKBLUE+display_time(int(rs_total_elapsed))+bcolors.ENDC) + print(bcolors.BG_ENDL_TXT+"[ Report Generation Phase Completed. ]"+bcolors.ENDC) + + if args_namespace.output == 'text': + os.system('setterm -cursor on') + + # Final cleanup + if os.name != 'nt': + os.system('rm /tmp/scanner_temp_* > /dev/null 2>&1') + diff --git a/scanner_tools.py b/scanner_tools.py new file mode 100644 index 0000000..7ea80ca --- /dev/null +++ b/scanner_tools.py @@ -0,0 +1,121 @@ +import subprocess +import shutil +import time +import json +import os +import requests +import sys + +# --- Tools --- + +def nmap_scan(args: str, target: str) -> str: + """ + Runs an Nmap scan against the target. + Args: + args: Nmap arguments strings (e.g., '-F', '-p80 -sV'). + target: IP address or hostname. + Returns: + The text output of the nmap command. + """ + valid_args = args.replace(";", "").replace("&", "").replace("|", "") # Basic sanitization + cmd = f"nmap {valid_args} {target}" + try: + return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT).decode('utf-8', errors='ignore') + except subprocess.CalledProcessError as e: + return f"Nmap Failed: {e.output.decode('utf-8', errors='ignore')}" + except Exception as e: + return f"Execution Error: {str(e)}" + +def check_dns(target: str) -> str: + """ + Checks for DNS records (A, AAAA, MX, NS) to identify infrastructure. + Args: + target: Hostname to check. + """ + try: + import dns.resolver + out = [] + for rtype in ['A', 'AAAA', 'MX', 'NS']: + try: + ans = dns.resolver.resolve(target, rtype) + out.append(f"{rtype}: {[r.to_text() for r in ans]}") + except: + out.append(f"{rtype}: None") + return "\n".join(out) + except ImportError: + return "Error: dnspython not installed." + except Exception as e: + return f"DNS Error: {e}" + +def analyze_web_headers(url: str) -> str: + """ + Fetches HTTP headers from a URL to check for security configurations. + Args: + url: The URL to check (e.g. http://scanme.nmap.org). + """ + if not url.startswith("http"): + url = "http://" + url + try: + res = requests.get(url, timeout=5, verify=False) + return json.dumps(dict(res.headers), indent=2) + except Exception as e: + return f"Request Failed: {str(e)}" + +def search_exploit_db(query: str) -> str: + """ + Searches ExploitDB/SearchSploit for known exploits. + Args: + query: The search term (e.g., "Apache 2.4", "WordPress"). + """ + if not shutil.which("searchsploit"): + return "Error: 'searchsploit' tool not found. Install exploitdb." + try: + # Limit to top 20 results + cmd = f"searchsploit {query} | head -n 20" + return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT).decode('utf-8', errors='ignore') + except Exception as e: + return f"Search Error: {e}" + +def run_hydra(target: str, service: str, user: str = "admin") -> str: + """ + Runs Hydra to brute-force a service. + Args: + target: IP address. + service: Protocol (ssh, ftp, telnet, rd). + user: Username to test (default: admin). + """ + if not shutil.which("hydra"): + return "Error: 'hydra' tool not found." + + pass_list = "password\n123456\nadmin\nroot\n" + with open("temp_pass.txt", "w") as f: f.write(pass_list) + + cmd = f"hydra -l {user} -P temp_pass.txt {target} {service} -t 4 -W 1 -I" + try: + out = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT).decode('utf-8', errors='ignore') + os.remove("temp_pass.txt") + return out + except Exception as e: + if os.path.exists("temp_pass.txt"): os.remove("temp_pass.txt") + return f"Hydra Error: {e}" + +def packet_capture(interface: str = "any", duration: int = 10) -> str: + """ + Captures network packets using TShark. + Args: + interface: Network interface (default: any). + duration: Seconds to capture. + """ + if not shutil.which("tshark"): + return "Error: 'tshark' (Wireshark) not found." + + filename = f"capture_{int(time.time())}.pcap" + cmd = f"tshark -i {interface} -a duration:{duration} -w {filename}" + try: + subprocess.run(cmd, shell=True, check=True) + return f"Capture saved to {filename}. Analyze this file for traffic patterns." + except Exception as e: + return f"Capture Failed: {e}" + +# List of callable tools for easy registration +ALL_TOOLS = [nmap_scan, check_dns, analyze_web_headers, search_exploit_db, run_hydra, packet_capture] diff --git a/setup_manager.py b/setup_manager.py new file mode 100644 index 0000000..1da6c53 --- /dev/null +++ b/setup_manager.py @@ -0,0 +1,68 @@ +import sys +import shutil +import subprocess +import platform +import os + +class SetupManager: + def __init__(self): + self.os_type = platform.system().lower() # windows, linux, darwin + self.tools = { + "nmap": {"cmd": "nmap", "win": "winget install Insecure.Nmap", "linux": "sudo apt-get install nmap -y", "mac": "brew install nmap"}, + "hydra": {"cmd": "hydra", "win": "winget install thsmi.hydra", "linux": "sudo apt-get install hydra -y", "mac": "brew install hydra"}, + # Searchsploit is often part of exploitdb + "searchsploit": {"cmd": "searchsploit", "win": "echo 'Please install ExploitDB manually or via WSL'", "linux": "sudo apt-get install exploitdb -y", "mac": "brew install exploitdb"}, + "tshark": {"cmd": "tshark", "win": "winget install WiresharkFoundation.Wireshark", "linux": "sudo apt-get install tshark -y", "mac": "brew install wireshark"} + } + + def check_tool(self, tool_name): + """Checks if a tool is installed and available in PATH.""" + return shutil.which(self.tools[tool_name]["cmd"]) is not None + + def get_missing_tools(self): + """Returns a list of tools that are not installed.""" + return [tool for tool in self.tools if not self.check_tool(tool)] + + def install_tool(self, tool_name): + """Attempts to install the tool using the OS-specific command.""" + if tool_name not in self.tools: + return False, "Unknown tool" + + cmd = self.tools[tool_name].get(self.os_type) + if not cmd: + cmd = self.tools[tool_name].get("linux") if self.os_type == "linux" else None + + if not cmd: + return False, f"No install command for {tool_name} on {self.os_type}" + + if self.os_type == "windows" and "winget" in cmd: + # Check if winget exists + if not shutil.which("winget"): + return False, "Winget not found. Please install manually." + + print(f"[*] Installing {tool_name} via: {cmd}") + try: + # shell=True is needed for complex commands/pipes, but be careful with input + subprocess.run(cmd, shell=True, check=True) + return True, "Installed successfully" + except subprocess.CalledProcessError as e: + return False, f"Installation failed: {e}" + except Exception as e: + return False, f"Error: {e}" + + def auto_install_missing(self): + """Attempts to install all missing tools.""" + missing = self.get_missing_tools() + results = {} + for tool in missing: + success, msg = self.install_tool(tool) + results[tool] = msg + return results + +if __name__ == "__main__": + manager = SetupManager() + print(f"OS: {manager.os_type}") + print("Checking tools...") + for tool in manager.tools: + status = "INSTALLED" if manager.check_tool(tool) else "MISSING" + print(f" {tool}: {status}") diff --git a/test_basic.py b/test_basic.py new file mode 100644 index 0000000..043f4af --- /dev/null +++ b/test_basic.py @@ -0,0 +1,20 @@ +import os +import sys + +def test_files_exist(): + """Simple test to verify critical files are present.""" + required_files = [ + "scanner.py", + "scanner_tools.py", + "gui.py", + "requirements.txt" + ] + for f in required_files: + assert os.path.exists(f), f"File {f} is missing" + +def test_imports(): + """Test that modules can be imported without error.""" + try: + import scanner_tools + except ImportError as e: + assert False, f"Failed to import scanner_tools: {e}" diff --git a/vulnscan_cli.ps1 b/vulnscan_cli.ps1 new file mode 100644 index 0000000..b3fbb1d --- /dev/null +++ b/vulnscan_cli.ps1 @@ -0,0 +1,17 @@ +param( + [string]$Target, + [string]$Key +) + +if (-not $Target) { + Write-Host "Usage: .\vulnscan_cli.ps1 -Target [-Key ]" -ForegroundColor Yellow + exit +} + +$argsList = @("scanner.py", "$Target") +if ($Key) { + $argsList += "--key" + $argsList += "$Key" +} + +python $argsList diff --git a/vulnscan_cli.sh b/vulnscan_cli.sh new file mode 100644 index 0000000..4138875 --- /dev/null +++ b/vulnscan_cli.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "Usage: ./vulnscan_cli.sh [api_key]" + exit 1 +fi + +TARGET=$1 +KEY=$2 + +CMD="python3 scanner.py $TARGET" + +if [ ! -z "$KEY" ]; then + CMD="$CMD --key $KEY" +fi + +$CMD From 37d094ac06ad8f3694d5bba78221e49ca68463cb Mon Sep 17 00:00:00 2001 From: Purvansh Bhatt <48984515+purvanshbhatt@users.noreply.github.com> Date: Tue, 16 Dec 2025 10:47:35 -0500 Subject: [PATCH 2/2] feat: Introduce environment variable loading and `mcp_config.json` for server configuration, and refine tool descriptions. --- mcp_config.json | 13 +++++++++++++ mcp_server.py | 31 +++++++++++++++++-------------- requirements.txt | 4 ++++ 3 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 mcp_config.json diff --git a/mcp_config.json b/mcp_config.json new file mode 100644 index 0000000..9be6f20 --- /dev/null +++ b/mcp_config.json @@ -0,0 +1,13 @@ +{ + "mcpServers": { + "vulnerability-scanner": { + "command": "python", + "args": [ + "mcp_server.py" + ], + "env": { + "GOOGLE_CLOUD_PROJECT": "vulnwatch-vvpok" + } + } + } +} \ No newline at end of file diff --git a/mcp_server.py b/mcp_server.py index 45c0b9d..396c90c 100644 --- a/mcp_server.py +++ b/mcp_server.py @@ -1,8 +1,14 @@ - +from mcp.server.fastmcp import FastMCP import os import sys -import importlib.util -from mcp.server.fastmcp import FastMCP +from dotenv import load_dotenv + +# Load environment variables +load_dotenv() + +# Set GCP Project from env or default +gcp_project = os.environ.get("GOOGLE_CLOUD_PROJECT", "vulnwatch-vvpok") +os.environ["GOOGLE_CLOUD_PROJECT"] = gcp_project # Add current dir to path to import scanner_tools sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -10,14 +16,12 @@ try: import scanner_tools except ImportError: - print("Error: scanner_tools.py not found. Please ensure it is in the same directory.") + print("Error: scanner_tools.py not found. Please ensure it is in the same directory.", file=sys.stderr) sys.exit(1) # Initialize FastMCP Server mcp = FastMCP("Vulnerability Scanner Agent") -# --- Register Tools --- - @mcp.tool() def nmap_scan(args: str, target: str) -> str: """ @@ -31,7 +35,7 @@ def nmap_scan(args: str, target: str) -> str: @mcp.tool() def check_dns(target: str) -> str: """ - Checks for DNS records (A, AAAA, MX, NS). + Checks for DNS records (A, AAAA, MX, NS) to identify infrastructure. Args: target: Hostname to check. """ @@ -42,7 +46,7 @@ def analyze_web_headers(url: str) -> str: """ Fetches HTTP headers from a URL to check for security configurations. Args: - url: The URL to check. + url: The URL to check (e.g. http://scanme.nmap.org). """ return scanner_tools.analyze_web_headers(url) @@ -51,18 +55,18 @@ def search_exploit_db(query: str) -> str: """ Searches ExploitDB/SearchSploit for known exploits. Args: - query: The search term. + query: The search term (e.g., "Apache 2.4", "WordPress"). """ return scanner_tools.search_exploit_db(query) @mcp.tool() def run_hydra(target: str, service: str, user: str = "admin") -> str: """ - Runs Hydra to brute-force a service (WARNING: Intrusive). + Runs Hydra to brute-force a service. (WARNING: Use only on authorized targets). Args: target: IP address. service: Protocol (ssh, ftp, telnet, rd). - user: Username to test. + user: Username to test (default: admin). """ return scanner_tools.run_hydra(target, service, user) @@ -71,12 +75,11 @@ def packet_capture(interface: str = "any", duration: int = 10) -> str: """ Captures network packets using TShark. Args: - interface: Network interface. + interface: Network interface (default: any). duration: Seconds to capture. """ return scanner_tools.packet_capture(interface, duration) if __name__ == "__main__": - # Run the server - print("Starting MCP Server...", file=sys.stderr) + print(f"Starting MCP Server for Project: {gcp_project}", file=sys.stderr) mcp.run() diff --git a/requirements.txt b/requirements.txt index 5f7684b..6899a92 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,7 @@ flet agent-framework-azure-ai openai python-dotenv +pyinstaller +mcp +google-auth +google-cloud-aiplatform