6-Web安全——基於POST提交的報頭注入

目錄

1. 基於POST提交的報頭注入

2. user-agent報頭注入

3. Referer報頭注入

4. Cookie報頭注入

5. 總結


 

 

1. 基於POST提交的報頭注入

 

當進行常規注入時頁面看不到明顯變化,找不到注入點的時候可以嘗試報頭注入,基於POST提交注入的報頭注入有以下幾種:

  1. user-agent報頭注入
  2. Referer報頭注入
  3. Cookie報頭注入

 

2. user-agent報頭注入

 

分析Less-18源代碼產生SQL注入的原因:

//通過全局變量獲取ip地址,User-Agent字段中的信息
$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];
echo "<br>";
echo 'Your IP ADDRESS is: ' .$IP;
echo "<br>";
//echo 'Your User Agent is: ' .$uagent;
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
	{
	
	//對提交的用戶名和密碼進行安全校驗
	$uname = check_input($_POST['uname']);
	$passwd = check_input($_POST['passwd']);
	$fp=fopen('result.txt','a');
	fwrite($fp,'User Agent:'.$uname."\n");
	fclose($fp);
	
	//查詢數據庫的結果是否一致
	$sql="SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
	$result1 = mysql_query($sql);
	$row1 = mysql_fetch_array($result1);
		if($row1)
			{
			echo '<font color= "#FFFF00" font size = 3 >';
			//結果一致則將數據插入到uagents表中
			$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
			mysql_query($insert);
			//echo 'Your IP ADDRESS is: ' .$IP;
			echo "</font>";
			//echo "<br>";
			echo '<font color= "#0000ff" font size = 3 >';			
			echo 'Your User Agent is: ' .$uagent;
			echo "</font>";
			echo "<br>";
			print_r(mysql_error());			
			echo "<br><br>";
			echo '<img src="../images/flag.jpg"  />';
			echo "<br>";
			
			}
		else
			{
			echo '<font color= "#0000ff" font size="3">';
			//echo "Try again looser";
			print_r(mysql_error());
			echo "</br>";			
			echo "</br>";
			echo '<img src="../images/slap.jpg"   />';	
			echo "</font>";  
			}
	}

check_input函數用於對輸入的用戶名和密碼進行檢測,以字符的形式存入數據庫,而不是直接拼接到SQL語句中執行,這樣就無法注入了。然後將前臺提交的用戶名和密碼和數據庫中的結果進行對比,是否一致。如果一致的話就將uagent,ip,uname等數據插入到security數據庫下的uagents表中。

 

uagent在http協議中的一個User-Agent字段,該字段通常,表示"用戶代理"的意思,用於將客戶端的操作系統和瀏覽器信息告知服務器,服務端可以根據這個字段,判斷並統計終端用戶的類型,一般很多安全軟件可以僞造這個字段,欺騙服務器。

 

http請求頭中的User-Agent字段中攜帶了瀏覽器,操作系統版本等信息,瀏覽器是Firefox,基於46.0版本,操作系統是win10。

 

user-agent報頭注入的思路過程是,首先要求登錄成功,然後修改$uagent參數,使用報錯注入方式在插入信息執行命令報錯,反饋錯誤信息,登錄成功後輸出uagent信息包括報錯信息,從而達到user-agent報頭注入目的。

 

插入數據的SQL語句構造:

INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES(1 or updatexml(1,concat('#',(database())),0),2,3);

數據庫報錯反饋回來的錯誤信息正好是我們想要的。

 

 

 

想要實現user-agent報頭注入還需要一個Burp Suite軟件,使用Burp Suite軟件修改瀏覽器提交的POST請求報文中的頭部字段信息,這裏主要會用到Burp Suite的兩個功能:Proxy代理和Repeaater重發器。

 

查看端口代理:點擊Proxy ——> 點擊Options選項:
 

點擊Add選項添加配置,然後Burp Suite軟件就會偵聽127.0.0.1地址的8080端口的數據包並攔截下來。

 

 

再配置Firefox瀏覽器代理功能:點擊選項 ---->  高級   ---->  選擇網絡,點擊設置:

 

使用一個用戶名admin和密碼admin登錄,點擊submit,然後Burp Suite軟件就會把偵聽到的數據包攔截下來:

 

將User-Agent字段中原來的內容刪掉,替換成自定義構造的SQL語句:  

如果不適應Burp Suite軟件代碼形式的錯誤信息提示的話,可以點擊POST的Response響應報文中的Render選項以圖形化的形式顯示錯誤信息。

 

使用user-agent報頭注入獲取表名:

' or updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),3),'192.168.1.1','test')#

使用user-agent報頭注入獲取列名,獲取用戶名和密碼等數據,按照上面的方式構造SQL語句即可。

 

 

3. Referer報頭注入

 

分析Less-19源代碼產生SQL注入的原因:

Referer報頭注入和user-agent報頭注入的原理類似,對於用戶名和密碼後臺會進行安全校驗,然後對用戶名和密碼進行對比,如果一致則說明登陸成功,然後會將referer,ip_address插入到referers表中。

 

Referer是HTTP協議頭部信息中的一部分,Referer表示從哪個鏈接跳轉到此頁面的,包含一個URL,當瀏覽器向web服務器發送請求的時候,一般都會帶上referer,告訴服務器當前網頁是從哪個網頁鏈接過來的,因此服務器可以獲得一些信息用於處理。Referer常用於防盜鏈,防止惡意請求,空referer。

 

 

首先需要用一個用戶名和密碼登錄成功,然後可以修改$referer參數,通過報錯注入在插入信息執行命令時報錯,反饋錯誤信息,登錄後輸出referer信息包括報錯信息,以此來達到報錯注入的效果。

 

打開Burp Suite軟件,查看端口代理:點擊Proxy ——> 點擊Options選項:

 

 

 

Referer報頭注入構造的SQL語句如下所示:

' or updatexml(1,concat('~',(database())),3),'192.168.1.1')#

 

 

把http請求頭部信息中Referer字段中原先的內容刪掉,替換成Referer報頭注入自定義的SQL語句,點擊Go發送http請求頭部信息:

使用user-agent報頭注入獲取表名,獲取列名,獲取用戶名和密碼等數據,也是按照上面的方式構造SQL語句。

 

 

4. Cookie報頭注入

 

分析Less-20源代碼產生SQL注入的原因:

通過分析源代碼後,發現同樣也對提交的用戶名和密碼進行對比查詢了,但與user-agent報頭注入和Referer報頭注入不同的是,調用了setcookie函數對用戶名設置一個cookie,setcookie函數的作用是向客戶端發送一個 HTTP cookie。

 

函數原型如下:

setcookie(name,value,expire,path,domain,secure);

 

name和value參數是必需參數,其他的則爲可選參數,具體參數說明如下:

  1. name:表示cookie 的名稱。
  2. Value:表示cookie 的值。
  3. expire:設置cookie 的有效期。
  4. path :設置cookie 的服務器路徑。
  5. domain:設置cookie 的域名。
  6. secure:是否通過安全的 HTTPS 連接來傳輸 cookie。

 

setcookie('uname', $cookee, time()+3600); 這一行代碼的作用就是向客戶端發送一個名字爲uname的HTTP cookie,有效期爲3600秒(一個小時)。

 

 

當提交用戶名和密碼登陸成功會生成一個cookie,web頁面會輸出cookie的值,客戶端向數據庫服務端發送cookie驗證不需要再次輸入用戶名和密碼,提交的cookie值不需要進行check_input校驗,這會讓username從$cookee中獲取的cookie可以隨意修改,存在SQL注入。

 

 

Cookie是http協議請求頭中的一個字段:

Cookie是一種客戶端技術,用於記錄客戶端的身份信息,例如通過cookie可以登錄網站。也就是說,服務器會給每個用戶的數據以cokkile的形式寫入每個用戶的瀏覽器中(通常cookie會進行加密),不同用戶的cookie也是不同的,當用戶通過各自的瀏覽器訪問服務器時就會帶着自己的數據,這樣服務器通過cookie來辨別不同用戶身份,並把數據返回給相應的用戶。

 

 

使用用戶名和密碼登錄,然後刷新頁面:

 

打開Burp Suite軟件,查看端口代理:點擊Proxy ——> 點擊Options選項:

現在我們要根據這行代碼分析並進行SQL注入:

$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";

從這行代碼可以確定閉合方式是單引號的。

 

 

確定閉合方式後,現在http請求頭中的cookie字段替換成自定義的SQL語句:

' order by 4#

 

從數據庫返回的錯誤提示來看,當前數據庫表的列數沒有4列的,那麼把4改爲3的時候,web頁面顯示正常,說明當前表的列數實際上只有3列的:

 

 

再通過聯合查詢注入確定顯示位,構造的SQL語句如下:

確定顯示位置後,就可以將2或者3的位置更改爲version()函數或者database()函數,爆出數據庫的版本和名字。

 

使用cookie報頭注入獲取數據庫下所有表名:

Cookie: uname='union select 1 , group_concat(table_name) , 3 from information_schema.tables where table_schema=database() #

 

使用cookie報頭注入獲取數據庫下表的所有列名:

Cookie: uname='union select 1 , group_concat(column_name) , 3 from information_schema.columns where table_schema=database() and table_name='users' #

 

使用cookie報頭注入獲取當前數據庫下表的所有用戶名和密碼:

Cookie: uname='union select 1 , group_concat(username , '@' , password) , 3 from users #

 

5. 總結

基於POST提交方式的SQL注入跟GET提交方式本質上是沒有區別的,POST提交的區別在於在進行SQL注入的過程中所提交的參數形式不一樣。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章