学web总是能让我学到新的知识,很开心,很有趣,很好玩
打开题目
一个登录按钮,一个注册按钮,其余没有什么发现,对于web来说,常规先测试一下robots.txt文件
果然又发现,有一个bak文件,我们下载下来看看
我一看,这不又是序列化的题吗?是可以执行curl命令的,但是现在还没有什么头绪,我们先注册一个账号看看
也没有什么信息,我们点进admin看看
乍一看没什么思路,我们看一下源代码
这里给了一个链接说是博客页面,猜测就是这里使用了curl获取页面,暂时还不知道怎么利用,我们再看看有没有什么能提供思路的地方
看了看,发现链接可能存在sql注入
我们尝试注入一下,测试了一下,确实存在注入点,当我们输入1 and 1=1#页面正常显示
但当我们输入1 and 1=2#时,页面就报错了
确定存在注入点,我们看看有几个字段
使用联合查询的时候,waf把我们拦截下来了,尝试一下使用注释绕过
成功绕过了,并且测试字段数量为4,因为为5的时候,页面就报错了
我们先查询一下当前的数据库名字
注意,查询的时候要把1改为-1才行,查询到数据库名字为fakebook
我们乘胜追击,查一下他的表名
查出来表名为users,我们再看看他有些什么字段
分别有no,username,passwd,data,USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS这些字段,我都看过了,只有data字段有点用,我们把data字段的数据取出来看看
是一段序列化后的字符串,那思路就很明确了,我们需要反序列化他,传入恶意的代码
我们分析一下最早拿到的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);
}
}
我们一个一个分析
get函数:会传入一个url值,就是我们输入的blog值,然后会curl这个url,把url返回的内容输出到页面上,curl是可以使用file协议来包含文件的
get里面的几个curl函数解释如下
curl_init:初始化新的会话,返回 cURL 句柄,供curl_setopt()、 curl_exec() 和 curl_close() 函数使用。
curl_setopt:为 curl 会话句柄设置选项。
curl_exec:执行给定的 curl 会话。
curl_getinfo:获取最后一次传输的相关信息。
然后我们再看看
isValidBlog函数:对我们注册时传入的blog值进行过滤,不然我们注册的时候就可以直接用file伪协议进行文件读取了
了解了代码都是干嘛的之后,我们就可以构造php序列化字符串了
根据之前报错显示出来的路径为/var/www/html/view.php,我们可以构造下面的代码
<?php
class UserInfo
{
public $name = "abc";
public $age = 123;
public $blog = "file:///var/www/html/flag.php";
}
$a=new UserInfo();
echo serialize($a);
找一个php解释器运行一下就可以得到一串序列化字符串了
然后用这串字符串sql注入
我们再看看源代码
成功返回了flag.php的内容,我们把它使用base64解码一下,就可以得到flag了
但这题好像没有禁用load_file函数,所以,直接使用no=-1 union/**/select 1,load_file(‘/var/www/html/flag.php’),3,4就可以直接做出来
哈哈哈哈