diff --git a/CONTRIBUTORS.svg b/CONTRIBUTORS.svg index 1be72c9..9d42b19 100644 --- a/CONTRIBUTORS.svg +++ b/CONTRIBUTORS.svg @@ -1,12 +1,12 @@ - + - - + + - + \ No newline at end of file diff --git a/core/app.py b/core/app.py index 6a0130d..fc2cb8b 100644 --- a/core/app.py +++ b/core/app.py @@ -16,10 +16,16 @@ class Scanner: - def __init__(self, timeout: int = 10, proxies: Dict[str, str] = {}): + def __init__( + self, + timeout: int = 10, + headers: Dict[str, str] = {}, + proxies: Dict[str, str] = {}, + ): self.found: List[Tuple[str, str]] = [] self.timeout = timeout self.proxies = proxies + self.headers = headers self.user_agents = ( Path(f"{base_dir}/txt/user_agents.txt").read_text().splitlines() ) @@ -57,6 +63,7 @@ def start(self, targets: List[str], workers: int = 10): def send(self, url: str): user_agent = random.choice(self.user_agents) headers = {"User-Agent": user_agent} + headers.update(self.headers) try: response = requests.get( url, @@ -67,13 +74,13 @@ def send(self, url: str): ).text for pattern in self.sql_errors: pattern = pattern.strip() + self._lock.acquire() if re.findall(pattern, response): - self._lock.acquire() self.found.append((url, pattern)) console.print( f"[yellow bold]>>> [/yellow bold] {url} [red bold]{pattern}[/red bold]" ) - self._lock.release() + self._lock.release() except KeyboardInterrupt: exit() diff --git a/core/cli.py b/core/cli.py index 2577682..d3f14e3 100644 --- a/core/cli.py +++ b/core/cli.py @@ -2,12 +2,33 @@ from pathlib import Path import os.path import argparse +import re # add anything you want to be global here console = Console() base_dir = Path(__file__).resolve().parent.parent +# Convert string headers to a dict Headers +def extract_headers(headers: str) -> dict: + """ + >>> extract_headers('User-agent: YES') + {'User-agent':'YES'} + >>> extract_headers('User-agent: YES\nHacker: 3') + {'User-agent':'YES','Hacker':'3'} + """ + headers = headers.replace("\\n", "\n") + sorted_headers = {} + matches = re.findall(r"(.*):\s(.*)", headers) + for match in matches: + header = match[0] + value = match[1] + if value[-1] == ",": + value = value[:-1] + sorted_headers[header] = value + return sorted_headers + + def cli_opts() -> argparse.Namespace: parser = argparse.ArgumentParser(description="A simple tool to detect SQL errors") parser.add_argument( @@ -21,6 +42,7 @@ def cli_opts() -> argparse.Namespace: "-w", "--workers", help="Number of threads", required=False, type=int, default=10 ) parser.add_argument("-p", "--proxy", help="Proxy host", required=False) + parser.add_argument("-H","--header", help="Custom header", required=False) parser.add_argument( "-t", "--timeout", help="Connection timeout", required=False, default=10, type=int ) diff --git a/sqlidetector.py b/sqlidetector.py index 83f84fd..b417979 100644 --- a/sqlidetector.py +++ b/sqlidetector.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 from sys import stdin, argv -from core.cli import cli_opts, print_logo +from core.cli import cli_opts, extract_headers, print_logo from core.app import Scanner @@ -17,11 +17,15 @@ def main(): timeout = opts.timeout workers = opts.workers + if opts.header: + headers = extract_headers(opts.header) + else: + headers = {} if opts.proxy: proxy = {"http": opts.proxy, "https": opts.proxy} else: proxy = {} - app = Scanner(timeout, proxy) + app = Scanner(timeout,headers, proxy) app.start(targets, workers) if opts.output: app.write_report(opts.output)