Lucene search
+L

IIS Shortname Disclosure

🗓️ 31 Jul 2026 18:12:07Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 2 Views

IIS tilde (~) / 8.3 short-name enumeration vulnerability.

Refs
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""IIS shortname (8.3) disclosure (NSE http-iis-short-name-brute)."""

from kittysploit import *
from lib.protocols.http.http_client import Http_client


class Module(Scanner, Http_client):
    __info__ = {
        "name": "IIS Shortname Disclosure",
        "description": (
            "Detects IIS tilde (~) / 8.3 short-name enumeration vulnerability by comparing "
            "status codes for existing vs non-existing shortname probes "
            "(NSE http-iis-short-name-brute)."
        ),
        "author": ["KittySploit Team"],
        "severity": "medium",
        "references": ["https://nmap.org/nsedoc/scripts/http-iis-short-name-brute.html"],
        "tags": ["http", "iis", "shortname", "scanner", "misconfig", "windows"],
        "agent": {
            "risk": "active",
            "effects": ["network_probe"],
            "expected_requests": 4,
            "reversible": True,
            "approval_required": False,
            "produces": ["tech_hints", "risk_signals"],
        },
    }

    def run(self):
        # Require an IIS fingerprint and a repeatable differential. A single
        # status-code difference is commonly caused by WAFs and route catch-alls.
        valid_paths = ("/*~1*/a.aspx", "/*~1*/b.aspx")
        invalid_paths = (
            "/1234567890*~1*/a.aspx",
            "/9876543210*~1*/b.aspx",
        )
        valid = [
            self.http_request(method="OPTIONS", path=path, allow_redirects=False)
            for path in valid_paths
        ]
        invalid = [
            self.http_request(method="OPTIONS", path=path, allow_redirects=False)
            for path in invalid_paths
        ]
        responses = valid + invalid
        if any(response is None for response in responses):
            return False

        headers = {
            str(key).lower(): str(value).lower()
            for response in responses
            for key, value in (getattr(response, "headers", None) or {}).items()
        }
        server_hint = headers.get("server", "")
        powered_by = headers.get("x-powered-by", "")
        if "microsoft-iis" not in server_hint and "asp.net" not in powered_by:
            return False

        valid_codes = [int(response.status_code) for response in valid]
        invalid_codes = [int(response.status_code) for response in invalid]
        if len(set(valid_codes)) != 1 or len(set(invalid_codes)) != 1:
            return False
        code_a = valid_codes[0]
        code_b = invalid_codes[0]
        if code_a == code_b:
            return False
        self.set_info(
            severity="medium",
            reason="Repeatable IIS shortname (~) differential response detected",
            status_existing_probe=code_a,
            status_missing_probe=code_b,
            confidence="high",
        )
        return True

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

29 Sep 2026 10:07Current
5.8Medium risk
Vulners AI Score5.8
2