运行长度为25,一个bb换成ccc,就逃逸1个字符,也就是说需要25个bb才能将后面的字符串给挤出来
<?php // $lmg = '";s:4:"pass";s:6:"hack";}'; // echo strlen($lmg)."\n"; // $lmg3 = "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"; // echo strlen($lmg3); $lmg2 = "bb"; echo str_repeat($lmg2, 25); ?>将name变量参数变为25个bb+";s:4:"pass";s:6:"hack";}
测试代码:
运行结果:构造完的字符串,反序列化后发现密码被改为了hack,而我们并未直接修改pass的参数,从而实现字符串的逃逸
地址:
打开题目扫描一下发现w文件下载,因为本文主要交php反序化就不绕了
发现config.php中又flag,所以要读取文件,在profile.php中发现读取文件的代码
如果能让photo为config.php,而这数值来自$profile的反序列化,查看$profile
public function update_profile($username, $new_profile) { $username = parent::filter($username); $new_profile = parent::filter($new_profile); $where = "username = '$username'"; return parent::update($this->table, 'profile', $new_profile, $where); }发现有过滤
public function filter($string) { $escape = array('\'', '\\\\'); $escape = 'http://www.likecs.com/' . implode('|', $escape) . 'http://www.likecs.com/'; $string = preg_replace($escape, '_', $string); $safe = array('select', 'insert', 'update', 'delete', 'where'); $safe = 'http://www.likecs.com/' . implode('|', $safe) . '/i'; return preg_replace($safe, 'hacker', $string); }要进行字符串的逃逸应该先考虑用nickname来构造字符串逃逸photo应为nickname在其前面
然后发现nickname有正则过滤,考虑用数组来进行绕过
数组绕过后就考虑进行逃逸将photo挤出去
所以我们需要构造nickname的参数值为";}s:5:"photo";s:10:"config.php";}
这里为什么要在前面加一个}呢???,因为为了绕过nickname的正则匹配我们将其构造成了数组,数组在反序列化要进行闭合,可以尝试一下
构造代码
运行结果发现数组位置进行了闭合
这就是为啥上面要先进行}在逃逸
构造我们想要的内容后要进行逃逸,我们发现过滤的时候将where改成了hacker,进行了字符串拓展增建了一个字符串,我们构造的字符串长度为34所以我们要构造34个where进行逃逸
然后查看profile.php的图片,base64解码就获得了config.php中的flag
反序列化字符串逃逸(替换后导致字符串变短)
字符串变短的逃逸类似于变长,都是利用了替换字符串导致的可输入变量的改变,从而可以闭合
测试代码: