CTF中sql注入的一些知识

扶醉桌前 提交于 2019-12-07 00:47:07

最近一直在学习sql注入的知识,感觉sql注入确实是漏洞中的一大难点。首先是自己对数据库结构的不熟悉,所以构造的一些语句总是不能理解。其次是没有对自己学习的知识做好总结,看了很多视频、博客、题目,每次我都感觉自己好像知道要怎么去做了,可是再拿到一道题目,我还是只会加单引号,甚至在单引号没有报错的时候就不知所措。最后是没有好的状态,急功近利,想要一蹴而就,但这sql注入又哪是几天就能弄明白的,所以我还是想明白了,要多花时间去钻研,要多做思考,不能眼高手低,真正的把原理和方法弄懂。

所以我先对最近遇到的一些问题进行总结,等慢慢学习更多以后,再对此进行补充。

1、为什么有时候要用单引号闭合前面的引号,而有的时候却不用闭合呢?

2、为什么union前面搜索的值不存在,却还是可以把union联合查找的值给输出来呢?

3、为什么在url中不能用#号,而要用%23来表示呢?

4、在猜解列名时为什么要在表名前后加引号,而猜解字段内容时却不用加呢?

5、information_schema是啥?为啥猜解的时候要一直用这个东西?

6、为什么有时候引号输进去也不会报错?这个时候要怎么做?

 

 

 

 

 

1、关于引号的问题,其实这是因为sql语句的两种写法

这两种写法都是正确的,只是安全性不同罢了,所以在你看不到源代码的时候,也不能确定是否要加单引号去闭合,只能先加一个单引号来闭合尝试。

这两张图片是来自于:http://cbb.sjtu.edu.cn/course/database/lab8.htm,这里面对sql注入进行了很充分的解释。

 

 

 

2、union是联合查询,查询的字段值必须要和前面查询的相等,所以可以先用order by 语句来确认查询的字段值有多少个,然后再用union 查询,查询的值可以用数字 1 来填充,也可以查当前数据库database(),数据库版本 version(),使用者user(),只要后面的字段值和前面相同就行了。

但是有的时候显示的地方被前面查询的值给占用了,导致后面我们想查询的值没有地方显示怎么办呢,就把前面要查询的值给去掉,因为union查询的时候,如果有一边查询的是不存在或错误的就不显示,只显示另一边查询正确的语句。

有时候页面可以显示数据的地方只有一个,那么就要用union后面查询的值来确定显示的是哪一个字段值。然后把想要查询的值放在那个能显示的字段处。

 

 

 

 

 

3、其实这个问题之前就有考虑过,而且也在其他博客上得到了答案,在这里就当作记录吧,在url中#会被当作锚链接,如果在url中直接提交#就会变为空,所以要用url编码后的%23来代替,这样url会在传递时解码为#就可以把之后不需要的给注释掉。

 

 

4、在猜解列名时,后端的查询语句最后是 where table_name = 所以要将表名打引号,作为字符串形式来查找,不然就会报错。而在猜解字段内容时,后端的查询语句最后是 from ,就可以直接填表名。

 

 

5、information_schema是一个拥有数据库中所有信息的库,包含了所有的库,表,列。所以在猜解的过程中要使用这个库来进行猜解。猜解的过程如下:

在使用union查询时,已经得知了当前数据库 database(),就可以进行下一步表名的猜解了。

union select 1,2,table_name from information_schema.table where table_schema=database()

table_name就是表名,information_schema.table就是这个information_schema库存放表信息的表,table_schema就是表所属的数据库。这样就可以得到当前数据库中所有的表名。当然也可以使用group_concat(table_name)来将这些表名连接起来输出。接下来再进行列名的猜解。

union select 1,2,column_name from information_schema.columns where table_name = 'XXX'

这里和上面一个步骤是差不多的,这些单词就不再解释了。继续下一步猜想要的列的字段内容吧。

union select 1,2,YYY from XXX

最后就得到了我们想要的内容。

 

 

6、在我遇到的题目中,目前有一种情况是叫“宽字节注入”,如果代码中用了addslashes()函数,这个函数会把所传进来的参数中带有的预定义字符前面加上转义符'\'。那我们自己加进去想要闭合的单引号就失去了效果,但是有一种方法可以让这个引号重新起到效果,就是宽字节注入,因为gb2312或者gbk这种编码方式,是两个字符编码一个汉字,所以我们如果在构造payload的时候在引号之前加一个 %df 让这个%df和转义符'\'一起编码成一个汉字,那后面的引号就可以逃逸出来了。为什么是%df,因为在gbk编码里一般第一个字符的ascii码大于128就会认为这两个字符组成一个汉字了。

 

因为这一篇博客中的内容,是我先在笔记中写好然后复制过来的,所以可能格式看起来不太舒服,见谅,sql注入中的问题远不止这些,这里只是记录了一些我作为新手时遇到的问题,希望如果有其他和我一样有这样困惑的人可以得到大致的答案。我还会继续补充的,写的不好多多包涵。如果有朋友愿意和我交朋友讨论技术等等的话,可以加我的qq:1013024906 备注CSDN+名字。。。谢谢

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!