diff --git a/README.md b/README.md index 06157bd..7fd0377 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,7 @@ To customize the deception server installation several **environment variables** | `CANARY_TOKEN_URL` | External canary token URL | None | | `DASHBOARD_SECRET_PATH` | Custom dashboard path | Auto-generated | | `PROBABILITY_ERROR_CODES` | Error response probability (0-100%) | `0` | -| `SERVER_HEADER` | HTTP Server header for deception | `Apache/2.2.22 (Ubuntu)` | +| `SERVER_HEADER` | HTTP Server header for deception, if not set use random server header | | | `TIMEZONE` | IANA timezone for logs and dashboard (e.g., `America/New_York`, `Europe/Rome`) | System timezone | ## robots.txt diff --git a/docker-compose.yaml b/docker-compose.yaml index 600034d..6f81a47 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -20,7 +20,7 @@ services: - MAX_COUNTER=10 - CANARY_TOKEN_TRIES=10 - PROBABILITY_ERROR_CODES=0 - - SERVER_HEADER=Apache/2.2.22 (Ubuntu) + # - SERVER_HEADER=Apache/2.2.22 (Ubuntu) # Optional: Set your canary token URL # - CANARY_TOKEN_URL=http://canarytokens.com/api/users/YOUR_TOKEN/passwords.txt # Optional: Set custom dashboard path (auto-generated if not set) diff --git a/helm/templates/configmap.yaml b/helm/templates/configmap.yaml index c08aaa5..2990f61 100644 --- a/helm/templates/configmap.yaml +++ b/helm/templates/configmap.yaml @@ -14,8 +14,13 @@ data: MAX_COUNTER: {{ .Values.config.maxCounter | quote }} CANARY_TOKEN_TRIES: {{ .Values.config.canaryTokenTries | quote }} PROBABILITY_ERROR_CODES: {{ .Values.config.probabilityErrorCodes | quote }} - SERVER_HEADER: {{ .Values.config.serverHeader | quote }} CANARY_TOKEN_URL: {{ .Values.config.canaryTokenUrl | quote }} + {{- if .Values.config.dashboardSecretPath }} + DASHBOARD_SECRET_PATH: {{ .Values.config.dashboardSecretPath | quote }} + {{- end }} + {{- if .Values.config.serverHeader }} + SERVER_HEADER: {{ .Values.config.serverHeader | quote }} + {{- end }} {{- if .Values.config.timezone }} TIMEZONE: {{ .Values.config.timezone | quote }} {{- end }} diff --git a/helm/values.yaml b/helm/values.yaml index ac51756..8a6bc1d 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -73,7 +73,9 @@ config: maxCounter: 10 canaryTokenTries: 10 probabilityErrorCodes: 0 - serverHeader: "Apache/2.2.22 (Ubuntu)" +# timezone: "UTC" +# serverHeader: "Apache/2.2.22 (Ubuntu)" +# dashboardSecretPath: "/my-secret-dashboard" # canaryTokenUrl: set-your-canary-token-url-here # timezone: "UTC" # IANA timezone (e.g., "America/New_York", "Europe/Rome"). If not set, system timezone is used. @@ -269,6 +271,17 @@ wordlists: - .git/ - keys/ - credentials/ + server_headers: + - Apache/2.2.22 (Ubuntu) + - nginx/1.18.0 + - Microsoft-IIS/10.0 + - LiteSpeed + - Caddy + - Gunicorn/20.0.4 + - uvicorn/0.13.4 + - Express + - Flask/1.1.2 + - Django/3.1 error_codes: - 400 - 401 diff --git a/src/config.py b/src/config.py index 2d5e645..f3bf7f0 100644 --- a/src/config.py +++ b/src/config.py @@ -23,7 +23,7 @@ class Config: api_server_port: int = 8080 api_server_path: str = "/api/v2/users" probability_error_codes: int = 0 # Percentage (0-100) - server_header: str = "Apache/2.2.22 (Ubuntu)" + server_header: Optional[str] = None # Database settings database_path: str = "data/krawl.db" database_retention_days: int = 30 @@ -84,9 +84,10 @@ class Config: api_server_url=os.getenv('API_SERVER_URL'), api_server_port=int(os.getenv('API_SERVER_PORT', 8080)), api_server_path=os.getenv('API_SERVER_PATH', '/api/v2/users'), - server_header=os.getenv('SERVER_HEADER', 'Apache/2.2.22 (Ubuntu)'), + probability_error_codes=int(os.getenv('PROBABILITY_ERROR_CODES', 0)), + server_header=os.getenv('SERVER_HEADER') database_path=os.getenv('DATABASE_PATH', 'data/krawl.db'), database_retention_days=int(os.getenv('DATABASE_RETENTION_DAYS', 30)), - probability_error_codes=int(os.getenv('PROBABILITY_ERROR_CODES', 0)), timezone=os.getenv('TIMEZONE') # If not set, will use system timezone + ) diff --git a/src/generators.py b/src/generators.py index 16c0c32..6e24ba8 100644 --- a/src/generators.py +++ b/src/generators.py @@ -9,7 +9,8 @@ import string import json from templates import html_templates from wordlists import get_wordlists - +from config import Config +from logger import get_app_logger def random_username() -> str: """Generate random username""" @@ -36,6 +37,16 @@ def random_email(username: str = None) -> str: username = random_username() return f"{username}@{random.choice(wl.email_domains)}" +def random_server_header() -> str: + """Generate random server header""" + + if Config.from_env().server_header: + server_header = Config.from_env().server_header + else: + wl = get_wordlists() + server_header = random.choice(wl.server_headers) + + return server_header def random_api_key() -> str: """Generate random API key""" diff --git a/src/handler.py b/src/handler.py index 90214ac..a45661d 100644 --- a/src/handler.py +++ b/src/handler.py @@ -13,7 +13,7 @@ from templates import html_templates from templates.dashboard_template import generate_dashboard from generators import ( credentials_txt, passwords_txt, users_json, api_keys_json, - api_response, directory_listing + api_response, directory_listing, random_server_header ) from wordlists import get_wordlists @@ -52,7 +52,7 @@ class Handler(BaseHTTPRequestHandler): def version_string(self) -> str: """Return custom server version for deception.""" - return self.config.server_header + return random_server_header() def _should_return_error(self) -> bool: """Check if we should return an error based on probability""" diff --git a/src/wordlists.py b/src/wordlists.py index 62e4045..342930a 100644 --- a/src/wordlists.py +++ b/src/wordlists.py @@ -57,7 +57,8 @@ class Wordlists: }, "users": { "roles": ["Administrator", "User"] - } + }, + "server_headers": ["Apache/2.4.41 (Ubuntu)", "nginx/1.18.0"] } @property @@ -111,6 +112,10 @@ class Wordlists: @property def error_codes(self): return self._data.get("error_codes", []) + + @property + def server_headers(self): + return self._data.get("server_headers", []) _wordlists_instance = None diff --git a/wordlists.json b/wordlists.json index f1aae81..fddf3d3 100644 --- a/wordlists.json +++ b/wordlists.json @@ -193,5 +193,13 @@ 500, 502, 503 + ], + "server_headers": [ + "Apache/2.4.41 (Ubuntu)", + "nginx/1.18.0", + "Microsoft-IIS/10.0", + "cloudflare", + "AmazonS3", + "gunicorn/20.1.0" ] }