WEB安全之常见漏洞篇之SQL注入(基础 原理篇)
2022-11-14 18:32:20 Author: 渗透安全团队(查看原文) 阅读量:7 收藏

0x01 漏洞原理

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

0x02 漏洞危害

Web 服务器会向数据访问层发起 Sql 查询请求,如果权限验证通过就会执行 Sql 语句。这种网站内部直接发送的Sql请求一般不会有危险,但实际情况是很多时候需要结合用户的输入数据动态构造 Sql 语句,如果用户输入的数据被构造成恶意 Sql 代码,Web 应用又未对动态构造的 Sql 语句使用的参数进行过滤,则会带来意想不到的后果。

 Sql 注入带来的威胁主要有如下几点

    攻击者未经授权可以访问数据库中的数据,盗取用户的隐私以及个人信息,造成用户的信息泄露。通过操作数据库对某些网页进行篡改;修改数据库一些字段的值,嵌入网马链接,进行挂马攻击;攻击者进而可以对网页进行篡改,发布一些违法信息等。服务器被远程控制,被安装后门。可以对数据库的数据进行增加或删除操作,例如私自添加或删除管理员账号。数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。破坏硬盘数据,导致全系统瘫痪;

0x03 SQL注入类型

1.SQL注入按照注入点类型来分分为:

数值型注入,字符型注入,搜索型注入

数值型:当输入的参数为整形时,如果存在注入漏洞,可以认为是数值型注入,例如:

加单引号,URL:www.text.com/text.php?id=3’对应的sql:select * from table where id=3’ 这时sql语句出错,程序无法正常从数据库中查询出数据,就会抛出异常;
and 1=1 ,URL:www.text.com/text.php?id=3 and 1=1对应的sqlselect * from table where id=3and 1=1 语句执行正常,与原始页面如任何差异;
and 1=2URL:www.text.com/text.php?id=3 and 1=2对应的sqlselect * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果,所以返回数据与原始网页存在差异如果满足以上三点,则可以判断该URL存在数字型注入。

字符型:当输入的参数为字符串时,称为字符型。字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的,例如:

加单引号:select * from table where name=’admin’’由于加单引号后变成三个单引号,则无法执行,程序会报错;
加 ’and 1=1 此时sql 语句为:select * from table where name=’adminand 1=1’ ,也无法进行注入,还需要通过注释符号将其绕过;Mysql 有三种常用注释符:
-- 注意,这种注释符后边有一个空格# 通过#进行注释
/* */ 注释掉符号内的内容因此,构造语句为:select * from table where name =’adminand 1=1—’ 可成功执行返回结果正确;
and 1=2— 此时sql语句为:select * from table where name=’adminand 1=2 –’则会报错如果满足以上三点,可以判断该url为字符型注入。

搜索型简介

  在搭建网站的时候为了方便用户搜索该网站中的资源,程序员在写网站脚本的时候加入了搜索功能,但是忽略了对搜索变量的过滤,造成了搜索型注入漏洞,又称文本框注入。其中又分为POST/GET,GET型的一般是用在网站上的搜索,而POST则用在用户名的登录,可以从form表单的method="get"属性来区分是get还是post。搜索型注入又称为文本框注入,例如:

%’ and 1=1 and ‘%’=’%’ and exists (select * from admin) and ‘%’=’%’ and exists(select id from admin where id=1) and ‘%’=’%’ and exists (select id from admin where len(username)<10 and id=1) and ‘%’=’%’ and exists (select id from admin where len(password)=7 and id=1) and ‘%’=’%’ and (select top 1 asc(mid(username,1,1)) from admin)=97 and ‘%’=’搜索型注入也无他,前加%’ 后加 and ‘%’=’对于MSSQL数据库,后面可以吧 and ‘%’='换成–

2.根据请求方式的不同,可分为:

GET型注入、POST型注入、HEADER型注入 、Cookie注入

GET型注入:

GET 是 HTTP 协议的传输方式。它的特点就是可以直接以 URL 的形式传输数据。而GET型注入漏洞就是利用这一特点,对数据库进行注入测试。

POST型注入:

在 HTTP 常用方法中,POST 方法提交的实体不存储在 URL 中,而是存储在 HTTP 协议实体内容中,在大多过程中,用户时无法感知的。而我们的注入信息是存储与 HTTP 实体内容中而不是 URL,通过改造实体内容,达到实际执行 SQL 语句获取到更多信息的目的。

http头注入:

后台开发人员为了验证客户端头信息,比如常用的 cookie 验证,或者通过 http 请求头信息获取客户端的一些信息,比如 useragent 、accept 字段等等,会对客户端的 http 请求头信息获取并使用 sql 进行处理,如果此时没有足够的安全考虑,则可能会导致基于 http 头的 sql 注入漏洞。

Cookie注入:

(1)程序对get和post方式提交的数据进行了过滤,但未对cookie提交的数据库进行过滤。
(2)在条件1的基础上还需要程序对提交数据获取方式是直接request("xxx")的方式,未指明使用request对象的具体方法进行获取,也就是说用request这个方法的时候获取的参数可以是是在URL后面的参数也可以是cookie里面的参数这里没有做筛选,之后的原理就像我们的sql注入一样了。

3.按照注入技巧来分类

联合注入、盲注、堆叠注入、二次注入、无列名注入、宽字节注入、其他

联合注入:联合查询注入是联合两个查询语句进行注入攻击,使用关键词 union select 对两个表进行联合查询。两个表的字段数要相同,不然会出现报错。

盲注简介
盲注就是在sql注入过程中,sql语句执行的选择后,选择的数据不能回显到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。

盲注原理
盲注的本质就是
猜解,在没有回显数据的情况下,我们只能靠‘感觉’来体会每次查询时一点点细微的差异,而这差异包括运行时间的差异和页面返回结果的差异。
对于基于布尔的盲注来说,我们可以构造一条注入语句来测试我们输入的布尔表达式,而这布尔表达式结果的真假,决定了每次页面有不同的反应。
对于基于时间的盲注来说,我们构造的语句中,包含了能否影响系统运行时间的函数,根据每次页面返回的时间,判断注入的语句是否被成功执行。

盲注分类

 •基于布尔SQL盲注 •基于时间的SQL盲注 •基于报错的SQL盲注

盲注的流程:

找寻并确认sql盲注点强制产生通用错误界面注入带有副作用的查询根据布尔表达式的真假结果,结合不同的返回结果确认注入是否成功

布尔盲注:布尔盲注一般适用于页面没有回显字段(不支持联合查询),且web页面返回True 或者 false,
构造SQL语句,
利用and,or等关键字来其后的语句 true 、 false使web页面返回true或者false,
从而达到注入的目的来获取信息的一种方法
没有错误提示 也没有回显 但是输入错误的话页面会有反应 也就是说 只有 true 和false

例如 :sql-labs /less-7 它只有两种提示 所以可以用布尔盲注playload:and length(database()) =8 --+ /判断数据库名长度

时间盲注通过一个页面加载的时间延时来判断但是这和网络,性能,设置的延时长短有关系当对数据库进行查询操作,如果查询的条件不存在,语句执行的速度非常快,执行时间基本可以认为是0,通过控制sql语句的执行时间来判断

判断语句

1and length(database())>3#
1and length(database())=5 #
1and mid(database(),1,1)=‘d’ # 判断单个字符
1and substr(database(),1,1)=‘d’ # 判断单个字符
1and ord(substr((select database()),1,1))=98 # 使用ascii码判断单个字符
1and ascii(substr((select database()),1,1))=98 # 使用ascii判断单个字符
1and left(database(),4)=‘dvwa’ # 判断一个字符串,即多个字符

报错盲注:众所周知,盲注并不会返回错误信息,使得sql注入的难度提高。而报错型注入则是利用了MySQL的第8652号bug :Bug #8652 group by part of rand() returns duplicate key error来进行的盲注,使得MySQL由于函数的特性返回错误信息,进而我们可以显示我们想要的信息,从而达到注入的效果,语句

?id=1' union Select 1,count(*),concat(你希望的查询语句,floor(rand(0)*2))a from information_schema.columns group by a

堆叠注入: 在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。

二次注入:在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据。在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。

无列名注入:顾名思义,就是在不知道列明的情况下进行sql注入。在mysql => 5的版本中存在一个名为 information_schema 的库,里面记录着 mysql 中所有表的结构。通常,在 mysql sqli 中,我们会通过此库中的表去获取其他表的结构,也就是表名、列名等。但是这个库经常被 WAF 过滤。

0x04 工具&插件推荐

SQLMAP-项目地址:https://github.com/sqlmapproject/sqlmapMDUT-项目地址:https://github.com/SafeGroceryStore/MDUT超级SQL注入工具穿山甲、胡萝卜、啊D、明小子HackBar、Max HackBar(浏览器插件自行获取)

0x05 知识星球

星 球 免 费 福 利

 转发公众号本文到朋友圈

 截图到公众号后台第1、3、5名获取免费进入星球

欢 迎 加 入 星 球 !

代码审计+各类渗透小白学习资源+各种资料文档+各种工具

进成员内部群

星球的最近主题和星球内部工具一些展示

关 注 有 礼

关注下方公众号回复“666”可以领取一套精品渗透测试工具集和百度云视频链接。

 还在等什么?赶紧点击下方名片关注学习吧!


群聊 | 技术交流群-群除我佬

干货|史上最全一句话木马

干货 | CS绕过vultr特征检测修改算法

实战 | 用中国人写的红队服务器搞一次内网穿透练习

实战 | 渗透某培训平台经历

实战 | 一次曲折的钓鱼溯源反制

免责声明
由于传播、利用本公众号渗透安全团队所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号渗透安全团队及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!
好文分享收藏赞一下最美点在看哦

文章来源: http://mp.weixin.qq.com/s?__biz=MzkxNDAyNTY2NA==&mid=2247494519&idx=2&sn=9e26b0de226aa588d9c79a0ae8f32c2d&chksm=c17616d8f6019fcee546d69bdd0ba9d5349bf7bcdae6c5c92c362ad0edc4d3dab270500e4bcf#rd
如有侵权请联系:admin#unsafe.sh