在学习 SQL 注入之前,我们首先需要了解一下 Web 应用的构成。
Web 应用构成
我们可以把它看做三部分:
(这里分类对实际来说不是十分准确,但是如果没有这方面的知识,为了方便理解 SQL注入,我们可以暂时笼统地这样认为)
- 前端
- 后端
- 数据库即我们要学的 SQL
数据库顾名思义就是存储数据的地方,后端查询到需要的数据然后给前端,前端则是数据显示给你。
举个例子,你在前端说你要看张三的成绩(在查询成绩页面上输入『张三』),后端收到你的消息,就去数据库里找张三的成绩,找到后再返回给前端,前端把张三的成绩显示在页面上,你就知道张三的成绩了。
大家在这里可以思考一下,上面的步骤哪一步是很危险的。
提示:『小偷去偷东西,哪里有门(或者说入口)就从哪里进去,他不会说前面是一堵墙他也要把整座墙炸了进去偷东西。』
SQL 注入原理
上面那个例子,输入张三就可以知道张三的成绩,那我还想知道张三这位同学的所有信息,我可以在这个输入框里达到吗?而且我们明面上唯一可以操作的就是这个输入框,很显然我们就要以这里为突破口。这个输入框也被称之为注入点。
那么要想原本只返回成绩的入口获得其他信息,那我们就要知道这个入口在后端是如何获得信息的(对数据库语法不熟练的同学在学完本节后需要自行学习数据库语法):
获得成绩的数据库语句
SELECT score FROM Info WHERE name='张三'
现在需要其他信息,就要将数据库语句换成:
SELECT * FROM Info WHERE name='张三'
有没有在这条查询语句里看到熟悉的两个字,没错就是『张三』,这是我们在前端自己输入的,现在它进入到了后端的代码里,后端会把这条 SQL 语句查询到的数据返回给前端。
这里暂停思考一分钟,如果你已经会了 SQL 语法,或许你已经想到了成功注入的方法?
我们没办法跑到人家服务器上修改源码把『score』改成『*』,但是我们可以控制我们输入的字符,如果输入 :
张三' union SELECT * FROM Info WHERE name='张三
那么最后执行的语句是:
SELECT score FROM Info WHERE name='张三' union SELECT * FROM Info WHERE name='张三'
这样就完成了 SQL 注入。
如果有点难理解的话也可以反向思考,我们需要执行下面这条语句才能拿到张三的所有信息:
SELECT * FROM Info WHERE name='张三'
但是源码的查询语句已经是 SELECT score
我们没有办法更改这个『score』,所以考虑把两条语句用 union 连起来执行,完整语句就会是:
SELECT score FROM Info WHERE name='张三' union SELECT * FROM Info WHERE name='张三'
完整语句减掉已存在语句 SELECT score FROM Info WHERE name=''
就可以得到需要输入的是:张三' union SELECT * FROM Info WHERE name='张三
总结
现在可以知道 SQL 注入本质是拼接代码,客户端提交的数据直接和后端代码拼接成 SQL 语句被执行,即通过输入来修改后台 SQL 语句达到攻击目的的技术。