SQL注入入门介绍 – 作者:ATL安全团队

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模块演示:

图片[1]-SQL注入入门介绍 – 作者:ATL安全团队-安全小百科

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

图片[2]-SQL注入入门介绍 – 作者:ATL安全团队-安全小百科

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

图片[3]-SQL注入入门介绍 – 作者:ATL安全团队-安全小百科

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

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

图片[4]-SQL注入入门介绍 – 作者:ATL安全团队-安全小百科

或者不使用注释,而是插入其他的逻辑运算改变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 的记录,所以一样可以登录成功。

登录结果如下:

图片[5]-SQL注入入门介绍 – 作者:ATL安全团队-安全小百科

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

0x07 源码分析与防御思路

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

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

图片[6]-SQL注入入门介绍 – 作者:ATL安全团队-安全小百科

我们可以看到,脚本是从前台获取到用户名,然后将密码进行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;
}

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

图片[7]-SQL注入入门介绍 – 作者:ATL安全团队-安全小百科

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

图片[8]-SQL注入入门介绍 – 作者:ATL安全团队-安全小百科

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

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

来源:freebuf.com 2020-11-12 12:04:02 by: ATL安全团队

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论