一、常见漏洞类型
关于web安全测试,目前主要有以下几种攻击方法:
- XSS
SQL注入
- 跨目录访问
- 缓冲区溢出
- cookies修改
- Htth方法篡改(包括隐藏字段修改和参数修改)
- CSRF
- CRLF
- 命令行注入
今天主要讲下SQL注入。
二、SQL注入
1、SQL 注入危险性、可能原因
严重性: 高
类型: 应用程序级别测试
WASC威胁分类: WASC-19
漏洞分类方法WASC介绍参考博文
CVE 引用: 不适用
安全风险:
- 可能会查看、修改或删除数据库条目和表 —SQL盲注
- 可能会窃取或操纵客户会话和 cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以及执行事务 —跨站的脚本编制
可能原因:
未对用户输入正确执行危险字符清理
2、场景重现
攻击者利⽤SQL注⼊漏洞,可以获取数据库中的多种信息(例如:管理员后台密码),从⽽脱取数据库中内容(脱库)。在特别情况下还可以修改数据库内容或者插⼊内容到数据库,如果数据库权限分配存在问题,或者数据库本⾝存在缺陷,那么攻击者可以通过SQL注⼊漏洞直接获取web shell或者服务器系统权限。
例如,如果应用程序根据用户的输入(如用户名和密码)来查询用户帐户的数据库表,以认证用户,而攻击者能够将恶意数据注入查询的用户名部分(和/或密码部分),查询便可能更改成完全不同的数据复制查询,可能是修改数据库的查询,或在数据库服务器上运行 Shell 命令的查询。
一般而言,攻击者会分步实现这个目标。他会先学习 SQL 查询的结构,然后使用该知识来阻挠查询(通过注入更改查询语法的数据),使执行的查询不同于预期。假设相关查询是:
SELECT COUNT(*) FROM accounts WHERE username='$user' AND password='$pass'
其中 $user 和 $pass 是用户在登录页面上输入的值(可能是来自 GET 请求查询参数,也可能是来自 POST 请求主体参数)。此查询的一般用法,其值为 u s e r = j o h n 、 user=john、 user=john、password=secret123。形成的查询如下:
SELECT COUNT(*) FROM accounts WHERE username='john' AND password='secret123'
如果数据库中没有这个用户密码配对,预期的查询结果便是 0,如果此类配对存在(也就是数据库中有名称为“john”的用户,且其密码为“secret123”),结果便是 >0。这是应用程序的基本认证机制。但攻击者可以用下列方式来更改此查询:
攻击者可以提供单引号字符(')所组成的输入,使数据库发出错误消息,其中通常包含关于 SQL 查询的有价值的信息。攻击者只需在发送的请求中包含用户值 ',并在密码中包含任何值(如 foobar)。结果便是下列(格式错误)的 SQL 查询:SELECT COUNT(*) FROM accounts WHERE username=''' AND password='foobar'
后端执行这段代码查询数据可能会产生发生语法错误,这时攻击者便得知查询是根据表达式 username=‘ u s e r ′ a n d p a s s w o r d = ′ user' and password=' user′andpassword=′pass’ 来构建的。攻击者了解查询的格式这一关键信息后,下一步只需使用:
user =' or 1=1 or ''=' password = foobar
生成的查询如下:
SELECT COUNT(*) FROM accounts WHERE username='' or 1=1 or ''='' AND password='foobar'
这个sql表示查询“accounts”表的所有记录,因为 1=1 表达式永远为真,于是用户(攻击者)也会被视为有效。这个探测方法有若干变体,例如,发送 '; or '(您应该记住,几乎所有供应商都有他们自己唯一的 SQL“版本”。具体地说,发送 ’ having 1=1,也会生成错误消息,此消息会泄露有关列名称的信息。
3、sql盲注
降低 SQL 注入攻击风险的一般方式,是禁止详细的 SQL 错误消息,攻击者通常便利用这些消息(如上述示例所示报错信息提供了sql具体内容),轻易找出容易遭受“SQL 注入”的脚本。
这种隐藏报错信息的解决方案还不能够真正解决问题,攻击者可以通过sql盲注技术进行攻击,这种注入方法不需要依赖返回 SQL 错误消息,便能找出容易遭受“SQL 注入”的脚本。
sql盲注需要修改发送请求的参数(被嵌入在 SQL 查询中的参数),这项修改包括搭配原始字符串来使用 AND Boolean 表达式,使sql条件能够直接得出 true或 false,最终结果应该与原始结果相同(例如:登录成功)或者不同(例如:登录失败)。在某些少见的情况中,得出 true 的 OR 表达式也很有用。
4、检测⽅法
- 识别⽤户输⼊。SQL注⼊漏洞可能在系统输⼊参数中,这些参数执⾏数据库操作。
- GET、POST参数中。
- COOKIE参数中。
- http请求头。主机头、引⽤站点(referer)、User-Agent和X-Forwarded-For等。
- 检测SQL注⼊。使⽤SQL注⼊测试语句对输⼊参数进⾏测试。
- 特殊符号:单引号,分号,web服务器响应报错。
- 条件响应:and 1=1、and 1=2、’ or ‘1’=‘1、’ or ‘1’='2,两次web服务器响应不同。
- 时间延时:sleep(5)、waitfor delay ‘0:0:5’,系统服务器延迟响应。
- 参数相加:对数字类型进⾏加减运算,字符类型使⽤数据库连接符号进⾏连接。系统服务器响应与原来的响应相同。
- 利⽤SQL注⼊。对以上测试进⼀步利⽤,⼿⼯构造SQL注⼊语句或者使⽤SQLMAP检测脚本构造注⼊语句。
5、防护⽅案:
问题的补救方法在于对用户输入参数进行过滤、校验或者采⽤参数预处理的⽅式
。
通过验证用户输入未包含危险字符,便可能防止恶意的用户导致应用程序执行计划外的任务,例如:启动任意 SQL 查询、嵌入将在客户端执行的 Javascript. 代码、运行各种操作系统命令,等等。
建议过滤出所有以下字符:
[1] |(竖线符号)
[2] & (& 符号)
[3];(分号)
[4] $(美元符号)
[5] %(百分比符号)
[6] @(at 符号)
[7] '(单引号)
[8] "(引号)
[9] '(反斜杠转义单引号)
[10] "(反斜杠转义引号)
我公司采用的就是这种方法哦,将特殊符号加入一个黑名单,在全局的监听器中过滤掉含有这些黑名单中特殊符号的查询,基本上就能解决sql注入问题了。