In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)05/31 Report--
Today, I would like to share with you the relevant knowledge points of php unserialize deserialization vulnerability analysis. The content is detailed and the logic is clear. I believe most people still know too much about this, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.
The topics are as follows:
Vulnerability resolution: (the regular expression on line 11 of the above figure code should be changed to:'/ O:\ dmordial')
The topic examines the use of php deserialization functions. In the line 10 loadData () function, we found that the unserialize function inversely sequenced the passed $data variable. Before deserialization, the content of the variable is judged, do not consider bypassing, trace the variable to see if the variable is controllable. In line 6 of the code, the loadData () function is called, and the $data variable comes from the variable passed in by the _ _ construct () constructor. Line 32 of the code instantiates the Template class and passes in the key 'data' data in cookie as initialization data, and we can control the $data data. Start thinking about bypassing the judgment of incoming data.
Line 11, the first if, intercepts the first two characters to determine whether the deserialized content is an object, and if so, the return is empty. The php deserializable type is String,Integer,Boolean,Null,Array,Object. After removing the Object, consider bypassing the objects stored in the array.
The second if determines that the matching string is\'O: any decimal:'. After the object is deserialized in an array, it can still be matched, and the return is empty. Consider how to bypass regular matching. The source code for PHP deserialization is as follows:
In the PHP source code var_unserializer.c, the deserialization string is processed, the character is judged on line 568 of the code, and the corresponding function is called for processing. When the character is'O', the yy13 function is called. In the yy13 function, the next character of the'O' character is judged. If it is':', the yy17 function is called. If it is not, the yy3 function is called, return 0 is directly called, and the deserialization ends. Let's move on to the yy17 function. By observing the yybm [] array, the first if determines whether it is a number, if it is a number, it jumps to the yy20 function, and the second judgment jumps to yy19 if it is a'+ 'sign. In yy19, it continues to judge the characters after the + sign, if it is a number, it jumps to yy20, if not, it jumps to yy18, and Y18 finally jumps to yy3 to exit the deserialization process. As a result, the'+ 'can be added after the' Oconfusion'to bypass the regular judgment.
After bypassing the filtering, we then consider how to take advantage of deserialization. The essence of deserialization is to restore the serialized string to the corresponding class instance. In this process, what we can control is the content of the serialized string, that is, the value of the variable in the corresponding class. We can not directly call the function in the class, but PHP will automatically trigger some function calls under certain conditions. This kind of function is called magic method. Through controllable class variables, the magic method that triggers automatic invocation, and the available points in the magic method, the exploitation of deserialization vulnerabilities is formed.
In line 31, the createCache () function is called when the object is destroyed, and the function puts the contents of $template into the file corresponding to $cacheFile. The file_put_contents () function, which is created when the file does not exist. From this, a sentence can be constructed and written to the current path.
$cacheFile and $template are class variables, and deserialization is controllable, so construct the following deserialization, don't forget to add the'+ 'sign
URL coding is required for putting cookie.
Atest.php 1: {iRAPR 0: Orange8: "Template": 2: {SRAV 9: "cacheFile"; SRAV 10: ". / test.php"; SRAV 8: "template"; Srig 25: "";}}
The file was successfully written:
Case analysis
In this example analysis, the Typecho-1.1 version is selected, in which users can deserialize Cookie data for foreground Getshell. The flaw occurs on line 230 of the install.php file, as follows:
In line 3 of the code above, after decoding the base64 of the data in Cookie, the deserialization operation is carried out, and the value is controllable. Next, take a look at the code trigger conditions. Several key judgments of the document are as follows:
The first if judgment, you can pass any value of finish= through GET bypass, the second if to determine whether there is a GET or POST parameters, and to determine whether Referer is empty, the fourth if to determine whether Referer is this site. This is followed by judgment, as shown in the following figure:
The first if determines whether $_ GET ['finish'] is set, and then determines whether the config.inc.php file exists, which exists after installation, and the third determines whether the _ _ typecho_config parameter in cookie is empty, not empty. Enter the else branch. To sum up, the specific structure is as follows:
$config = unserialize (base64_decode (Typecho_Cookie::get ('_ typecho_config'); Typecho_Cookie::delete ('_ typecho_config'); $db = new Typecho_Db ($config ['adapter'], $config [' prefix'])
The deserialization result is stored in the $config variable, and then $config ['adapter'] and $config [' prefix'] are used as initialization variables of the Typecho_Db class to create class instances. We can find the constructor code for this class in the var/Typecho/Db.php file, as follows:
Line 6 of the above code performs a string concatenation operation on the incoming $adapterName variable. For PHP, if the $adapterName type is an object, the _ _ toString () magic method of this class is called. As a trigger point for deserialization, let's search globally for _ _ toString () to see if there are any available points. When you actually search, you will find that three classes all have a _ _ toString () method defined:
The first var\ Typecho\ Config.php:
Calling the serialize () function for serialization automatically triggers _ _ sleep (), which can be further exploited if there is an available _ _ sleep ().
The second place var\ Typecho\ Db\ Query.php:
This method is used to build SQL statements and does not perform database operations, so it is of no use for the time being.
The third place var\ Typecho\ Feed.php:
In line 19, $this- > _ items is a class variable, deserialization can be controlled, in line 27, $item ['author']-> screenName, if the class stored in $item [' author'] does not have a 'screenName' attribute or the attribute is private, the magic method _ _ get () in the class will be triggered, which can be used as a further use of the point to continue to look down at the code, and no dangerous function calls are found.
Write down a wave of magic methods and the corresponding trigger conditions, as follows:
_ _ wakeup () / / trigger _ _ sleep () when using unserialize / / trigger _ _ destruct () when using serialize / / trigger _ _ call () when an object is destroyed / / trigger _ _ callStatic () when calling an inaccessible method in the context of an object / / trigger _ _ get () when calling an inaccessible method in a static context / / used to read data from inaccessible properties _ _ set () / used to write data to an inaccessible attribute _ _ isset () / / trigger _ _ unset () when calling isset () or empty () on an inaccessible attribute / / trigger _ _ toString () when using unset () on an inaccessible attribute / / trigger _ _ invoke () when using a class as a string / / trigger when a script attempts to call an object as a function
In the Typecho_Request class of var/Typecho/Request.php, we find the _ _ get () method and trace the call to the method, as shown in the following figure:
Both the array_map () function and the call_user_func function can be used as utilization points, with $filter as the calling function and $value as the function argument, tracking variables to see if they are controllable. These two variables are derived from class variables, and deserialization is controllable. From the above analysis, we can see that the _ _ get method is triggered when $item ['author'] satisfies certain conditions.
Suppose an instance of the Typecho_Request class is stored in $item ['author'], and $item [' author']-> screenName is called at this time. Without this attribute in the Typecho_Request class, the _ _ get ($key) method in the class is called, and the value passed in by $key is scrrenName. The process of passing parameters is as follows: $key='scrrenName'= > $this- > _ param [$key] = > $value
We set the value of $this- > _ param ['scrrenName'] to the function we want to execute, and construct $this- > _ filter as the parameter value of the corresponding function, as shown below:
Next, let's take a look at the construction of the Typecho_Feed class, which is in the var/Typecho/Feed.php file with the following code:
Line 7 of the above code satisfies that self::RSS2 is equal to $this- > _ type to enter the branch, so $this- > _ type needs to be constructed. Item ['author'] is the trigger point, and $this_items needs to be constructed. The specific structure is as follows:
Line 22 of code does not need to be added in actual use. Install.php calls the ob_start () function on line 54 of code, which buffers the output. After the end of deserialization exploit, an exception is triggered in line 121of var\ Typecho\ Db.php code, and the ob_end_clean () function is called on line 237th of var\ Typecho\ Common.php code to clear the buffer content, resulting in the execution result cannot be seen. Consider ending the program by reporting an error in advance before entering exception handling. The data is thus constructed. The implementation results are as follows:
Repair suggestion
There are two main reasons for this loophole:
When the config.inc.php file exists, you can bypass the judgment and continue to execute the code.
The parameters of the deserialization function passed in are controllable
Fix: determine whether config.inc.php exists on the first line of the install.php file, and if so, exit code execution.
Conclusion
After reading the above analysis, I do not know if you have a certain understanding of the use of deserialization, the CMS used in this article can be downloaded here, of course, if there is anything inappropriate in the article, I hope you will correct it. If you are interested in our project, please contact us by email at hongrisec@gmail.com. This is the end of Day11's analysis article. Finally, we have left a CTF topic for you to practice. The title is as follows:
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.