Skip to content

Grafana Enumeration

3 min read Created Sep 14, 2026 Last updated Sep 14, 2026

Grafana is a monitoring and visualization platform that runs on port 3000 by default. Enumeration identifies the version, checks for default credentials, and maps accessible API endpoints. Many Grafana instances allow unauthenticated access to dashboards or use default credentials (admin:admin), making it a frequent low-hanging target in internal networks and CTFs.

Version Detection

The login page and API both expose the Grafana version.

┌──(kali㉿kali)-[~]
└─$ curl -s http://$TARGET_IP:3000/api/health | python3 -m json.tool
{
  "commit": "e531e4e",
  "database": "ok",
  "version": "8.2.6"
}

Version is critical for CVE matching. Versions before 8.3.0 are vulnerable to CVE-2021-43798 (directory traversal).

┌──(kali㉿kali)-[~]
└─$ curl -s http://$TARGET_IP:3000/login | grep -oP 'Grafana v[0-9.]+'
Grafana v8.2.6

Default Credentials

Grafana ships with default credentials admin:admin. On first login it prompts for a password change, but many instances skip this.

┌──(kali㉿kali)-[~]
└─$ curl -s -o /dev/null -w '%{http_code}' http://admin:admin@$TARGET_IP:3000/api/org
200

HTTP 200 means default credentials work. 401 means they were changed. Try other common passwords: admin:grafana, admin:password.

Anonymous Access

Grafana can be configured to allow anonymous (unauthenticated) access to dashboards. Check whether the API responds without credentials.

┌──(kali㉿kali)-[~]
└─$ curl -s http://$TARGET_IP:3000/api/dashboards/home | python3 -m json.tool

A JSON response with dashboard data instead of a 401/redirect means anonymous access is enabled. Dashboards may expose internal hostnames, database connection strings, and infrastructure topology.

Dashboard and Datasource Enumeration

With valid credentials (or anonymous access), list all dashboards and configured data sources.

┌──(kali㉿kali)-[~]
└─$ curl -s -u admin:admin http://$TARGET_IP:3000/api/search?query= | python3 -m json.tool
[
  {
    "id": 1,
    "uid": "abc123",
    "title": "Infrastructure Overview",
    "uri": "db/infrastructure-overview",
    "type": "dash-db"
  },
  {
    "id": 2,
    "uid": "def456",
    "title": "Database Monitoring",
    "uri": "db/database-monitoring",
    "type": "dash-db"
  }
]

Dashboard titles reveal what systems are monitored. Open each by UID for connection strings, internal IPs, and credential references in panel queries.

┌──(kali㉿kali)-[~]
└─$ curl -s -u admin:admin http://$TARGET_IP:3000/api/datasources | python3 -m json.tool
[
  {
    "id": 1,
    "name": "Prometheus",
    "type": "prometheus",
    "url": "http://10.10.10.50:9090",
    "access": "proxy",
    "isDefault": true
  },
  {
    "id": 2,
    "name": "MySQL",
    "type": "mysql",
    "url": "10.10.10.51:3306",
    "access": "proxy",
    "database": "webapp",
    "user": "grafana_reader"
  }
]

Data sources reveal internal hosts, database names, and service accounts. The proxy access mode means Grafana proxies queries to the data source, which can be abused for SSRF.

User and Organization Enumeration

┌──(kali㉿kali)-[~]
└─$ curl -s -u admin:admin http://$TARGET_IP:3000/api/users | python3 -m json.tool

Returns usernames, emails, and roles. Admin users can reset other users' passwords via the API.

API Key Enumeration

Admin users can list and create API keys. Existing API keys may have broader access than the compromised account.

┌──(kali㉿kali)-[~]
└─$ curl -s -u admin:admin http://$TARGET_IP:3000/api/auth/keys | python3 -m json.tool

Existing API keys are listed but their secret values are not shown. Create a new admin API key if needed for persistent access.

If the version is below 8.3.0, check CVE-2021-43798 directory traversal for unauthenticated file read.

References