HTTP請求頭引發的注入問題 (SQL注入)


關於請求頭中注入問題的演示,這里我寫了一些測試案例,用來測試請求頭中存在的問題。我們常見的會發生注入的點有 Referer、X-Forwarded-For、Cookie、X-Real-IP、Accept-Language、Authorization,User-Agent

HTTP Referer:是header的一部分,當瀏覽器請求網頁時,會自動攜帶一個請求來源,如果后端存在交互,則會引發注入問題的產生。
User-Agent 請求頭,該請求頭攜帶的是用戶瀏覽器的標識信息,如果此時帶入數據庫查詢,則同樣會觸發注入問題的產生。
X-Forwarded-For:簡稱XFF頭,它代表客戶端,用於記錄代理信息的,每經過一級代理(匿名代理除外),代理服務器都會把這次請求的來源IP追加在X-Forwarded-For中
Cookie:指某些網站為了辨別用戶身份、進行 session 跟蹤而儲存在用戶本地終端上的數據(通常經過加密)
X-Real-IP:只記錄真實發出請求的客戶端IP。
Accept-Language:請求頭允許客戶端聲明它可以理解的自然語言,以及優先選擇的區域方言
HTTP_CLIENT_IP:該屬性是PHP內置屬性,同樣取得的是客戶端的IP,同樣可控,如果帶入數據庫,則會產生注入問題。

Cookie 注入: 該注入的產生原因是因為程序員沒有將COOKIE進行合法化檢測,並將其代入到了數據庫中查詢了且查詢變量是可控的,當用戶登錄成功后會產生COOKIE,每次頁面刷新后端都會拿着這個COOKIE帶入數據庫查找,這是非常危險的.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf8">
</head>
<body>
<form action="" method="post">
	賬號: <input type="text"  name="uname" value=""/><br>
	密碼: <input type="password" name="passwd" value=""/>
	<input type="submit" name="submit" value="Submit" />
</form>
	<?php
		header("Content-type: text/html;charset=utf8");
		error_reporting(0);
		$connect = mysqli_connect("localhost","root","12345678","lyshark");
		if($connect)
		{
			$cookee = $_COOKIE['uname'];
			if($cookee)
			{
				$sql="SELECT username,password FROM local_user WHERE username='$cookee' LIMIT 0,1";
				$query = mysqli_query($connect,$sql);
				echo "執行SQL: " . $sql . "<br>";
				if($query)
				{
					$row = mysqli_fetch_array($query);
					if($row)
					{
						echo "<br> COOKIE 已登錄 <br>";
						echo "您的賬號: " . $row['username'] . "<br>";
						echo "您的密碼: " . $row['password'] . "<br>";
					}
				}
			}

		    if(isset($_POST['uname']) && isset($_POST['passwd']))
		    {
			$uname=$_POST['uname'];
			$passwd=$_POST['passwd'];
			$passwd = md5($passwd);
			$sql="select username,password FROM local_user WHERE username='$uname' and password='$passwd' LIMIT 0,1";
			$query = mysqli_query($connect,$sql);
		        if($query)
		        {
		        	$row = mysqli_fetch_array($query);
		        	$cookee = $row['username'];
		        	if($row)
		        	{
		        		setcookie('uname', $cookee, time() + 3600);
		        		$format = 'D d M Y - H:i:s';
		        		$timestamp = time() + 3600;
		        		echo "COOKIE已設置: " . date($format, $timestamp);
		        	}
		        }
		    }
		}
	?>
</body>
</html>

當登錄成功后,再次刷新頁面,就會將cookie帶入數據中查詢,此時觀察cookie,可以閉合,則就會產生注入問題。

執行payload Cookie: uname=admin' and 0 union select database(),2--+ 可爆出數據庫名稱。

查詢數據庫同樣可以爆出,數據庫的版本號。

稍微修改一下代碼,當代碼中設置COOKIE的位置上增加了Base64編碼后,該如何注入呢?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf8">
</head>
<body>
<form action="" method="post">
	賬號: <input type="text"  name="uname" value=""/><br>
	密碼: <input type="password" name="passwd" value=""/>
	<input type="submit" name="submit" value="Submit" />
</form>
	<?php
		header("Content-type: text/html;charset=utf8");
		error_reporting(0);
		$connect = mysqli_connect("localhost","root","12345678","lyshark");
		if($connect)
		{
			$cookee = base64_decode($_COOKIE['uname']);
			if($cookee)
			{
				$sql="SELECT username,password FROM local_user WHERE username='$cookee' LIMIT 0,1";
				$query = mysqli_query($connect,$sql);
				echo "執行SQL: " . $sql . "<br>";
				if($query)
				{
					$row = mysqli_fetch_array($query);
					if($row)
					{
						echo "<br> COOKIE 已登錄 <br>";
						echo "您的賬號: " . $row['username'] . "<br>";
						echo "您的密碼: " . $row['password'] . "<br>";
					}
				}
			}

		    if(isset($_POST['uname']) && isset($_POST['passwd']))
		    {
			$uname=$_POST['uname'];
			$passwd=$_POST['passwd'];
			$passwd = md5($passwd);
			$sql="select username,password FROM local_user WHERE username='$uname' and password='$passwd' LIMIT 0,1";
			$query = mysqli_query($connect,$sql);
		        if($query)
		        {
		        	$row = mysqli_fetch_array($query);
		        	$cookee = $row['username'];
		        	if($row)
		        	{
		        		setcookie('uname', base64_encode($cookee), time() + 3600);
		        		$format = 'D d M Y - H:i:s';
		        		$timestamp = time() + 3600;
		        		echo "COOKIE已設置: " . date($format, $timestamp);
		        	}
		        }
		    }
		}
	?>
</body>
</html>

直接將Payload加密在線https://base64.us/加密后,放入COOKIE中

Cookie: uname=admin' and 0 union select database(),2--+
Cookie: uname=YWRtaW4nIGFuZCAwIHVuaW9uIHNlbGVjdCBkYXRhYmFzZSgpLDItLSs=

Usage-Agent 注入問題: Usagen-Agent是客戶請求時攜帶的請求頭,該頭部是客戶端可控,如果有帶入數據庫的相關操作,則可能會產生SQL注入問題.

create table User_Agent(u_name varchar(20),u_addr varchar(20),u_agent varchar(256));

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf8">
    <title>SQL 注入測試代碼</title>
</head>
<body>
<form action="" method="post">
	賬號: <input style="width:1000px;height:20px;" type="text"  name="uname" value=""/><br>
	密碼: <input  style="width:1000px;height:20px;" type="password" name="passwd" value=""/>
	<input type="submit" name="submit" value="Submit" />
</form>
	<?php
		header("Content-type: text/html;charset=utf8");
		error_reporting(0);
		$connect = mysqli_connect("localhost","root","12345678","lyshark");
		if($connect)
		{
		    if(isset($_POST['uname']) && isset($_POST['passwd']))
		    {
				$uname=$_POST['uname'];
				$passwd=$_POST['passwd'];
				$passwd = md5($passwd);

		        $sql="select username,password FROM local_user WHERE username='$uname' and password='$passwd' LIMIT 0,1";
		        $query = mysqli_query($connect,$sql);
		        if($query)
		        {
		        	$row = mysqli_fetch_array($query);
		        	if($row)
		        	{
		        		// 獲取到用戶的Agent客戶請求體
		        		$Uagent = $_SERVER['HTTP_USER_AGENT'];
						// REMOTE_ADDR 是調用的底層的會話ip地址,理論上是不可以偽造的
						$IP = $_SERVER['REMOTE_ADDR'];

						echo "<br>歡迎用戶: {$row['username']} 密碼: {$row['password']} <br><br>";
						echo "您的IP地址是: {$IP} <br>";

						$insert_sql = "insert into User_Agent(u_name,u_addr,u_agent) values('$uname','$IP','$Uagent')";
						mysqli_query($connect,$insert_sql);
						echo "User_Agent請求頭: {$Uagent} <br>";
		        	}
		        }
		    }
		}
	?>
</body>
</html>

登錄成功后,才可以顯示你的客戶端數據,也就是先要完成登錄。

登錄成功后,會自動獲取客戶端的user_agent信息,HTTP_USER_AGENT 屬性對我們來說可控,且通過insert語句帶入到了數據庫,此時我們可以構建注入語句。首先我們通過burp提交登錄請求。

然后再登陸成功后,我們繼續增加注入語句,將其寫道user-agent上完成報錯注入。

修改agent驗證,可被繞過,此處的語句帶入數據庫變為了insert into User_Agent values('1)','u_addr','u_agent')有時,不存在回顯的地方即使存在注入也無法得到結果.,但卻是一個安全隱患,需要引起重視.

IP來路引發的注入問題: 這里我又寫了一段代碼,看似沒有任何注入問題,原因是目標主機IP地址是可控的。

<?php

function GetIP(){
        static $retIP;

        if(isset($_SERVER)){
                if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
                        $retIP = $_SERVER['HTTP_X_FORWARDED_FOR'];
                }else if(isset($_SERVER['HTTP_CLIENT_IP'])){
                        $retIP = $_SERVER['HTTP_CLIENT_IP'];
                }else{
                        $retIP = $_SERVER['REMOTE_ADDR'];
                }
        }
        return $retIP;
}

$connect = mysqli_connect("127.0.0.1","root","123","lyshark");
if($connect)
{
        $addr = GetIP();
        $sql = "select * from ip where address='$addr' limit 0,1";
        $query = mysqli_query($connect,$sql);
        $row = mysqli_fetch_array($query);
        echo '本機IP:' . $row['address'];
        if ($row['address'] == $addr)
        {
                echo "注冊過了..";
        }
}
?>

<?php echo '<hr><b> 后端執行SQL語句:  </b>' . $sql;?>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM