« 那些日子(终) | 返回首页 | 关于 openGL 的 4444 贴图 »

防止中间人攻击

去年,几个游戏组的同事给我描述了他们发现的针对游戏的中间人攻击(MITM attack)。有人做了一个代理服务,种植木马到用户机器上,使用户机器对游戏服务器的 tcp 连接都重定向到代理服务上。(这个步骤其实不一定在用户机器上做,网关和路由器上都理论上存在被做手脚的可能,这是用户自身无法保证的。

代理服务可以一直监听用户到服务器的通讯,直到认为认证过程结束,不再转发用户的数据,改由自己操作用户的帐号。这样就可以达到转移用户虚拟财产的目的。

今天,和几个同事讨论了这个问题和解决方案。

之前,游戏部门的同事已经做出很多改进,增强了通讯协议的安全。但仔细分析后,我发现还是有些漏洞,想总结一下,找到个更安全的方案。

先列出一个简化版的协议,后面再讨论其中的问题:

  1. client 产生一个随机数,用 client 和 server 共知的秘密(在这里是用户密码和将军令产生的 OTP 一次性密码),加密个随机数,发还给 server 。为了保证 server 能认可这个结果,还需要附加一个校验值 checksum 共同编码。

  2. server 解出一个随机数,校验完毕后,以此为通讯密钥,建立一个加密信道,和 client 保持通讯。

在这里,由于中间人不知道 client 和 server 公有的秘密,而这个秘密又没有在通讯中传递,所以它只能充当转发人的角色,而不能监听和伪造双方中的任一方。


这里存在的问题:

网易的将军令产品(以及市面上的类似产品)能产生的 OTP 长度有限,是 6 位 10 进制数字,大约是 20bit 左右。如果把安全寄托在 OTP 上,强度太低。

因为协议中的握手过程,大家需要相互认可,这个认可标准是不受保护的。唯一可以利用的是事先约定的秘密。中间人完全可以截获握手过程的一切通讯,然后离线暴力尝试,以这个握手成功的标准去找出 OTP。当 OTP 的强度只有 20bit 时,在很短的时间就可以试出来。而 OTP 的有效期可以长达一分钟,是很难理论上杜绝这种暴力攻击的。

我的建议:

第一,可以使用 RSA 这样的算法,把共有的秘密转移到 RSA 的 key pair 中。这样就有了 128bit 甚至更高的强度。RSA 的 public key 可以有更多的方案发放到 client 中,所以理论上可行。问题仅在于 RSA 等不对称加密算法运算量太大,仅靠软件实现时,有可能服务器承担不起。

第二,我们降低 checksum 的长度,不超过 8bit 。这样,不只合法的 OTP 会满足这个 checksum ,还会有大量的 fake OTP 也满足 checksum 。中间人在穷举的时候会拿到大量 fake OTP 。按 OTP 一共 20bit 计算,大约有 2^12 约四千种可能。由于 OTP 有一分钟的生命期,只需要限制在这一分钟内允许尝试的次数(比如说 4 次),那么,单次握手,被试出的可能性就只有千分之一了。在此基础上需要进一步限制同一 ip 对任意帐号的尝试频率。可以提高安全性。


有道 的周枫在我们讨论的时候找到了一份 ppt ,其中 16 到 19 页讨论了类似的问题( Page 16: How to set up a strong, shared key, given only a short OTP ),可供参考。

Comments

@zhuzhuor 基本同意你的见解
是不是可以用低强度的rsa密码,虽然高强度的不好运算,低强度的应该可以吧?
请问我在一个ACTIVE X控件里面如何获取初始化我的客户端的ssl证书,非常感谢
一定要保证加密的key从其他途径被双方获知。比如使用密保卡的答案进行加密,在很多实际应用中,用户都不一定喜欢购买实物的卡。那么另外一种做法就是在注册用户时就给定一个授权文件,没有授权文件时就要通过邮件来发送了。这样唯一的不好的地方就是网吧用户每次都要去邮箱下载这么一个文件。但对于固定电脑用户,已经非常安全和实用了。 还有一种做法,就是让客户端都不一样,在安装成功时就从服务器获取通讯的KEY,这样黑客必须在安装游戏客户端时就一直处于嗅探状态,明显是不容易的。
其实这种加密方式有什么意义呢? 客户端代理服务器 中间的任何数据都经过代理服务器 如果知道加密手段,你们采用的任何加密都是无效的. 这些key必然都会被代理服务器所截获
我反而觉得对于国内的网游,最大的不安全因素是server开发人员的rp,其次才是采用何种技术防hack。毕竟网游的客户端不可能任何东西都用高强度加密的。
编程是为了解决问题发展起来的技术,问题的解决方法不止一个,加上各门各派手法不同,思想不同,甚至是哲学上的不同,所以千变万化 差不多就是“每个魔术师的施法手段都不同”的意思 写程序可能需要一些天分,但更多的是要多学多练多实践。一点也不神秘
To Hermit: 记得大概4年前,面试网易的时候,dingdang跟我说,游戏测试和开发,差很远的。这条路,恐怕很难走。不过细节我也不清楚了。
关注云风大哥的BLOG对自己而言能获取更多精神上的激励,同时也能见识到自己未曾接触过的知识点。 to Hermit 云风大哥概要的说是“一点点积累的”是很重要的一点的。先不说编程仅仅是计算机技术里的冰山一角,单就编程里本身就是包罗万象,何况具体到与实际应用挂钩时所涉及的细节问题更是千变万化。云风大哥对于每个关注他BLOG的朋友的问题解答讨论自然是无力面面俱到的。很认同 七生 说的“程序員還是比較提倡獨立思考,自己先做功課,勤用Google,多編程实践。有一定思考沉淀及理解水平后的討論,才能對雙方都有助益,思維碰撞產生火花,也才有興趣繼續下去。” 学习的途径很多,关键在于自己是否能静下心坚持下去,兴趣只是个开始。可以通过一些专业或著名的相关书籍自学,也可以根据自身目前的水平来决定参加一些专业学习机构的培训学习……一路下来依旧是个“积累”的过程。 留言下来,也是对自己的一种鞭策:-)
七生说的很是在理啊! 我建议Hermit mm给云风发邮件或其他个人的方式讨论问题,毕竟blog不太适合讨论主题之外的问题
@七生 谢谢。^_^ 理解了。然后我就去找这本书吧。
哦,看出来了 Hermit是MM
笔记创建于2008年5月23日 08-5-23 很多人都在看云风的blog,我也跟了很久。 一开始的漫不经心,到对感兴趣,到心驰神往,云风的职业精神确实不经意间影响了许多人;譬如Hermit、sboy,我等等。除了对前辈的敬仰敬佩外,更多的想去做一个新的云风。 不过,道路总是一步一步走出来的,就像云风所说是一点点积累的 。不过对新手们来说,这太抽象了,缺少了理想中的五颜六色,缺少了武侠中的奇招妙式。我想高与低的差别,也许就是这份积累的耐性与坚持。 与那些迷茫的旅者们共勉!
如果使用RSA算法,1000req/s 的认证请求对于现有的服务器来说几乎是完全不能承受的。 云风说的关于OTP算法挺不错的,不过可能会有点缺陷。限制同IP访问多帐号是不可行的。因为大量的网吧,还有小区网络很有可能是共享IP的。
为何不直接使用成熟的免费的OpenSSL?因为通讯计算的开销太大?
@zhuzhuor 网易通行证用的用户密码是不安全的。可以不和 OTP 联合使用,单独用在网易别的服务上。所以我们认为最坏情况它是不具保密价值的。即,考虑其最坏情况:敌人已知其自设密码。 我指的 RSA 运算量大,就指交换密钥的消耗。 网易游戏至少需要满足同时 10 万次的认证请求。即使摊在一台服务器上,依旧需要满足 1 秒内至少 1000 次的认证请求。这在软件实现时负担很大。 另外,要求 client 以自己 ip 做 key 是行不通的,client 往往不知道自己的准确外部 ip ,尤其是在不安全的环境中。
Hermit,程序員的世界并無那么多浪漫幻想色彩,你用平常心對待吧,你帶入的情緒會讓程序員們感到有點莫名其妙的。無責任推薦你找「计算机程序的构造和解释」這本書來看看囧 至于提問,程序員還是比較提倡獨立思考,自己先做功課,勤用Google,多編程实践。有一定思考沉淀及理解水平后的討論,才能對雙方都有助益,思維碰撞產生火花,也才有興趣繼續下去。云風所說的積累也許是這個意思。 程序員只是懶于做重復無效率之事。對于技術討論者是不會故意有什么偏見的。你不用多心。
路过.. 1. 如果这个木马已经种到client机器上了,那说什么也没用了 2. 如果enemy只能在router上做手脚的话: 2.1 如果router上想搞恶意破坏的话,根本用不着重定向,只需要drop掉client或者server的包就可以了,这个没辙 2.2 如果router上还想对client的帐户资产动手脚的话: 2.2.1 如果client与server之间的数据包没有加密,router能解析得到包的明文的话,同没辙 2.2.2 如果client和server之间的通讯都加密的话,就算router重定向走了,别人没有这个session的密钥的话还是不能继续冒充client和server通讯 于是就遇到了client和server的怎么共享秘密的问题 我觉得直接client的帐户密码+OTP就行了 OTP1分钟变一次,再加上client密码就很长了,暴力破解也要把client用户密码一起破了吧 你要是说client密码router知道那我没办法... 你所说的这个里面好像还稍微有点密码学的authentication的问题 http://lab.zhuzhu.org/download/authentication_protocol.pdf 这个是我们上课时候的课件,你可以参考参考 其实会被冒充的关键在于通讯的过程中没有加入client和server不能冒充/抵赖的信息 简单的,比如server可以要求client把client的ip信息作为密钥的一部分,这样router想冒充都没法冒充 再复杂一点的,可以把client的操作系统型号,什么mac地址啥的一起hash一下作为初始认证的信息 认证server的话可以用ssl证书,很方便 另外澄清两个概念: 1. RSA不是用来通讯的,SSL(https)通讯的时候也只是用RSA之类的公钥密码协议传输个初始密钥啥的,之后的通讯过程还是用AES之类的对称密码协议 所以RSA根本不会占用太多的服务器资源 2. to wulf:这些认证握手的过程完全在底层,用户还是照常只要输入自己的密码就可以了,用户体验不会发生什么变化的
我很向往游戏制作这个行业,向往到我不想去读研究生,只一心想进入这个行业,到云风手下做事。只是我不知道我是不是会有这样的机会,有没有这种能力来实现这个理想。我不知道网易明年会不会到武汉大学来招聘毕业生,也不知道招聘的话我会不会通的过。但是我想,只要有兴趣,只要有这个爱好,应该可以的吧?非常希望能够得到你的指点! 我现在还是非常迷茫的。如果我不去做游戏,我就只能去考研,在我们那个专业做程序。我一点都不觉得有趣,因为我觉得一切简直都是太傻瓜式了,什么东西都是现成的,做好的,运行效率啊什么的根本不谈。就这样,我想优化什么的就不可能,因为毫无必要。反而用户会因为你耽误了工作进度而抱怨。我不想这样,我觉得自己也是个在技术上追求精益求精的人,所以我非常佩服云风,我希望能够循着前辈的脚步继续走下去。我不知道前途是怎样的,但是我觉得只要有希望,我就会努力的。 我个人是个领悟能力比较强的人(在我们专业可以这样说吧),但是掌握的计算机知识和本领与云风比起来那就是原子核与原子的比较。但是我觉得原子核占据了原子几乎全部的质量,只要肯学,没有什么学不会的。当然我觉得如果能够在这样一个大团队里面工作,那将是受益匪浅的。同时,作为一个程序员,得忍受孤独和寂寞,但是我相信我行,因为我热爱这个行业。 作为一个迷茫的旅者,我希望已经到达目的地的王者能给我一些教训来指点迷津。非常感谢!
拜读大作,有一处不太明白: 20BIT的比特流是如何生成8BIT的checksum的?生成同一个checksum的比特流之间有没有明显的关系?如果server认可一个checksum的话,是不是有其他的OTP可以被认可啊?
首先,我仅有大学理科c语言的基础,而且是四年以前学的。 其次,我现在在做游戏测试(黑盒)。 我的目的(由低到高、由近而远): 1.设计测试用例时,能根据时序和逻辑进行设计。 2.测试执行时,能判断bug属于客户端还是服务器问题,是数据传输还是逻辑错误。 3.游戏项目后期黑盒测试不重要时,能理解和执行他人设计的白盒测试。 4.理解游戏服务器/客户端架构以及其它必要的知识。 5.策划设计时,创意想象不至于过分超出程序实现范围,能给与没有逻辑错误的流程图。 6.能编写简单的小程序(比如excell里的宏),能提出表达准确的自动测试需求。 …… 鉴于对于程序的理解过少,以上表述可能有误。 请前辈们指点。
云风,我也问过你的。 可能当时我的问题没表达清楚。 所以你就回答:我是一点点积累的。 在我看来,这个回答很好,也很不好。 我真的不愿意相信被你对程序的热情所渲染的我,会被你拒绝带领进入这个神秘神奇的领域。 对于门外汉的不屑吗?或者别的……比如自己太忙、没有时间回答我的问题。 仍是会在工作间隙,慢慢去了解这个广袤的领域,也在一直关注你的blog,持续吸收着你对于技术的热情和执着。 其实,只是有些郁闷了,或者自卑:可能某些人认为mm学程序语言太扯淡了吧…… 好吧,大家可以说我情绪化了,不过请指点一下,也请不要打击我对于这个领域的好奇和好感。
我对程序非常感兴趣(源于工作需要、程序本身的神秘感、优秀程序员的热情的渲染),不知道为什么,我咨询做程序的同事,或者是认识的程序员,他们都不乐意积极回答我的一些问题。 也许是我的问题太过幼稚了,或者我现在学语言已经晚了? 我在游戏业,做过策划、做着测试,名校理科出身,有必要也有IQ基础去接触程序;加之有兴趣和耐心……嗯,可以排除“我没必要学语言”这个说法。 可能我的问题的确是太幼稚了。 …… 好吧,我自己顿悟了,偏硬件逻辑的,或者偏数据结构的,反正先都拿来看,自己慢慢摸索吧。 —————————————— 我只是很不理解的是:我认为这个领悟很神奇,而这个领域的人拒绝带领我去共享他那神秘的世界。
防止中间人攻击, 在密码学里也是一个专门研究的方面. 有相关的数学算法实现的好像, 具体不是太了解.
ppt去掉blog.codingnow.com/2008/05/这段地址 就可以下载了 应该是blog自动加了相对地址
好像那个ppt的链接挂了?
在密码学,或是网络安全都有很多人作出了不懈的努力,不过实际应用中确实是很无言! 高强度的密码:用户记不住! 超干净的环境:用户保不住! 确实很无奈! !!好像离题了!!这些问题非常头疼,一旦和网络沾边,问题会激增数倍。

Post a comment

非这个主题相关的留言请到:留言本