什么是SQL注入呢。SQL注入就是WEB应用没对用户输入的数据进行限制和检查,导致恶意攻击者可以通过网页的显示情况不同甚至是直接显示数据而获取数据库数据的一种攻击方式。
首先看下回显注入,这个简单,这个SQL注入是由于浏览器没有对URL后面id的参数进行限制,我们通过联合查询这样的SQL语句就能查询到有哪些数据库并且直接显示在网页上,想要查询其他的数据,更改查询语句即可。
现在我们来说下盲注,就是你不能从网页上直接获得数据,比如说我在本地搭建了一个网站,它的网页URL是这样的:
http://localhost/index.php?id=1,它的网页跟上图不一样,不直接显示你要查询的数据,只会显示两种不同的情况,我们把它认为是TRUE和FALSE,通过and判断?id=1 and 1=1 它是TRUE,?id=1 and 1=2 它是FALSE,也就是说and后面的数据是对的,就是TRUE,是错的,就是FALSE。当然实际不会直接显示TRUE和FALSE,而是两种不同的页面而已。
这个时候我们该怎么要获得我们要查询的数据呢,那就要利用ASCII,ASCII就是给每种英文字符和特殊符号的一种编码,比如A-65、a-97等,我们先看下面这样的URL:
http://localhost/index.php?id=1’ and ascii(substr((select database()),0,1))>97 --+
这个我从里向外解析下,select database() 这个查询数据库的语句;substr() 这是php的截取字符串函数,第一个参数是查询到的数据库,第二个参数0是索引,也就是从截取字符串的第一个字母开始向后截,第三个参数1就是只截取1个字符,也就是说substr()取到的数据时数据库名的第一个字母,而ascii()这个函数就是取这个字母的ASCII码值,然后与数值97比较。
首先我们是不知道数据库名的,如果这个库名的第一个字母是a,那么>、<97都显示FALSE,=97显示TRUE;数据库名第一个字母如果不是a,通过更改ASCII码值97,利用二分法可以减小步骤快一点也就是>97或<97,然后在取97区间的一半;同理判断数据库名其他的字母通过更改substr()第二个参数索引就行,查表名同理,修改substr()第一个参数里的select语句就行,通过这种方法我们就可以取得数据库中得信息了。。
这就是SQL注入盲注获取数据的原理,当然这样是很慢,写脚本交给机器跑就行,这也是我们平常为什么通过and 1=1 和 and 1=2 来判断SQL注入的原因。
现在我们再看一种SQL注入获取数据的方式:报错注入,这个漏洞影响CMS系统joomla,版本号为3.7.0,CVE编号为CVE-2017-8917。搭建环境一套是PHPstudy系统,这个系统集php、MySQL、Apache于一体的环境,将我们的joomla放到WWW目录,然后进入joomla主页完成安装即可,这个简单,不上图了,我们看一下sql注入存在的位置。
这里我先解析一下报错注入获取数据的原理,我用的报错函数是updatexml(Doc,XPathstring,new_value),Doc是文档对象,new_value是用来替换XPathstring字符串的值,原理就是XPathstring字符串形式是:'html/body/h1',利用concat()组合出来的字符串不是XPath形式的字符串来产生报错从而执行congcat()函数里的SQL语句,这里的0x3a是:,这里用来concat()函数拼接的,你也可以换其他的,不用纠结,总的需要一个来作为拼接参数。
解析一下这个注入的缘由,这个组件的构造函数说明位于componentscom_fieldscontroller.php,这里我们看出要加载com_fields这个组件,需要两个且条件,即 view=fields&&layout=modal,即构造的URL:http://localhost/Joomla_3.7.0/index.php?option=com_fields&view=fields&layout=modal
该组件的模型存在注入问题位于administratorcomponentscom_fieldsmodelsfields.php,在getListQuery函数里,getState()函数获取list的fullordering的键值,而这里没有对fullordering进行严格的过滤,就把它传给查询参数。
而State状态这个参数会被View视图获取,位于administratorcomponentscom_fieldsviewsfieldsview.html.php页面,会作为display函数的一个参数,用于展示在网页上,这也是这个报错注入回显在网页上的原因。
由此,最终的exp注入方式如下:
http://localhost/Joomla_3.7.0/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml(1,concat(0x3a,(select%20database()),0x3a),1)