你真的会SQL注入攻击吗?

Posted 边界安全

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你真的会SQL注入攻击吗?相关的知识,希望对你有一定的参考价值。

作者在网络上看过无数的关于手工注入的讲解


却没有一个真正完整把原理说清楚的文章,直接就是附上爆库、爆表的语句,甚至也没有详细说过任何一个mysql函数的概念。


sqlmap语句滚瓜烂熟。这也间接的导致了现在许多人只会学不会造,永远都在求绕过姿势


为了让每一个学习注入的人完整地了解SQL注入,此处以Mysql Union Query(联合查询)注入类型来讲解。了解Mysql注入前我们还必须先了解“information_schema”这个数据库。为了更直观地展示,以图形化界面phpMyadmin来说明这个数据库。


information_schema数据数据库是MySQL自带的数据库,简单来说它存储着整个Mysql数据库的数据信息,其中就包含Mysql里面的所有库、表、字段的关系结构。


在PHPMysql中打开information_schema数据库中的SCHEMATA表。看最关键第二个字段“SCHEMA_NAME”,你是否会觉得很熟悉?



没错,它就是显示Mysql数据库中所有的库名。不信你可以在Mysql命令行使用Show databases;查看你数据库中的所有库子。如下图:

你真的会SQL注入攻击吗?

那么说来我们要获取一个Mysql数据库中的所有库名则可以使用SQL语句“select SCHEMA_NAME from information_schema. SCHEMATA”。(注意这里的:information_schema. SCHEMATA是什么意思呢?点号的前面是数据库名,点号后面则是表名,例如a.bc表示a数据库下的bc表)。


你真的会SQL注入攻击吗?

OK,那么我们来想想如何获取一个数据库中的所有表呢?没错,也是在information_schema数据库中。只不过我们不是看“SCHEMA_NAME”这个表了,而是看“TABLES”表了,这个表是存储着所有的每个数据库每个表的结构。如下图(不完整的截图):

你真的会SQL注入攻击吗?

注意看,第二个字段是数据库的名字,第三个字段“TABLE_NAME”则是表名,上图是说Mysql数据库下      有“time_zone_name 、time_zone_transition 、time_zone_transition_type 、user、”等几个表。那么获取一个数据库中的所有表的SQL语句则为“select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA =你要获取表的数据库名”,例如我要获取“Mysql”这个数据中的所有表,如下图:

你真的会SQL注入攻击吗?

下一步我们要了解如何获取字段了,字段的信息存储在information_schema数据的COLUMNS表中。如下图中(截图不完整),第二个字段“TABLE_SCHEMA”是数据库名称,第三个字段“TABLE_NAME”是当前数据库中的表名。第四个字段“COLUMN_NAME”是当前表下的字段。

你真的会SQL注入攻击吗?

以上图第一行举例说明:mysql数据库下的user表中的Reload_priv字段。这样我们要获取一个表中的所有字段则可以使用这样的SQL语句“select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME=获取字段的表”,如下图获取Mysql数据库下的user表的所有字段名称。

你真的会SQL注入攻击吗?

很完美,我们已经学会了使用information_schema查询一个数据库中的所有库名、表名、字段等信息,这对我们学习SQL注入非常有用处,是不是觉得很绕,对,刚开始学习这些就是非常地绕,大家可以动动手练习一下就会熟能生巧了。


完成了上面的练习之后,笔者讲解UNION注入大家就会学的更明白了。首先如何判断注入点,大多数人所说的and 1=1、and 1=2来判断的确是可以的,但我们更需要明白每一个步骤的原理。


http://xxxx.com/huangou.php?id=5 and 1=1 返回和原来一样的页面

你真的会SQL注入攻击吗?

http://xxxx.com/huangou.php?id=5 and 1=2 返回空数据的页面

你真的会SQL注入攻击吗?

为什么会这样就可以判断呢?我们来使用Mysql数据库来查询试试。Select password from mysql.user where user=’root’ and 1=1;和 and 1=2 试试。如下图:

你真的会SQL注入攻击吗?

是的,正是因为1=1永远成立,而and是逻辑运算符,必须前后条件成立整个语句才成立,所以进行了输出SQL语句的结果内容。而1=2是 不成立所以在这里就没有输出任何内容。这进一步说明WEB程序将我们输入的 and 1=1 带入了SQL查询语句中进行查询,通过返回页面的不同来判断。

你真的会SQL注入攻击吗?

判断为SQL注入之后第二步是判断字段数,使用order by函数(用于查询出的结果排序的函数)。通过order by 1 、order by 2……order by 8,都是返回正常页面,如下图:

你真的会SQL注入攻击吗?

当我们输入order by 9的时候,突然就返回空数据的页面了(与and 1=2页面一样)。如下图:

你真的会SQL注入攻击吗?

这时候初学者会有两个疑问:1、为什么会出现这样的情况?2、为什么要这样做?带着两个问题我们来解决,进入Mysql测试一下就会明白了(下图字段数不一样)。

你真的会SQL注入攻击吗?

上图可以很快发现,order by 2这样的意思是通过字段数量来进行排序,例如要查询host、password两列通过字段数量排序只有2列,如果使用order by 3则提示未知的字段数。恩,所以报错了,没有把结果显示出来。

那么为什么要去猜字段数量呢?因为我们将会用到union 函数,我们看看这个函数的说明:

你真的会SQL注入攻击吗?

注意划红线的地方,通过union连接的两条SQL语句必须字段数列一样。之后我们就可以使用union select 1,2,3,4,6,7,8 来查看这8个字段中哪几个字段位能在网页中正常显示的。

你真的会SQL注入攻击吗?

从上图可以发现,8个字段位的第2、5、7个字段能够在正常网页中显示了。这时候你也许可以直接插入user()、database()、version()等Mysql的常量。但是我们这章要说如何获取数据。首先我们可以通过database()获取当前数据库

你真的会SQL注入攻击吗?

获取了数据库之后,我们就需要查询表了。

还记得上节课说的如何从information_schema.TABLES。没错,如何构造呢?现在知道2、5、7可以显示数据,那就将我们要显示的数据放在这三个任意一个位置,我们现在要显示TABLES表中的TABLE_NAME字段,所以把它放在5上面去,那么后面还要规定从哪个数据表里面查的字句则构造整个SQL语句为:

http://www.xxx.com/huangou.php?id=5 union select 1,2,3,4,TABLE_NAME,6,7,8 from information_schema.TABLES  where TABLE_SCHEMA='taogou123' limit 1,1

整个SQL语句的含义是从information_schema库中的TABLES表查询TABLE_NAME,条件是TABLE_SHCEMA=‘taogou123’,后面的limit 1,1是限制查询结果,比如查询出结果有100条,如果使用了limit 1,1则代表从第一条起,只显示一条。

你真的会SQL注入攻击吗?

那是否如果要查询第二条则为:limit 2,1(从第二条开始只显示一条结果),疑问来了?为什么我们只显示一条,而不是全部查询出来呢?很简单,是因为我们每个字段上面只能放一个数据,不能同时放多个数据,那么如何同时放多个数据呢?可以使用concat()、group_concat函数来,这两个函数我们可以简单认为是连接字符串,比如group_concat(user(),database(),version())就是把这三个常量的注入结果连接在一起,当做一个整体字符串显示在注入结果中。这里则将group_concat放在要查询的TABLE_NAME上。语句如下:

http://www.xxx.com/huangou.php?id=5 union select 1,2,3,4,group_concat(TABLE_NAME,0x3c2f62723e),6,7,8 from information_schema.TABLES  where TABLE_SCHEMA='taogou123'

上语句可以发现我们已经将limit去除了,但是问题是0x3c2f62723e是什么玩意?很简单,这是一个十六进制,转换为字符串则是:“</br>”,学过html的都知道吧,这是换行的意思。如果我们不加上这个十六进制,打印的结果则是每个表连接在一起,可以从下图看效果,图1则是没用使用换行符的,图2是使用换行符的,那么更为直观好看的就是使用了换行符的。

你真的会SQL注入攻击吗?

图1

你真的会SQL注入攻击吗?

图2

这时候我们就要查询关键表了,可以从结果看出(当然这里被遮挡了)关键表是duoduo_user,接下来就是获取这个表的字段了,如果你不知道如何构造获取字段的SQL语句,那麻烦你看看上节提到的如何获取某个表中的字段。

http://www.xxx.com/huangou.php?id=5 union select 1,2,3,4,group_concat(COLUMN_NAME,0x3c2f62723e),6,7,8 from information_schema.COLUMNS  where TABLE_NAME='duoduo_user'

恩,语句一目了然,就是查询从information_schema.COLUMNS中查询COLUMN_NAME字段,条件是TABLE_NAME要为duoduo_user。

那么很简单了,我们知道如要要获取“ddusername”、“ddpassword”核心的用户密码的正常SQL语句是:select ddusername,ddpassword from duoduo_user; 当然这是在Mysql查询的时候这样写,如果代入我们的SQL语句中则必须用group_concat(ddusername, 0x3c2f62723e, ddpassword)包含起来。最后的SQL语句则为:

http://www.xxxx.com/huangou.php?id=5 union select 1,2,3,4,group_concat(ddusername, 0x3c2f62723e,ddpassword),6,7,8 from duoduo_user

点到为止,到这来实际上我们已经完成了一次注入测试,不必要再做任何性的东西了,最后笔者居然发现这个网站早就被小黑渗透了,作者只能说这名小黑太小孩子了。总结下来,我们可以发现其实我们只要掌握了基本的Mysql语句、了解SQL注入常用的函数、了解information_schema数据库的查库、查表、查字段操作,基本可以完全进行Mysql注入,无论是现在说的Union select注入还是报错注入、基于布尔值、时间的盲注等等,甚至还可以看懂别人构造的SQL语句,学习SQL注入不再是梦!


难得正经一次,就说到这里吧。




以上是关于你真的会SQL注入攻击吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免 SQL 注入攻击?

在 MySQL 中使用准备好的语句可以防止 SQL 注入攻击吗?

IIS安全狗总是提示SQL注入攻击,可是日志并没有显示,这是怎么回事??

knex.where容易受到sql注入攻击吗?

我可以通过使用参数来避免所有 SQL 注入攻击吗?

使用存储过程可以防止 SQL 注入/XSXX 攻击吗?