HTTP消息的结构其实并不复杂,它由客户端请求与服务器端响应两部分构成。无论是请求还是响应,都包含一个起始行、一个或多个头域(Header)、一个标志头域结束的空行,以及可选的消息体。其中,头域可细分为通用头、请求头、响应头和实体头四类。每个头域的格式固定为:域名、冒号、域值。域名不区分大小写,域值前可包含任意数量的空格,头域还支持跨行,只需在续行开头添加一个空格或制表符即可。
下面展示一个典型的HTTP请求头示例:
GET / HTTP/1.1
Connection: Keep-Alive
Keep-Alive: 300
Accept:*/*
Host: host
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16 ( .NET CLR 3.5.30729; .NET4.0E)
Cookie: guest_id=v1%3A1328019064; pid=v1%3A1328839311134
那么问题来了——如何利用这些HTTP头域进行SQL注入呢?换句话说,能否将恶意SQL语句隐藏在请求头中,使服务端在解析时落入陷阱?答案是肯定的,而且操作手法并不复杂。
首先,你需要一款能够管理Cookie的浏览器插件。以常见的Cookie管理器为例,启动插件后,导航至目标网站。

接下来,编辑目标网站的Cookie值,用于验证是否存在HTTP头注入漏洞。具体操作是:找到类似language_id的字段,在其值后面添加一个单引号',然后刷新页面观察反应。

刷新页面后,如果出现报错或异常现象,则说明很可能存在注入点。

确认存在注入漏洞后,可以换用更强大的工具——Tamper Data插件。该插件能够拦截并修改浏览器发出的每一个请求,包括请求头。使用Tamper Data编辑请求内容,将SQL注入语句插入其中。

比如输入一个经典的SQL注入语句:

如果尝试order by 5--,结果报错,则说明列数不匹配。调整数字,直到不再报错。例如,上述报错后,可以推断出用户表只有4列。

接下来,在Cookie管理器的language_id字段里,把值改成类似这样的注入语句:
-1+UNION+ALL+SELECT+1,2,3,4
或者更直接地,使用version()、user()、concat(database())、group_concat等函数来获取数据库版本、用户信息或数据库名称。
当然,使用SqlMap这类自动化注入工具会更加高效。关于SqlMap的具体用法,后续会专门撰文介绍。

相关阅读:
HTTP(HyperText Transfer Protocol)即超文本传输协议,用于传输万维网(WWW)数据,详细规范请参考RFC2616。HTTP协议采用请求/响应模型:客户端向服务器发送请求,请求头包含请求方法、URI、协议版本,以及类似MIME的消息结构(内含请求修饰符、客户信息和内容)。服务器则以状态行作为响应,内容包含协议版本、成功或错误编码,以及服务器信息、实体元信息和可能的实体内容。
