less-1~Less4联合注入讲解
less-1:基于字符型(单引号)注入点的联合注入
我们首先进入第一关:
可以看到提示我们“请输入 id 作为带有数值的参数”,我们在网址后添加 ?id=1 作为参数,发现页面变化如下:
再次输入id=2测试,页面返回如下:
可以看到随着我们输入的参数不同,页面的返回情况不同,这就说明我们输入的这个参数被带入到了数据库中执行了,也就是我们在前端输入的参数和其后端的数据库有交互。
注入类型判断
接下来我们尝试寻找注入点,在我们输入的参数后加一个单引号(“ ' ”)进行测试,发现页面报错:
当我们在参数后边输入一个字符单引号(“ ' ”)时,前端页面发生报错,说明后端对一些特殊字符没有做很好的过滤处理,这个时候就会存在sql注入漏洞,并且注入点很有可能就是字符型。
接下来我们去解析一下为什么输入单引号(“ ' ”)页面会发生报错,我们首先看一下这个网页的源代码:(D:\phpStudy\PHPTutorial\WWW\sqli-labs-master\Less-1,找到自己的下载路径就可以看到php源代码)
可以看到源代码中的sql查询语句为:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
其中id='$id'就是我们传入的参数,当我们执行“ id=1' ”的时候实际上执行的语句是:
$sql="SELECT * FROM users WHERE id='$id'' LIMIT 0,1";
这样这条sql语句就会因为单引号(“ ' ”)的干扰而无法正常执行,从而报错。一旦出现并且页面给了我们报错的回显,就说明存在sql注入,接下来我们就要寻找注入点了。当参数可控时,看参数是否对数据产生影响,若有影响则可能是注入点。
我们首先测试是不是单引号的字符型注入,输入语句:
?id=1' and '1'='1
进行测试,实际执行的sql语句为:
$sql="SELECT * FROM users WHERE id='1' and '1'='1' LIMIT 0,1";
and '1'='1' 这个语句一定是真的,所以如果是单引号的字符型注入,那么页面无论如何也会返回正常: ![](https://img-blog.csdnimg.cn/909d25cceef34d139dfd0556a8db9b80.png)
之后我们在输入语句:
?id=1' and '1'='2
进行测试,实际执行的sql语句为:
$sql="SELECT * FROM users WHERE id='1'' and '1'='2' LIMIT 0,1";
and '1'='2' 这个语句一定是假的,所以如果是单引号字符型注入那么页面一定显示不正常(但是不会出现报错):
页面显示不正常,说明注入点就可能是单引号(“ ' ”),这里只能推断出可能是这种类型,后面如果爆破语句能够爆破成功的话,就是单引号类型的注入,如果爆破报错的话还需要进一步测试,例如第三关。我们在单引号(“ ' ”),之后输入我们的注入语句即可。
猜解数据库中字段数
找到注入点之后我们要去猜解该数据库中有多少个字段,因为该靶场使用的是mysql数据库,所以用 order by x 语句进行判断(order by x 语句解析:https://www.w3school.com.cn/sql/sql_orderby.asp)。
使用 order by x 进行猜解的时候可以使用二分法进行猜解,先使用大一点的数字数字进行测试,如果报错就换数字的一半进行测试,当范围缩小时在依次测试,例如这里先假设数据库中有8个字段进行测试:输入语句:
?id=1' order by 8 --+
(--+为注释,将--+之后的语句都注释),输入语句后执行发现页面报错:
说明该数据库的字段数小于8,之后我们用4进行测试也报错,再用3进行测试时发现页面回显正常,说明数据库中有3个字段:
接下来我们要判断页面有没有显示位,显示位能显示多少数据,我们使用联合查询去判断( 联合查询语句解析:https://www.runoob.com/sql/sql-union.html)
我们输入语句:
?id=-1' union select 1,2,3 --+
这里我们输入的参数变为了“ -1 ” 原因是为了页面不显示之前的查询结果,因为union操作符用于合并两个或多个 SELECT 语句的结果集,如果输入?id=1' 那么页面回显的就是后端第一次查询到的内容,并不会回显我们想要的内容,如下:
位于?id=1'后面的union语句并没有被回显出来,当输入id=-1'时页面回显如下:
可以看到页面的显示了2,3列,而第1列并没有被显示出来,也就是说我们的注入语句要写到2列和3列的位置上才可以被页面回显出来 。
举例来说,比如我们通过order by命令知道了表的列数为20。然后再使用union select 1,2,3…,20 from table,网页中显示了信息8,那么说明该网页只能够显示第8列中信息,不能显示其他列的信息。也可以理解为该网页只开放了8这个窗口,你想要查询数据库信息就必须要通过这个窗口。所以如果我们想要知道某个属性的值,比如id,就要把id属性放到8的位置上,这样就能通过第8列爆出id的信息。
联合注入常用函数
system_user()系统用户名user()用户名current_user()当前用户名session_user()链接数据库的用户名version()当前数据库的版本@@basedir当前数据库的安装路径@@version_compile_os当前数据库的操作系统information_schema保存着关于MySQL服务器所维护的所有其他数据库的信息。tables储存了数据库库名,以及该库中包含的表名table_schema表示数据库名table_name 表示表名column_name 表示列名columns 存储了字段名
爆破数据库库名以及版本号
我们输入注入语句:
?id=-1' union select 1,database(),version() --+
页面回显如下:
爆破数据库中的表名以及数据库安装路径
输入注入语句:
?id=-1' union select 1,group_concat(table_name),@@basedir from information_schema.tables where table_schema='security' --+
页面回显如下:
上面的代码翻译一下其实就是“从information_schema数据库中的tables表中查找数据库security所含有的表有哪些,并且将查出来的表用逗号分隔开显示” ,同时查询当前数据库的安装路径并且返回到显示位3上面
爆破某张表中的列名以及当前数据库的用户名
输入注入语句:
?id=-1' union select 1,group_concat(column_name),user() from information_schema.columns where table_name='users' and table_schema='security' --+
页面回显如下:
想要显示其他表的话直接把语句中的table_name='users' 里面的users换为其他表名就可以。
查询每一列的具体字段内容
输入注入语句:
?id=-1' union select 1,group_concat('~',id,'~',username,'~',password),3 from users --+
页面回显如下:
到此为止,第一关就结束了。
less-2:基于整数型注入点的联合注入
首先进入第二关:
可以看到和第一关一样让我们输入参数,我们输入 ?id=1 测试页面的回显:
页面回显正常,说明前端输入的参数和后端的数据库有交互,接下来输入单引号 “ ' ” 来测试页面是否存在漏洞:
可以看到报错了,说明百分之90该页面存在注入漏洞,只要找到注入点就可以进行注入,有时候并不会显示报错,但是也不代表不存在漏洞,可以通过页面响应时间等方法进行判断,后续我将更新这些判断方法。
注入类型判断
接下来我们判断注入点是什么,我们先判断其是不是字符型注入,使用语句:
?id=1' and '1'='1
?id=1' and '1'='2
我们发现当我们输入第一个测试条件的时候页面回显了报错:
但是按道理来讲,and '1'='1 是永远成立的,不应该报错,那么只有一种可能,那就是他底层SQL语句查询功能中写入的参数并不是字符型,所以当我们输入多个单引号后,SQL语句无法执行从而报错。我们查看一下源代码验证我们的猜想:
可以看到和第一关源代码不同的是SELECT查询中WHERE条件后的参数并没有用单引号进行闭合,所以是“整数型注入”。一般情况下如果“单引号字符型”不行的话就去试试是不是“整数型注入”
我们在输入测试语句:
?id=1 and 1=1
页面回显:
可以看到页面回显正常,之后再用测试语句:
?id=1 and 1=2
页面回显:
可以发现页面回显不正常,说明注入类型是整数型注入,之后的操作和第一关的操作一样,只不过不需要在参数后面加单引号闭合而已,这里就不再赘述了。
less-3:基于 ') 注入点的联合注入
首先进入第三关:
输入参数判断与后台数据库有无交互:
页面回显正常,web页面与后台数据库有交互。
注入类型判断
首先输入单引号查看页面回显:
页面回显错误,但是与之前不同的是报错内容中多了一个单括号,我们首先测试是不是单引号的字符型注入,输入语句:
?id=1' and '1'='1
页面回显如下:
页面回显正常,我们接着输入语句:
?id=1' and '1'='2
页面回显如下:
页面回显不正常,说明有可能是单引号的字符型注入 ,接下来我们尝试使用一条注入语句测试一下能不能正常回显出我们想要的语句,我们就用ORDER BY语句测试一下当前数据库中有几条字段,输入语句:
?id=1' order by 8 --+
页面回显如下:
可以看到页面报了SQL语法错误,但是正常报错应该是“Unknown column '8' in 'order clause”,那就说明我们的注入点有问题,可能并不是基于单引号的字符型报错,之前我们输入单引号测试的时候多了一个单括号,我们知道在SQL语句中,where后的查询参数可以用括号括起来,我们猜测一下这一关的参数就是用括号括起来的,我们输入 ') 进行测试,输入语句:
?id=1') and 1=1 --+
页面回显如下(需要用注释注释掉后面的语句):
页面回显正常,接着输入注入语句:
?id=1') and 1=2 --+
页面回显如下:
页面回显不正常,那么可能就是基于 ') 的注入类型,接着输入一个简易的注入语句测试一下,这里依旧用ORDER BY 语句测试,输入注入语句:
?id=1') order by 3 --+
页面回显如下:
可以发现页面回显正常,因为之前查到了字段数为3,这里就不再进行猜解了,如果字段数小于3的话会报错“Unknown column '3' in 'order clause” ,接下来我们看一下网页的源代码:
可以看到参数是在括号里面的,我们的猜想是正确的。
到这里我们就知道这第三关的注入类型是基于 ') 的注入,下面的爆破方法和第一关一样,这里不再赘述,只需要把注入点改为 ') 就可以了。
less-4:基于 ") 注入点的联合注入
首先我们进入第四关:
输入参数id=1进行测试页面的交互:
回显正常,Web与后台数据库有交互。
注入类型判断
输入单引号进行测试:
奇怪的是我们发现并没有报错,那么就有可能是数据库后台把单引号过滤了,既然单引号类型被过滤了,那么我们就去测试双引号(一般来说都是这样一个一个测试,不过如果有经验的话测试一次看页面回显的报错情况就能大致知道是什么类型的注入),我们输入注入语句:
?id=1"
页面回显如下:
页面报错并且爆出了单括号,根据第三关的经验我们首先测试是不是基于 ") 的注入类型 ,输入注入语句:
?id=1") and 1=1 --+
页面回显:
再次输入注入语句:
?id=1") 1=2 --+
页面回显:
页面回显不正常但是没有报错,说明有可能是基于 ") 的注入类型,接下来我们输入ORDER BY 语句进行测试:
?id=1") order by 3 --+
页面回显如下:
可以发现页面回显正常,因为之前查到了字段数为3,这里就不再进行猜解了.
到这里我们就知道第四关的注入类型是基于 ") 的注入,下面的爆破方法和第一关一样,这里不再赘述,只需要把注入点改为 ") 就可以了。
总结
这里对SQL注入进行了初步的讲解,主要讲解了联合注入以及一些简单的注入类型判断,后续我会更新其他系列的注入方式,例如报错注入、二分法猜解注入、时间延迟注入、导出文件字符型注入、POST类型注入等注入类型。
第一次写博客,感谢观看,如有错误,请及时私聊指正。
版权归原作者 Joker—M 所有, 如有侵权,请联系我们删除。