zoukankan      html  css  js  c++  java
  • 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="1000px;height:20px;" type="text"  name="uname" value=""/><br>
    	密码: <input  style="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;?>
    


    版权声明: 本博客,文章与代码均为学习时整理的笔记,博客中除去明确标注有参考文献的文章,其他文章【均为原创】作品,转载请务必【添加出处】,您添加出处是我创作的动力!

    警告:如果您恶意转载本人文章,则您的整站文章,将会变为我的原创作品,请相互尊重!
  • 相关阅读:
    java的几种对象(PO,VO,DAO,BO,POJO)
    建立标准编码规则(四)-C#编码规范分类及实现
    建立标准编码规则(三)-CodeFixProvider 给代码分析器增加修复建议
    建立标准编码规则(二)-DiagnosticAnalyzer 增加诊断分析代码
    建立标准编码规则(一)-自定义C#代码分析器
    领域模型与微服务
    asp.net core 中使用StyleCop.StyleCopAnalyzers
    asp.net core中使用HttpClient实现Post和Get的同步异步方法
    asp.net core 如何集成kindeditor并实现图片上传功能
    一名前端Web架构师的成长之路(转载)
  • 原文地址:https://www.cnblogs.com/LyShark/p/13488807.html
Copyright © 2011-2022 走看看