第四章:服务的架构一定有漏洞
2020-01-10 15:41:41 Author: mp.weixin.qq.com(查看原文) 阅读量:53 收藏

第三章:服务的架构一定有漏洞(上)

相较前两章,这一章的内容就相对温和许多了。服务的架构一定会有漏洞,这都是大家心知肚明的事。

反而没什么好吃惊的。

这一部分我会拆成几个章节写。这一章主要是在讲「暴露在外的部分」

状况一:扫描攻击

关于网站的部分,最常见的攻击有几种:

  • XSS 攻击:盗取用户 cookie

  • SQL Injection:存取数据库,捞取资料,窜改数据

  • Directory Traversal Attack:摸清机器档案目录,甚至获取机器权限 等等....

诸如此类的攻击手法,我在这本书里面就不讲得太详细了。

关于此类的内容,在 OWASP 里面有非常非常多的内容。如果你对于这些常见扫描攻击陌生,建议去读读 OWASP 出的一些指南。

http://www.owasp.org.cn/owasp-project/secure-coding

这本书我想讲的是解法、防御。

解法:

这些基础漏洞,主要出自于语言、框架,或者是低阶程序员的疏失。有几个方向你可以进行。

  1. 安装代码扫描工具

我自己擅长的是 Rails 框架上的项目开发,Rails 的开发观念以及第三方生态相对于完善。框架自带 XSS 防御、 SQL Injection 防御、XSRF 防御。如果硬要在里面写出不安全的代码,得程序员硬干 override 才能办到。

至于 Rails 界有一套服务叫 codeclimate,除了扫描代码质量,也可以扫描可能可能出现漏洞的代码。

另外,也有一套服务叫 sqreen,这套服务能充当 WAF,自动阻拦可疑扫描,并且追踪所有 rubygems 的更新与 security patch,当架构上的第三方库太老旧或是有安全疑虑,系统会自动通知开发者需要更新。

  1. 雇用白帽黑客、 资安谘询公司

安装代码扫描工具,可以很大程度防御与过滤一般的「机械式攻击」。

但「机械式」攻击,不是一般互联网服务最大的威胁。而是黑客的「手工攻击」。

机器是死的,人是活的。

如果你的服务非常重要,保卫著许多人的资产。我建议还是雇用正统资安谘询公司,人工灰盒审计(等于是请资安顾问对自己的公司实施各种攻击,找到所有可能性的攻击与脆弱点,出具报告修复)一次。而且这个灰盒审计得定期执行。

状况二:后台攻击

第二种状况,是针对「后台合法攻击」。

什么是针对后台合法攻击呢?我在这里揭露一个事实吧:

许多服务的架构都是这样设计的,后台只可能在两个地方:

  • example.com/admin

  • admin.example.com

命中率高达 99%。

而且呢,在外网就能够存取。

也就是如果你的其中一位客服或员工被猜到密码,这套服务马上就沦陷。而且因为是正常操作,不会触发任何警报。

解法:

首先,这个架构有几个地方需要改变。当然有时候你的财力物力不一定马上可以做到。但起码可以降低相当大的风险。

  1. 改名,换网域

绝对不能叫

  • example.com/admin

  • admin.example.com

你可以叫
example.cc/admin

或者

a.example.cc

至少不那么好猜,以及防御黑客盗到员工 cookie 就能打进来。

  1. 限制存取来源

这里有一个小细节,example.cc 不能是真实网域,得是一个你虚构的域名。唯有修改 /etc/hosts 才能正确的 mapping。

这样避免了被猜到域名,直接在公开网段上被存取得知的可能性。

再来,将该机器限制只能从特定 IP 连线,也就是员工必须要使用 VPN 或者是办公室才能连入。

当然最好的情况是将 admin 放在内网里面,当然如果短时间作不到,这也是一个暂时可以接受的 workaround。

  1. 读写分离

什么叫读写分离呢?也就是 admin 与 public service 是两套服务。public service 是给用户的服务,用户只能读以及有限的改写自己有权限改的资料(比如个人 profile 等等)

而 admin 的代码,是跑在另外一份机器上与另外一份架构上。这些「写」「变更」的部分是与用户接触的服务完全阻隔开来。

  1. Log 机制

因为资料变更写入通常会造成安全性。所以有几个机制需要加入设计:

  1. 网站只能做软删除,而不允许硬删除操作。

  2. 任何操作都要记录 Log,谁在什么时候,做了某事。并打到 slack 进行记录通知。做多重 Log 备份。

  3. 关键操作,需要三重确认,多人签名,放行机制审核。

状况三:数据窜改攻击

大家的服务都是暴露在互联网上的。这里有一个危险但真实的思路。黑客极有可能直接打进 service,合法的用 web shell,操作数据库改数据。

这边我翻译成白话:以币所的情况就是骇客直接改数据库,改成自己馀额有100颗 BTC,然后合法提走。

如何防御这样的攻击呢?

  1. 建立历史变动记录

互联网实做点数与储值系统都是直接更改「最后馀额」。

而相对安全的架构是:将帐号馀额做版本控制,就是经过「合法操作」的加扣馀额都会被纪录。如果当下馀额,与帐号的历史版本不一致,那么这笔纪录就是「伪造的」。

而在进行任何馀额上的合法变动(如买卖,提领,兑换)等等的操作,都必须再次验证过去历史数据是否匹配,若为伪造,该个帐号会立刻被冻结。

  1. 数据验证

分个人与全站。

一个个人有无数笔的帐号版本,但对到最后,应与当下馀额一致。

全站资产,站上也就是比如站上的应有多少 BTC,经过变动以后应该还是应有相对应的 BTC。

每几个小时扫描一次。只要发现异常,立刻冻结与 slack 与简信发出警告。

  1. 建立行为白名单与黑名单

内部风控可以先自我列出什么是「不可能」的「状况」。直接写入风控系统。

比如说「注册一两天」的新帐号,立刻要提领超过 10 颗比特币。(洗钱或盗号嫌疑)

或者已经超过 60 天没有登入,突然间登入,登入后两分钟内马上要提空馀额。(盗号嫌疑)

真实状况不是不可能没有。只是看起来「可疑」。

而这一类的「可疑行为」。一律 delay 动作或冻结,进人工审核处理。

针对站上的用户,建立分级评分机制。按照风控分数自动锁定与放行。

状况四:服务器被入侵潜伏

有一些黑客,入侵服务器后,并不急著马上「下手」。

而是潜扶在机器里面,跑后门。「传资料」回去,这些资料包括但不限于「数据库密码」「使用者数据」「其他机器的 ip 清单」「管理员的密码」等等等等….

有几个方向可以防范与侦测:

  1. 不正常的流量

数据库往往非常庞大。为了将数据库运走,往往会产生「不正常」的流量与使用量。

  1. 防火墙白名单

只准机器被连某些 port,而不准机器连外

  1. 管理员登入 log

管理员登入机器,必定发送 log 到 slack,且 cc 管理员群。

  1. 使用「容器」部署

一台机器如果你发现被入侵,虽然没有造成实质损坏,但这一台服务器绝对不能再上线。以免有什么你不知道的后门等等。

比较好的方式,是一开始就用容器如 Docker 架构部署。机器从 OS/ 套件 / 代码都是 script 自动拼组而成的。

而不是手工安装的。摧毁被污染的服务器时,成本才不会过大。

状况五:以前已经修好的 bug,某次代码修改后又不小心打开了

一个互联网服务是活的。我们不能强求一个服务是绝对安全绝对没有 bug 的。但起码要是相对安全的。

有一些状况是之前这个 bug 被修复了。但是在几个月后,因为其他机制的引入,bug 又被打开了。

这里你可以引入一个架构概念,叫 security as test。就是写 integration test,将入侵手法的行为写成 test。确保代码更动时,这个 bug 不会被触发。

总结

关于架构的潜在问题还有很多,在此我只列出最常见的五个情形。

这里面的思维我想强调一个概念,就是绝对的安全是不存在的。你的程序员也不可能阻挡所有的攻击。毕竟程序员的思路主业是「建设」。黑客的思路主要是「破坏窃取」。

而攻击往往比较简单。而身为架构建设者,在规划改善这些架构时你的思路应该是,我如何用 20% 的精力,做到 80% 的风险管理。

所谓「风控」,这个字包含了风险管理和风险控制。

风险管理,它是指如何在项目或者企业在一定的风险的环境里,把风险减至最低的管理过程。它的基本程序包括风险识别、风险估测、风险评价、风险控制和风险管理效果评价等环节。

风险控制是指风险管理者采取各种措施和方法,消灭或减少风险事件发生的各种可能性,或者减少风险事件发生时造成的损失。

这里总结一下你现在可以主动做的事:

  1. 如何大规模的技术性降低风险?你可以安装什么服务,一次性大幅上升公司的防御能力。

  2. 如何避免「一个人」被渗透,就会产生大规模的损失?关于人类的弱点是什么?

  3. 最脆弱的数据环节在哪里?如何自动校验这件事?

    如何自动化防范过去的错误不再发生。

第四章:服务的架构一定有漏洞(下)

上一章讲的多半是关于直接暴露在外部用户的架构。

这一章我们要讲的是内部的架构。我会直接以一个区块链交易所作为例子。说明如何设计「相对安全」的架构。

系统关键脆弱瓶颈,改造成 API 导向

以一个区块链交易所,最脆弱的瓶颈在于以下几点:

  • 用户提币

  • 交易上链

  • 钱包存取

  • 用户存币

在前面一章的状况,我已经说过骇客常见的手法就是窜改数据库,直接假造馀额,进行提款。

关于这一点,其实可以用校验馀额与用户分层行为风控避掉。

比较危险的真不在这一环。而在于更后面的几层环节。

冷热钱包设计

现在坊间币所都夸耀自己有冷热钱包设计。其实这已经是目前标配了。

什么叫做冷热钱包设计呢?

区块链币所的原理是:

  1. 存币是扫描区块链帐本记录,扫描到用户专属钱包地址有存款动作以后,相对应的在数据库上记上一笔。

  2. 提币是发起提币后,通知币所的热钱包,要提币走人,发起提币。

用户专属的钱包与币所的热钱包,不是同一个钱包。

你可以想像成用户专属的钱包就如同存款机一样,你是把一千元存到机器里面。然而,你可以转身到街头的分行,找柜台,再把这一千元提领出来。

风险在哪里呢?

用户可以在存款机存了假钞 1000 万,然后去银行柜台说他要提 1000 万。

在早期很多币所,只有一台 web,连钱包都放在同一台 web 机器上。黑客甚至不需要改代码,只要在 web 机器上调用提款指令,整间币所的钱就被提走了。

你想,这么蠢的事情怎么可能发生呢?嗯,业界还挺多人是这样的设计的…..你在网上看到的那些新闻,嗯….

这些币所的设计很呆,基本上就是一支机器人,定期归集去用户的小钱包,将钱搜集回来,都堆到银行柜台里。然后抢匪只要去银行柜台假装自己要提款,或直接抢钱,就可以把银行抢空了。

这种真实世界不可能发生的情况,却在业界里面很常见。

当然,这样就被搞到破产,实在太好笑了。所以后来大家改了架构设计,变成机器人去搜集用户的钱,然后通通存到冷钱包里面(可以想像成金库),然后从金库里面只拿 1/10 的钱放在柜台里面。

这样就算柜台被打劫一空,顶多也只是损失 1/10 金额而已。

这就是冷热钱包架构设计的简单版本。

关于钱包的进阶设计,我们会在后面其他的章节深入探讨。

Ask, Don’t tell

刚刚我们说到了提款这件事。很大的危险在于 Web 服务与钱包放在一起。

所以这里我们必须引入第一个概念。Web 服务不可以直接直通钱包。目前区块链钱包都是走 RPC。也就是提款的方式,是 web 机器直接对钱包发一个指令通知要提币。

这个方式很有风险。比较好的方式应该是:

  • STEP 1: web 只能跟「提币 Service」请求需要提币,而不是直接「告诉钱包」要提币。只有「提币 Service」可以跟钱包对话,必须「提币 Service」批准提币,才可以将请求上链。

  • STEP 2:提币 Service 要自带风控功能,也就是异常金额提币,必须直接在这层直接被阻断或 delay。

  • STEP 3:提币不可以是请求一次就发送一次。应该至少累积一定次数 50 次,或者是至少 10 分钟- 20 分钟,批量放行。以免黑客或洗钱洗币份子的行为无法被阻挡。

  • STEP 4:黑币钱包地址自动进黑洞。所谓黑币是只有一些资金,是黑客盗币所所得。币所都有联防系统,只要地址被加入黑名单,存款与提款行为,都会自动失效。

  • STEP 5:非热门时段,主动降低提币速度与提高风控层级。我们是亚洲币所,服务时间很集中都会再 +0800 的特定时段。如果有大额提币发生在冷门时段,这些提币应该要被 delay 到上班时间由人工介入处理。避免重大损失。

所以这里的概念,主要是不能「用户告诉你什么,就执行什么」,而是得向「风控系统」「申请通过」,而且利用「批量审核」做出时间差,若有什么差池,有机会挽救。

大额存币控管

前面我们讲到的是提币风险。其实存币也有风险。

几个业界曾经有出现的状况是:

  1. 洗币。用户大额存币并同时大额提币。害交易所背锅。(以前 EOS 就考虑要对经手黑钱的钱包进行冻结制裁,被许多交易所反对。因为如此,锁到的不是黑客,而是交易所的钱会牵连被冻。只经手 1000 EOS,结果 100 万 EOS 钱包被冻,也太倒楣了吧)

  2. 智能合约攻击。有一些 Token 的智能合约没有写好。合约 owner 或甚至路过 user 可以任意增发。充进交易所砸盘换取其他币提现。

  3. 51% 算力攻击。前一阵子行情不好,有心人针对某些币发起 51% 算力攻击,制造大笔假交易,充入币所,再提款。

  4. 币本身的 security 问题,许多币都是 opensource 软件,而且只有少量业馀程序员维护(甚至活跃的维护者数量都比起一般正规币所的程序员少上许多)。bug 一堆,而这些 bug 可能会造成假充值。黑客发现这些 0day 以后,往往没有兴趣攻击一般 user,而是直接攻击交易所。如果交易所的钱包工程师,没有时时更新钱包,很容易被盯上。

好在这一类的情形都有一些特征,就是

  • 针对交易所

  • 单次大额

  • 冷门时段

所以交易所的防御只是辛苦,但不那么复杂。

可以从两个方向去防御:

1) 审核大额存币

大量存币直接 drop / delay,或者是直接打入可疑款项。

以我们站上的情况,除非是经常交易的大户。否则很少人有大量存币的情况。也就是在风控上就要针对用户分层。

如果是不常交易的用户,突然间存进大量币,然后马上就要交易或提款。这绝对非常可疑。关于提款与交易行为要先全部暂停。

2) 加入由资安谘询公司的币所联防联盟

我们公司的资安顾问是慢雾安全。专注于区块链生态。

加入这一类资安公司组织的联防联盟有很多好处。首先是其他币所要是被入侵了。类似的入侵手法,会在脱敏后,告诉参与联盟的会员,所以第一时间这些洞会被补起来。

第二,洗币地址是共享的。联盟内交易所能够整合,第一时间自动防御。

第三,建设一个互联网项目,大家都有一些共用插件(如 TradingView),或者是底层 library ,或者是币本身的 0day。

资安公司会主动跟踪,告知,甚至发布自己的临时 patch。省去自己追踪的精力。

Application as Service

在这一章节里面,我提到的属于区块链行业的示范。其实同样的思路适合互联网上大多数行业。

这里的思路是你的思路整个架构都应该解耦合,不允许一个系统可以 command all。

也就是某些业务模块在逐渐成熟之后,应该单独抽出一个 service,用 API 形式呼叫,并且加上权限校验。

不管是使用者的 App 与系统沟通,或者是内部系统与系统之间的沟通,都应该使用 API + ACL + persmission management。

当然,经营这件事最挑战的事在于。区块链行业是一阵风,在一年内吹起,明明所有竞争者都是初创团队,需要用初创团队的极速打法。但是架构设计上却得用 5-6 年成熟互联网公司的成熟安全架构。否则只要一不留神,币所都不是没生意倒的,而是被黑客黑倒的。

所以虽然业界有万间交易所,但是最后真正能存活下来的交易所并不多。主要这个赛道真是综合能力的考核。如何兼顾币所的业务以及开发速度以及风控上的防御。更别说在人才招聘的速度与品质。这才是区块链从业者的考验。

总结

这里总结一下你现在可以主动做的事:

  1. 立刻加入签约一间资安公司。资安公司不是你出事时才要找。还没出事就得先找好。请他们立刻帮你做体检以及架构调整。

  2. 团队自我检查找出脆弱瓶颈点,改版成独立 service,并加上风控设计

  3. 对自己的项目解耦合。不能预设内部节点的操作都是可信的。而是如果都不可信,怎么样设计出合理的白名单。


文章来源: http://mp.weixin.qq.com/s?__biz=MzUyNTk1NDQ3Ng==&mid=2247484927&idx=4&sn=f173a8b254d06b7a71b919404db2ff4f&chksm=fa17793ccd60f02aad2b729619759d67ebe40ab41acef1f6e80b1bde8ade601a6d1341572935#rd
如有侵权请联系:admin#unsafe.sh