[BUUCTF题解][GYCTF2020]Ezsqli
### 知识点
SQL无列名注入
过程
做题先搜集(扫目录+检查HTTP报文+查看初始页面HTML代码),找到一个README.md,但是妹有什么用。

看题目名就大概猜到和SQL相关,对这里数据输入点测试,可以确定是数字型。


对关键字进行测试,发现如information、union、and、or等会被检测到而无法执行。

看来是要通过无列名注入了,考虑到又是盲注,这里采用使用替代表注出表名,本题可用的表是sys.schema_table_statistics_with_buffer,先得到表名。
?id=1^(select(ascii(substr((select(group_concat(table_name))from(sys.schema_table_statistics_with_buffer)where(table_schema=database())),1,1))>1))^1

明显flag位于f1ag_1s_h3r3_hhhhh表中,接下来就是从这个表中获取到数据了。
接下来无列名注入采用的是构造相同查询语句比较,如select (query_string_A) > (query_string_B)就会将query_string_A得到的字段与query_string_B得到的字段依次比较得出逻辑值,所以可以在排除其他非目标字段后对目标字段进行比较从而注出目标字段值。
但是前提需要解决两个问题,一是非目标字段的之间判断的影响,二是目标字段比较的方式。
非目标字段的之间判断的影响:Mysql比较采用的是依次比较,这就意味着如果顺序靠前的字段不相等,那么比较结果就会是不相等的考前字段比较的逻辑值,这个好解决,依次把顺序位于目标字段前面的字段值找出即可,而且由于Mysql在数字和字符进行比较时会把两者均转化为数字进行比较,所以实际上找出在转化后逻辑判断相等的数字也是可行的。
二是目标字段比较的方式:比较方式与普通盲注不同的是,由于比较顺序的影响,实际有效的逻辑符号的只有大于号和小于号。思路是通过在猜测的目标字符加上额外字符来辅助进行判断,可以参考如下的相关语句的逻辑值:
SELECT "c~">"bb"; #1
SELECT "c!">"bb"; #1
SELECT "b~">"bb"; #1
SELECT "b!">"bb"; #0
SELECT "a~">"bb"; #0
SELECT "a!">"bb"; #0
可见当使用的是正确的字符猜测是,额外字符!和~的情况进行异或刚好为1,其他则会为0,这样就能很好的判断出那个字符是正确猜测了。
但是还需要注意一些小细节,如:比较时大小写字目视为相等均采用了小写字母的ASCII值,所以并不能有效的判断大小写;如果目标字段不是顺序为最后一位的话,目标字段的最后以为并不方便判断。
会到题目上来,先测试有多少字段在flag所在的表中,当字段数目不一致时是无法正确执行SQL语句的。


第一个字段很好判断出来,是数字1或者是以1开头的字符串,第二个字段就是flag,将如下格式的payload携程自动脚本就能注出flag了
1^(select((select 1,"{}"){}(select * from f1ag_1s_h3r3_hhhhh)))^1
注出完成,成功得到flag字段所有值。


浙公网安备 33010602011771号