0CTF 2016piapiapia

一来就试了一下sql注入 无
然后找到一个register.php 的页面 那边有个上传 也无上传漏洞
dirsearch 添加延时参数 找到www.zip 下载下来得到源码
拿到源码 class.php config.php index.php profile.php register.php update.php
config.php 那边有flag 从那边应该可以拿到flag
update.php 这边正则匹配了 过滤提交的数据 但是判断nickname那边有长度限制可以用nickname的数组来绕过长度限制就不会die

png29 这边用到了serialize() 可以试一下反序列化

29.PNG

前面
有个update_profile 到class.php 看一下update_profile 的定义方法

1
2
3
4
5
6
7
8
9
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);
}


再往下有个filter()

1
2
3
4
5
6
7
8
9
10
11
public function filter($string) {
$escape = array('\'', '\\\\');
$escape = '/' . implode('|', $escape) . '/';
$string = preg_replace($escape, '_', $string);

$safe = array('select', 'insert', 'update', 'delete', 'where');
$safe = '/' . implode('|', $safe) . '/i';
return preg_replace($safe, 'hacker', $string);
}


update()

1
2
3
4
public function update($table, $key, $value, $where) {
$sql = "UPDATE $table SET $key = '$value' WHERE $where";
return mysql_query($sql);
}

update.php 就先正则表达式将提交的参数值过滤 再序列化将非法字符替换成hacker
这反序列化还有文件读取

flag在config中 这边有序列化 过滤替换 反序列化 文件读取
就是反序列化字符逃逸 构造包含config.php的数据利用字符串逃逸 再在profile.php中读取得到
反序列化是以”;}结束的 把这个往前放置 就可以将反序列化提前结束的内容就丢弃了
突破口:
反序列化字符逃逸,首先序列化的字符是可控的 前面的长度是可控的 但是update.php将参数序列化,可控变量的长度就被写死了
要控制得通过序列化后数据过滤替代那边

1
2
3
4
5
6
7
8
9
10
11
public function filter($string) {
$escape = array('\'', '\\\\');
$escape = '/' . implode('|', $escape) . '/';
$string = preg_replace($escape, '_', $string);

$safe = array('select', 'insert', 'update', 'delete', 'where');
$safe = '/' . implode('|', $safe) . '/i';
return preg_replace($safe, 'hacker', $string);
}


select insert update delete where替换成hacker 写入where替换成hacker 字符串长度+1 因此实际的长的都大于序列化固定长度
i:0;s:3:”123”; -> 就是类似于s:后面这个值 反序列化字符串的逃逸,反序列化只能将nickname的s长度反序列化成功其他的长度已经被写死了, 剩下的字符串 构造class.php因为里面包含了flag 并将其位置放到photo上然后将photo扔掉
这样profile.php 中读取的photo就是我么构造的config.php 就能拿到flag了
假设:

构造这样一个 defg会被丢弃qwert占了原本的位置
目的是将”;}s:5:photo;s:10:”config.php”;} 这串总共34位 插入到序列化的字符串中
hacker比where多一个字符那就得需要挤出34位 也就是34个where 上传后再去profile查看内容

30.PNG

payload :wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere”;}s:5:photo;s:10:”config.php”;}

profile.php 那边查看源码 base64解码一下就可以了

31.PNG

32.PNG