2020 年双节前夕,国内疫情稳定,长假将启,各项安保措施比以往有所升级,而此时更是网络安全重点保障时期,信息安全工作尤其不能懈怠。各用户单位也陆续启动响应,对网络安全负责人、联络人通知到位,深度排查网络安全风险,及时调整网络安全策略,部署实施态势感知、应急响应、持续安全评估、安全监测巡检等安全措施,并确保安全人员现场保障。安保工作如火如荼,天存信息的技术工程人员也相继奔赴各个信息重保工作现场。
一、安全措施与前期建设
1.1 个人心理建设
在三个重点客户的工作现场轮流值守期间,我需要时刻紧盯日志审计平台,跟踪满屏的访问日志,捕捉攻击行为的蛛丝马迹,深感责任重大。相信技术工程人员都会有类似感受:每每遇到这种境况,或多或少会事先祈祷一切顺利,平安渡劫。
1.2 安全措施建设
重保安全的准备工作一点也含糊不得。“工欲善其事,必先利其器”,一个典型的机房安全建设设计是这个样子的——
有这张严防死守的安全图纸在手,再加上各安全厂商的 IT 精英们悉数到场镇守,安全感油然而生。设想,在我方强大布防下,任他什么扫描、洪水攻击、DDoS 攻击、注入或是跨站,应该都挤不进这密不透风的防控体系。蜗居于安全中心的 WEB 应用服务器,应该能高枕无忧了。即便攻击者挖到了应用或中间件的“0-Day”漏洞,或者事先植入了 WebShell,在主机安全加固环节,或攻击者利用 WebShell 时,我方的 WAF 和入侵行为检测也能排查出问题所在,并做出预警和拦截。
然而,最担心的事情,还是自然地发生了。
二、安全事件始末
重保期间某日,我们接到了一则上级通知,还附带有一份漏洞描述文件。
附带的漏洞利用过程描述文件,如下。
我们立即着手排查原因,力求快速修补这个漏洞。
NO.1 首先排查日志。基于漏洞利用过程文件的描述,我们逐一检查了 WAF 的攻击日志,显示无异常。
NO.2 查询入侵行为检测。它确实只是一条访问日志,不是攻击行为。
NO.3 登入服务器,跟踪这个文件所有的访问日志和访问IP,寥寥数条,没有所谓的上下文关联,无法还原出一个完整的攻击过程。
NO.4 最后,进入 WEB 应用的目录,找到这个文件,粗略浏览代码,发现这是一个任何人都有权限访问的文件,没有任何用户和会话的检查机制。这是一个典型的越权 任意文件上传漏洞。
用户单位要求紧急处置这一加急任务,对于 IT 安全运维部门,有以下几种解决方式:
- 设置应用的访问控制策略,只允许特定 IP 访问这个上传组件功能。而由于应用系统的业务面向 Internet 用户,每天都会有业务数据通过 HTTP 协议上传系统,限制特定 IP 并不可行。
- 临时关闭上传功能。基于上述实际情况,同样无法实现。
- 限制上传目录的执行权限,可以禁止上传文件的执行。然而这并非用户可以接受的解决方案。
其实,最根本的解决办法是协调开发部门,对这个上传功能增加用户限制和会话绑定。现实问题再一次横亘在大家面前,一个5年前开发并交付的系统,找到当初的开发参与人员进行修复,当下更不具备可操作性。而 WAF 不能配置理解业务执行过程的的访问规则,焦点便对准了我们负责 WEB 应用安全的几家厂商。客户要求第二天上午 8:00 前必须完美解决,时间紧迫。
在重保期间,红头文件和加急电话,成了压在我们几个相关人员头顶上的大山。
幸好在运维期间,我把公司的 WEB 业务补丁平台,放置在了关键业务的前端。现在,余下要做的就是整理客户需求,编写用户补丁了。
客户的 WEB 应用环境和需求如下:
- WEB 服务器上有两个应用目录
/app_a/
和/app_b/
,分别对外负责不同业务。 - 其中
/app_a/
不需要对外有上传功能,上传功能可以关闭,面向公网用户开放。 /app_b/
只允许内网访问,公网用户不能访问,上传功能不可关闭,内网用户的 IP 是以 10 开头的 IP。- 上传功能需要验证用户和
session
绑定,登录后才能执行上传操作。
三、安全事件处置
接下来是着手编写虚拟补丁并上线补丁。虚拟补丁如下:
代码语言:txt复制{
"rules": [
{
"meta": {
"phase": 1,
"function": "如果请求文件名以/szyx开头,而且请求文件名中包含upload_json.jsp,则进行拦截,并记录日志。"
},
"if": [
"begin(REQUEST_FILENAME, '/szyx')",
"contain(REQUEST_FILENAME, 'upload_json.jsp')"
],
"then": {
"action": "deny",
"log": "不允许在访问/szyx相关应用的时候,访问upload功能模块."
}
},
{
"meta": {
"phase": 1,
"function": "如果客户端为公网IP(不是10.开头),却访问非/szyx开头的页面,则进行拦截,并记录日志."
},
"if": [
"!begin(REQUEST_FILENAME, '/szyx')",
"!begin(REMOTE_ADDR, '10.')"
],
"then": {
"action": "deny",
"log": "不允许公网IP的客户端(此处为非10开头的客户端ip)访问非/szyx相关的应用."
}
},
{
"meta": {
"phase": 4,
"comment": "如果登录成功(登录成功的标志是Set-Cookie中有jcxx_cookie_session_xtbz和flushcookie成员存在),则记录代表登录成功的变量到SESSION中。"
},
"if": [
"REQUEST_FILENAME == '/sys/system/login/logincheck'",
"REQUEST_METHOD == 'POST'",
"notNull(RESPONSE_SET_COOKIES.jcxx_cookie_session_xtbz)",
"notNull(RESPONSE_SET_COOKIES.flushcookie)"
],
"then": "SESSION.login_success@300 = 1"
},
{
"meta": {
"phase": 1,
"function": "如果进来的请求URL中包含upload_json.jsp,则进行会话检查."
},
"if": "contain(REQUEST_FILENAME, 'upload_json.jsp')",
"then": {
"if": "SESSION.login_success != 1",
"then": {
"action": "deny",
"log": "No Auth! You don't have access to the upload page!"
}
}
}
]
}
编写好虚拟补丁,意味着 80% 的工作量已完成,心情可以舒缓一些了。
下一步,要验证补丁的有效性。对此,我们分别模拟内网用户和外网用户对虚拟补丁做访问和攻击测试,日志截图如下:
内网越权访问(基于IP的访问控制策略验证):直接访问,直接拦截。(如图)
内网越权访问拦截日志:拦截日志报出,因为没有用户登录和会话的绑定,这次越权请求被拒绝。
外网IP访问限制:
处置结果:用户单位的安全问题“越权 任意文件文件上传漏洞”被上线的虚拟补丁完美解决,客户表达了感谢,我们也又一次通过了安全考验。(钱文芳 | 天存信息)