Header简介
什么是Header头?
通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成。HTTP的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。cookie也属于header头,如下图
GET / HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Header注入原理
什么是Header注入?
Header注入,该注入是指利用后端验证客户端口信息(比如常用的cookie验证)或者通过Header中获取客户端的一些信息(比如User-Agent用户代理等其他Header字段信息),因为这些信息在某些地方是会和其他信息一起存储到数据库中,然后再在前台显示出来,又因为后台没有进过相对应的信息处理所以构成了sql注入。
引入知识:
超全局变量
PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。这些超全局变量是:
$_REQUEST (获取GET/POST/COOKIE) COOKIE在新版本已经无法获取了
$_POST (获取POST传参)
$_GET (获取GET的传参)
$_COOKIE (获取COOKIE的值)
$_SERVER (包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组)
$_SERVER 常用方法:
$_SERVER['HTTP_HOST'] 请求头信息中的Host内容,获取当前域名。
$_SERVER["HTTP_USER_AGENT"] 获取用户相关信息,包括用户浏览器、操作系统等信息。
$_SERVER["REMOTE_ADDR"] 浏览网页的用户ip。
updatexml()函数
updatexml() 更新xml文档的函数
语法:updatexml(目标xml内容,xml文档路径,更新的内容)
接下来会有单独文章介绍报错函数
updatexml(1,concat(0x7e,(SELECT database())),1)
实际上这里是去更新了XML文档,但是我们在XML文档路径的位置里面写入了子查询,我们输入特殊字符,然后就因为不符合输入规则然后报错了
但是报错的时候他其实已经执行了那个子查询代码!注意:必须使用concat函数拼接一个特殊字符才会报错,如下图
注入实现
此处用到Header注入靶场可用sqlilabs自行搭建,打开url如下图
上图我们看到自己的User-Agent被系统记录,打开burp进行抓包,尝试修改User-Agent,发送数据包如下图
返回浏览器观察,页面变化,如下图
把数据包发送到burp的repeater模块,进行测试,输入单引号,发现页面报错,如下图
闭合原语句,尝试使用报错注入,payload:xxx'and updatexml(1,concat(0x7e,database()),1) or',如下图
其余步骤:
其余步骤和其他测试无太大区别,只需要不断替换子查询语句即可
自动化工具
sqlmap
--level 3 //sqlmap默认测试所有的GET和POST参数,当--level的值大于等于2的时候也会测试HTTP Cookie头的值,当大于等于3的时候也会测试User-Agent和HTTP Referer头的值。最高可到5
扩展
下面是一些个人想法,有机会搭个靶场
header头如果通过SQL语句被保存在了数据库中,在没有进行过滤的情况下,应该可以尝试,插入的数据是子查询查出来的,这个在浏览器回显的地方就可能会直接出现想要的数据