Lucene search
+L

Azure Storage Service Probe

🗓️ 10 Jul 2026 11:31:42Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 3 Views

Azure Storage Service Probe scans for anonymous listing of Queue, Table, and File services.

Refs
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Probe Azure Queue, Table, and File storage services for anonymous exposure."""

from __future__ import annotations

import json

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


SERVICE_PATHS = {
    "queue": "/?comp=list",
    "table": "/Tables",
    "file": "/?comp=list",
}


class Module(Scanner, Http_client):
    __info__ = {
        "name": "Azure Storage Service Probe",
        "description": (
            "Probe Azure Queue, Table, and File endpoints for anonymous listing or "
            "readable responses (complements blob-focused modules)."
        ),
        "author": ["KittySploit Team"],
        "severity": "medium",
        "tags": ["cloud", "scanner", "azure", "storage", "queue", "table", "file"],
        "agent": {
            "risk": "active",
            "effects": ["network_probe"],
            "expected_requests": 4,
            "reversible": True,
            "approval_required": False,
            "produces": ["tech_hints", "risk_signals"],
        },
    }

    account = OptString("", "Storage account name (e.g. myaccount)", required=True)
    services = OptString("queue,table,file", "Comma-separated services to probe", required=False)
    output_file = OptString("", "Optional JSON output file", required=False)

    def _service_list(self):
        raw = str(self.services or "queue,table,file")
        return [item.strip().lower() for item in raw.split(",") if item.strip()]

    def _host_for_service(self, service: str, account: str) -> str:
        suffix = {
            "queue": "queue.core.windows.net",
            "table": "table.core.windows.net",
            "file": "file.core.windows.net",
        }.get(service)
        return f"{account}.{suffix}" if suffix else ""

    def _classify(self, service: str, status_code: int, body: str, headers) -> str:
        text = (body or "").lower()
        hdrs = {str(k).lower(): str(v) for k, v in (headers or {}).items()}
        if status_code == 200:
            if service == "queue" and "<enumerationresults" in text:
                return "public_listing"
            if service == "table" and ("<feed" in text or "<table" in text):
                return "public_listing"
            if service == "file" and ("<shares>" in text or "<enumerationresults" in text):
                return "public_listing"
            return "accessible"
        if status_code in (401, 403) and any(k.startswith("x-ms-") for k in hdrs):
            return "auth_required"
        if "storage services" in text or "x-ms-" in text:
            return "service_detected"
        return "unknown"

    def run(self):
        account = str(self.account or "").strip().lower()
        if not account:
            print_error("Storage account name is required")
            return False

        findings = []
        for service in self._service_list():
            host = self._host_for_service(service, account)
            if not host:
                continue
            old_target = self.target
            old_port = getattr(self, "port", 443)
            old_ssl = getattr(self, "ssl", True)
            try:
                self.target = host
                self.port = 443
                self.ssl = True
                path = SERVICE_PATHS.get(service, "/")
                resp = self.http_request(method="GET", path=path, allow_redirects=False)
            finally:
                self.target = old_target
                self.port = old_port
                self.ssl = old_ssl

            if not resp:
                continue
            signal = self._classify(service, resp.status_code, resp.text or "", resp.headers)
            item = {
                "service": service,
                "host": host,
                "path": path,
                "status_code": resp.status_code,
                "signal": signal,
            }
            findings.append(item)
            if signal in ("public_listing", "accessible"):
                print_warning(f"[{service}] {host}{path} -> {signal} ({resp.status_code})")
            elif signal == "auth_required":
                print_info(f"[{service}] {host} requires authentication")
            else:
                print_info(f"[{service}] {host} -> {signal}")

        if not findings:
            return False

        exposed = [f for f in findings if f["signal"] in ("public_listing", "accessible")]
        if exposed:
            self.set_info(
                severity="high",
                reason=f"{len(exposed)} Azure storage service(s) anonymously accessible",
                findings=findings,
            )
            if self.output_file:
                self._save(findings)
            return True

        detected = [f for f in findings if f["signal"] != "unknown"]
        if detected:
            self.set_info(severity="info", reason="Azure storage services detected", findings=findings)
            if self.output_file:
                self._save(findings)
            return True
        return False

    def _save(self, findings):
        try:
            with open(str(self.output_file), "w") as fp:
                json.dump({"findings": findings}, fp, indent=2)
            print_success(f"Results saved to {self.output_file}")
        except Exception as exc:
            print_error(f"Failed to save output: {exc}")

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

10 Jul 2026 11:31Current
5.8Medium risk
Vulners AI Score5.8
3