diff --git a/README_port_scanner.md b/README_port_scanner.md new file mode 100644 index 0000000..a84f6a0 --- /dev/null +++ b/README_port_scanner.md @@ -0,0 +1,84 @@ +# Port Scanner CLI + +This is a simple, multi-threaded TCP port scanner written in Python. It is designed to find open ports on a target host. + +## Features + +* Scans a target host (IP address or hostname). +* Supports scanning a range of ports, a list of ports, or a single port. +* Uses multiple threads for faster scanning. +* Clear and simple output of open ports. + +## Prerequisites + +* Python 3.6+ +* No external libraries are required. + +## How to Run + +1. **Navigate to the project directory.** + Ensure you have the `port_scanner_main.py` script and the `port_scanner` directory. + +2. **Run the application from your terminal.** + Provide the target host and optionally a port range. + + ```bash + python port_scanner_main.py [options] + ``` + +### Command-Line Options + +* `host`: (Required) The target host to scan (e.g., `127.0.0.1`, `example.com`). +* `-p, --ports`: (Optional) The port range to scan. Defaults to `1-1024`. + * Formats: + * Range: `1-65535` + * Comma-separated list: `80,443,8080` + * Single port: `22` +* `-t, --threads`: (Optional) The number of threads to use for scanning. Defaults to `20`. + +### Example Usage + +**Scan the default port range (1-1024) on localhost:** +```bash +python port_scanner_main.py 127.0.0.1 +``` + +**Scan a specific range of ports on a remote host:** +```bash +python port_scanner_main.py example.com -p 1-200 +``` + +**Scan specific ports:** +```bash +python port_scanner_main.py example.com --ports 22,80,443 +``` + +**Increase the number of threads for a faster scan:** +```bash +python port_scanner_main.py scanme.nmap.org -t 50 +``` + +**Example Output:** +``` +Scanning host scanme.nmap.org for open ports... + +--- Open Ports Found! --- + [+] Port 22 is open + [+] Port 80 is open +``` + +## Disclaimer + +* **LEGALITY**: Unauthorized port scanning of networks is illegal in many countries. This tool is intended for educational purposes and for use on networks where you have explicit permission to conduct scanning. The user assumes all liability for any misuse of this tool. +* **ACCURACY**: The accuracy of the scan can be affected by firewalls, intrusion detection systems (IDS), and network latency. A port that is reported as closed may be filtered or blocked. +* **PERFORMANCE**: Scanning a large range of ports can take a significant amount of time, even with multiple threads. + +## File Structure +``` +. +├── port_scanner_main.py # Main CLI application script +├── port_scanner/ +│ ├── __init__.py # Makes port_scanner a Python package +│ └── scanner.py # Core logic for port scanning +└── README_port_scanner.md # This documentation file +``` diff --git a/README_pwned_checker.md b/README_pwned_checker.md new file mode 100644 index 0000000..6338822 --- /dev/null +++ b/README_pwned_checker.md @@ -0,0 +1,103 @@ +# Account Pwned Checker CLI + +This tool checks if an email account has been compromised in a known data breach by using the 'Have I Been Pwned?' (HIBP) API. + +## Features + +* Checks a single email address against the HIBP database. +* Lists the details of each breach found for the account. +* Provides clear output for both compromised and non-compromised accounts. + +## Prerequisites + +* Python 3.6+ +* `requests` library +* A 'Have I Been Pwned?' API Key + +## Installation & Setup + +1. **Get an API Key:** + * You must have an API key to use the HIBP API. You can get one for free from the [HIBP API Key Page](https://haveibeenpwned.com/API/Key). + * Once you have your key, open the `pwned_checker/checker.py` file. + * Replace the placeholder `"YOUR_API_KEY_HERE"` with your actual API key: + ```python + # In pwned_checker/checker.py + headers = { + "hibp-api-key": "YOUR_API_KEY_HERE" # <-- PASTE YOUR KEY HERE + } + ``` + +2. **Navigate to the project directory.** + Make sure you have the `pwned_main.py` script and the `pwned_checker` directory. + +3. **Create a virtual environment (recommended):** + ```bash + python -m venv venv_pwned + source venv_pwned/bin/activate # On Windows: venv_pwned\Scripts\activate + ``` + +4. **Install dependencies:** + Navigate to the `pwned_checker` directory and run: + ```bash + pip install -r requirements.txt + ``` + +## How to Run + +1. Open your terminal or command prompt. +2. Make sure your virtual environment is activated. +3. Navigate to the root directory containing `pwned_main.py`. +4. Run the application with the email you want to check: + ```bash + python pwned_main.py "some.email@example.com" + ``` + +### Example Usage + +**To check an email:** +```bash +python pwned_main.py "test@example.com" +``` + +**Example Output (If Breaches are Found):** +``` +Checking account: test@example.com + +--- Account Found in Breaches! --- +The account 'test@example.com' was found in the following breaches: + + - Breach: Adobe + Domain: adobe.com + Date: 2013-10-04 + Description: In October 2013, 153 million Adobe accounts were breached... + + - Breach: MyFitnessPal + Domain: myfitnesspal.com + Date: 2018-02-25 + Description: In February 2018, the health and fitness service MyFitnessPal suffered a data breach... +``` + +**Example Output (If No Breaches are Found):** +``` +Checking account: a.secure.email@example.com + +--- No Breaches Found --- +The account 'a.secure.email@example.com' was not found in any known breaches. +``` + +## Disclaimer + +* This tool relies on the 'Have I Been Pwned?' service. Its accuracy is dependent on the data maintained by HIBP. +* A "not found" result does not guarantee an account is secure, only that it has not appeared in a breach known to HIBP. +* Handle your API key securely. Do not commit it to public repositories. The method of placing it directly in the source code is for simplicity; for more secure applications, use environment variables or a secrets management system. + +## File Structure +``` +. +├── pwned_main.py # Main CLI application script +├── pwned_checker/ +│ ├── __init__.py # Makes pwned_checker a Python package +│ ├── checker.py # Logic for interacting with the HIBP API +│ └── requirements.txt # Python dependencies +└── README_pwned_checker.md # This documentation file +``` diff --git a/README_sensitive_data_scanner.md b/README_sensitive_data_scanner.md new file mode 100644 index 0000000..d8cfd7c --- /dev/null +++ b/README_sensitive_data_scanner.md @@ -0,0 +1,86 @@ +# Sensitive Data Scanner CLI + +This tool recursively scans a specified directory to find sensitive data patterns within files, such as API keys, private keys, and credit card numbers. + +## Features + +* Scans all files within a directory and its subdirectories. +* Uses a predefined set of regular expressions to identify potential sensitive information. +* Reports the file path and the type of sensitive data found. + +## Patterns Detected + +The scanner looks for the following patterns: +* AWS Access Key ID +* AWS Secret Access Key (Note: this pattern is broad and may cause false positives) +* Google API Key +* Generic API Key patterns +* RSA and SSH Private Keys (looks for the header) +* Credit Card Numbers (Visa, Mastercard, American Express, Discover) +* U.S. Social Security Numbers + +## Prerequisites + +* Python 3.6+ +* No external libraries are required. + +## How to Run + +1. **Navigate to the project directory.** + Ensure you have the `scanner_main.py` script and the `sensitive_data_scanner` directory. + +2. **Run the application from your terminal.** + Provide the path to the directory you want to scan as a command-line argument. + + ```bash + python scanner_main.py /path/to/your/directory + ``` + +### Example Usage + +**To scan a directory named `my_project`:** +```bash +python scanner_main.py ./my_project +``` + +**Example Output:** +``` +Scanning directory: ./my_project + +--- Sensitive Data Found! --- + +[+] File: ./my_project/config/prod.env + - Found 1 instance(s) of 'AWS Access Key ID' + Example: AKIAIOSFODNN7EXAMPLE + - Found 1 instance(s) of 'AWS Secret Access Key' + Example: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + +[+] File: ./my_project/src/dev/test_keys.txt + - Found 1 instance(s) of 'RSA Private Key' + Example: -----BEGIN RSA PRIVATE KEY----- +``` + +**If no data is found:** +``` +Scanning directory: ./clean_project + +--- No Sensitive Data Found --- +Scan complete. No files with matching sensitive data patterns were found. +``` + +## Disclaimer + +* **This tool is not foolproof.** It uses regular expressions to find patterns, which can result in both **false positives** (flagging data that is not sensitive) and **false negatives** (missing sensitive data that doesn't match a pattern). +* The results should be manually reviewed to confirm if the flagged data is truly sensitive. +* This tool is intended for educational and basic scanning purposes. For enterprise-grade data loss prevention (DLP), consider using more advanced, dedicated security solutions. +* The tool reads all files as text. It may not be effective on binary files and will ignore files it cannot read due to permissions or encoding issues. + +## File Structure +``` +. +├── scanner_main.py # Main CLI application script +├── sensitive_data_scanner/ +│ ├── __init__.py # Makes sensitive_data_scanner a Python package +│ └── scanner.py # Core logic for file scanning and regex matching +└── README_sensitive_data_scanner.md # This documentation file +``` diff --git a/index.html b/index.html index 452ca1f..83cf480 100644 --- a/index.html +++ b/index.html @@ -1,35 +1,63 @@ - - - - - - - - - - React App - - - -
- - - + + + + Cybersecurity Tools Collection + + + +

Cybersecurity Tools Collection

+

This repository contains a collection of various security-related tools. Click on a tool's documentation to learn more about its functionality and how to use it.

+ + diff --git a/port_scanner/__init__.py b/port_scanner/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/port_scanner/scanner.py b/port_scanner/scanner.py new file mode 100644 index 0000000..65a7042 --- /dev/null +++ b/port_scanner/scanner.py @@ -0,0 +1,53 @@ +import socket +from concurrent.futures import ThreadPoolExecutor, as_completed + +def scan_port(host, port, timeout=0.5): + """ + Scans a single port on a target host. + + Args: + host (str): The target host IP address or hostname. + port (int): The port to scan. + timeout (float): Connection timeout in seconds. + + Returns: + True if the port is open, False otherwise. + """ + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(timeout) + try: + s.connect((host, port)) + return True + except (socket.timeout, ConnectionRefusedError, socket.gaierror, OSError): + return False + finally: + s.close() + +def scan_ports(host, start_port, end_port, max_workers=20): + """ + Scans a range of ports on a target host using multiple threads. + + Args: + host (str): The target host IP address or hostname. + start_port (int): The starting port of the range. + end_port (int): The ending port of the range. + max_workers (int): The maximum number of threads to use. + + Returns: + A sorted list of open ports. + """ + open_ports = [] + with ThreadPoolExecutor(max_workers=max_workers) as executor: + # Create a future for each port scan + future_to_port = {executor.submit(scan_port, host, port): port for port in range(start_port, end_port + 1)} + + for future in as_completed(future_to_port): + port = future_to_port[future] + try: + if future.result(): + open_ports.append(port) + except Exception as exc: + # Can be useful for debugging if something goes wrong with a future + pass + + return sorted(open_ports) diff --git a/port_scanner_main.py b/port_scanner_main.py new file mode 100644 index 0000000..823c049 --- /dev/null +++ b/port_scanner_main.py @@ -0,0 +1,50 @@ +import argparse +import sys +from port_scanner import scanner + +def main(): + parser = argparse.ArgumentParser(description="A simple TCP port scanner.") + parser.add_argument("host", help="The target host to scan (IP address or hostname).") + parser.add_argument("-p", "--ports", dest="port_range", default="1-1024", + help="Port range to scan (e.g., '1-1024', '80,443', '22'). Defaults to '1-1024'.") + parser.add_argument("-t", "--threads", dest="threads", type=int, default=20, + help="Number of threads to use for scanning. Defaults to 20.") + args = parser.parse_args() + + target_host = args.host + port_range_str = args.port_range + num_threads = args.threads + + ports_to_scan = [] + try: + # Handle different formats like '1-1024' or '80,443' or '22' + if '-' in port_range_str: + start, end = map(int, port_range_str.split('-')) + ports_to_scan = range(start, end + 1) + elif ',' in port_range_str: + ports_to_scan = [int(p.strip()) for p in port_range_str.split(',')] + else: + ports_to_scan = [int(port_range_str)] + except ValueError: + print(f"Error: Invalid port range format '{port_range_str}'. Use formats like '1-1024', '80,443', or '22'.") + sys.exit(1) + + print(f"Scanning host {target_host} for open ports...") + + # In this implementation, we will pass the start and end of the main range. + # A more complex implementation would handle disjointed lists of ports. + start_port = min(ports_to_scan) + end_port = max(ports_to_scan) + + open_ports = scanner.scan_ports(target_host, start_port, end_port, max_workers=num_threads) + + if not open_ports: + print("\n--- No Open Ports Found ---") + print(f"No open ports were found in the specified range on {target_host}.") + else: + print("\n--- Open Ports Found! ---") + for port in open_ports: + print(f" [+] Port {port} is open") + +if __name__ == "__main__": + main() diff --git a/pwned_checker/__init__.py b/pwned_checker/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pwned_checker/checker.py b/pwned_checker/checker.py new file mode 100644 index 0000000..299b406 --- /dev/null +++ b/pwned_checker/checker.py @@ -0,0 +1,30 @@ +import requests +import json + +API_URL = "https://haveibeenpwned.com/api/v3/breachedaccount/{account}" + +def check_pwned(account): + """ + Checks the 'Have I Been Pwned?' API for a given account. + + Args: + account (str): The email address to check. + + Returns: + A list of breach data if found, None otherwise. + """ + headers = { + "hibp-api-key": "YOUR_API_KEY_HERE" # A free API key can be obtained from https://haveibeenpwned.com/API/Key + } + try: + response = requests.get(API_URL.format(account=account), headers=headers, timeout=10) + if response.status_code == 200: + return response.json() + elif response.status_code == 404: + return None # Not found, so not pwned + else: + print(f"Error: Received status code {response.status_code} from the API.") + return None + except requests.exceptions.RequestException as e: + print(f"An error occurred: {e}") + return None diff --git a/pwned_checker/requirements.txt b/pwned_checker/requirements.txt new file mode 100644 index 0000000..f229360 --- /dev/null +++ b/pwned_checker/requirements.txt @@ -0,0 +1 @@ +requests diff --git a/pwned_main.py b/pwned_main.py new file mode 100644 index 0000000..4d02849 --- /dev/null +++ b/pwned_main.py @@ -0,0 +1,28 @@ +import argparse +from pwned_checker import checker + +def main(): + parser = argparse.ArgumentParser(description="Check if an email account has been compromised in a data breach using the 'Have I Been Pwned?' service.") + parser.add_argument("email", help="The email address to check.") + args = parser.parse_args() + + print(f"Checking account: {args.email}") + breaches = checker.check_pwned(args.email) + + if breaches: + print("\n--- Account Found in Breaches! ---") + print(f"The account '{args.email}' was found in the following breaches:") + for breach in breaches: + print(f"\n - Breach: {breach['Name']}") + print(f" Domain: {breach.get('Domain', 'N/A')}") + print(f" Date: {breach.get('BreachDate', 'N/A')}") + print(f" Description: {breach.get('Description', 'N/A')}") + elif breaches is None: + print("\n--- No Breaches Found ---") + print(f"The account '{args.email}' was not found in any known breaches.") + else: + print("\n--- An Error Occurred ---") + print("Could not retrieve data. Please check your API key and internet connection.") + +if __name__ == "__main__": + main() diff --git a/scanner_main.py b/scanner_main.py new file mode 100644 index 0000000..d1948f6 --- /dev/null +++ b/scanner_main.py @@ -0,0 +1,32 @@ +import argparse +import os +from sensitive_data_scanner import scanner + +def main(): + parser = argparse.ArgumentParser(description="Scan a directory for files containing sensitive data like API keys, private keys, and credit card numbers.") + parser.add_argument("directory", help="The directory to scan recursively.") + args = parser.parse_args() + + if not os.path.isdir(args.directory): + print(f"Error: Directory not found at '{args.directory}'") + return + + print(f"Scanning directory: {args.directory}\n") + all_findings = scanner.scan_directory(args.directory) + + if not all_findings: + print("--- No Sensitive Data Found ---") + print("Scan complete. No files with matching sensitive data patterns were found.") + return + + print("--- Sensitive Data Found! ---") + for filepath, findings in all_findings.items(): + print(f"\n[+] File: {filepath}") + for pattern_name, matches in findings.items(): + print(f" - Found {len(matches)} instance(s) of '{pattern_name}'") + # To avoid printing too much data, maybe just show the first match or a count + # For now, let's print the first match to give an idea of what was found + print(f" Example: {matches[0]}") + +if __name__ == "__main__": + main() diff --git a/sensitive_data_scanner/__init__.py b/sensitive_data_scanner/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sensitive_data_scanner/scanner.py b/sensitive_data_scanner/scanner.py new file mode 100644 index 0000000..1d52ceb --- /dev/null +++ b/sensitive_data_scanner/scanner.py @@ -0,0 +1,63 @@ +import re +import os + +# Pre-compiled regex patterns for performance +SENSITIVE_DATA_PATTERNS = { + "AWS Access Key ID": re.compile(r"AKIA[0-9A-Z]{16}"), + "AWS Secret Access Key": re.compile(r"(?i)[a-z0-9\/+]{40}"), # This is a broad pattern, may have false positives + "Google API Key": re.compile(r"AIza[0-9A-Za-z\-_]{35}"), + "Generic API Key": re.compile(r"[aA][pP][iI]_?[kK][eE][yY].*['|\"]([a-zA-Z0-9-_.]{16,})['|\"]"), + "RSA Private Key": re.compile(r"-----BEGIN RSA PRIVATE KEY-----"), + "SSH Private Key": re.compile(r"-----BEGIN OPENSSH PRIVATE KEY-----"), + "Credit Card (Visa)": re.compile(r"4[0-9]{12}(?:[0-9]{3})?"), + "Credit Card (Mastercard)": re.compile(r"5[1-5][0-9]{14}"), + "Credit Card (Amex)": re.compile(r"3[47][0-9]{13}"), + "Credit Card (Discover)": re.compile(r"6(?:011|5[0-9]{2})[0-9]{12}"), + "Social Security Number": re.compile(r"\d{3}-\d{2}-\d{4}") +} + +def scan_file(filepath): + """ + Scans a single file for sensitive data patterns. + + Args: + filepath (str): The path to the file to scan. + + Returns: + A dictionary of findings, with the key being the pattern name + and the value being a list of found strings. + """ + findings = {} + try: + with open(filepath, 'r', encoding='utf-8', errors='ignore') as f: + content = f.read() + for pattern_name, regex in SENSITIVE_DATA_PATTERNS.items(): + matches = regex.findall(content) + if matches: + if pattern_name not in findings: + findings[pattern_name] = [] + findings[pattern_name].extend(matches) + except Exception as e: + # Could be a binary file or a permissions error + pass # Silently ignore files that can't be read + return findings + +def scan_directory(directory): + """ + Recursively scans a directory for files containing sensitive data. + + Args: + directory (str): The path to the directory to scan. + + Returns: + A dictionary where keys are file paths and values are dictionaries + of findings for that file. + """ + all_findings = {} + for root, _, files in os.walk(directory): + for filename in files: + filepath = os.path.join(root, filename) + file_findings = scan_file(filepath) + if file_findings: + all_findings[filepath] = file_findings + return all_findings