轻松理解什么是 SQL 注入

作为长期占据 OWASP Top 10 首位的注入,OWASP 对于注入的解释如下:

将不受信任的数据作为命令或查询的一部分发送到解析器时,会产生诸如 SQL 注入、NoSQL 注入、OS 注入和LDAP 注入的注入缺陷。攻击者的恶意数据可以诱使解析器在没有适当授权的情况下执行非预 期命令或访问数据。

SQL 注入是最普遍存在的,也是往年危害最大的漏洞,今天我们就来简单理解关于 SQL 注入的一切。

SQL 注入的字面意思

学习 SQL 注入首先要了解什么是 SQL,在百度百科的解释如下:

结构化查询语言 (Structured Query Language) 简称 SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名。

从解释上来看,SQL 是用来对数据库系统进行操作的结构化查询语言,数据库存储数据,SQL 就是用来告诉数据我要什么数据,我要存储什么样的数据。

关于数据库,通常分为两类,一类是关系型数据库,还有一类是非关系型数据库,那么什么是关系型数据库,百度百科的解释如下:

关系数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。标准数据查询语言SQL就是一种基于关系数据库的语言,这种语言执行对关系数据库中数据的检索和操作。 当前主流的关系型数据库有 Oracle、DB2、PostgreSQL、Microsoft SQL Server、Microsoft Access、MySQL、浪潮 K-DB 等。

关于非关系型数据库,百度百科的解释如下:

非关系型数据库,又被称为 NoSQL(Not Only SQL ),意为不仅仅是 SQL( Structured QueryLanguage,结构化查询语言),NoSqL 描述的是大量结构化数据存储方法的集合,根据结构化方法以及应用场合的不同,主要可以将 NOSQL 分为以下几类: (1)Column-Oriented 面向检素的列式存储,其存储结构为列式结构,同于关系型数据库的行式结构,这种结构会让很多统计聚合操作更简单方便,使系统具有较高的可扩展性。这类数据库还可以适应海量数据的增加以及数据结构的变化,这个特点与云计算所需的相关需求是相符合的,比如 GoogleAppengine 的 BigTable 以及相同设计理念的 Hadoop 子系统HaBase 就是这类的典州代表。需要特别指出的是,Big Table 特别适用于 MapReduce 处理,这对于云计算的发展有很高的适应性。 (2)Key-Value。 面向高性能并发读/写的缓存存储,其结构类似于数据结构中的 Hash 表,每个 Key 分别对应一个 Value,能够提供非常快的查询速度、大数据存放量和高并发操作,非常适合通过主键对数据进行查询和修改等操作。Key-Value 数据库的主要特点是具有极高的并发读/写性能,非常适作为缓存系统使用。MemcacheDB、BerkeleyDB、Redis、Flare 就是 Key-Value 数据库的代表。 (3)Document-Oriented。 面向海量数据访问的文档存储,这类存储的结构与 Key-Value 非常相似,也是每个 Key 别对应一个 Value,但是这个 Value 主要以 JSOn(JavaSriptObjectNotations) 或者 XML 等格式的文档来进行存储。这种存储方式可以很方便地被面向对象的语言所使用。这类数据库可在海量的数据中快速查询数据,典型代表为 MongoDB、CouchDB 等。

在了解完 SQL 之后,我们来理解一下什么是注入:

注入:顾名思义就是插入的意思,在这里的意思就是在正常的 SQL 语句中,插入我们构造的语句,在获取正常结果的情况,执行我们构造的 SQL 语句获取额外的数据,导致数据泄漏。

通过实例了解 SQL 注入

在学习 SQL 注入实例之前,大家要先明白一些 http 协议的基础,比如如何通过 GET/POST/cookie 的方式向页面提交参数数据,这里就不多说了,下面就以大家最熟悉的 php+mysql 作为例子来解释 SQL 注入的过程。

我们就以最常见的 GET 来作为理解的对象,假设有一个查看个人信息的页面,链接如下:

http://www.xazlsec.com/userinfo.php?id=1

懂 http 协议的朋友肯定知道上面链接中哪个是提交的参数,是我们可以控制的并任意修改的,在浏览器请求这个链接的时候,参数 id 的值会被服务端,通过函数 $_GET['id'] 获取,正常的 sql 语句如下:

select * from users where id = $_GET['id'];

提交之前的链接后,id 的值 1 就会被带入上面的查询语句,如下:

select * from users where id = 1;

这样做也没什么不妥,功能完全实现了,但是有了这群不按常理出牌的人之后,就不安全了,平民老百姓没人去修改 url 上的参数,大部分根本不理解这个 url 是如何构成的,所以世界本来是安全的,有了这些搞安全的,世界就不安全了。

当我们把 url 改成下面这样:

http://www.xazlsec.com/userinfo.php?id=-1 union select database(

我们的参数 id 的值就变成了 -1 union select database()这时的数据库查询语句就变成了:

select * from users where id = -1 union select database()

懂数据的肯定知道上面的语句的结果,返回的结果是原本程序做不到的,这就实现了 SQL 注入。

关于 SQL 注入有两个方面,一个是 SQL 注入漏洞:

通过简单的测试,测试这个参数存在 SQL 注入利用的可能就可以说这里存在 SQL 注入漏洞

还有一个就是 SQL 注入攻击:

在确定存在 SQL 注入漏洞的情况下,通过手工或者工具的方式,将数据库中的敏感信息 dump 出来或者利用数据库的特定获取系统的权限,这是一个利用的过程,在如今法律如此严格的情况下,在做渗透测试的时候,切记不要做这一步。

SQL 注入如何防御

从上面的例子可以看出,我们的参数是通过拼接字符串的方式进行的,在写 php 代码的时候,通过 $_GET['id'] 获取到参数值之后直接拼接到了 SQL 查询语句的后面,不过你提交的参数是什么都被当作 SQL 语句来执行了,那么我们如何解决这个问题呢?

如今为了解决 SQL 注入的问题,从一开始的过滤到现在使用的数据库操作的库,使用参数化查询的方式,将用户输入或者参数的值全部当作字符串来处理,不管你输入的是什么,在 SQL 查询语句中,你就是一个字符串,这样你构造的查询语句就被当作字符串来处理了,语句不被执行也就不会存在 SQL 注入的问题了。

俗话说,只要是用户输入的都不可以信任,一个系统用户可控的参数千千万,只要有一个地方疏忽,那你之前做的一切就前功尽弃了,扩展一下,不仅仅是用户输入的不可信,只要是数据可以伪造的都不可信,比如 http 协议里的 Referer/user-agent 等。

总结

说了这么多废话,这个文章的目的就是让一些没什么基础的人了解一下大家常说的 SQL 注入相关的东西,从上面的描述可以看出,想要学习 SQL 注入,最起码的 http 协议是要学的,不同数据的查询语句以及数据库特性也是需要了解的,一个网站的数据处理流程也是需要了解的,在有基础的情况下,了解 SQL 注入的原理,然后就是进阶阶段,以前的大佬经常发的文章关于绕过什么的,慢慢积累就可以了。

推荐阅读

我们来聊一聊渗透测试

轻松理解什么是 webshell

原文发布于微信公众号 - 信安之路(xazlsec)

原文发表时间:2018-06-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Netkiller

数据库与图片完美解决方案

目录 1. 背景 2. 解决思路 3. 解决方案 4. plugin 的开发与使用 5. 在事务中使用该插件 6. 通过触发器调用图片处理函数 1. 背景 我以...

2885
来自专栏nnngu

MySQL 存储过程的简单使用

首先创建一张 students 表 SQL脚本如下: create table students( id int primary key auto_in...

2884
来自专栏杨建荣的学习笔记

海量数据迁移之传输表空间(一) (r5笔记第71天)

在自己接触的很多的数据迁移工作中,使用外部表在一定程度上达到了系统的预期,对于增量,批量的数据迁移效果还是不错的,但是也不能停步不前,在很多限定的场景中,有很多...

2397
来自专栏Java技术分享圈

杨老师课堂之JavaEE三大框架Hibernate入门第一课

701
来自专栏刘望舒

Android 数据库开发(一)SQLite3概述

前言 SQLite是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目,设计目...

2189
来自专栏hanlp学习笔记

如何在ubuntu使用hanlp

  以前,我对大部分的处理中文分词都是使用python的结巴分词工具,该分词工具是在线调用API, 关于这个的分词工具的原理介绍,我推荐一个好的博客:

470
来自专栏liuchengxu

在 Golang 开发中使用 Makefile

使用 Golang 已经有一阵了,在 Golang 的开发过程中,我已经习惯于不断重复地手动执行 go build 和 go test 这两个命令. 不过,现...

1541
来自专栏信安之路

利用DNS协议回显数据

这个问题已经是去年提出的了,之前也看到过,在 CTF 题目环境中利用过却对原理不慎了解,在公司大佬们的帮助下成功了理解了一波原理。

1490
来自专栏沃趣科技

sysbench的lua小改动导致的性能差异

最近在配合某同事做一项性能压测,发现相同数据量、相同数据库参数、相同sysbench压力、相同数据库版本和sysbench版本、相同服务器硬件环境下,我和同事的...

1343
来自专栏杨建荣的学习笔记

MySQL中批量初始化数据的对比测试(r12笔记第71天)

一直以来对于MySQL的存储过程性能还是颇有微词的,说实话够慢的。有时候想做一些对比测试,存储过程初始化几万条数据都得好一会儿,这功夫Oracle类似的测试...

3297

扫码关注云+社区

领取腾讯云代金券