关于sql注入(3)union注入

         还是关于我对SQL注入的理解,首先,通过对注入点有无回显,以及回显信息的认识,SQL注入可以分为union注入(有回显信息,且回显信息较多,例如用户名密码之类的信息),报错注入(页面没有回显,只能通过报错信息来进行推导),布尔盲注(页面没有回显,会通过反馈真值与假值来进行判断)。

        然后就是我对SQL注入现在的理解,与思路。

一.判断类型(是否存在sql注入,存在那种sql注入)

1.查找注入点:可以通过对其传入的可控参数(常见的有id,password等等)进行简单的构造,通过服务端返回的内容来判断有无注入 ,注入位置有GET数据(大多存在地址栏)、POST数据(大多存在输入框中)、HTTP头部、cookie数据。

2.判断是字符型注入还是数字型注入:首先我们假设注入类型为数字型,分别输入如下的语句。如果被测试对象是数字型,那么第一行测试语句会返回user_id为1的查询结果,而第二行语句由于条件and 1=2不成立,所以查询结果为空。如果被测试对象为字符型的话,将下面语句拼接到sql中,由于user_id的值都不匹配,所以应该是都不返回任何结果,(但是注意如果user_id本身是int类型,实际查询过程中是会返回结果的,这可能是因为对输入的字符进行了截断并转换了类型,造成1 and 1=2在字符类型中会返回user_id为1的查询结果。当然如果第二个语句返回了结果,我们也可以以此判断出该注入类型是字符型。)

1 and 1=1
1 and 1=2

3.闭合方式的判断:字符型需要闭合符' ') " ")等,数字型不需要闭合。(作用:手工提交闭合符号,结束前一段查询语句,后面即可加入其他语句。)

4.注释符号“--+’或‘#’或'%23'(可以使它们后面的语句不被执行,同时也使前面的语句被执行)。 (注意:get请求传参时字符串中不允许出现空格和特殊字符,故注释符号可以为‘--+’‘--%20’‘%23’等,可用urlencode编码解决这个问题。)

二.猜解sql查询语句中的字段数

       去猜测出查询语句中的字段个数,如下注入语句所示,假设为字符型注入,先利用1'实现引号闭环,再利用or 1=1这样可以暴露出表中所有的数据,最后利用order by 数字#去看是否报错来明确查询语句中的字段数。

1' or 1=1 order by 1 #
1' or 1=1 order by 2 #
或者
1' or 1=1 union select 1, 2, 3 #

三.判断回显

        由于开头的 1 会干扰回显,所以可以选择去掉1(或者换成负数也行,换成负数会导致前面的值不成立,然后才会继续执行后面的语句)

?可控参数=-1' union select 1,2,3#

四. 通过命令来获得相关库,表,列,字段的信息:

SQL一些最重要的命令(常用)

    SELECT - 从数据库中提取数据
    UPDATE - 更新数据库中的数据
    DELETE - 从数据库中删除数据
    INSERT INTO - 向数据库中插入新数据
    CREATE DATABASE - 创建新数据库
    ALTER DATABASE - 修改数据库
    CREATE TABLE - 创建新表
    ALTER TABLE - 变更(改变)数据库表
    DROP TABLE - 删除表
    CREATE INDEX - 创建索引(搜索键)
    DROP INDEX - 删除索引

        除了这些常用的命令以外,还应该学会怎么构造payload,以及各种函数的理解,与调用。然后实践才是检验真理的唯一标准,上题。

题目

[SWPUCTF 2021 新生赛]sql

通过网页头信息的提示我们可以知道,在这一题里面,可控变量为wllm,通过上文提到的步骤,可以判断注入类型为union注入。

输入单引号,发现报错,同时,根据报错提示也找到了它的闭合方式

判断字段,发现被警告,说明,存在过滤(可能是过滤了空格,也可能是 order by 关键字,还可能是注释符)

通过测试可知,空格,#号(--+)被过滤了,通过尝试可知可以使用%09,或者/**/等等来代替空格,%23来代替#。

经过测试,共有 3 列。

经过测试,回显位为后两位。(因为%09来代替空格真的眼睛花,所以改用/**/来代替空格)

查询数据库,发现名称为:test_db,那么再继续向下查看。

发现又被警告了,说明除了上文发现的过滤,还存在有其他的字符被过滤。可能是information_schema 被过滤了,经过测试,是等号被过滤了。用 like 关键字可以替换等号。

通过替换以后,成功查询到了关键信息

这里使用了group_concat()函数(group_concat()的作用:确保所有查询信息能放到一行显示出来(以逗号分隔开))

然后就是朴实无华的查询出来了列名,然后就是查询flag列的内容

结果懵逼了,flag好像出来了,又好像没出来。通过查找资料与学习,我发现flag的字段被限制了。然后根据大佬的 wp ,发现substr,substring 都被过滤了,说用 mid 函数分段读取。

这里是mid()函数的用法

先查询前二十位,然后再二十位,二十位查

最后,通过一段一段复制,得到了完整的flag。

        小结,这题,真牛逼,让我开眼界涨见识了,主要是因为他的过滤,导致“复制粘贴”注入无法实现,只能手搓,但是这个手搓也让我更加理解和记住了sql语句的构成,也明白了很多sql语句中可替换的部分,以及一个新的函数,也就是mid() 函数的使用。让小白开眼界了。

        纯小白,如有不足和错误,欢迎指正!

  • 41
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值