Sql注入即攻击者利用web应用程序对用户输入数据的合法性判断或过滤不严,构造非法sql语句在管理员不知情的情况下获取数据库敏感数据,如用户隐私、管理员账号密码等的一种网络攻击手段。
数字型注入:输入参数数据类型为整型时,如数据库中的年龄、分值等,存在注入漏洞则其为数字型注入。例:
在url地址中输入:http://xxx.xx.xx/index.php?id=1 and 1=1 页面返回正常
在url地址中输入:http://xxx.xx.xx/index.php?id=1 and 1=2 页面返回错误
字符型注入:输入参数数据类型为字符型时,如数据库中的名字、密码等,存在注入漏洞则其为字符型注入。例:
在url地址中输入:http://xxx.xx.xx/index.php?id=1’ and ‘1’=’1 页面返回正常
在url地址中输入:http://xxx.xx.xx/index.php?id=1’ and ‘1’=’2 页面返回错误
两者区别:数字型注入不需要单引号闭合,而字符型注入一般需要单引号来闭合。
基于布尔的盲注:利用web页面返回值只有true和false,根据返回值判断是否存在注入点,以便获取数据库信息。
基于时间的盲注:在某些场合下,页面只有一种返回结果,需要使用具有延时功能的函数sleep()、benchmark()等,通过判断这些函数是否正常执行来获取数据库中的数据。即利用web页面响应的时间差来判断是否存在注入点。例如http://xxx.xx.xx/index.php?id=1’ and if(1=1,sleep(8),1)# 当’and 1=1为真时延迟8秒返回 ,假则直接返回,由此测试是否存在注入点。
基于错误信息的注入:有些web页面在会返回错误提示信息,根据错误信息对代码中的SQL语句的结构进行猜测与验证,回显有用的相关数据库错误信息,引导进一步注入。
联合查询注入:即将两表合并查询,但需要满足以下条件:存在注入点且有回显位;列数和数据类型要一致。
堆查询注入:利用分号 ; 结束一条SQL语句的原理,构造多条SQL语句,以执行任意非法操作。不过受环境局限很大。
(1)SQL注入点探测;
(2)收集后台数据库信息;
(3)猜解用户名和密码;
(4)查找Web后台管理入口;
(5)入侵和破坏。
(1)加 ‘ 或 “ 如果返回页面错误则存在注入点
(2)加 and 1=1 或 ‘ and 1=1 --+ 或 ’) and 1=1 或 “) and 1=1 或者and ’1’ = ‘1返回正确
加 and 1=2 或 ‘ and 1=2 --+ 或 ’) and 1=2 --+ 或 “) and 1=2 --+或者and ’1’ = ‘2返回错误
(--(后面有个空格,因为不加空格,--直接和系统自动生成的单引号连接在了一起,会被认为是一个关键词,无法注释掉系统自动生成的单引号。)与 # 表示注释,在get请求传参注入时常使用--+的方式来闭合;如果是post请求,则可以直接使用#来进行闭合。其中#的urlencode编码为%23)
手工注入无疑是对一个信安学者对SQL注入的掌握程度的考验,但注入手段层出不穷,防注入手段也日新月异,光靠手工注入太耗人力成本了。sqlmap作为一个自动化的注入工具,可以轻易的帮助我们扫描、发现并利用给定URL的SQL注入漏洞,并且自带多个脚本,支持多种数据库如MySQL 、Oracle 、PostgreSQL 、Microsoft SQL Server、Microsoft Access 、IBM DB2, SQ Lite 、Firebird 、Sybase和SAPMaxDB等。学注入不学Sqlmap,简直就像出门不带手机。
在sqlmap中一共有五个探测等级,默认等级为一。
等级为一时会测试get和post的数据。
等级为二时会测试HTTP头的cookie注入。
等级为三时会测试HTTP的user-agent、referer头、xff头等的注入
等级越高,包含的playload越多,探测范围越广,探测时间也相对较长。
-u 指定目标URL (可以是http协议也可以是https协议)
-d 连接数据库
--dbs 列出所有的数据库
--current-db 列出当前数据库
--tables 列出当前的表
--columns 列出当前的列
-D 选择使用哪个数据库
-T 选择使用哪个表
-C 选择使用哪个列
--dump 获取字段中的数据
--batch 自动选择yes
--smart 启发式快速判断,节约浪费时间
--forms 尝试使用post注入
-r 加载文件中的HTTP请求(本地保存的请求包txt文件)
-l 加载文件中的HTTP请求(本地保存的请求包日志文件)
-g 自动获取Google搜索的前一百个结果,对有GET参数的URL测试
-o 开启所有默认性能优化
--tamper 调用脚本进行注入
-v 指定sqlmap的回显等级
--delay 设置多久访问一次
--os-shell 获取主机shell,一般不太好用,因为没权限
-m 批量操作
-c 指定配置文件,会按照该配置文件执行动作
-data data指定的数据会当做post数据提交
-timeout 设定超时时间
-level 设置注入探测等级
--risk 风险等级
--identify-waf 检测防火墙类型
--param-del="分割符" 设置参数的分割符
--skip-urlencode 不进行url编码
--keep-alive 设置持久连接,加快探测速度
--null-connection 检索没有body响应的内容,多用于盲注
--thread 最大为10 设置多线程
apostrophemask.py 用UTF-8全角字符替换单引号字符
apostrophenullencode.py 用非法双字节unicode字符替换单引号字符
appendnullbyte.py 在payload末尾添加空字符编码
base64encode.py 对给定的payload全部字符使用Base64编码
between.py分别用“NOT BETWEEN 0 AND #”替换大于号“>”,“BETWEEN # AND #”替换等于号“=”
bluecoat.py 在SQL语句之后用有效的随机空白符替换空格符,随后用“LIKE”替换等于号“=”
chardoubleencode.py对给定的payload全部字符使用双重URL编码(不处理已经编码的字符)
charencode.py 对给定的payload全部字符使用URL编码(不处理已经编码的字符)
charunicodeencode.py 对给定的payload的非编码字符使用Unicode URL编码(不处理已经编码的字符)
concat2concatws.py 用“CONCAT_WS(MID(CHAR(0), 0, 0), A, B)”替换像“CONCAT(A, B)”的实例
equaltolike.py 用“LIKE”运算符替换全部等于号“=”
greatest.py 用“GREATEST”函数替换大于号“>”
halfversionedmorekeywords.py 在每个关键字之前添加MySQL注释
ifnull2ifisnull.py 用“IF(ISNULL(A), B, A)”替换像“IFNULL(A, B)”的实例
lowercase.py 用小写值替换每个关键字字符
modsecurityversioned.py 用注释包围完整的查询
modsecurityzeroversioned.py 用当中带有数字零的注释包围完整的查询
multiplespaces.py 在SQL关键字周围添加多个空格
nonrecursivereplacement.py 用representations替换预定义SQL关键字,适用于过滤器
overlongutf8.py 转换给定的payload当中的所有字符
percentage.py 在每个字符之前添加一个百分号
randomcase.py 随机转换每个关键字字符的大小写
randomcomments.py 向SQL关键字中插入随机注释
securesphere.py 添加经过特殊构造的字符串
sp_password.py 向payload末尾添加“sp_password” for automatic obfuscation from DBMS logs
space2comment.py 用“/**/”替换空格符
space2dash.py 用破折号注释符“--”其次是一个随机字符串和一个换行符替换空格符
space2hash.py 用磅注释符“#”其次是一个随机字符串和一个换行符替换空格符
space2morehash.py 用磅注释符“#”其次是一个随机字符串和一个换行符替换空格符
space2mssqlblank.py 用一组有效的备选字符集当中的随机空白符替换空格符
space2mssqlhash.py 用磅注释符“#”其次是一个换行符替换空格符
space2mysqlblank.py 用一组有效的备选字符集当中的随机空白符替换空格符
space2mysqldash.py 用破折号注释符“--”其次是一个换行符替换空格符
space2plus.py 用加号“+”替换空格符
space2randomblank.py 用一组有效的备选字符集当中的随机空白符替换空格符
unionalltounion.py 用“UNION SELECT”替换“UNION ALL SELECT”
unmagicquotes.py 用一个多字节组合%bf%27和末尾通用注释一起替换空格符宽字节注入
varnish.py 添加一个HTTP头“X-originating-IP”来绕过WAF
versionedkeywords.py 用MySQL注释包围每个非函数关键字
versionedmorekeywords.py 用MySQL注释包围每个关键字
xforwardedfor.py 添加一个伪造的HTTP头“X-Forwarded-For”来绕过WAF
靶场环境搭建:sqli-labs-master 或者 DVWA
工具:Sqlmap、burpsuite、phpstudy_pro(建站)
以sqli-labs-master为例:
运行salmap 输入参数-u和url进行检测注入点:
检测出了四种注入,并给出了注入playload
列出所有数据库:
列出当前数据库:
列出当前数据库的表:
查看uses表中的列名属性:
获取表字段中的数据:
Burpsuite中的CO2插件的安装:
对CO2进行配置(即sqlmap.py和使用的python路径,路径中不能有空格,否则会识别错误):
进行代理抓包并发送到CO2攻击模块:
点击run即可自动运行sqlmap:
在Options板块中可以根据自己的需要进行注入,可在detection中选择攻击等级,在Enumeration中勾选自己想要获取的信息,再次点击run即可:
如查看当前用户是否具有管理员权限:
利用burpsuite与sqlmap的联动可以更为简单的使用sqlmap,不再需要输入繁琐的命令,同时能直接将抓到的包为sqlmap所用。
Sql注入的防御我个人觉得主要在于权限、数据和语句审查三个方面。
(1)在权限上,我们可以进行分级管理,严格控制用户的权限,避免越级行为;
(2)在数据上,我们可以提前将数据加密,这样即使数据泄露,也仍能保证一定的安全;
(3)在语句审查上,我们可以对包含有一些特殊字符如#,+,--,”,and,等符号的sql语句进行审查及过滤,同时可进行参数化传值,避免直接将变量写入到sql语句中。
除此之外,我们还可以利用一些专门的sql安全参数,如sqlserver中的Parameters集合,它在数据库中的功能是对数据进行类型检查和长度验证当程序员在程序设计时加入了Parameters集合,系统会自动过滤掉用户输入中的执行代码,识别其为字符值。如果用户输入中含有恶意的代码,数据库在进行检查时也能够将其过滤掉。同时Parameters集合还能进行强制执行检查。一旦检查值超出范围。系统就会出现异常报错,同时将信息发送系统管理员,方便管理员做出相应的防范措施。 或者对访问者的数据进行严格的多层验证,只有通过验证的数据才能合法的访问系统。