第一章: 用户的密码一定会被盗
乍看这个标题,非常耸动。
但是,我却得无奈的说出这件事实。这个情形不但是事实,而且一天到晚在区块链世界里面发生。
区块链行业无异是当今黑客眼中的肥羊。
因为在这个行业,黑客实施攻击的成本与其他行业可能是一样的,但是投资报酬率却可能是最高的。
「用户的密码一定会被盗」,已经是我们做这一行安全架构时,会有的「假设前提」。
问题是,如果用户的密码一定会被盗,你还能如何防御用户的身家财产安全。
什么是「撞库」?
「撞库」这个词,目前在资安界大家已经非常熟悉了。
这个词的意思是「撞库是黑客通过收集互联网已泄露的用户和密码信息,生成对应的字典表,尝试批量登陆其他网站后,得到一系列可以登录的用户。
很多用户在不同网站使用的是相同的帐号密码,因此黑客可以通过获取用户在A网站的账户从而尝试登录B网址,这就可以理解为撞库攻击。」
每个用户一生一定会用过很多不同互联网服务,然而,因为基于人类的惰性,很多人用的都是同一套密码同样使用在不同的服务中。很少人会针对不同服务,使用不同套密码。更别说自己养成安全意识,使用「1Password」之类的密码管理软件,这通常只有一些高阶用户或者是程序员才会有的习惯。
而负责开发服务的程序员面对「撞库」这个问题的解决方方很单纯,总会脱口而出:「那我们教育用户 1Password 管理密码」,或「提醒他们要定时换密码」不就得了。
这其实是一个过于单纯的思维。
所以身为防御方,在设计架构时,你得换个思维:不是防止黑客开第一道锁。而是让黑客意识到只破第一道锁是图劳而功的,要取得真正有价值的信息,得过至少三道锁。
防护手段一:二步验证
二步验证是现在互联网服务里面,正规军必备的一道验证。
我们可以这么比喻,密码很像是印章,拿到密码就如同印章一样。但是真正取钱,你还是得让用户签名。
这个签名,就是所谓的二步验证。
二步验证有几种方式,常见的有:
这个方式,是确保「用户背后为本人」的一个常规手段。
不过,这个方法只适用于一般不敏感的互联网服务。
如果你经营的是区块链交易所的话,建议还是不能单纯只用「手机号码短信验证」验证。因为这种方法有一些其他的风险性在:
比如说用户被不肖份子锁定,手机信号从 4G 被降到 2G,被拦截短信盗号成功。
用户的手机被同事拿走,接收短信,假装是本人
当然你会问,那换 Google 演算法就会比较安全吗?
其实也未必。我曾经听过交易所界一些很普遍被打进去的案例:
交易所的数据库被从网站上开后门,黑客改不了数据,但能读数据。而这些交易所关于 Google 演算法的二步验证的用户种子,是明码写在数据库里面的,Google 演算法是公开的,所以黑客一样可以算出真正的通行密码。有加密等于没有加密。
防护手段二:IP 阻挡与第三方验证
这就让我们引到了下一个手段,三步确认用户行为。
使用者的密码虽然是有可能撞库被泄漏。
但是还是有办法去放缓黑客的攻击的。
1. IP 验证与尝试次数
黑客用的多半是跳板 IP。所以 IP 要不是从奇怪的小国过来,就是会与用户平常惯用的 IP 非常不同。
作为系统防御者,你可以设置不同 IP 尝试错误次数超过3-5次,就自动发短信警告用户。黑客就算尝试登入成功,因为来源 IP 网段不同,还是要通知用户有不同 IP 灯入。
再来,你还可以加入一道降速手段。密码正确之后,还要加入一道图形验证码,防止用户被程序自动攻破。
而如果用户真的被成功登入,进行关键敏感操作(如提现或提币),必须在系统设计上间隔 2-5 分钟以上才能操作。
并且提币这个动作要有第三道确认(如邮件确认)。
这是为了争取让有些用户,有时间差可以反应阻挡攻击。
2. 第二道密码以及通知用户确认
业见比较有名的例子是:支付宝在设计上,有分登入密码,与取款密码。
这也是防止用户因为一道密码与设备被连环攻破,会带来的连环损失。
在币所的实务上,在取款最终步时,在用户最后的取款流程,我们也会加上 email 确认,确保用户是经过至少四道以上的确认是本人,才能进行金额上的操作。
3. IP 切换,cookie 立即作废,自动强制登出使用者
除了盗取用户的密码外,有的服务,是用来钓鱼使用者的 cookie 的。
这有一些手段你可以主动用来防御:
一个帐号只能同时有一个 IP 登入
当 IP 切换立刻会被强制登出
cookie 在登入后几小时候,没有动作,也会自动被登出
确保这些 cookie 即使被偷了,也不一定有用。
有一些服务,系统是提供 API 操作的。比如说有些币所支持量化交易,用户可以用 Token 就可以操作交易以及提币。
与 password 外泄的情况一样,你也要假设用户的 Token 一定会外泄(因为该用户可能使用同一把 Token 放在不同的交易软件上)。
这有几件事你可以做:
这样可以避免用户使用「看盘软件」放 Token 时,就把自己帐号交出去。
早期像 poloniex 的 API token 就是没有分权限的。iOS 上的查询馀额软件会要求你给 Token。
你如何知道这些馀额软件会不会作恶?你不能知道。也不能禁止用户交 Token 给它们。
但你能做的,就是帮用户先把一层关。
量化交易操作,多数是小额进出。少有大额交易发生。有一些交易是这样的,黑客黑进帐号后,不是将币提走,而是换个交易对,砸盘套利,再到其他交易对大幅拉盘,让其他帐号获利然后转帐提款。
API 的操作往往都是有固定行为的。如果该操作不是「正常行为」,系统的风控应该要自动拦下。
当然,为了不干扰正常用户。可以主动让用户分层。比如说 LV1 的用户的交易,每天交易额是多少。LV5 的用户的交易,每天交易额是多少。
而 LV 的设计,可以是保证金,可以是使用天数,可以是经过考试。让 LV 越高的用户,通常也有越强的自我保护意识。
API 端点也是容易被 DDoS 与身份盗窃的重灾区。
所以 API 在设计上应该要设计 rate limit,与请用户设计 IP 白名单。而不是任意的 IP 就能存取。这样才能保证是用户授权的客户端操作。
每个互联网服务储存的用户价值性都不同。
有的互联网用户资料有价值的部分只有「密码」,有的是「个资」。
交易所之所以是黑客眼中的肥羊,是因为交易所有里面用户的「个资」与「资产」。
黑客会向交易所攻击的部分:
针对单个用户:想办法拿到 KYC 资料,以及提走币
针对交易所:想办法拿到大量 KYC 资料,变身为用户领走资产,改交易所数据库合法提领资产,偷 Token 假装是用户直接操作转出等等等等...
所以当在施行防护措施时,开发者得去思考,一个用户在站上的价值资料在哪里。
如何让真的「本人用户」能存取到,而只有「密码」却什么都存取不到。或者是虽然拿到「Token」了,能操作的权限却非常有限。
我认为这是开发者最先要去思考的第一个课题。
如果「使用者的身份识别」一定被偷走,那么你要如何让损失降到最低?
或者是退而求其次,若是用户帐户被盗。站方与被盗用户,都还有时间差能够有机会阻挡攻击。
上面我们谈的都是被动式攻击。
但事实上,我们做的可以不只有被动,而是可以主动设计防御措施。
因为目前黑客多半不是手工作业。而都是自动作业。而且是非常精密的全自动作业。
通常黑客的攻击手法是分几阶段的:
这方面粗步的阻挡有几种方式:
就如同现在在提款机上的警语,警方往往会在提款机上面贴上标签,若要用户大额转帐,请小心是骗子。
你也可以在提款介面,API Token 申请介面,Email 邮件,等等这些「接触点」。
进行用户的再教育。提醒用户可能会出现的情形,避免用户被一系列的诱导,交出自己手上的钥匙。
这里总结一下你现在可以主动做的事:
第二章:服务的代码一定会外泄
我们第二章这个标题,这就更耸动了。说实在,天下真的没有不外泄的代码。代码外泄的原因有很多:
等等等等。各式你所想像不到的情形。
代码外泄有多恐怖呢?
原本黑客攻击你的服务,是要不断的用工具猜测弱点的。拿到弱点以后针对不同情况,手工夺取权限。
如果黑客能拿到代码,就可以省下巨大的研究精力。
单纯泄漏代码,还不算是最危险的事。
泄漏代码最大的危险性是:当今互联网上大把从业程序员,为了开发方便,直接把密码写进代码里面。而且还「上了版本控制系统」XD
也就是这些密码一旦进版本控制系统以后,就擦都擦不掉了。当黑客黑进 Git Repo 之后,能够循线找到一大堆被写死的第三方密码。
外泄程式码,情节往往不是最严重的。
因为一个互联网服务,一定是配套的:
代码 + 数据库 + 第三方服务
只拿到代码库没用。得同时拿到「代码 + 数据库 + 第三方服务」,整套服务才 work。
但是如果公司的程序员偷懒,把存取数据库以及第三方的金钥通通都写进代码库里面。当代码一旦被盗,暴露的风险就会无限的大。
前一阵子,B 站就曾经发生一个事故,他们的代码不知道是被黑客还是离职员工拿到。直接被开源在 Github 上面。
https://news.sina.com.cn/o/2019-04-22/doc-ihvhiqax4456543.shtml
撇开 B 站的代码风格不说,光一堆敏感密码被写死在代码里面。这件事就成为技术圈的笑柄。
所以说并不是只有初创企业没有经过训练的互联网程序员会犯这样的错,连美股上市互联网公司的代码,也会有这样的问题。
解法
你可以做的方式是:将密码变成环境变数,本地用本地的环境变数,测试服务器用测试服务器端的环境变数,正式服务器用正式服务器端的环境变数。
至少将代码、数据库、第三方的连结切断。
程序员在本地也只能调用测试环境的数据与服务,即便员工离职带走的,也只能是代码与测试服务的权限。
这样能避免:
黑客攻击系统,分两个思路:
攻击系统本身
攻击人本身
攻击「人」往往比较好下手的。
早期 Github 并没有强制大家绑 2FA 帐号,所以很多开发者,是没有绑 2FA 验证的。
反正就是写写小工具,还要绑个 2FA 也太蛋疼了。直到这些程序员变老了,变成...架构师,CTO...。
但是他们还是没有对 Github 绑 2FA 验证。这时候问题就爆发出来了,一个拥有最高权限的技术开发人员,他的帐号是没有加密的。
这样黑客只要针对这个帐号做社交攻击就好了。而这些 CTO 的私人 email 甚至不是保密的,而是写在他的 Github Profile 上。
与其撞库这么多用户的密码,不如直接去撞库 CTO 的密码,更加的划算。
这是一个相当致命的脆弱瓶颈。
另外,还有一个场景,就是 CTO 本人是有安全意识的。但是公司的程序员没有,所以即便 CTO 本人把自己的裤子抓的紧紧的,其他程序员还是一样没穿裤子在外面走来走去。
大部分的互联网项目,都是用 Github Team 的的方案,Team Repo owner 有 2FA 没有用,只要 Team member 有一个人没有设,他就是可能的脆弱瓶颈。
现今黑客都比较聪明,思绪是先拿到一份公司的 email(可能是 slack,可能是其他服务,预先拿到所有帐号的名单),再一个一个进行撞库攻击。总能打穿一个。
解法
对所有的公司服务,一律开启 2FA 验证。
不管是 Slack、Github、Trello、Redmine 等等。一律打开 2FA。
因为攻击资浅程序员,投资报酬率,远远高过于攻击一个普通用户。
Github 在程序员界可说是无人不知,无人不晓。几乎每个互联网公司都会使用 Github。
但是,我得诚挚建议各位业界朋友,如果你的项目与资产有关,建议你还是不要把代码放在 Github 上面。
为什么呢?
再来,除了 Github 之外,还有一些地方,程序员是会上传代码上去,并且 Grant Access 的。
比如说自动跑测试的服务,有些自动跑测试的服务,能推送代码上正式服务器。。。。
还有一些自动检测代码整洁度的服务,这些服务也能拿到你的代码。
解法
如果你的服务尚小,也暂时没有什么攻击价值的话,还是可以安心的放在第三方服务上。毕竟你没有本钱自己再独立维护一套代码管理工具。
如果你的服务变大,或者你的服务是有金融价值的话。
你应该考虑把这些服务转成私有企业化版本,部署在自己的内网,而非租用公开服务。
若这些服务有特定意义,暂时无法私有化。也得尽量至少对所有雇员上 2FA。若该服务不提供 2FA,请直接搬离。
现在很多公司,是直接发给程序员笔电的,方便在家办公。
虽然发生机率极低。但是程序员的笔电掉了,相关的信息也可能外泄。
或者是程序员离职不想要归还这些电脑。
这样的解法是发给程序员的电脑,一开始就是由公司设定,并且公司端可以追踪这些电脑上的位置,以及抹除这些电脑上的信息。
这里总结一下你现在可以检查以及主动做的事: