info: name: zammad_version_scan author: devjoshi2005 severity: 3 description: > Zammad version scan - detects a Zammad helpdesk instance via its web branding and probes the /api/v1/version endpoint. Properly configured Zammad deployments protect the version endpoint with authentication (unauthenticated requests receive Zammad's distinctive "Authentication required" JSON error); the module reports this as the version-unknown outcome instead of guessing a version. It does not assess vulnerabilities. reference: - https://docs.zammad.org/ - https://github.com/zammad/zammad profiles: - scan - http - info_severity - zammad payloads: - library: http steps: # Step 1: product confirmation on the unauthenticated root page. # Real Zammad serves the single-page application at / with # Zammad (verified against a current public Zammad # instance). Non-Zammad targets cannot match and are never # misreported. - method: get timeout: 3 headers: User-Agent: "{user_agent}" allow_redirects: true ssl: false url: nettacker_fuzzer: input_format: "{{schema}}://{target}:{{ports}}/" prefix: "" suffix: "" interceptors: data: schema: - "http" - "https" ports: - 80 - 443 - 8080 response: condition_type: and log: "Zammad helpdesk detected, version not assessed (version endpoint requires authentication)" conditions: status_code: regex: "200" reverse: false content: regex: "(?i)zammad" reverse: false # Step 2: version unknown outcome - the unauthenticated version API is # rejected with Zammad's distinctive JSON error (verified on a current # Zammad instance: "error_human":"Authentication required" among the # returned keys). "Version unknown" is a # first-class outcome, never a guessed version. Reverse proxies and # other products reject the same request with HTML pages, so they # cannot trigger this step. - method: get timeout: 3 headers: User-Agent: "{user_agent}" allow_redirects: false ssl: false url: nettacker_fuzzer: input_format: "{{schema}}://{target}:{{ports}}/api/v1/version" prefix: "" suffix: "" interceptors: data: schema: - "http" - "https" ports: - 80 - 443 - 8080 response: condition_type: and log: "Zammad version endpoint accessible, version unknown (protected by authentication)" conditions: status_code: regex: "401|403" reverse: false content: regex: '"error_human"\s*:\s*"Authentication required"' reverse: false