Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How ecshop instances are exploited from deserialization to type obfuscation vulnerabilities

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)05/31 Report--

This article introduces you from deserialization to type confusion vulnerability ecshop instance utilization is how, the content is very detailed, interested friends can refer to, hope to be helpful to you.

GMP types confuse vulnerability exploitation conditions

Php 5.6.x

Deserialization entry point

The trigger point that can trigger _ _ wakeup (in php

< 5.6.11以下,可以使用内置类) 漏洞详情 gmp.c static int gmp_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */{ ... ALLOC_INIT_ZVAL(zv_ptr); if (!php_var_unserialize(&zv_ptr, &p, max, &unserialize_data TSRMLS_CC) || Z_TYPE_P(zv_ptr) != IS_ARRAY ) { zend_throw_exception(NULL, "Could not unserialize properties", 0 TSRMLS_CC); goto exit; } if (zend_hash_num_elements(Z_ARRVAL_P(zv_ptr)) != 0) { zend_hash_copy( zend_std_get_properties(*object TSRMLS_CC), Z_ARRVAL_P(zv_ptr), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *) ); } zend_object_handlers.c ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC) /* {{{ */{ zend_object *zobj; zobj = Z_OBJ_P(object); if (!zobj->

Properties) {rebuild_object_properties (zobj);} return zobj- > properties;}

From the snippet in gmp.c, we can roughly understand the original words of the vulnerability discoverer taoguangchen.

Magic methods such as _ _ wakeup can cause ZVAL to be modified in memory. Therefore, attackers can convert * * object into integer or Bool ZVAL, so we can access any object stored in object storage through Z_OBJ_P, which means that attributes in any object can be overwritten through zend_hash_copy, which can cause a lot of problems and security problems in certain scenarios.

The above words may not be understood by code snippets alone, but we can look at them with actual tests.

First, let's look at a piece of test code.

I show a variety of environments in different situations in the code.

Let's see what the result is.

Array (1) {[0] = > & int (1)} object (stdClass) # 1 (3) {["aa"] = > string (2) "hi" ["bb"] = > string (2) "hi" [0] = > object (obj) # 5 (1) {["ryat"] = > & int (1)} object (b) # 2 (1) {[ryat "] = > int (1)} object (stdClass) # 3 (1) {[aa "] = > int (2)} object (stdClass) # 4 (0) {}

I successfully modified the first declared object.

But what happens if I change the deserialized class to b?

$inner ='s bb 1: "1"; aV3: {SJV 2: "aa"; SARV 2: "hi"; Srig 2: "bb"; Srig 2: "hi"; iRAPR 0: "b": 1: {shi 4: "ryat"; R2R2;}}'

Obviously, it doesn't affect other class variables.

Array (1) {[0] = > & object (GMP) # 4 (4) {["aa"] = > string (2) "hi" ["bb"] = > string (2) "hi" [0] = > object (b) # 5 (1) {["ryat"] = > & object (GMP) # 4 (4) {["aa"] = > string (2) "hi" ["bb"] = > string ( 2) "hi" [0] = > * RECURSION* ["num"] = > string (2) "32"}} ["num"] = > string (2) "32"} object (stdClass) # 1 (2) {["aa"] = > int (1) ["bb"] = > int (2)} object (b) # 2 (1) {["ryat"] = > int (1)} object (stdClass) # 3 (1) {["aa"] = > int (2)} object (stdClass) # 6 (0) {}

If we add a _ _ Wakeup function to class b, it will have the same effect.

But if we set the variable in the wakeup magic method to 2

Class obj {var $ryat; function _ _ wakeup () {$this- > ryat = 2;}}

As you can see from the returned result, we have successfully modified the second declared object.

Array (1) {[0] = > & int (2)} object (stdClass) # 1 (2) {["aa"] = > int (1) ["bb"] = > int (2)} object (b) # 2 (4) {["ryat"] = > int (1) ["aa"] = > string (2) "hi" ["bb"] = > string (2) "hi" [0] = > object (obj) # 5 (1) ["ryat"] = > & int (2)} object (stdClass) # 3 (1) {["aa"] = > int (2)} object (stdClass) # 4 (0) {}

But if we change ryat to 4, the page will directly return 500 because we have modified the unallocated object space.

After completing the previous experiments, we can simplify the conditions for exploitation of the vulnerability.

If we have a controllable deserialization entry, and the target backend PHP installs the GMP plug-in (this plug-in is not installed by default in the original php, but comes with part of the packaging environment), if we find a controllable _ _ wakeup magic method, we can modify the object properties declared before deserialization and cause actual security problems in line with the scenario.

If the target php version is 5.6 string (3) "ECS" [130] = > string (9) "ecs_error" [131] = > string (8) "exchange" [132] = > string (9) "cls_mysql" [133] = > string (11) "cls_session" [134] = > string (12) "cls_template" [135] = > string (11) "certificate" [136] = > string (6) "oauth3" String (15) "oauth3_response" [138] = > string (14) "oauth3_request" [139] = > string (9) "transport" [140] = > string (6) "matrix" [141] = > string (16) "leancloud_client"

You can also see from the code that several library files have been introduced into the file header.

Require (dirname (_ _ FILE__). / includes/init.php'); require_once (ROOT_PATH. 'includes/lib_order.php'); require_once (ROOT_PATH. 'includes/lib_goods.php'); require_once (ROOT_PATH. 'includes/cls_matrix.php'); include_once (ROOT_PATH. 'includes/cls_certificate.php'); require (' leancloud_push.php')

Here we focus on init.php because most of the common classes of ecshop are declared in this file.

When we look at the class variables one by one, we can acutely see a special variable. Because of the special background structure of ecshop, most of the page content is compiled from templates, and this template class happens to be declared in init.php.

Require (ROOT_PATH. 'includes/cls_template.php'); $smarty = new cls_template

Going back to order.php, we look for methods related to $smarty, and it is not difficult to find that they are mainly concentrated in two methods.

$smarty- > assign ('shipping', $shipping); $smarty- > display (' print.htm');

Here we mainly focus on the display method.

At a cursory glance, the logic of the display method is roughly

Request the corresponding template file-- > after a series of judgments, compile the corresponding template file-- > output the compiled file address

The more important code is defined in the function make_compiled.

Function make_compiled ($filename) {$name = $this- > compile_dir. '/'. Basename ($filename). '.php';. If ($this- > force_compile | | $filestat ['mtime'] > $expires) {$this- > _ current_file = $filename; $source = $this- > fetch_str (file_get_contents ($filename)); if (file_put_contents ($name, $source, LOCK_EX) = = false) {trigger_error (' can\ 't write:'. $name);} $source = $this- > _ eval ($source);} return $source;}

When the process comes to this point, we need to find out what our goal is first.

Taking a fresh look at cls_template.php 's code, we can see that there are only a few functions involved in code execution.

Function get_para ($val, $type = 1) / / processing the call data of insert external functions / functions that need to be run by include {$pa = $this- > str_trim ($val) Foreach ($pa AS $value) {if (strrpos ($value,'=')) {list ($a, $b) = explode ('=', str_replace (array ('','& ampquot;'),', $value) If ($b {0} = ='$') {if ($type) {eval ('$para [\''. $a. ''] ='. This- > get_val (substr ($b, 1)). ';);} else {$para [$a] = $this- > get_val (substr ($b, 1));}} else {$para [$a] = $b } return $para;}

Get_para is only called in select, but there is no place where select can be triggered.

And then pop_vars.

Function pop_vars () {$key = array_pop ($this- > _ temp_key); $val = array_pop ($this- > _ temp_val); if (! empty ($key)) {eval ($key);}}

Just with GMP we can control the $this- > _ temp_key variable, so as long as we can call this method anywhere in the above process, we can cooperate with the variable override to construct a code execution.

Looking back at the code flow, we found this code in the compiled PHP file.

Order_info.htm.php

After traversing the form, pop_vars happens to be triggered.

In this way, as long as we control the _ temp_key attribute that overrides the cls_template variable, we can complete a getshell

Final utilization effect

So much for the ecshop instance utilization of vulnerabilities from deserialization to type obfuscation. I hope the above can be helpful and learn more. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report