sqli是个老生常谈的话题,我们知道sqli漏洞层出不穷,我们知道sqli技能培训一片红火,农历年的最后一天,来讲讲SQLi的检测问题。
SQLi是如何造成的,有一堆的文章科普,这里就一句话交代——代码与数据的界限不明
二、危害
SQLi有哪些危害,也有一堆的文章科普,这里就一句话交代——要么要数据(也就是常说的脱裤,数据库数据读取篡改删除),要么要控制权(web写马,操作系统文件系统读写,命令执行),危害的程度取决于攻击者的最终目的
三、攻击步骤
SQLi有哪些危害,也有一堆的文章科普,一句话交代不清,分个类
1. 通用漏洞
(1)判断是否存在注入
a. 直接回显
b. 基于错误的回显:编译错误的敏感信息回显与运行时错误的语句执行结果回显
c. 盲注:响应内容差异与响应时间差异
(2)选择注入技术
(3)攻击
2. PoC
注意:这两种最大的区别是——是否具备频繁的试错操作(这个特征在关联分析SQL语句与对应的HTTP web日志时非常有用)
四、安全产品
我们在通过已有的产品看看有哪些成熟的解决方案:
(2)源码层——源码审计(静态代码分析)、安全编码组件(e.g.参数化查询)
(3)web服务器层——web server安全组件
(4)协议层——WAF/IDS/IPS
------------------------------------------------------------------------------------检测技术的分割线---------------------------------------------
包括发现sqli攻击,sqli攻击结果确认
五、检测技术(判断是否为sqli攻击)
(1)静态签名(攻击签名 signature-based,以字符串模式匹配为主)
a. owasp-modsecurity-crs
基于历史攻击案例的经验之谈,一般为输入参数/响应内容中包含用正则描述的特征字符串则判定为攻击
缺点:HTTP与SQL属于CFG(Context-Free Grammars),正则表达式属于FSM(Finite-state machine)描述语言,正则表达能力有限,总存在漏报与误报,最容易误报的owasp-crs 规则集中,SQLI毫无悬念的独占鳌头
(2)词法lexical+语法grammar+语义semantic分析
a. libdejector , blackhat 2005, Hanson && Pattresn, 给出了以下观点
"Input validataion needs to be done with a mechanism strong enough to recognize the language"
HTTP与SQL属于CFG(Context-Free Grammars),正则表达式属于FSM(Finite-state machine)描述语言,用正则来描述规则总会有误报与漏报
b. libinjection, blackhat 2012 , Nick Galbreath 词法分析
缺点:
从语法上说,标准SQL语法本身不复杂,复杂的是丰富的DB产品衍生的SQL变种语句及解析器特例;
从语义上说,这里有个案例
"select * from table where 1=1 and Age='18' and Address='云南省文山州广南县小村'”" 实际并不是SQLI,仅仅只是为了满足多条件查询页面中不确定的各种因素而采用的一种构造一条正确能运行的动态SQL语句的一种方法
这种方法尝试从sqli成因的本源来解决问题,区分代码段与数据段
(3)动态建模 dynamic profile(自学习 learning-based)
a. 正常行为的动态建模 (anomaly-based)
以imperva Securesphere产品为例Dynamic Profile

a.字符串特性:长度、字符分布规律、字符串结构(可用HMM/NFA)、前缀/后缀
b. 类型: 字符型,数值型等
...
注意:样本的选择与清洗非常重要,imperva采用以下策略来优化样本库的质量
(1)已知恶意行为筛选:黑规则(攻击签名)、严格的协议校验,严格的编码校验——(签名库是基础,在后期的模型评估中也可以做为参照标准)
(2)响应码筛选:404 500剔除
(3)扫描器(自动化脚本)筛选——(bot识别是必须的)
(4)请求者过滤:只接受可信IP,可信user发起的请求——(IP信誉库在内的情报支撑是必须的)
(5)训练基线:请求者(IP/User)数目限制(e.g. 至少50个用户对目标发起过请求);请求时间段限制(e.g. 12个小时的不同时间段均有对目标的请求);请求次数(对目标的请求次数至少50次)
(6)自适应:自适应分成两部分,一种当目标发生变化时(e.g. 程序结构发生变化);一种是鲁棒性,当错误样本混入时,能将其自动剔除。
缺点:需满足正常请求远远大于异常请求的假设前提
参考:
《A Learning-Based Approach to the Detection of SQL Attacks》
b、攻击行为的动态建模
六、确认技术(判断sqli攻击是否成功,并且更进一步的发现是什么漏洞造成的SQL攻击)
(1)动态确认:sqli漏洞扫描器
a. sqlmap
动态确认存在的问题:
1. 为了避免破坏性操作,scanner一般选择非登陆扫描,因此对需登陆的SQLI检测能力差
2. scanner 在盲注的情况下,对找到正确的注入点较困难
(2)静态确认:
方法一:漏洞扫描器的检测步骤与策略静态化
数据源:HTTP请求与HTTP响应
分两种:
通用漏洞:模拟sqlmap等扫描器判断是否存在注入的步骤(当然基于原来不变的情况下,策略需要微调与简化)
poc漏洞:poc直接转换为规则,比较简单
下面是用友FE协作办公系统 /common/codeMoreWidget.jsp SQL Injection POC面检测规则样例:
if path endsWith ”/common/codeMoreWidget.jsp“
and similarity(querystring, "12%27%20UNION%20ALL%20SELECT%20sys.fn_varbintohexstr(hashbytes(%27MD5%27,%271234%27))–”) > 0.9
and responsebody contains “81dc9bdb52d04dc20036dbd8313ed055" then
output "['用友系统漏洞', '/common/codeMoreWidget.jsp', 'Yongyou SQL注入漏洞', 'jsp']"
end
缺陷:
虽然避免了动态扫描器的潜在性破坏操作,网络带宽占用,但同时也丢失了扫描器的人机交互定制优势与简化过程中的检出率牺牲
方法二:web log与DB log关联分析
数据源:web log与DB log
第一步:分析db log,找出有危害的SQLI语句
第二步:,将DB中的SQLI语句与HTTP web日志对应起来,找到攻击的web入口
在对应的过程中,我们需要优先考虑一个问题,如何确认是否对应成功?
对通用SQLI攻击,如果对同一操作对象(表table,列field)的试错语句+攻击语句同时存在DB log与HTTP log中,关联正确;
对PoC SQLI攻击,如果对同一操作对象(表table,列field)的正常语句取样+攻击语句+指纹信息同时存在DB log与HTTP log中,并且DB与web的指纹信息一致,关联正确
第三步:攻击信息输出
(1)漏洞信息——看到了你
输出漏洞指纹,Nday? 0day
(2)攻击行为风险定级-你在干什么
0:badsqlstatement SQL语句不符合语法,当web server开启错误信息回显时会暴露db语句等信息
1:probe 探测性注入语句
2:dbread 读取DB信息语句
3:dbupdate 修改DB table数据语句
4:dbdelete 删除DB table数据语句
5:fileread 读取系统文件语句
6:filewrite 写系统文件语句
7:oscmdexcute 执行系统命令语句
(3)攻击者浅层信息提取- 你是谁
攻击者ip-geo,sessionid
第四步:防御策略输出
缺陷:
db日志源的获取
可以看出,从单维度的漏洞检测来看,检测技术基本就是三板斧,规则、沙箱与统计,但安全防御从来都是多维度上的攻防,我们需要用系统化的工程方法来给出解决方案,而“数据驱动的安全”明显是成本最低的解决方案,数据驱动不是说我们搜集了多少数据,而是关注数据的分层(基础数据层ip;dns,网络数据层五元组;终端层;应用层;用户行为层)与关联(大数据有意思的地方不是量,还是让异构的数据沟通起来,web log与db log的案例就是一次有效的简单对外),这方面需要摸索的地方有很多很多,来年继续。