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 to deserialize vulnerabilities in PHP

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)06/01 Report--

How to deserialize vulnerabilities in PHP, in view of this problem, this article introduces the corresponding analysis and solutions in detail, hoping to help more partners who want to solve this problem to find a simpler and easier way.

Serialization and deserialization

Why serialize and deserialize?

At first, I didn't understand why it took so much trouble to deserialize and then deserialize back. I took one more step, read all kinds of articles and cited all kinds of chestnuts, all just wanted to tell us that the purpose of serialization is to facilitate the transmission and storage of data.

Along with a passage I saw on the Internet.

The PHP file will destroy the object after the end of execution, so the next time there is a page that happens to use the object that has just been destroyed, there will be nothing you can do. You can never let it be destroyed. Wait for you. So people have come up with a way to save the object for a long time. This is the serialization of PHP, so when we use it next time, we just have to deserialize it and ok it.

What is serialization and deserialization?

Serialization

The key function serialize (): turns the object created in PHP into a string

After consulting the data, we found that

When the private property is serialized, the format is the class name, member name

The format of protected property serialization is * member name

Deserialization

The key function unserialize (): converts the serialized string back to the PHP value

Note: remember to complete the empty string when you have protected and private attributes

Why is there a deserialization vulnerability?

The PHP deserialization vulnerability, also known as PHP object injection, is caused by improper processing of input data by the program.

Prerequisites for deserialization vulnerabilities:

Must have a unserailize () function

The parameters of the unserailize () function must be controllable (to successfully achieve the function of controlling the parameters you enter, you may need to bypass some magic functions

Write a little chestnut below.

The above chestnut has the premise to exploit deserialization vulnerabilities. Because of the existence of echo, we can also directly utilize xss.

Very simple chestnuts.

D0g3 platform

A question from the lab masters:

Http://120.79.33.253:9001/

The title is given directly to the source code.

Bugku-welcome to the bugkuctf

After going through the test site of the previous php pseudo protocol, I got two source codes after base64 decoding.

Index.php

Hint.php

Observe the dangerous function unserialize (), follow up that there is a file_get_contents () function in hint.php, which can read the file, then we only need to observe whether file is controllable to solve the problem easily.

So we only need to control $this- > file to read the file we want.

Of course, this question not only takes the deserialization test, but also requires some other operations to get flag.

The above simple chestnuts can be directly serialized to generate the corresponding payload and then deserialized to achieve the function, but it is usually not so simple for you to use successfully, so you need to master some things below

Some magic tricks.

Before bypassing magic methods, we need to understand the operating mechanism of some magic methods-PHP's 16 magic methods

You need to know the running order of the relative important functions.

_ _ weakup () that can be bypassed

It's actually a CVE vulnerability, CVE-2016-7124. The execution of _ _ wakeup is skipped when the number of member attributes is greater than the actual number.

There are already a lot of explanations on the Internet. For example, an article on the Internet, https://blog.csdn.net/qq_19876131/article/details/52890854, makes it clear that we only need to know that the number of members is greater than the actual number of members.

Take stock of two recent questions about deserialization the 12th National Information Security Competition for College students-JustSoso

PHP pseudo protocol + base64 decoding to get two files

Index.php

Hint.php

After a cursory glance at the two files, it may be a bit confusing (I was confused at the time), but we just need to make it clear that the purpose of typing CTF is to get flag....

Sort it out and the ideas are as follows

What did the index.php file do?

Get type passes in two parameters (then the two parameters must be useful. Usually, the questioner will not be too idle to set a few more useless parameters.

File cannot contain the flag keyword

If payload is set, the url is cut, and the loop traversal matches the flag keyword, and exits when the match is reached

Payload by unserialize () ~ payload by unserialize () ~ payload by unserialize () ~

What did the hint.php file do?

Now that they are all called hint.php, then hint.php must have made a difference.

Throughout hint.php contains two classes

One of the classes is called Flag, and there is even a method called getFlag () in the class, so we know that our goal is it.

When you hit CTF, you have to know what you're doing, so regardless of anything else, let's just talk about deserialization, and then construct the parameter payload.

So on the premise of abandoning everything, we can even construct payload

Now that we are able to output flag, let's take a look at what other obstacles exist.

Prerequisites for exporting flag

Echo @ highlight_file ($this- > file,true); there is a judgment before: $this- > token = = $this- > token_flag

The value of $this- > token will not change, but $this- > token_flag will.

There are two ways of thinking here, one is blasting, the other is to solve this problem by referencing variables $Flag- > token = & $Flag- > token_flag

_ _ wakeup () is empty every time you print?

The point is, take advantage of CVE-2016-7124 earlier in this article. The execution of _ _ wakeup is skipped when the number of member attributes is greater than the actual number. This allows the Handle class to successfully call methods in the Flag class

Our keywords can't have flag?

After deserialization, our keywords will always contain flag words and will be regularly matched to.

You can use parse_url 's parsing vulnerabilities here. Specifically, you can take a look at the articles of a floating master and another master.

Probably parse_url () is specifically used to parse URL rather than URI. However, to comply with the need for PHP backward compatibility, three slashes are allowed for the file:// protocol (file:///... ). No other agreement can do that.

So if you use three slashes, the keyword will not be detected.

In fact, other test points can be bypassed, the core of the main idea of deserialization, I think after deserialization, with controllable parameters, we must complete a certain part of the function, not deserialization for deserialization.

DDCTF-Web check-in question

Topic address: http://117.51.158.44/index.php

After the disclosure of information, grab the bag and so on will get two source codes.

File 1:Application.php

The code is too long, so here are some useful features to simplify:

Class Application {var $path=''; private function sanitizepath ($path) {$path= trim ($path); $path=str_replace ('.. /','', $path); $path=str_replace ('.\\',', $path); return $path;} public function _ destruct () {if (empty ($this- > path)) {exit ();} else {$path= $this- > sanitizepath ($this- > path) If (strlen ($path)! = = 18) {exit ();} $this- > response ($data=file_get_contents ($path), 'Congratulations');} exit ();}}

File 1 probably does some processing on the $path variable; for example, empty it before and after, and remove.. / and..\

If the length is less than 18, you can read the contents of the file of the $path variable, the contents of the file of the $path variable, and the contents of the file of the $path variable.

So we construct a preliminary payload (which actually combines some information from file 2 to construct the path) as:. / config/flag.txt, but at this time we need to bypass a str_replace () function in file 1, and the length is less than 18, so we construct it again as. /. / config/flag.txt (it should be noted that although the current length is 21. But after a previous str_replace () replacement.. / is empty, the length is exactly 18.

File 2:app/Session.php

/ / url:app/Session.phpinclude 'Application.php'; / / include file-class Session extends Application {/ / key suggests an 8-bit string var $eancrykey =''; var $cookie_expiration = 7200; var $cookie_name = 'ddctf_id'; var $cookie_path ='; var $cookie_domain ='' Var $cookie_secure = FALSE; var $activity = "DiDiCTF"; public function index () {if (parent::auth ()) {/ / call parent method $this- > get_key () through parent::; if ($this- > session_read ()) {$data = 'DiDI Welcome you% s' $data = sprintf ($data,$_SERVER ['HTTP_USER_AGENT']); parent::response ($data,'sucess');} else {$this- > session_create (); $data =' DiDI Welcome you'; parent::response ($data,'sucess') } private function get_key () {/ / eancrykey and flag under the folder $this- > eancrykey = file_get_contents ('.. / config/key.txt'); / / flag may also be in this folder} public function session_read () {if (empty ($_ COOKIE)) {return FALSE } $session = $_ COOKIE [$this- > cookie_name]; if (! isset ($session)) {parent::response ("session not found", 'error'); return FALSE;} $hash = substr ($session,strlen ($session)-32); $session = substr ($session,0,strlen ($session)-32) If ($hash! = = md5 ($this- > eancrykey.$session)) {parent::response ("the cookie data not match", 'error'); / / call the parent class method return FALSE;} $session = unserialize ($session) via parent:: / / deserialize if (! is_array ($session) OR! isset ($session ['session_id']) OR! isset ($session [' ip_address']) OR! isset ($session ['user_agent']) {return FALSE;} if (! empty ($_ POST ["nickname")) {/ / POST is not empty $arr = array ($_ POST ["nickname"], $this- > eancrykey) $data = "Welcome my friend% s"; foreach ($arr as $k = > $v) {/ / print variable $data = sprintf ($data,$v); / / output} parent::response ($data, "Welcome") } if ($session ['ip_address']! = $_ SERVER [' REMOTE_ADDR']) {parent::response ('the ip addree not match'.'error'); return FALSE;} if ($session [' user_agent']! = $_ SERVER ['HTTP_USER_AGENT']) {parent::response (' the user agent not match','error') Return FALSE;} return TRUE;} private function session_create () {$sessionid ='; while (strlen ($sessionid)

< 32) { $sessionid .= mt_rand(0,mt_getrandmax()); } $userdata = array( 'session_id' =>

Md5 (uniqid ($sessionid,TRUE)), 'ip_address' = > $_ SERVER [' REMOTE_ADDR'], 'user_agent' = > $_ SERVER [' HTTP_USER_AGENT'], 'user_data' = >',); $cookiedata = serialize ($userdata); / / serialize $cookiedata = $cookiedata.md5 ($this- > eancrykey.$cookiedata); $expire = $this- > cookie_expiration + time () Setcookie ($this- > cookie_name, $cookiedata, $expire, $this- > cookie_path, $this- > cookie_domain, $this- > cookie_secure);}} $ddctf = new Session (); $ddctf- > index ();? >

Let's review how deserialization is performed:

Must have a unserailize () function

The parameters of the unserailize () function must be controllable

The first thing that comes into view is $session = unserialize ($session) in line 55 of file 2; this step executes the dangerous function unserialize ()

File one is included in file two, so you can use _ _ destruct () in file one to perform the function of file reading.

Combined with useful information, the $path variable is controlled through the deserialization of session to get flag. The comment / / eancrykey and flag under the folder on line 34 provides the corresponding location.

So we can get the flag by controlling the $path variable, and the $path needs to be deserialized.

But there are other test sites for this question, because you need to forge a cookie to get the corresponding key before you can deserialize.

Since we only talk about deserialization, let's simplify the topic. Construct the final payload as

This is the answer to the question about how to deserialize vulnerabilities in PHP. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.

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