AWS Hacking öğrenin ve pratik yapın:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
GCP Hacking öğrenin ve pratik yapın: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
* [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
* **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**'i takip edin.**
Eğer PHP'de `==` kullanılıyorsa, beklenmedik durumlar ortaya çıkabilir ve karşılaştırma beklenildiği gibi davranmayabilir. Bunun nedeni, "==" yalnızca aynı türe dönüştürülmüş değerleri karşılaştırmasıdır; karşılaştırılan verilerin türlerinin de aynı olduğunu kontrol etmek istiyorsanız `===` kullanmalısınız.
*`"string" == 0 -> True` Sayı ile başlamayan bir dize, bir sayıya eşittir
*`"0xAAAA" == "43690" -> True` Onaltılık veya ondalık formatta sayılardan oluşan dizeler, sayılar aynıysa diğer sayılar/dizeler ile True sonucu verecek şekilde karşılaştırılabilir (bir dizideki sayılar, sayılar olarak yorumlanır)
*`"0e3264578" == 0 --> True` "0e" ile başlayan ve ardından herhangi bir şey gelen bir dize, 0'a eşit olacaktır
*`"0X3264578" == 0X --> True` "0" ile başlayan ve ardından herhangi bir harf (X herhangi bir harf olabilir) ve ardından herhangi bir şey gelen bir dize, 0'a eşit olacaktır
*`"0e12334" == "0" --> True` Bu çok ilginçtir çünkü bazı durumlarda "0" dizesinin girdiğini ve bununla karşılaştırılan bazı içeriklerin kontrolünü sağlayabilirsiniz. Bu nedenle, "0e" ile başlayan ve herhangi bir harf içermeyen bir hash oluşturacak bir değer sağlayabilirseniz, karşılaştırmayı atlatabilirsiniz. Bu formatta **zaten hashlenmiş dizeleri** burada bulabilirsiniz: [https://github.com/spaze/hashes](https://github.com/spaze/hashes)
Daha fazla bilgi için [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
**Tür Değiştirme** varsayılan olarak `in_array()` fonksiyonunu da etkiler (katı bir karşılaştırma yapmak için üçüncü argümanı true olarak ayarlamanız gerekir):
Eğer bu fonksiyon **herhangi bir kimlik doğrulama kontrolü** için kullanılıyorsa (şifre kontrolü gibi) ve kullanıcı karşılaştırmanın bir tarafını kontrol ediyorsa, şifre değeri olarak bir dize yerine boş bir dizi gönderebilir (`https://example.com/login.php/?username=admin&password[]=`) ve bu kontrolü atlayabilir:
`===`**kullanılıyor olsa bile**, **karşılaştırmayı****tip dönüşümüne****duyarlı** hale getiren hatalar olabilir. Örneğin, eğer karşılaştırma **karşılaştırmadan önce veriyi farklı bir tür nesneye dönüştürüyorsa**:
**`preg_match()`** kullanıcı girişi **doğrulamak** için kullanılabilir (kullanıcı girişi üzerinde herhangi bir **kelime/regex****kara liste**'den **varsa** kontrol eder ve eğer yoksa, kod çalışmaya devam edebilir).
Ancak, regexp'nin başlangıcını belirlerken `preg_match()`**kullanıcı girişinin sadece ilk satırını kontrol eder**, bu nedenle eğer bir şekilde girişi **birden fazla satırda****gönderebilirseniz**, bu kontrolü atlatabilirsiniz. Örnek:
Bu kontrolü atlamak için **değerin yeni satırlarla urlencoded olarak gönderilmesi** (`%0A`) veya **JSON verisi** gönderebiliyorsanız, **birkaç satırda** gönderebilirsiniz:
(Bu atlatma, görünüşe göre PHP 5.2.5 üzerinde denendi ve PHP 7.3.15 üzerinde çalıştıramadım)\
Eğer `preg_match()`'e geçerli çok **büyük bir girdi** gönderebilirseniz, **işleyemeyecek** ve kontrolü **atlatabileceksiniz**. Örneğin, bir JSON'u kara listeye alıyorsa şunu gönderebilirsiniz:
Trick from: [https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223](https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223) and [https://mizu.re/post/pong](https://mizu.re/post/pong)
Kısacası, sorun PHP'deki `preg_*` fonksiyonlarının [PCRE kütüphanesi](http://www.pcre.org/) üzerine inşa edilmesinden kaynaklanıyor. PCRE'de belirli düzenli ifadeler, çok sayıda özyinelemeli çağrı kullanılarak eşleştirilir, bu da çok fazla yığın alanı kullanır. İzin verilen özyineleme sayısı için bir sınır belirlemek mümkündür, ancak PHP'de bu sınır [varsayılan olarak 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) olup, bu yığın içinde sığacak olandan fazladır.
[Bu Stackoverflow başlığı](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) da bu konunun daha derinlemesine tartışıldığı gönderide bağlantılıydı. Görevimiz şimdi açıktı:\
**Regex'in 100\_000+ özyineleme yapmasını sağlayacak bir girdi gönderin, bu da SIGSEGV'ye neden olacak, `preg_match()` fonksiyonunun `false` döndürmesini sağlayacak ve böylece uygulama girdimizin kötü niyetli olmadığını düşünecek, yükün sonunda `{system(<verybadcommand>)}` gibi bir sürpriz atarak SSTI --> RCE --> flag :) elde edeceğiz.**
Aslında regex terimleriyle, 100k "özyineleme" yapmıyoruz, bunun yerine "geri izleme adımlarını" sayıyoruz, ki [PHP belgeleri](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) buna varsayılan olarak `pcre.backtrack_limit` değişkeninde 1\_000\_000 (1M) olduğunu belirtmektedir.\
Eğer PHP başka bir sayfaya yönlendiriyorsa ancak başlık `Location` ayarlandıktan sonra **`die`** veya **`exit`** fonksiyonu çağrılmadıysa, PHP çalışmaya devam eder ve verileri gövdeye ekler:
* **register\_globals**: **PHP < 4.1.1.1**'de veya yanlış yapılandırıldığında, **register\_globals** aktif olabilir (veya davranışları taklit ediliyor olabilir). Bu, $\_GET gibi global değişkenlerde bir değer varsa örneğin $\_GET\["param"]="1234", **$param üzerinden erişebileceğiniz anlamına gelir. Bu nedenle, HTTP parametreleri göndererek, kod içinde kullanılan değişkenleri** geçersiz kılabilirsiniz.
* **Aynı alanın PHPSESSION çerezleri aynı yerde saklanır**, bu nedenle bir alanda **farklı çerezler farklı yollarla kullanılıyorsa**, bir yolun **diğer yolun çerezine erişmesini** sağlayabilirsiniz ve diğer yol çerezinin değerini ayarlayabilirsiniz.\
Bu şekilde, eğer **her iki yol da aynı isimde bir değişkene erişiyorsa**, **o değişkenin path1'deki değeri path2'ye uygulanabilir**. Ve ardından path2, path1'in değişkenlerini geçerli kabul edecektir (çereze path2'deki karşılık gelen ismi vererek).
* Makinenin kullanıcılarının **kullanıcı adlarını** aldığınızda, php dizinlerinin etkin olup olmadığını kontrol etmek için adresi kontrol edin: **/\~\<USERNAME>**.
* [**LFI ve RCE php sarmalayıcıları kullanarak**](../../../pentesting-web/file-inclusion/)
Bu fonksiyonlar genellikle PHP'de **şifrelerden hash oluşturmak** ve bir hash ile karşılaştırıldığında bir şifrenin doğru olup olmadığını**kontrol etmek** için kullanılır.\
Desteklenen algoritmalar: `PASSWORD_DEFAULT` ve `PASSWORD_BCRYPT` ( `$2y$` ile başlar). **PASSWORD\_DEFAULT genellikle PASSWORD\_BCRYPT ile aynıdır.** Ve şu anda, **PASSWORD\_BCRYPT**'in **girişte 72baytlık bir boyut sınırlaması vardır**. Bu nedenle, bu algoritma ile 72bayttan daha büyük bir şeyi hashlemeye çalıştığınızda yalnızca ilk 72B kullanılacaktır:
[**bu twitter dizisinden**](https://twitter.com/pilvar222/status/1784618120902005070?t=xYn7KdyIvnNOlkVaGbgL6A\&s=19) görebilirsiniz ki, 1000'den fazla GET parametresi veya 1000'den fazla POST parametresi veya 20 dosya gönderildiğinde, PHP yanıtında başlıkları ayarlamayacaktır.
Eğer bir **PHP sayfası hataları yazdırıyorsa ve kullanıcı tarafından sağlanan bazı girdileri geri ekrana basıyorsa**, kullanıcı PHP sunucusunun bazı**içerikleri yeterince uzun bir şekilde** yazdırmasını sağlayabilir, böylece sunucu **yanıta başlık eklemeye** çalıştığında bir hata verecektir.\
Aşağıdaki senaryoda **saldırgan sunucunun büyük hatalar vermesini sağladı** ve ekranda görebileceğiniz gibi PHP başlık bilgilerini **değiştirmeye çalıştığında, başaramadı** (örneğin CSP başlığı kullanıcıya gönderilmedi):
Php içindeki bu fonksiyon, **bir dize içinde yazılmış kodu çalıştırmanıza** olanak tanır ve **doğru veya yanlış döndürür** (ve buna bağlı olarak yürütmeyi değiştirir). Genellikle kullanıcı değişkeni bir dize ortasına yerleştirilecektir. Örneğin:\
Kod **sözdizimini****bozmanız**, **payload**'ınızı**eklemeniz** ve sonra **tekrar düzeltmeniz** gerekecek. **"and" veya "%26%26" veya "|"** gibi **mantıksal işlemler** kullanabilirsiniz. "or", "||" çalışmaz çünkü ilk koşul doğruysa payload'ımız çalışmayacaktır. Aynı şekilde ";" çalışmaz çünkü payload'ımız çalışmayacaktır.
**Diğer bir seçenek**, dizeye komutun yürütülmesini eklemektir: `'.highlight_file('.passwd').'`
**Diğer bir seçenek** (eğer iç kodunuz varsa) bazı değişkenleri değiştirerek yürütmeyi değiştirmektir: `$file = "hola"`
If you can **upload** a **.htaccess**, then you can **configure** several things and even execute code (configuring that files with extension .htaccess can be **executed**).
If you find a vulnerability that allows you to **modify env variables in PHP** (and another one to upload files, although with more research maybe this can be bypassed), you could abuse this behaviour to get **RCE**.
* [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/#ld\_preload-and-ld\_library\_path): Bu env değişkeni, diğer ikili dosyaları çalıştırırken rastgele kütüphaneleri yüklemenizi sağlar (bu durumda çalışmayabilir).
* **`PHPRC`** : PHP'ye **konfigürasyon dosyasını nerede bulacağını** belirtir, genellikle `php.ini` olarak adlandırılır. Kendi konfigürasyon dosyanızı yükleyebilirseniz, o zaman `PHPRC`'yi PHP'yi ona yönlendirmek için kullanın. İkinci yüklenen dosyayı belirten bir **`auto_prepend_file`** girişi ekleyin. Bu ikinci dosya, PHP çalışma zamanı tarafından diğer kodlardan önce **çalıştırılan** normal **PHP kodunu** içerir.
1. Shell kodumuzu içeren bir PHP dosyası yükleyin
2. Adım 1'de yüklediğimiz dosyayı çalıştırması için PHP ön işleyicisine talimat veren bir **`auto_prepend_file`** direktifi içeren ikinci bir dosya yükleyin
* Bu zinciri nasıl çalıştıracağınız hakkında daha fazla bilgi alın [**orijinal rapordan**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/).
Web sunucusu HTTP isteklerini ayrıştırır ve bunları [`http://host/cgi.php?foo=bar`](http://host/cgi.php?foo=bar\&ref=labs.watchtowr.com) gibi bir isteği çalıştıran bir PHP betiğine iletir, bu da bir parametre enjeksiyonuna izin verir. Bu, gövde içindeki PHP kodunu yüklemek için aşağıdaki parametreleri enjekte etmeyi sağlar:
Ayrıca, PHP'nin sonraki normalizasyonu nedeniyle "-" parametresini 0xAD karakteri kullanarak enjekte etmek mümkündür. [**bu gönderiden**](https://labs.watchtowr.com/no-way-php-strikes-again-cve-2024-4577/) örneği kontrol edin.
Bu fonksiyonlara yapılan çağrılarda kod ekleyip ekleyemeyeceğinizi kontrol edin (buradan): [here](https://www.youtube.com/watch?v=SyWUsN0yHKI\&feature=youtu.be)
Eğer bir PHP uygulamasını hata ayıklıyorsanız, `display_errors = On` ekleyerek `/etc/php5/apache2/php.ini` dosyasında hata yazdırmayı global olarak etkinleştirebilir ve apache'yi yeniden başlatabilirsiniz: `sudo systemctl restart apache2`
PHP Wrapper'ları ve protokolleri, bir sistemde **yazma ve okuma korumalarını atlamanıza** ve onu tehlikeye atmanıza olanak tanıyabilir. [**daha fazla bilgi için bu sayfayı kontrol edin**](../../../pentesting-web/file-inclusion/#lfi-rfi-using-php-wrappers-and-protocols).
Eğer `phpconfig()` çıktısında **Xdebug**'ın **etkin** olduğunu görüyorsanız, [https://github.com/nqxcode/xdebug-exploit](https://github.com/nqxcode/xdebug-exploit) üzerinden RCE elde etmeyi denemelisiniz.
Bir sayfada **rastgele bir sınıfın yeni bir nesnesini oluşturabiliyorsanız** RCE elde etme şansınız olabilir, nasıl yapılacağını öğrenmek için aşağıdaki sayfayı kontrol edin:
Yani, eğer **rakamlar ve harfler olmadan rastgele PHP çalıştırabiliyorsanız**, aşağıdaki gibi bir istek gönderebilirsiniz, bu yükü kullanarak rastgele PHP çalıştırmak için:
lt;>/'^'{{{{'; --> _GET` `${$_}[_](${$_}[__]); --> $_GET[_]($_GET[__])` `So, the function is inside $_GET[_] and the parameter is inside $_GET[__]` http --form POST "http://victim.com/index.php?_=system&__=$CMD" "input=$CODE"
AWS Hacking'i öğrenin ve pratik yapın:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
GCP Hacking'i öğrenin ve pratik yapın: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
* [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
* **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**'ı takip edin.**