admin管理员组

文章数量:1794759

2020年了,还要学习SQL注入吗?

2020年了,还要学习SQL注入吗?

本文是学习SQL注入的笔记和部分总结,详细的写了我认为重要的一些东西

目录

SQL注入漏洞基础

我们为什么要了解SQL注入漏洞

SQL注入原理

注入过程

注入方法

数字型注入

字符型注入

MySQL数据库的使用

MySQL的常用语句

元数据库

常用函数

注入手法

联合查询

案例:利用联合查询获取用户名和密码

报错注入

布尔盲注

延时注入


SQL注入漏洞基础 我们为什么要了解SQL注入漏洞

SQL注入漏洞(SQL Injection)是很高危的漏洞之一,通过OWASP top 10可以看到,注射漏洞仍排在榜首的位置,这就说明了它的危害性之高

SQL注入原理

攻击者利用SQL语句或字符串将非法数据插入到服务器端数据库中,以获取管理用户的权限,将数据库管理用户的权限进一步提高至操作系统管理用户权限,控制服务器操作系统,获取重要信及机密文件

注入过程
  • 发现注入点
  • 收集数据库信
  • 获取用户名密码
  • 寻找后台管理入口
  • 查看数据库中的内容
  • 注入方法 数字型注入

    输入参数一般为整形,如ID、页码等

    假设URL为:HTTP://www.example/test.php?id=1

    可以猜测,SQL语句有可能为 select * from table_test where id = 1

    ①如果在URL后加一个单引号 ,HTTP://www.example/test.php?id=1'

        此时,SQL语句变为 select * from table_test where id = 1',多了一个单引号,语句自然会出错,页面就会回显异常

    ②在URL后加 and 1 = 1,HTTP://www.example/test.php?id=1 and 1 = 1

        此时,SQL语句变为 select * from table_test where id = 1 and 1 = 1,因为and前后都为真,语句不会出错,页面回显正常

        将 and 1 = 1改为and 1 = 2,HTTP://www.example/test.php?id=1 and 1 = 2

        此时,SQL语句变为 select * from table_test where id = 1 and 1 = 2,因为and前为真,后为假,语句执行正常,页面却会出现错误

    此类数字型注入多出现在ASP、PHP等弱类型语言中

    字符型注入

    输入参数一般为字符串,与数字型不同,字符串类型多需要单引号来闭合

    可以猜测,字符型SQL语句可能为 select * from table_test where username =  'admin'

    ①如果注入时输入 admin and 1 = 1,此时SQL语句如下

        select * from table_test where username = 'admin and 1 = 1'

        所以我们可以在admin后加一个单引号并在最后加上注释符-- ,让它与之前的单引号进行闭合并注释掉多余的单引号

        输入 admin' and 1 = 1 --       

        select * from table_test where username = 'admin' and 1 = 1 -- '

    当然按照数据提交方式来分的话,还可以分为GET注入、POST注入、COOKIE注入等等,与上述两种注入方法相比,也就是展现形式不同,就是将猫又叫了个咪

    MySQL数据库的使用

    常用的三种数据库的注入,即SQL Server、MySQL、Oracle的注入,虽然是三种不同的数据库,但注入思路都是相同的,仅仅是不同的数据库语句有些许不同,所以,以MySQL为例进行说明

    MySQL的常用语句

    数据库创建;数据库查看;

    使用数据库;创建一个新表(id和name为表的字段名);查看数据库中的所有表;

    给表中插入数据;查表

    更改表的内容

    删除表中的内容

    删除表;删除数据库

    元数据库

    查询用户数据库名称

    select SCHEMA_NAME from INFORMATION_SCHEMA.SCHEMATA LIMIT 0,1

    意思是:从INFORMATION_SCHEMA.SCHEMATA表中查询出第一个数据库名称

    查询当前数据库表

    select TABLE_NAME from INFORMATION_SCEMA.TABLES where TABLE_SCHEMA = (select DATABASE()) limit 0,1

    意思是:从INFORMATION_SCEMA.TABLES表中查询当前数据库表,并且只显示第一条数据

    查询指定表的所有字段

    select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'cms' LIMIT 0,1

    意思是:从INFORMATION_SCHEMA.COLUMNS表中查询TABLE_NAME是cms的字段名,并且只显示第一条数据

    常用函数

    以下两种需要有相应权限

    load_file()函数读文件操作

    into outfile()写文件

    concat()函数    连接字符串    语法:concat(str1,'分隔符', str2,'分隔符', str3...)  也可不指定分隔符

    concat_ws()函数    连接字符串,可一次性指定分隔符    语法:concat_ws('分隔符', str1, str2, ...)

    group_concat()函数    分组聚合  

    length()    返回字符串长度

    hex()    将字符串转化成16进制

    ascii    返回ASCII码值

    注入手法 联合查询

    数据库中的内容可以回显到页面

    使用union select语句,生成两张虚拟表,将结果纵向拼接

    语句:···?id=1 union select 1,2,3···

    使用条件:

    • 两张虚拟表具有相同的列数
    • 虚拟表对应的列数据类型相同(数字可以代表任何数据类型)
    案例:利用联合查询获取用户名和密码

    所使用是搭建的供练习的环境,请勿在现实中使用本文所讲的方法,不要试图挑战法律的底线

    因为拼接的表必须列数相同,所以需要知道表有多少列

    利用order by,order by 20页面报错,说明没有20列

    接下来可尝试10列,如果报错,则没有10列;若未报错,则接下来可尝试15列,直到找到正确的列数

    最后成功测试出有15列,则在union select后写15个数字,查看页面回显

    可将3和11换成SQL语句,查询敏感信

    换成version()和database(),页面回显了版本信和数据库

    利用元数据库和group_concat获取表名

    将16进制转化成字符串

    找到有利用价值的表,获取该表的字段名

    用concat_ws函数将字符串拼接

    得到用户名和密码

    密码通过md5解密

    在线md5解密网站

    报错注入

    使用错误显示信,可以通过一些异常将字符串消提取出来

    此处记住一些经典语句即可,有兴趣可以查看下列连接

    www.freebuf/column/158705.html

    布尔盲注

    数据库名称长度

    在URL后添加布尔值,查看页面回显是否正常来推断想要的信

    例如URL为:HTTP://www.example/test.php?id=1

    可在后添加 HTTP://www.example/test.php?id=1 and length(database()) < 20 --+

    如果数据库长度<20,页面会正常回显,否则,会出现异常,由此可判断出数据库名称的长度

    数据库名

    在后添加 HTTP://www.example/test.php?id=1 and ascii(substr(database(),2,1)) > 100 --+

    意为,数据库名称,从第2个字符开始取,取1个,判断这个字符的ASCII码值是否大于100(可取>、<、=)

    经过数次判断,最终可得到数据库名称

    延时注入

    例如URL为:HTTP://www.example/test.php?id=1

    数据库名称长度

    可在后面添加 HTTP://www.example/test.php?id=1 and if(length(database()) < 20,sleep(5),1) --+

    意为,如果数据库名称长度小于20,返回页面时产生5秒延迟

    数据库名

    可在后添加 HTTP://www.example/test.php?id=1 and if(ascii(substr(database(),2,1)) > 100,sleep(5),1) --+

    意为,数据库名称,从第2个字符开始取,取1个,判断这个字符的ASCII码值是否大于100(可取>、<、=)

    经过数次判断,最终可得到数据库名称

    联合查询、报错注入、布尔盲注、延时注入的成本依次提高,所以,在手注时,前面的有用时能用前面的就用前面的

     

     

     

     

     

     

     

    本文标签: 年了SQL