前言

之前介绍了一些前后端结合的中间人攻击方案。由于 Web 程序的特殊性,前端脚本的参与能大幅弥补后端的不足,从而达到传统难以实现的效果。

攻防本为一体,既然能用于攻击,类似的思路同样也可用于防御。如果将前端技术结合到传统的 WAF 中,又能有如何的改进?

假人的威胁

简单易用,是 Web 服务最大的优势。然而,这也是个致命的弱点。

这种格式简单、标准一致的特征,使得攻击者能利用现有的安全工具,进行大规模、通用化的探测和入侵。甚至无需了解其中的原理。

试想一下,如果某个网站使用私有的二进制协议,那么即使存在漏洞,也得先考虑通信问题。若是寄托于现成的安全工具,那就更举步维艰了。然而现实中是不存在的。通用性和低成本,始终是首要因素。

要模仿这种简单的协议易如反掌。于是,各种需要重复劳动的地方,都能见到假人的身影。对于需要反复测试的安全领域,更是必不可缺。

传统 WAF

传统 WAF 大多关注于信息监控,记录拦截各种异常的输入输出。对于用户的真假鉴别,并非是其重点。

然而现实中,大多异常的请求,都不是正常用户发起的。有谁会那么闲,把各种帐号一次又一次输入测试撞库?或者反反复复的在浏览器里尝试内网探测?没有工具的协助,安全检测将是无比的折磨。

遗憾的是,WAF 很难从表面上识别用户的真假,只能对其一视同仁。通过之后更详细的规则进行综合分析,才能做出判定。因此,这样的决策似乎有些『有理无据』。

  • 有理。例如正常用户每秒只有几个请求,但攻击者开了漏洞扫描工具,短时间内产生了上百请求,这显然不符合常理

  • 无据。虽然判定一个用户并不难,但要拿出确凿的证据,却不容易。

这种模糊的规则难免会有一些的误差。若是内网里有人对网站进行入侵探测,很可能导致正常用户也被屏蔽;或者攻击者放慢扫描速度,兴许又能躲过监视。

当然,一套好的规则和模型能让拦截更精准,不过这需要大量的分析和积累。对于 Web 这类特殊群体,我们能否另辟蹊径,寻找一种既简单又靠谱的方案?

在之前讲解的流量劫持系列中也曾提到,后端分析是十分被动的。好在它掌控着流量大权,而 Web 这种特殊流量,同时具备可执行能力。因此可化守为攻,开辟一条全新的作战方案。

所以,我们得借助前端技术,来实现最终目标 —— 做一个有理有据的规则系统。

但一个令人信服的证据不会无中生有,必须人为约定和创造,并在适当的时候将其带上,做到真正的『理据服』。

现有解决方案

在开始构思的我们的『前后端 WAF』之前,有必要提一下现有的解决方案。

每当遇到这种禁止改包重放的场合,安全工程师们总能不假思索的给出解决方案。例如让页面产生个唯一的随机数和时间戳,加密后让后端去验证。

如果仅仅是为了解决个例,这样倒也无可厚非。然而现实中,这样的需求并不少见。如果要让每个业务都去现实这样的方案,将会极大增加前后端开发维护成本。

所以,把一些具体的方案抛给开发者,是很不合理的。对于开发者来说,理应投入全部精力在产品业务的开发上;与其不相关的事,都应交给适配层,让开发者无需了解任何细节,自动帮其实现。

于是,我们需要一个前后端相辅相成的切面系统,在其中透明解决这些琐碎的问题。这样才可大规模部署,以及后期统一更新和维护。

前后端结合 WAF

提到切面,Web『中间件』自然是我们的切入点。和过去的『中间人』劫持类似,我们在页面中注入一段脚本,以开启前端功能。

派出了位于前线的哨兵,就能提供更详细的情报,这在过去是难以实现的。如今前端技术日新月异,利用这些优势,我们开始构思一个全新的系统。

前面提到,如果能在发起请求时,提供一个证据来证明自己不是外人,那样后端就会好办的多 —— 不懂规矩的假人,自然会立即暴露破绽。

因此我们给页面 IO 做一层切面:在请求发出前一刻,带上一个蕴含各种私密信息的暗号,供后端验证。

借助之前《SSLStrip 的未来 —— HTTPS 前端劫持》中使用的技术,稍作修改即可实现前端层面的请求拦截。

如今我们目的更简单,只是携带一个额外参数而已,因此对于同站的请求,甚至无需修改目标 URL,将参数储存在 cookie 即可自动带入请求。

于是,开发者无需任何修改,就能获得更安全的防御。

秘钥策略

在秘钥中,我们可储存各种环境的上下文,例如:

  • 只能用一次的随机数,防止请求重放。

  • 表单数据的校验值,防止中途被改包。

  • 当前时间戳,让后端更精准的掌握发包间隔。

  • 浏览器 BOM 特征,校验是否和 UserAgent 描述的浏览器相符合。

  • ......

最终通过私有算法,将其编码成一个暗号秘钥。

当然,这个秘钥并不要求每次都严格验证。事实上首次访问,就是没有秘钥的;或者在钩子之外的网络请求,例如图片等资源文件,无法保证每次都有唯一的秘钥。

在 Web 富应用时代,『AJAX』和『JSONP』承载了绝大多数的接口请求,因此我们需严格防御。而普通的静态资源风险则小得多,可以更宽松一些。

后期对抗

不过,类似的系统曾经也有过尝试,但都是备受争议的。原因很简单,秘钥是在前端生成的,其中的秘密查看页面源码即可获得。一旦算法被解开,假人也能冒充真实用户,整个系统就失去了意义。

这也是为什么把『前端中间件』标注成黑色背景 —— 我们需要将前端脚本高度混淆,让攻击者难以在短期内破解其中的算法。

于是,我们可以把网络上的对抗,转换成逆向技术的比拼了。让攻击者需要具备更多的技能,从而提高入侵门槛。

黑盒对抗

即使无法破解,攻击者也能想尽办法,将其当做黑盒来使用。我们举几个能预测的情况,进行攻防模拟。

No.1

攻击者可完全无视加密细节,直接把假人的请求转到页面进行代理,因此看起来就像是正常业务发起的。

对于这样的情况,很难有绝对的防御措施。但可以用简单的策略:限制请求频率,从而降低攻击速度。

我们设定一个相对宽松的请求数阈值,如果一定时间里达到上限了,就让前端钩子 Pending 住请求,稍做休息再发出。并且堆积的越多,就让它推延更久。

如果正常用户短时间里操作太快,导致请求超标,那么惩罚几秒也情有可原(点的太快本来就会卡);但请求数持续居高不下的,那就很可疑了,是不是该好好休息下呢?

我们把请求数记录到全局存储里,在多个页面间共享,防止多开慢刷;并且页面关了仍然保留,下次回来继续惩罚,避免反复刷新页面清零。

No.2

即便如此,攻击者仍能想出一些规避方法。例如开上几个不同的浏览器、甚至虚拟机,作为完全隔离的环境,单独慢慢刷。

对付这样的假人,就得用一个靠谱的识别手段:用户行为分析。

正常的用户浏览页面,总是伴随着鼠标滚轮、移动、点击、触屏等事件。而且网络请求的发起,大多通过这些事件的驱动。若页面一动不动,却在不断的发请求,那很有可能就是开挂的。

甚至还可以考虑把采集到的行为数据,通过秘钥提交到后端进行分析,建立更详细的行为模型。

No.3

当然秘密总是会被发现的。行为采集这个门槛也难不倒攻击者,如今能模拟用户行为的机器人也不在少数,它们能逼真的模仿出各种事件,而我们也只能初略的分析。

不过能把攻击者的门槛提高到这一步,我们的目的也达到了 —— 我们并非要 100% 阻止假人,而是通过对抗减少假人。

End

在黑盒对抗下,由于攻击者 不了解实情,只能见招『猜』招,很是被动。我们可以不时更新下脚本,调整策略,或者添加一些巧妙的思路,不断折磨攻击者。

对于攻击者,显然不甘长久在黑盒中对抗,会想方设法破解脚本。

逆向对抗

好在相比传统语言,JavaScript 流行起来的时间还很短,成熟的逆向工具少之又少。而且运行于浏览器,又会牵扯到各种 DOM 与 BOM,因此还得了解不少的前端知识。

做一个好的混淆器,需要不少理论知识。不过不必搞的那样先进 —— 我们只需比攻击者想的更远就可以了。

在实际对抗中,无需太过纠结『技术』层面,更多的是需要『计谋』。有些东西其实原理很简单,但就是想不到。这里就不详细讨论混淆技术了,分享几个非技术层面对抗的案例。

脱壳迷惑

真正的脚本混淆器,应该是打乱原先的代码结构,并且加入各种多余语句,以增加调试复杂度。

不过目前有相当多的混淆器,只是加个壳而已 —— 把原先的代码进行加密,运行时解密再 eval 执行。要解开这种『混淆』毫不费力,把 eval 替换成 alert 就能原形毕露,相信大家都尝试过。

当然,我们也可以利用人们一些天真的想法,进行真假迷惑。

我们显然不会『加壳』原始代码,但可以准备一套伪代码,假装先解密再 eval。这套假代码看上去和真的一样,但里面的功能并不会触发,仅仅用以迷惑而已,把攻击者引到错误的方向上,从而浪费其时间。

而真正的代码,则夹杂在解密的区域,在脱壳之前已经开始运行了。

在解密伪代码的时候,还可以往其中插入大量无用的内容。例如眼花缭乱的特殊符号、成千上万的续行符,阻碍正常阅读。

尽管这不能解决根本问题,但能消耗攻击者的精力,这就是非技术对抗。

蜜罐钓鱼

既然想逆向,那总得先大致看一下脚本。在眼花缭乱的代码里,一段可读文本,就像是万木丛中一点红。利用它吸引攻击者的眼球,从而上钩。

例如,我们在代码开头的某个字符串里,写一段『... compressed by xxxtool』。攻击者看到这段文字,必然会好奇 xxxtool 是什么工具,于是就去网上搜索。

我们预先制作一个简单的网页,提供在线 JavaScript 的加密和解密。名字就叫 xxxtool,一个非常特殊的名字。我们从不推广这个页面,正常情况下根本不会有人来访问。

当攻击者搜到这个网站,自然会进来看看。发现还提供在线解密,以为找到了解药,立即将代码粘进来试试。

落入了我们的蜜罐,就免不了被我们忽悠了。如果是一般的脚本,就显示普通工具的结果;一旦发现是在解密自己的代码,赶紧拿出预先准备的那套伪代码,让攻击者误以为成功解开了。

同时,只要攻击者一进入我们的网页,就立即上报给云端,能及时了解有谁在研究我们的脚本。甚至还可以记录下访客的 IP,通知给 WAF 封杀一段时间。

当然,也未必要那么复杂。我们可以在一个永远到不了的条件分支里,请求一个特殊页面;如果某天发现这个页面有访问量了,显然是有好奇的人在尝试破解。

End

类似的对抗思路还有很多,以后有时间再分享。只有『技术』与『计谋』结合,才能在对抗中更胜一筹。

回到正题,对于这个系统来说,即使被破解也不会有太大的损失。只要换一套秘钥算法和混淆方案,又可以继续我们的防御。自动化的部署,能让我们的更新维护更简单,为持久对抗提供强有力的保障。

后记

我们把传统的网络攻防,转换成逆向技术的对抗,让系统涉及更多的领域。对于攻击者来说,就需要掌握更多的技能点,从而提高入侵的门槛。

退一步,即使攻击者能轻易破解我们的系统,那也无法立即应用于现有的安全工具,必须改造才能使用,同样能大幅增加攻击成本。

对抗假人 —— 前后端结合的 WAF的更多相关文章

  1. 前后端结合的 WAF

    前言 之前介绍了一些前后端结合的中间人攻击方案.由于 Web 程序的特殊性,前端脚本的参与能大幅弥补后端的不足,从而达到传统难以实现的效果. 攻防本为一体,既然能用于攻击,类似的思路同样也可用于防御. ...

  2. Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题

    现互联网公司后端架构常用到Spring+SpringMVC+MyBatis,通过Maven来构建.通过学习,我已经掌握了基本的搭建过程,写下基础文章为而后的深入学习奠定基础. 首先说一下这篇文章的主要 ...

  3. 快速web开发中的前后端框架选型最佳实践

    这个最佳实践是我目前人在做的一个站点,主要功能: oauth登录 发布文章(我称为"片段"),片段可以自定义一些和内容有关的指标,如“文中人物:12”.支持自定义排版.插图.建立相 ...

  4. JSON(及其在ajax前后端交互的过程)小识

    一. json介绍 json是一种轻量级的数据交换格式,规则很简单: 并列的数据之间用逗号(,)分隔: 映射用冒号(:)表示: 并列数据的集合(数组)用方括号([])表示: 映射的集合(对象)用大括号 ...

  5. com.panie 项目开发随笔_前后端框架考虑(2016.12.8)

    (一) 近日和一同学联系,说了我想要做一个网站的打算.她很感兴趣.于是我们协商了下,便觉得一起合作.她写前端,我写后台.因为我对于前端样式设计并不怎么熟悉. (二) 我们决定先做一个 个人博客. 网上 ...

  6. SpringMVC前后端数据交互总结

    控制器 作为控制器,大体的作用是作为V端的数据接收并且交给M层去处理,然后负责管理V的跳转.SpringMVC的作用不外乎就是如此,主要分为:接收表单或者请求的值,定义过滤器,跳转页面:其实就是ser ...

  7. 前后端分离中,Gulp实现头尾等公共页面的复用

    前言 通常我们所做的一些页面,我们可以从设计图里面看出有一些地方是相同的.例如:头部,底部,侧边栏等等.如果前后端分离时,制作静态页面的同学,对于这些重复的部分只能够通过复制粘贴到新的页面来,如果页面 ...

  8. nodeJS(express4.x)+vue(vue-cli)构建前后端分离详细教程(带跨域)

    好想再回到大学宿舍,当时床虽小,房随小,但是心确是满的 ----致  西安工程大学a-114舍友们 转载请注明出处:水车:http://www.cnblogs.com/xuange306/p/6185 ...

  9. 浅谈WEB前后端分离

    重审业务逻辑 用过MVC的童鞋都知道业务逻辑(Bussiness Logic),但是大多对这概念又是模棱两可,业务逻辑从来都是这样难以理解,谈论前后端分离之前这个概念非常有必要探讨一下! 在简单的CR ...

随机推荐

  1. 前端开发中SEO的十二条总结

    一. 合理使用title, description, keywords二. 合理使用h1 - h6, h1标签的权重很高, 注意使用频率三. 列表代码使用ul, 重要文字使用strong标签四. 图片 ...

  2. ASP.NET Core应用针对静态文件请求的处理[3]: StaticFileMiddleware中间件如何处理针对文件请求

    我们通过<以Web的形式发布静态文件>和<条件请求与区间请求>中的实例演示,以及上面针对条件请求和区间请求的介绍,从提供的功能和特性的角度对这个名为StaticFileMidd ...

  3. Visual Studio 2012远程调试中遇到的问题

    有的时候开发环境没问题的代码在生产环境中会某些开发环境无法重现的问题,或者需要对生产环境代码进行远程调试该怎么办? Vs已经提供给开发者远程调试的工具 下面简单讲讲该怎么用,前期准备:1.本地登录账户 ...

  4. Nginx反向代理,负载均衡,redis session共享,keepalived高可用

    相关知识自行搜索,直接上干货... 使用的资源: nginx主服务器一台,nginx备服务器一台,使用keepalived进行宕机切换. tomcat服务器两台,由nginx进行反向代理和负载均衡,此 ...

  5. BAT“搅局”B2B市场,CIO们准备好了吗?

    "CIO必须灵活构建其所在企业的IT系统,深入业务,以应对日新月异的数字化业务环境."   BAT军团"搅局"B2B市场,CIO们准备好了吗? 庞大的企业级市场 ...

  6. XAMARIN.ANDROID SIGNALR 实时消息接收发送示例

    SignalR 是一个开发实时 Web 应用的 .NET 类库,使用 SignalR 可以很容易的构建基于 ASP.NET 的实时 Web 应用.SignalR 支持多种服务器和客户端,可以 Host ...

  7. atitit.attilax的软件 架构 理念.docx

    atitit.attilax的软件 架构 理念.docx 1. 预先规划.1 2. 全体系化1 3. 跨平台2 4. 跨语言2 5. Dsl化2 5.1. 界面ui h5化2 6. 跨架构化2 7. ...

  8. Configure a bridged network interface for KVM using RHEL 5.4 or later?

    environment Red Hat Enterprise Linux 5.4 or later Red Hat Enterprise Linux 6.0 or later KVM virtual ...

  9. 关于Hadoop用户体系的设想(胡思乱想)

    关于Hadoop的用户体系设计设想 Hadoop并没有一个完整的用户体系,其权限控制的对象,主要是Linux的其它用户(即非安装Hadoop的用户),控制方式也和Linux的文件权限很像,目前权限控制 ...

  10. 我的MYSQL学习心得(八) 插入 更新 删除

    我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得( ...