有什么蛛丝马迹可以判断系统存在SQL注入漏洞,且如何临时应对?

作者:Sender Su  来源:原创内容  发布日期:2024-04-15  最后修改日期:2024-04-15

了解网络安全防御工作的人即使不是技术背景,都会知道 SQL 注入漏洞的常见程度以及这种漏洞危害的严重性。按行内普遍共识,SQL 注入漏洞和弱密码漏洞一样,都是属于不可原谅的漏洞。

article banner

笔者:国际认证信息系统审计师、软考系统分析师

为啥 SQL 注入漏洞(以下简称 SQLi)如此常见?归根到底还是因为网络安全防御整体就是反人性的。人的自由意志产生了随意性,所以随意性是与生俱来的人性。网络安全攻防双方的焦点实际就是落在对随意性的控制上。

而 SQLi 之所以不可原谅,是因为这早就有了各种有效的控制措施,只要在软件开发阶段严格执行这些控制措施,SQLi 就能得到避免。但时至今日仍然在软件中出现此类漏洞,要么是疏忽,要么是懒惰,所以都是人性。

去年软件 MOVEit 的 SQLi:CVE-2023-34362[1],令到美国多级政府部门、各类企业产生大规模数据泄漏,影响深重。幸好是该软件在我国内用得不多,未构成大规模影响,不然后果也是不堪设想。

有鉴于此,在2024年3月,美国网络安全与基础设施安全局发布了题为《Secure by Design Alert: Eliminating SQL Injection Vulnerabilities in Software 》的网络安全指引[2],要求软件行业从根本上推进解决软件中存在的 SQLi 问题。

指引内容不多,但就让我想起来自己碰到过的那个糟糕的实例,到处都是 SQLi,全靠一些临时措施凑合应付眼前的危机。

顺带一提,该系统的开发商从未能在设计的高危漏洞响应时间内给出补丁,从情况估计,系统的客制化没有做好版本和分支的管理,那么其软件工程质量情况也就可想而知了。

几种可用于判别是否存在 SQLi 的情况

信息系统可以从外部表征去发掘其内情,外部表征最常见就是 WEB 交互过程的数据流,以及前端页面的代码质量等等。另外,漏洞之间的相互关系也是可以考虑的。

1、XSS 漏洞是 SQLi 的伴生,因为没有对用户输入进行过滤

SQLi 的首要原因是没有把用户的任何输入都按潜在恶意去看待。手头的实例完美地暴露了这一点:在渗透测试中未等发现 SQLi,就已经发现了存在 XSS。测试用的 XSS PAYLOAD 在该系统的某个功能中输入,在信息系统的输出中会被完整地加载运行。

因此,可以提醒各位网络安全管理员:如果发现信息系统存在 XSS,则很有可能就会同时存在 SQLi。

鉴于该系统发现了如此简单直接的 XSS ,于是就预估会发现 SQLi,后面的渗透测试就专门奔着这种可能性去仔细检查。

2、系统界面的运行参数放在客户端一侧,该模块就有可能存在SQLi

大多数 WEB 程序员都会从写一个小型 CMS 系统开始学习 WEB 开发,而 CMS 系统的前端很常见是把UI的运行参数,比如用户在看的是哪个栏目的第几页,放在 URL 参数中,让用户提交回去后端时利用。

这种做法的安全性,依赖的就是参数化的预处理 SQL 命令,而不是手工拼接的 WHERE 条件(想想其实自己在二十年前也写过不少手工拼接的 WHERE 条件表达式)。

对于功能复杂的业务系统前端界面来说,这种做法就是在给自己挖坑。在这种场景下,参数化的 SQL 命令要等到良好和正确的运用,需要充分的需求分析和精确的详细设计为基础。但实际上大多数项目都难有这样的前置条件,于是开发过程就成了挑战程序员人性的过程。

而笔者碰到的这套系统就是把大量的界面控制参数直接放在浏览器 COOKIE 中,F12 调出开发工具看得一清二楚。

后端程序从 COOKIE 提取参数时依然是不作过滤,拿到什么就是什么,甚至直接把用于 WHERE 条件的整个 CASE 表达式放在 COOKIE 里面保存,渗透测试结果,存在 SQLi 妥妥的。

有同学看到这里就会说,难道这系统没用 ORM 吗?ORM 不是能避免 SQL 注入攻击吗?

笔者也是抱着疑问,干脆反编译了这个系统的一些模块来看,结论是用了,但不是所有的模块都用了......人性啊(赶工期啊)。

其实 ORM 并不是万能的,需要有正确的运用,尤其依然是不要拼接查询条件表达式,不过这扯远了。

3、不注意统一字符集的前端代码环境,系统存在 SQLi 也是基本没跑

利用 UNICODE 字符转义实现 SQL 注入也是攻方必备技能。反过来从软件开发角度观察,如果连前端页面文件的字符集都不统一,那可以肯定后端对字符集的处理也不会很严谨,那么利用 UNICODE 字符实现 SQL 注入就很可能成为事实。

那么身边这套系统是什么情况呢?

找了三个不同模块的前端页面文件,编辑器打开观察,发现两种字符集、三种不同换行符......

很明显,这系统在开发时根本就没统一过前端代码开发环境,WINDOWS, LINUX, MACOS 三种环境都用上,估计是不同的程序员就有不同的个人开发环境吧。而且各用各的字符集,WINDOWS 环境的用 GB2312,LINUX 和 MACOS 的用 UTF-8。

于是后面的渗透测试,利用 UNICODE 字符实施 SQLi 就轻而易举地获取到了所有数据。

对 SQLi 漏洞的临时应对办法

对于发现的这些情况,笔者采取了如下的临时处置办法:

1、利用 WAF 设备

这也是对于大多数网络安全管理员来说是最容易实现的做法。通过 WAF 对存在 SQLi 的地址 URL 设置参数过滤、COOKIE 内容过滤等规则,过滤存在恶意的参数。

如果难以过滤,在 WAF 设备支持的前提下,还可以强制修改参数内容,固化用户的一些操作,比如前面提及到发现这个系统直接把 CASE 表达式写在 COOKIE 变量中,那么就通过 WAF 设备强制设置 COOKIE 变量内容,使得无论攻击者如何篡改 COOKIE 都无效。但这种做法就必须放弃系统对用户的可用性。其实这也是所有临时措施的基本出发点,以降低可用性换取提高安全性,需要充分做好向用户的宣贯和沟通。

2、利用反向代理服务器

反向代理服务器可以在过滤操作上实现和 WAF 设备相类似的功能,甚至还能更灵活一些。但具体配置过程就比较麻烦,还和信息系统本身的运行配置是否可以调整有关。

一般地,配置过程包括:调整信息系统的配置,使其业务端口不直接对网络开放,仅允许本机地址访问;建立独立的反向代理服务器代理信息系统的访问,使用户只能通过反向代理服务器访问系统;使用反向代理服务器例如 Apache HTTP Server 的 mod_rewrite 模块设定规则实现对 COOKIE 内容、URL 和 GET 参数的过滤或强制修改;如果需要检查和修改 POST 数据,还需要为反向代理服务器添加 ModSecurity 模块[3]并设定规则予以实现,该模块自2024年1月25日起转交 OWASP 维护,且已扩展支持 NGINX 和 IIS。

3、开发用户和业务系统之间的中间层实现

更进一步地,还可以基于反向代理服务器开发用户和业务系统之间的中间层,从而实现更复杂、可靠的且尽量保持系统可用性的安全控制。不过这种做法一般只适用于已经没有开发技术支持的遗留系统,且不可能是临时应对措施。如果系统还有开发商提供支持,一般不需要做到如此复杂。所以这里也就不具体谈。

4、逆向工程自行修改代码打补丁

在甲方人员具备足够能力的情况下,对于一些未作混淆的运行时代码,还可以考虑通过逆向工程还原出准源代码,修补漏洞后实施。但这个措施是极其不通用的,倒不是担心与开发商之间可能会产生纠纷,只是技术上比较难实现,对人的能力要求高。

尤其是如果系统的后端是经过编译产生的机器语言执行文件(.so,.dll,.exe等等)那难度就很高了,现在的程序员懂汇编的都没几个,不像我们当年汇编语言是个人必修课。

有人或会追问:我在采购开发商提供的系统时,合同约定了不能逆向工程,那么我为了修补漏洞而逆向不就违反了合同约定?

笔者对此的研究认为,关键在于网络安全法第二十二条的规定:“网络产品、服务应当符合相关国家标准的强制性要求。网络产品、服务的提供者不得设置恶意程序;发现其网络产品、服务存在安全缺陷、漏洞等风险时,应当立即采取补救措施,按照规定及时告知用户并向有关主管部门报告。

即使合同中这方面的约定比较模糊,但如果开发商未能立即对漏洞提供补救措施,就已经涉嫌违法。甲方作为需要履行网络安全保护义务的网络运营者,按上位法要求自行实施必要的补救措施,同时未侵犯乙方的其他权益(比如向除监管部门之外的第三方披露漏洞情况或乙方知识产权等),乙方若对此提出异议,最终产生的商誉损失还是乙方自己承担。因此,理性的乙方是不可能提出异议的。

更适当的做法自然是在合同中就产品存在网络安全风险因素时的应对处置作专门约定。

小结

虽然本文的内容确实是笔者在现实中碰到的情况,但为了避免啰嗦,本文不会给出具体是什么厂商的什么产品、存在漏洞的 URL 路径和参数之类的信息。

本文的目的在于从软件开发的角度,通过发现信息系统在外部表征上的不严谨或存在其它漏洞的情况,进而预判系统是否存在 SQLi,以及在确认存在 SQLi 但没有补丁时的采取的临时应对措施。这些措施的内在意义包括:

1、放弃可用性换取提高安全性是临时解决办法的基本要求。

2、保持与用户的沟通和理解是确保临时解决办法得以有效维持的关键因素。

3、对WEB服务器反向代理功能的充分利用是解决问题的另一种思路。

4、WAF不是万能的,首先要正确地配置,其次要能及时调整。

Secure by Design Alert的三条原则

Secure by Design Alert: Eliminating SQL Injection Vulnerabilities in Software 文档指出的三条原则概述如下:

原则1:承担客户安全结果的责任。要求开发商必须承担安全责任,确保使用安全的SQL命令处理和运行机制,在代码合并时进行检查,定期进行网络安全代码审计以发现常见的安全漏洞,并同时发布对应的缓解措施。

原则2:拥抱激进的透明度和问责制。主动以CVE方式披露自身存在的重要漏洞,并寻求提升为CWE的缺陷类别,分析和发布与漏洞有关的根本原因和处置办法。

原则3:建立组织结构和领导力来实现目标。将业务导向安全设计的软件开发融入到企业内部管理体制,理解安全优先的软件开发模式最终可以获得财务成本上的优势,配以适当的激励措施和组织架构,持续推进安全实践和定期审计,维持和记录各类缓解措施,从根本上解决安全漏洞。

参考资料

[1] Progress MOVEit Transfer SQL Injection Vulnerability

https://nvd.nist.gov/vuln/detail/CVE-2023-34362

[2] Secure by Design Alert: Eliminating SQL Injection Vulnerabilities in Software 

https://www.ic3.gov/Media/News/2024/240325.pdf

[3] ModSecurity

https://github.com/owasp-modsecurity/ModSecurity

本栏目相关
  •  2022-05-11 CIS-CAT 配置评估工具介绍及操作实践
  •  2022-03-16 Windows 系统安全基线及软件工具介绍
  •  2022-03-11 安装RHEL/CentOS时如何选择配置安全策略?
  •  2022-08-28 网络攻防中的色彩象征
  •  2022-03-17 详细了解微软安全合规工具包(SCT)
  •  2022-03-25 从甲方角度介绍“CIS互联网安全中心”
  •  2022-03-28 如何应用CIS互联网安全中心发布的《CIS关键安全控制措施集》之一:总览
  •  2023-01-06 MSSQL数据库自动备份和自动复制转移备份
  •  2022-05-19 网络安全日志收集甲方基础实践
  • 微信订阅号二维码

    本页网址二维码: