【网络安全系列】SQL注入总结


SQL 注入是一种常见的通用漏洞,在 CTF 中也是常客。

我对于通用漏洞的理解:和任何框架没有关系,和任何语言没有关系。

曾经做完 sqli-lab 的我非常的天真,想尝试把 SQL 注入漏洞进行系统性的总结归档,我发现,这真的太难太难了。

所以就有了现在这篇文章,采用问答的方式,记录一些自己遇到和收集的 SQL 注入的思想,让自己能在遇到具体问题时进行具体的分析。


1 基本原理

将用户输入的参数当作 SQL 语句执行。

更好的解释:用户输入的参数可以改变 SQL 的语法或语义。

2 防御与利用

攻与防不能独立的看待,需要根据实际的问题去解决。例如:使用 addslashes 能防御 SQL 注入,但是在某些特殊情况又可以进行绕过(如:宽字节注入、数组注入),但是用一些简单的方法又能防御掉这些绕过(如:set UTF-8、类型检查)。


问:如何检测 SQL 注入?

无源码:

  1. 使用 SQLmap 跑一下。
  2. 使用常见的闭合方式 fuzz 一下。
  3. 手动闭合?不推荐,测试不完全。

有源码:

  1. 中型代码
    1. 查看 SQL 语句编写是否规范(具体请查看后文的防御方式)。如:
    2. 查看官方文档是否有自动类型转换,构造数组或其他数据类型绕过。如:AntCTF 8-bit-pub
  2. 小型代码:搜集 tricks,逐个分析以及测试。

问:怎么绕过 addslashes?

  1. 利用宽字节注入。(正常运行函数)
  • 条件:MySQL 的编码为 GBK。
  • 原理:PHP 对字符的编码为 UTF-8,%27'%5c 为反斜杠,%df 无字符。当给 PHP 发送 %df%27 时,PHP 会将引号进行转义,转义为 %df%5c%27。经过转义后的字符在 UTF-8 下是安全的,但是在 GBK 中 %df%5c 会转义为 字,而引号并没有被转义。
  • 修复:(参考:浅析白盒审计中的字符编码及SQL注入-PHITHON
    • 调用一下 mysql_set_charset 函数,设置当前连接的字符集为 GBK。使用 mysql_real_escape_string 进一步过滤。
    • 设置 GBK 之后,设置 character_set_client=BINARY。
    • 使用 PDO(PHP Data Object)。如果 PHP < 3.6,禁用 PHP 仿真预编译。
  1. 利用特殊类型进行绕过(不正常运行函数)
  • 条件:能控制传入参数的数据类型。$_GET[“a”] 可能为数组。
  • 原理:addslashes 只能处理字符串

问:SQL 注入有哪些利用方法?

基本功能:

  1. 任意账户登陆。(有些转义函数可能无法实现完全可控,例如:antCTF的8-bit-pub)。
  2. 数据库读取。

进阶功能:

  1. 系统文件读取。
  2. 系统文件写入,即写 Webshell。
  3. 执行命令。

问:过滤关键字如何绕过?

方法1:双写绕过

  • 条件:将过滤字符删除,只删除一次(没有进行递归删除)。
  • 原理:删除之后的字符串可以形成新的关键字 anandd。

方法2:大小写绕过

  • 条件:使用正则表达式进行匹配,但是没有使用 /i
  • 原理:大部分数据库对大小写不敏感。

问:在数据库的报错信息中,如何显示自己需要的字符串?

2020 年 n1ctf 中 Web-SignIn 一题中用到

  • exp()函数

问:在做白盒审计时,如何快速定位是否存在 SQL 注入?

  • 全局搜索关键字:select、query、db、sql等。
    • 宽字节注入:GBK
    • 二次 urldecode 注入:urldecode, rawurldecode
  • 查看所使用的库文档,找文档的 escape。

问:常见的 SQL 注入的防御方法有哪些?

  1. GPC/runtime 函数过滤(部分防御 SQL 注入,具体参考《代码审计》一书)。
    1. GPC 负责对 GET,POST,Cookie 过滤。
    2. runtime 负责对文件过滤。
  2. 过滤函数和类
    1. addslashes 函数(addslashes 不知道任何有关 MySQL连接 的字符集,转义后更有可能导致错误)
    2. mysql_real_escape_string 函数
    3. intval 函数
  3. PDO 预编译

问:预编译的方法怎么绕过?

方法1:

  • 条件:将用户输入的参数直接写入预编译语句。
  • 原理:预编译是数据库提供的功能,分为 prepare 和 execute。prepare 是将需要执行的语句(不带数据)发送数据库,数据库进行词法分析、语法分析、语义分析,固定执行的具体流程。execute 将数据发送给数据库,发送的数据只能被作为字符串处理,无法改变 SQL 语句的执行流程。

方法2:

  • 条件:模拟预编译。
  • 原理:PHP 的模拟预编译的实质是转义,也就是调用 mysql_real_escape_string 函数进行转义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值