freeBuf
主站

分类

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

特色

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

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

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

FreeBuf+小程序

FreeBuf+小程序

SQL注入入门介绍
2020-11-12 12:04:02

0x01 前言

数据库,不管是做前端、后端、渗透、运维,只要是从事计算机行业,多少都会需要接触到它。提到了网络安全,它更是我们避不开的话题,同时SQL注入也是OWSAP TOP10中最大的一类安全风险。今天我就来总结一下接触SQL注入前需要知道的些知识点吧。


0x02 什么是sql

首先说起SQL注入,什么是SQL:

SQL,指结构化查询语言,全称是 Structured Query Language。

SQL 让我们可以访问和处理数据库。

SQL 是一种 ANSI(American National Standards Institute 美国国家标准化组织)标准的计算机语言。


SQL注释

这里以MySQL为例,先讲解一些注释的方法,方便我们理解下边演示注入是如何发生的。

# 单行注释,同一行内#号后的内容不会被执行

-- (杠杠空格)同样是单行注释,和#的用法相同

/*...*/ 多行注释,“...”部分的内容不会执行


0x03 漏洞的描述与产生原因

漏洞描述:

Web程序中对于用户提交的参数未做过滤直接拼接到SQL语句中执行,导致参数中的特殊字符破坏了SQL语句原有逻辑,攻击者可以利用该漏洞执行任意SQL语句,如查询数据、下载数据、写入webshell、执行系统命令以及绕过登录限制等。


漏洞产生的原因:

通过用户可控参数中注入SQL语法,破坏原有SQL结构。

程序编写者在处理程序和数据库交互时,使用字符串拼接的方式构造SQL语句。

未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中。


SQL注入漏洞的危害:

可以获取数据库中多种信息(例如:管理员后台密码),从而脱库。在特别情况下还可以修改数据库内容或者插入内容到数据库,如果数据库权限分配存在问题,或者数据库本身存在缺陷,那么攻击者可以通过SQL注入漏洞直接获取webshell或服务器系统权限。


0x04 注入点与注入类型

一些注入点可能存在的位置:

GET数据

POST数据

Cookie数据

HTTP头部(HTTP请求报文其他字段)



SQL注入类型的分类:

从数据类型分类来看,SQL注入分为数字型和字符型。

数字型数据两边没有被单引号、双引号包括。例如:userid = 3

字符型正好相反,数据的两边会被单引号、双引号包括。例如:username = “admin”


根据注入手法分类,大致可分为以下几个类别:

UNION query SQL injection (可联合查询注入)

联合查询

Error-based SQL injection (报错型注入)

报错注入

Boolean-based blind SQL injection (布尔型注入)

布尔盲注

Time- -based blind SQL inj ection (基于时间延迟注入)

延时注入

Stacked queries SQL injection (可多语句查询注入)

堆叠查询

*前四种一般用于查询,最后一种可以用于增删改查。


0x05 数据库结构与information_schema

关系型数据库有明显的层次结构:

库名->表名->字段名->字段内容

最后我们来认识一下MySQL的源数据数据库,里面存储了所有数据库和表,以及表中字段的信息,通过查询他就可以查询到几乎我们所需要的所有信息。

MySQL 源数据库数据库information_schema我们需要注意的部分如下:


字段

information_schema(源数据库数据库)


tables(存所有表名的表)

table_name(存表名的字段)

table_schema(存表所属数据库的字段)

columns(存所有字段名的表)

column_name(存字段名的字段)

table_name(存字段所属表的字段)

table_schema(存字段所属库的字段)


0x06 漏洞使用示例

知道了什么是SQL之后我们要了解漏洞的原理:

结合MySQL的注释规则,我们来看一个小例子:

正常的SQL语句为:

select * from user where username = 'admin' and password=''

这个是一个正常用户传递过来的的用户名为:admin

当用户输入的的用户名变为admin'#,SQL语句就变成了:

select * from user where username = 'admin'#' and password=''

结合上面讲解的注释规则,执行的SQL语句就变成了:

select * from user where username = 'admin'

这时密码的验证就被跳过了,于是就发生了SQL注入。


我们以DVWA平台的BruteForce模块演示:


当我们正常输入用户名:admin,并不输入密码时,会提示用户名或密码不正确:


当我们输入用户名admin’ #时,同样不输入密码,就会直接登陆成功:


同样,我们使用其他注释方式输入在用户名后面也可以起到相同的作用

比如输入:admin’ -- 也可以跳过密码验证:


或者不使用注释,而是插入其他的逻辑运算改变SQL语句的语义同样能够查到记录。

比如输入:admin' or '1'='1  这时整个SQL语句就变成了:

select * from user where username = 'admin' or '1'='1' and password=''

这时这个SQL语句的判断就变成了username = 'admin''1'='1' and password=''任意一个条件成立则为真,这里显然第二个条件为假,而第一个条件为真,语句整体则为真,会查询出username为admin 的记录,所以一样可以登录成功。

登录结果如下:


这样就实现了简单的SQL注入。在之后的文章中,我还将详细的介绍其他的注入方式。


0x07 源码分析与防御思路

知道了如何进行简单的sql注入,我们再来分析一下,为什么我们能够进行注入呢?

我们来简单分析一下网页后台的源码:


我们可以看到,脚本是从前台获取到用户名,然后将密码进行MD5运算后,直接拼接到SQL查询语句中。获取用户名和密码和SQL查询语句的代码如下:

$user = $_GET[ 'username' ];

$pass = $_GET[ 'password' ];

$pass = md5( $pass );

$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";


因为用户名没有做任何的操作就直接拼接到了查询语句中,这就导致了SQL注入漏洞。那么我们应该如何防御呢?


这里提供一个简单的思路,我们可以尝试对用户名进行过滤,过滤掉非法的字符,或者直接发现了非法字符就让程序停止运行。比如,我们在查询数据库之前添加这样一段代码:

if(strstr($user,"-")||strstr($user,"#")){
		echo "<script>alert('小伙子,你有问题!劝你给我老实点!')</script>";
		return;
}

这样我们就可以过滤掉“#”和“-”,防止他人使用注释去绕过密码的检测。现在来测试一下效果:


我们依然使用之前的#来绕过密码验证试试:


可以看到,点击了登录后,并没有成功登录,而是弹出了提示,说明我们成功防御了SQL注入。

当然,这里只对用户名做了简单的过滤,还有很多能够绕过过滤的方法,比如我们这里并没有对“or”进行过滤,我们就可以使用admin' or '1'='1的方式成功登录。所以在实际场景中还有很多需要过滤的敏感字符,以及一些其他的防御方法,就留给大家自行探索了!


# SQL注入 # 入门指南
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者