说到SQL注入,各色各样的文章可谓遍地都是,从产生原理到各种特定环境下的利用,都有所讲解。但那只是告诉你怎么灵活运用,肯定都会存在一个大前提:那就是你首先得有一个注入点!不错,这个问题很关键,手里没有注入点即使你会再多的注入姿势也用不上不是。所以说,善于发现注入点其实也是一件很了不起的事情,很多时候,其实注入点就在那里,而我们却视而不见,这耽误了多大事儿哇~~~
刚刚发现了一处挺有意思的注入点,这不,赶紧写个帖子来给大家分享一下。
其实在大概一两年前,也遇到过一个几乎和这个情况一模一样的注入点,不过那时候没写出来,今天又遇到一个这样的,就写出来给大家扩展一下思路,也没什么东西,就算是一点小伎俩吧,主要还是抛砖引玉。
作者:adwin
来自:Silic
http://blacklbap.org http://silic.org
http://www.okadwin.com
大家应该都见过很多网站在登陆的时候,会有用户名的提示,也就是说假如系统中存在两个用户,分别是lilei和lili,那么当你在用户名的输入框里输入字母l的时候,一般来说会显示一个下拉框,提示系统中存在lilei和lili这两个用户,你可以直接进行选择,而不用把你的用户名打全,我们暂且称之为自动补全功能?刚刚我就遇到了这么一个带有自动补全功能的系统登录页面(只是用户名补全啊,别想多了,密码肯定不会帮你补全的/淫荡的笑),当我输入一个字母a的时候,他果断帮我查找了系统中带有字母a的用户名:
当我继续输入的话,系统就会继续自动提示。
其实到这里大家可能就已经想到是怎么回事了。是的,大家都知道,HTTP是无状态协议,也就是说,我既然已经打开这个页面了,那么我对这个页面这次请求就已经完成了,这个时候按尿性客户端就不会再继续与服务端进行通信了,不过他既然实现了这个自动提示的功能,那肯定是通过javascript一类的技术实现再次向服务端发起请求,来查询我们所输入的内容,通过服务端返回的内容来进行提示。那么到这里问题就更加显而易见了:既然你是提示用户名,那么肯定是要进行数据库查询的,把我当前输入的内容带入数据库查询,然后返回需要提示的内容。问题来了,既然你肯定进行了数据库查询,那么会不会产生SQL注入呢?于是我尝试输入了一个单引号,结果丫的既什么也没返回,又没有报任何错误,难道对这个提交的数据进行过滤了?其实未必,我们没看到页面返回错误,可不代表真的没有返回错误,不要相信你的眼睛~
为了更清楚的看到向服务端提交了什么,是怎么提交的,抓包肯定是少不了的,所以嘛,别管他到底是怎么回事,抓个包先。如下图就是我在输入框只输入一个字母a时,向服务端提交的内容:
哟呵,POST了这么个玩意,这个格式就有点不太好搞了,得手动来了,如果是test=123456这种形式的话,直接扔sqlmap跑一下就好了嘛。好吧,那么我们就来继续测试。
为了验证这里到底是不是有SQL注入漏洞,光这么一个HTTP包是说明不了任何问题的,再来抓个输入单引号时候的包吧:
这回我们在输入框里填写的是一个单引号,POST的内容如上图所示。怎么样,这回就大不一样了吧?什么?没看出来有什么不一样?你再仔细看一下,一定要仔细看,给你十分钟的时间,仔仔细细的看!
十分钟过去了没?还是没看到什么关键的地方?唉,如果还是没看到的话,那就再多给你十分钟!
什么?二十分钟了还是没看到关键的地方?好吧,其实我也没看到(/大笑)……关键的地方截图没截到,在下边这张图上呢,来张完整的:
大家看到,返回了一个500的错误页面,其实不单单是一个简单的500错误页面,这个错误页面中其实还有我们想看到SQL错误信息,但是无奈这个数据内容没有换行,太长了,需要拉动滚动条才能看到,截图截不到,就这样凑合着看吧。。。
至此,我们已经看到了期待已久的SQL错误!到这里,你应该就明白,我们在浏览器上看不到返回错误,不代表真的没有返回错误哦。那么接下来的事情就不用我说了吧,直接构造SQL注入语句,从返回的数据包就能看到到底是如何了。例如我们提交【‘ and 1=(select @@VERSION)--】,就能看到我们想要的MSSQL的版本信息了。
至此,我们就彻底明白了这个SQL注入到底是怎么产生的了。所以我一直说,任何来自客户端的数据都是不可信任的。这也是给广大程序猿们提了个醒啊。