SQL语言是实现数据库操作的一种编程语言,数据库解析器通过解析SQL实现对数据的增删改查等操作。目前主流数据库有MySQL、Oracle、MSSQL、Postgresql、MongoDB等等。Web架构采用脚本语言+数据库的形式构建服务,SQLi就出现在脚本语言逻辑处理中。而SQLi(SQL Injection)攻击已经延续了十多年之久,历年占据OWASP Top10榜首。SQLi在传统框架中出现的频率极为高,而现代形式Web框架从底层屏蔽了SQLi出现的可能性。
#SQL基础
SQL语言分为DDL、DML、DCL、TCL等,其中DML语言是目前使用最高的。
DDL语言(Data Definition Language)
- create
- alter
- drop
- truncate
- comment
- rename
DML语言(Data Manipulation Language)
- select
- insert
- update
- delete
- merge
- call
- explain plan
- lock table
DCL语言(Data control language)
- grant
- revoke
TCL语言(Transcation control language)
- commit
- savepoint
- rollback
- set transcation
由于权限的原因,SQLi常使用的DDL+DML对系统后端数据库操作。一个基础SQLi的产生是后端系统未对用户输入的数据进行过滤,使用户输入数据与业务SQL语句拼接,导致产生非法操作。
1 |
|
攻击Payload
1 | http://127.0.0.1/index.php?name=admin';select @@version# |
至此一个基础SQLi攻击过程完毕,在复杂的业务场景中,SQLi并不局限于select形式的注入,还有insert、update、delete等形式的注入场景。相对于select来说更为复杂,不可见、难操作。
INSERT注入的奇思妙想:
1 | $sql = "insert into user(username, password)values('".$_GET[name]."', password('".$_GET['password']."'))"; |
UPDATE注入的奇思妙想:
1 | $sql = "update user set name='" .$_GET['name']. "' where id=1"; |
DELETE注入的奇思妙想:
1 | $sql = "delete from user where username='{$_GET['name']}'"; |
SQL注入还有一种盲注的场景,注入操作不会回显在页面中。通过SLEEP/BENCHMARK函数利用时间响应的不同推断注入结果。
#SQL编码
由于WAF(web application firewall)的出现,纯原生的SQLi Payload会被系统拦截,为了bypass waf就需要对SQL语句进行各种变形。
- 大小写编码(目前无效果)
- URLENCODE编码
- 注释编码
- 特定场景字符截断(宽字节注入)
- ASCII码
示例:
```shell
#select @@version
index.php?id=1+uni//on+sel//ect+char(64)+char(64)+char(118)+char(101)+char(114)+char(115)+char(105)+char(110)+char(111)+char(110)#;
#/etc/passwd
index.php?id=1+union+select+load_file(0x2F6574632F706173737764)#
1 |
|
#SQLi漏洞挖掘
挖掘SQLi漏洞分为黑盒模式和白盒模式,前者通过工具或手工不断测试,后者通过阅读业务代码分析具体代码逻辑。无论黑白盒模式,能发现问题方式都是好方式,如果业务代码较为复杂,需要借助半自动化工具辅助分析代码。
源码审计工具
- rips
- graudit
- AppScan Source
rips审计工具目前已更新为商业版本,这里可以结合graduit工具辅助挖掘SQLi漏洞;代码审计的核心是根据编程语言特性函数(漏洞函数)及入口参数进行追溯分析。
#SQLi防御
SQLi漏洞发生原因在于输入参数与业务SQL结合导致安全风险,基础业务接受的参数多为数字型和字符型。如果参数为数字型参数,可采用intval()函数强制转换参数为整型。如果参数未字符型参数,通过参数绑定的形式规避风险。
常规防御方式:
- intval()/addslashes()
- PDO/MySQLi参数绑定
- 正则过滤(不严谨)
- 三方安全组件(taint/suhosin)
- RASP机制(Runtime Application Self Protection)
传统型框架thinkphp/phpcms/dedecms/discuz等框架在SQL使用上较为混乱,现代型框架Laravel/yii/cakephp/symfony等框架在SQL上统一封装,底层多为PDO/MySQLi参数绑定,基本规避SQLi的风险。但是各大Web框架都支持原生SQL的写法,So。。。挖一挖总还会有的 :)
参考
- 《SQL注入与防御第二版》
- 《SQL学习指南第二版》
- silic注入指南(习科)
- MySQL OOB攻击