存档

‘Security’ 分类的存档

心中一块大石落地

2009年12月30日 Solrex Yang 14 条评论

从找到工作以来,我就在忙论文,因为中科院的硕士毕业是要发表论文的。还有半年临近毕业,已经火烧眉毛了,因此我一直生活在无法按时毕业的恐慌中,也不愿意在博客上多讲,可以发现我最近两个月的更新非常少。

今天是中期答辩的日子。因为没有文章,我很怕答辩时候被枪毙掉,那我只能延期毕业了。但是,昨天正在反复修改答辩幻灯片的时候,收到了一条天大的好消息,我投往 ICC 2010 的一篇文章被录用了,而且还是 oral session!ICC,IEEE 通信学会的旗舰会议啊,我这个小硕实在是太满足了,太满足了,顷刻间,我内牛满面!

再看看审稿意见,我不得不赞叹我的运气。三个审稿人,4444,4444,4434;修改意见里,一个是“没特别的修改意见”,一个是“文章太干巴,应该生动些”,只有最后一个提出了一个切实的修改意见。看到这样友好的评审结果,我又一次内牛满面!

于是乎,两篇论文,一篇已录用,我的中期答辩顺利通过。从目前来看,毕业已经不成问题,谢天谢地!我也总算不用再羞羞答答,敢挺直腰板说俺也是搞过科研的人了。

解决 GAppProxy Set-Cookie 和 HTTPS Cert Bugs

2009年7月9日 Solrex Yang 13 条评论

我自己写了一个类似 GAppProxy 的工具,支持 Python 和 PHP,有兴趣可以看这里

研究 GAppProxy 有两个原因:一、最近 Twitter 不能用,而我常用的 GAppProxy 却不支持我登录 Twitter;二、我最近在琢磨 SSL 证书的问题,正好用 GAppProxy 登录 Twitter 也有证书错误。

第一个 BUG:Set-Cookie Bug

GAPPProxy 目前对 Cookie 的处理有一些问题,主要出在对 header 中的多个 Set-Cookie 域处理错误,就会导致用户登录一些网站错误,无法获得正确的会话 Cookie。

举例,当服务器返回的 header 中有多个 Set-Cookie 域时,比如一般的 wordpress 返回的 header 中,Set-Cookie 域至少有三个:

Set-Cookie:
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-content/plugins; httponly
Set-Cookie:
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-admin; httponly
Set-Cookie:
wordpress_logged_in_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C545dcea44d5e69aec5c1203c64bee061;
path=/; httponly

GAPPProxy 会把它作为一个串传给本地浏览器:

Set-Cookie:
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-content/plugins; httponly,
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-admin; httponly,
wordpress_logged_in_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C545dcea44d5e69aec5c1203c64bee061;
path=/; httponly

这样本地浏览器对 Cookie 的设置就会错误。解决办法很简单,将这个长串用split(', ')切开,同样设置三个 Set-Cookie 域即可。

Update 20090710/Solrex:
有人评论说 ', ' 也是可能在 Cookie 中出现的合法字符串;那么我就另外想了一个办法,先用正则表达式替换将 ', ***=' 替换成 'n***=',再用 'n' 对字符串进行切割。由于在 Cookie 中正常出现的 ', ' 后面会首先跟着 ';' 或 ',',然后才可能出现 =,因此用 ‘, ([^,;]+=)’ 匹配就可以了。而且这次把修改放到服务器端了,原来的客户端就不需要修改了

Patch:

Index: fetchserver/fetch.py
===================================================================
--- fetchserver/fetch.py    (revision 92)
+++ fetchserver/fetch.py    (working copy)
@@ -29,6 +29,7 @@
from google.appengine.ext import webapp
from google.appengine.api import urlfetch
from google.appengine.api import urlfetch_errors
+import re
# from accesslog import logAccess

@@ -153,14 +154,12 @@
             if header.strip().lower() in self.HtohHdrs:
                 # don't forward
                 continue
-            ## there may have some problems on multi-cookie process in urlfetch.
-            #if header.lower() == 'set-cookie':
-            #    logging.info('O %s: %s' % (header, resp.headers[header]))
-            #    scs = resp.headers[header].split(',')
-            #    for sc in scs:
-            #        logging.info('N %s: %s' % (header, sc.strip()))
-            #        self.response.out.write('%s: %srn' % (header, sc.strip()))
-            #    continue
+            # NOTE 20090710/Solrex: Fix multi-cookie process problem
+            if header.lower() == 'set-cookie':
+                scs = re.sub(r', ([^,;]+=)', r'n1', resp.headers[header]).split('n')
+                for sc in scs:
+                    self.response.out.write('%s: %srn' % (header, sc.strip()))
+                continue
             # other
             self.response.out.write('%s: %srn' % (header, resp.headers[header]))
             # check Content-Type

第二个 BUG:HTTPS Cert Bug

简单地来说,GAppProxy HTTPS 连接的实现是一个欺骗本地浏览器的过程,类似于中间人攻击。它首先用 GAE 获得页面的明文,抓到本地,然后假冒 HTTPS 站点与本地浏览器通信。因此它就需要提供一个 SSL 证书,来完成 HTTPS 连接的建立。

但这就有一个问题,SSL 证书哪儿来的?目前 GAppProxy 对所有的站点都使用一个证书,而且这个证书是未经任何授权 CA 认证的证书,因此就会产生很多错误。首先,该证书中的授权机构不是可信 CA,Firefox 和 IE 中捆绑的证书中没有该 CA 的证书;其次,该证书的 CN (Common Name)与站点域名不同,不可用于站点的通信。因此可能每次都需要用户自己点击添加证书例外。

为了避免这种缺陷,我想出来的做法是——自己做 CA,正所谓做事情要专业,要骗就骗彻底点,骗得浏览器神不知鬼不觉。首先,建立 CA 的密钥,自己给自己签发一个证书作为 CA 的根证书,将该 CA 的证书安装到 Firefox 浏览器中,在运行时使用该 CA 为每个 HTTPS 连接的站点签发对应于该站点的证书。由于 Firefox 中已经安装了该 CA 的证书,那么所有该 CA 签发的证书都能够通过 Firefox 的检测了。

这个方法比较麻烦,而且需要电脑上有 openssl,对于 Linux 完全没有问题,对于 Windows 可能就有点儿困难了。所以我这里就给出个思路,具体实现就不谈了。
您可以在 http://share.solrex.cn/ibuild/ 找到我修改后的代码,感兴趣的话可以下载下来看看。

关于 eYouIPB 和 CASNET

2009年4月9日 Solrex Yang 6 条评论

我不知道为什么在干正事的时候想写这个东西,大概也算是一种强迫症吧,想起来某件事情就总觉得有义务马上去做。那么就赶快写完吧。

这篇文章是写给有心人看的,如果您不知道 eYouIPB 和 CASNET 是什么东西,那么您可以无视以下内容。

eYouIPB 是中科院研究生院目前使用的网关登录客户端,但只能在 Windows 下使用。我用 Python 写的一个小软件 CASNET,就是一个 Linux 下的登录替代品,不过目前它也可以支持 Windows。昨天有同学发信问我有关科苑网关登录的问题,我顺便在这里做个笔记吧。

1. 有关流量统计。目前 CASNET 不支持像 eYouIPB 那样的实时的流量统计功能,因为我觉得没有必要。科苑上网是按照流量收费的,而这个流量是指网关服务器统计的流量,而不是客户端统计的流量,所以客户端的实时精确流量统计没有太大意义。

eYouIPB 带有实时的统计流量功能,但这却造成了一些问题。eYouIPB 使用 WinPcap 库做流量统计,而且这个库的版本比较低。假如系统里安装了新的 WinPcap 库,例如 Wireshark(Ethereal) 网络监听程序就会安装 WinPcap 库,那么 eYouIPB 就无法工作了。WinPcap 是一个非常强大的抓包库,而 eYouIPB 仅仅使用了其中的流量统计功能,实在很让人费解它为什么要使用 WinPcap 库并且将它的 dll 包含在自己的软件中。我想应该有更简单的办法做流量统计——如果非做不可的话。

2. 有关登录方式。科苑上网有两种登录方式:一种是 eYouIPB,使用私有的协议;一种是网页登录,使用 https 表单交互。由于 eYouIPB 协议私有,CASNET 只能模拟网页登录的方式,所以您会发现 CASNET 登录速度会比 eYouIPB 慢一点儿,因为它有一个完整的 https 安全协商和交互过程,而 eYouIPB 只需要几次简单 tcp 数据包交换就可以了。不过因为同在一个局域网内,这个速度还是在可以忍受的范围之内。

3. 有关安全性。去年我曾经研究过 eYouIPB 的协议,发现还是相对简单的。我记录的笔记已经丢失,但大概是这个样子的(应用层):“首先 eYouIPB 向服务器发起一个连接,服务器应答可以连接,然后 eYouIPB 将用户名和域发送给服务器,服务器看上去会返回一个密钥,然后 eYouIPB 使用该密钥用某种加密算法加密用户口令(或者还有其它信息)发送给服务器,服务器验证口令,回应是否可以登入。”

从该协议的实现来看,安全性有限。一个是用户可以通过不停地登入登出收集明密文对,另外反汇编 eYouIPB 看起来也不是那么困难,尤其是可以使用 Winsock 32 的 API 来定位负责加密的代码段。一旦加密算法被了解,窃听 eYouIPB 的数据包就能获得用户的口令,那么帐户就可以被窃取。所以相比而言,https 的登录方式更值得信任。

PS: 今天顺便搜索了一下,有个朋友曾经对 1.03 版本的 eYouIPB 协议进行过分析,我感觉和 2.0 版本差距不大。而且这个人完全用 C 实现了 eYouIPB 1.03 的加解密函数如果他仅仅凭逆向工程做出这个结果的话,我是相当地佩服的(因为我花了一整天的工夫也没有做出来一点儿东西)。如果当初我能看到这个结果的话,说不定就有 clue 去模拟 eYouIPB 的协议而不是使用 https 方式了,现在是懒得再去钻研这个东西了。只是不知道 2.0 是否还在使用同样的加解密函数,如果仍在使用的话,那么对有心人来说这个口令保护措施基本上算是不存在了。

4. 有关软件运行速度。这个比较主要是 Windows 平台下,CASNET 是用 Python 脚本写成的,而看起来 eYouIPB 使用 VC++ 写的,在软件的大小和运行速度上 eYouIPB 要显然优于 CASNET。由于 CASNET 的 Windows GUI 版需要额外的 GTK 运行时库和 Python 库支持,大概会加载到内存中 16M 左右的数据,不过这些东西运行时真正用到的不多,所以有些部分除了初始化时,其它时候很可能是驻留在交换区中,所以还是可以接受的。

在 Linux 平台下,因为 GTK 和 Python 库是被非常广泛使用的,所以 CASNET 并不需要额外占用很多内存。

之所以会发布 Windows 版,是因为相比 eYouIPB 而言,Wireshark 对我更重要,所以我无法使用 eYouIPB,而又讨厌网页登录时每次都要选择下拉菜单。再加上顺便看看 PyGtk 在 Windows 下的表现如何。但比较讽刺的是,Windows GUI 版的 CASNET 下载量要超过其它版本加一起的下载量,看来它的存在还是对某些用户有一些帮助。

5. 有关软件功能。eYouIPB 的功能已经被锁定了很多年,但是 CASNET 一直在根据用户的需求增加或者删减某些功能,例如余额不足提醒,断线自动重连,一键切换登录模式等。还有一个未发布的功能是关机自动下线。这是一个我一直想实现的功能,因为当用户关机忘记离线时,恰好分配到原 IP 的用户就可以使用该帐号,造成流量被窃取。这个功能在 Linux 版本上已经基本实现,但是 Windows 版本仍然没有找到可用的方法实现。

一本过时的黑客教科书

2009年1月11日 Solrex Yang 5 条评论

——评《良性入侵-道德黑客非官方指导》

如果说放在原书出版的 2002 年,本书还是有相当价值的。但是我不理解为什么 2007 年电子科技大学出版社还会去翻译一本过时的黑客技术书籍?

在计算机安全和攻击的领域,时效性非常的强。在 2007 年再读一本讲述怎么攻击 Windows 9x 的书显然是不合时宜的,而且文中提到的各种漏洞和攻击方法早就被新的补丁和协议所防护,或者已经有了新的攻击类型,那么对于当前读者的意义也就不大了。就算是仅仅用于研究,读者也很难找到一个有漏洞的原型系统来做实验。

非常值得诟病的还有本书的翻译,我不得不说,很难看到比这本书翻译得更烂的了,连文字都不通顺,随便举一个例子(第103页):

“(前面一段是代码)作为一个基本的规则,你需要等待更长时间,你会更安全。如果有三分钟的时延,显示,登出。TCP 端口扫描,像 Portscan.java 或者其他的 Windows 的端口扫描(我承认我不小心发现了一句语句重复的排版错误),像 Portscan.java 或者其他的 Windows 的端口扫描这样的 TCP 端口扫描程序将不会对主机的安全性构成威胁,主机将更加安全。”

我基本上第一次没看懂这一段是什么意思。另外还值得一提的是本书的代码量相当大,几乎能占到四成,代码量大不是问题,但是异常多的代码就让人怀疑是否用代码来充实书的内容了,会让读者觉得钱花得不值。(但也有一个可能是受美国法律的限制,不能出口一些敏感代码,只能把代码放到书里来逃避规定,一些密码学的书籍曾这样做过。)

再加上 80 元的售价,天那,给我 80 元我会买很多好书,但绝对不会是这一本。

分类: Reading, Security 标签: ,

密码保护:内网穿透反向隧道代理技术

2009年1月6日 Solrex Yang 查看留言请输入密码

这是一篇受密码保护的文章。您需要提供访问密码:


分类: IT, Security 标签: , ,

即时通信软件协议

2008年11月13日 Solrex Yang 4 条评论

我十多天前发表的那篇《定制自己的免费天气预报短信》,相信引起了不少人的兴趣。这篇文章是为那些希望更深入了解即时通信协议,并想做一些 hack 工作的同学提供的一个小索引。

关于飞信的协议,可以参考下面两篇文章,某人的博客和一个飞信插件的源代码:

[1] 付安民, 张玉清. 飞信即时通监控系统的设计与实现. 计算机工程, 2008, 34(13).

[2] 付安民, 张玉清. 即时通实时监控系统的设计与实现. 通信学报, 2008, 29(10).

[3] http://hi.baidu.com/nathan2007/blog/category/飞信协议分析

[4] Pidgin 飞信插件

关于其它常见 IM 的协议,可以参考下面这篇文章和一个开源软件的源代码:

[5] R.B. Jennings, E.M. Nahum, D.P. Olshefski, et al. "A study of Internet instant messaging and chat protocols," IEEE Network, vol.20, no.4, pp. 16-21, 2006.

[6] Pidgin - multi-protocol Instant Messaging client that allows you to use all of your IM accounts at once.

我真的很希望飞信的 Pidgin 插件能更成熟,比如群功能之类的还要完善,最好以后能 merge 到 Pidgin 中,这样我就不用在 Pidgin 之外再开着一个 Libfetion Linux 客户端了。而 Libfetion 仍然也有亟待完善的地方,比如群管理员无法成功发送群消息。如果聪明的您能完成一个近于完美的 Linux 飞信客户端,我真的要谢谢您呢!

分类: Open Source, Security 标签: , , , , ,

一个对 Tor 的新型重放攻击方法

2008年9月3日 Solrex Yang 5 条评论

Tor 是一个旨在抵御流量分析的匿名网络访问服务,它也可以被用为穿透网络 censorship 的工具,它的官方网站为:http://torproject.org (很可惜的是,大陆用户已经无法正常访问这个站点了)。

由于 Tor 在中国的使用还算比较广泛,我的朋友中也有不少使用它作为穿墙工具的,我想关于它的安全问题应该有人感兴趣。这篇博客将简要介绍 ICC(International Conference on Communications, 世界通信大会) 2008 的一篇论文 A New Replay Attack Against Anonymous Communication Networks 中描述的对 Tor 匿名性的一个很有效的攻击方法,这篇论文荣获了 ICC 2008 Best Paper Award(好好好好羡慕啊~~~)。

Tor 网络是由洋葱路由器(下简称路由器)、目录服务器和洋葱代理服务器(下简称代理服务器)组成的。所谓洋葱路由,就是用户发出的消息会被多层加密,每到一个路由节点,路由器解密一层来获得下一跳信息,就像剥洋葱一样一层一层解密,到最后一层才是用户的原始消息。

Tor 的工作方式是经过多次转发消息来保护原始地址不被侦知。其进行一次通信的流程是:用户在 PC 机上安装洋葱 socks 代理服务器,设置浏览器或应用程序通过本机的代理服务器访问网络;代理服务器从目录服务器得到可用的路由器列表,在用户发起 TCP 请求时,本机代理服务器选择中间通过哪些路由器转发消息,然后将用户的 TCP 包多层加密后发送出去;转发路径上经过的路由器对消息逐层解密转发,最后一跳的路由器(出口路由器)和目的主机进行正常的 TCP 通信,然后将返回的消息按照原始路径发送给用户。

这样入口路由器知道通信的发起者却不知道接收者,中间路由器只管转发,而出口洋葱路由器知道通信的接收者却不知道发起者,这就保证了用户访问网络的匿名性。

A 文中采取的攻击方法是:假定攻击者可以控制入口路由器和出口路由器,由于 Tor 采用计数器模式的 AES 加密算法(能否解密和包的顺序有关),那么在入口路由器处重放已经发送过的消息(包的顺序被打乱),就会造成出口路由器解密失败,收到错误的数据包。由于攻击者控制了入口和出口路由器,那么通过将入口路由器重放消息的时间和出口路由器检测到错误的时间联系起来,就能确定这次通信的源和目的地,破坏了网络访问的匿名性。

更坏的是如果消息的重放发生在用户通信的末尾,在用户结束通信后和 TCP 连接断开之间,用户甚至都不知道他的网络行为已经被发现。

虽然假定攻击者可以控制入口和出口路由器看起来是一个很强的条件,但 A 文中通过实验验证了拥有洋葱路由网络的路由器并成为入口并不算很难(Tor 网络本身就是由许多志愿者的主机组成的),再加上一个修改过的代理服务器软件,完全可以实现对使用该软件的用户的路由选择策略的控制。如果攻击者拥有足够的资源(比如某些强力部门),使用足够多的主机加入 Tor 网络,根据 Tor 的路径选择策略优化这些路由器的分布,我觉得也有可能实现上述条件。

总的来说,相比与其它一些对匿名网络流量进行监控的攻击方法,A 文的攻击是相当简单直接并且高效的。我简单查看了 Tor 软件的 ChangeLog,没有发现它对这一攻击进行有针对性的修改(也许是我看的不认真)。

所以呢,对中国用户来说,通过 Tor 来穿墙是可以的,但是过于相信 Tor 的匿名性并且用其去发布敏感信息或者进行其它不法行为是要三思而后行的,这也就是为什么 Tor 软件自己也说:
This is experimental software. Do not rely on it for strong anonymity.

分类: Security 标签: , , ,

Math in CS: 数论和公钥密码学

2008年6月13日 Solrex Yang 2 条评论

1940年,英国数学家哈代在他的一本小书《一个数学家的辩白》(A Mathematician's Apology)中说:“如果有用的知识是这样的知识(我们暂时同意这样说):它大概会在现在或相对不远的未来,为人类在物质上的享受方面作出贡献,因而,它是否在单纯的智力上满足人们乃是无关紧要的,那么,大量更高级的数学就是无用的。现代几何和代数、数论、集合论和函数论、相对论、量子力学——没有一种比其它的更经得住这种检验,也没有真正的数学家的生涯可以在这个基础上被证明是有价值的。”但是我们会看到,哈代这个断定在当时“不远的未来”几乎被一一证明是错误的,数论就是其中一个。

在 1970 年代以前,人们所知道的密码学都是对称密码学,就是在加密和解密过程中需要使用同一个密钥。在那个时代,一些密码算法已经能保证足够的安全性,比如数据加密标准 DES。但是人类的需求是很难完全得到满足的,他们为每次密钥交换的复杂度而苦恼,比如在战时如果密码本被敌方获得,就必须重新向无线电收发员分发密码本,这个工作量和代价是相当大的;还有一个需求就是数字签名,能不能用加密实现对数字文件的签名,像手写的签名一样,确保该文件出自谁人之手?

上述问题,就是 Whitfield Diffie 和 Martin Hellman 1976 年在他们那篇划时代的论文《密码学的新方向》(New Directions in Cryptography)中提出的,他们也给出了其中一个问题的解决办法,那就是 Deffie-Hellman 密钥交换算法(后来被改为 Deffie-Hellman-Merkle 密钥交换算法,里面还有一段小故事。)。但是 DH 没做完的功课,仅仅在一年后就被 RSA 解决了,那就是 Ron Rivest, Adi Shamir, 和 Leonard Adleman 的 "A Method for Obtaining Digital Signatures and Public-Key Cryptosystems"。RSA 的加密和解密使用的是不同的密钥,即公钥和私钥,你可以将你的公钥扔到世界上任何一个位置,我用你的公钥加密一段信息,除了你用自己的私钥解密,没有别的人能从中得到原始消息。就相当于你把打开了的箱子扔的满世界都是,但箱子一旦锁上,就只有你能再打开。

RSA 算法自其诞生之日起就成为被广泛接受且被实现的通用公钥算法,但是 RSA 算法还带来一个另外的意义,那就是:数论知识从未像现在这样被广泛地使用着。RSA 程序的普及率要远远大于 Windows,因为每台 Windows 上都装配着 RSA 算法程序,但 RSA 并不仅仅装配 Windows。每当你登录邮箱、网上银行、聊天软件、安全终端,你都在使用着数论带来的好处。而且相比之前密码学的字母替换和置换,混淆和扩散,DH 和 RSA 使用的东西更有资格说自己是数学。

大概也是由于其基于数学的简洁性,RSA 和 DH 算法描述要比 DES, AES 简练许多,我在这篇小文中都能写完。

RSA

RSA 用到了数论中的三个基本定理:费马小定理、欧拉定理和中国剩余定理(几乎处处都在),和一个古典难题:大整数分解问题。如果你是数学系的学生,对这些概念一定不会陌生。

费马小定理:若 p 是素数,a 是正整数且不能被 p 整除,则: ap-1 = 1(mod p)。或者另一种形式:ap=a(mod p),这种形式不要求 a 与 p 互素。

欧拉定理:对任意互素的 a 和 n,有 aΦ(n) = 1(mod n)。其中,Φ(n)是欧拉函数,即小于 n 且与 n 互素的正整数的个数。

大整数分解问题:将两个整数乘起来是简单的,但是将一个整数分解为几个整数的乘积是困难的,尤其是当这个数比较大的时候。迄今为止没有有效的算法来解决这个问题,甚至我们连这个问题的计算复杂度量级是多少都不知道。

那么 RSA 算法是什么样的呢?

密钥的产生:
1. 选择两个素数 p 和 q.
2. 计算 n = p*q.
3. 计算 Φ(n) = (p-1)(q-1) (这是欧拉函数的性质)
4. 选择 e<Φ(n) 并使得其与 Φ(n) 互素。
5. 确定 d<Φ(n) 并使得 d*e = 1(mod Φ(n))。
6. 这时候,私钥就是{d, n},公钥就是{e, n}。
加密算法:
假设 M 是明文(M<n),那么密文就是 C = Memod n。(为什么明文是数字?在计算机科学里任何数据最终表示都是数字。)
解密算法:
假设 C 是密文,那么明文就是 M = Cd mod n。

我们来证明一下算法是否正确,由于 Cd = Me*d = Mk*Φ(n)+1 (mod n)。

如果 M 和 n 是互素的,显然直接由欧拉定理我们就能得到:
Cd = Mk*Φ(n)*M1 = M (mod n) = M
说明算法是正确的;
如果 M 和 n 不互素,由于 n 是两个素数 p 和 q 的乘积且 M<n,那么 M 要么是 p 的倍数,要么是 q 的倍数,由 e*d = 1(mod Φ(n)) = 1(mod (p-1)(q-1)) 我们可得:
e*d = 1(mod (p-1)) 且 e*d = 1(mod (q-1))
则 e*d 可以写成: e*d = k*(p-1)+1, e*d = h*(p-1)+1
由费马小定理,我们有:Me*d = Mk*(p-1)+1 = M(mod p) 和 Me*d = Mh*(q-1)+1 = M(mod q)。
由于 p 和 q 均为素数,且 p, q 均整除 Me*d-M,所以我们有:
Cd = Me*d = M (mod p*q) = M (mod n) = M

从上面我们可以看到 RSA 算法实现了加密和解密使用不同密钥,而且证明了这个算法的正确性。但 RSA 算法要想实用,光有正确性还不够,最重要的一点是安全性,即从公钥{e, n}无法推导出私钥{d, n}。在 RSA 算法中我们可以看到,关键要知道 Φ(n),知道了 Φ(n),使用欧几里德算法就能求出 e 的逆元,就得到了用户的私钥{d, n}。要求出 Φ(n),就必须知道 p,q,但 p,q 是不公开的,仅仅知道 p,q 的乘积 n 去求 p,q,根据大整数分解古典难题,当 n 比较大时其分解在计算上是不可行的。这就保证了 RSA 算法的安全性。

而且 RSA 算法是可逆的,所以它就有能力同时实现加密和签名的功能。由于公钥是公开的,每个人都可以用你的公钥加密一段信息发给我,而私钥是保密的,所以只有你能看到别人用你的公钥加密的消息;而也因为可逆性,如果你用私钥解密一段明文(实际是加密),所有人都可以用你的公钥加密它来得到明文(实际是解密),因为私钥只有你一个人知道,这个消息只有可能是你发出的,就相当于你对这段明文做了一个签名。

DH 密钥交换算法

DH 密钥交换算法较 RSA 算法更为简单,它也是基于数论中的一个古典难题:离散对数问题。

离散对数问题:若 p 是素数,p 已知,考虑方程 y = gx mod p,给定 g,x 求 y 是简单的,但给定 y,g 求 x,即求 x = logg,py mod p,在计算上是不可行的。

DH 密钥交换算法的描述如下:
已知公开的素数 p 和 p 的本原根 α
1. 用户 A 选择秘密的 Xa<p,计算 Ya = αXa mod p,将其发送给 B。
2. 用户 B 选择秘密的 Xb<p,计算 Yb = αXb mod p,将其发送给 A。
3. A 和 B 分别计算 Ka = (Yb)Xa mod p 和 Kb = (Ya)Xb mod p,就同时得到了共享的密钥 K=Ka=Kb,然后就可以用 K 进行加密传输了。

DH 密钥交换算法的优点在于:双方在通信前不需要知道任何共享的密钥,而是通过公开的 p 和 α 协商出一个密钥来进行加密通信。

先看一下算法的正确性,Ka = Kb 是否成立:
Ka = (Yb)Xa = (αXb)Xa = αXa*Xb (mod p)
Kb = (Ya)Xb = (αXa)Xb = αXa*Xb (mod p)
Bingo! Ka 和 Kb 是相同的。

再来看一下算法的安全性,就是能否从公开的信息推导出 K 来:
由于密钥是 K = αXa*Xb,那么攻击者必须知道 Xa 和 Xb 才能得到共享的密钥 K,而公开的信息只有 Ya 和 Yb,由离散对数问题,从 Ya,Yb 求出 Xa,Xb 在计算上是不可行的,就保证了算法的安全性。

从上面两个算法我们可以看出,数论在公钥密码学中的重要地位,恐怕哈代当时怎么也想不到三十多年后人人都在使用他所认为在实际生活中毫无用处的数论吧!

从安全的角度理解——为什么要使用 Google 的服务?

2008年4月29日 Solrex Yang 15 条评论

我很喜欢 Google 的一些服务 Gmail, Reader, Documents等等,而且我也一直大力倡导周围的人使用 Google 的服务。在我看到一些人仍在使用 163, sina 的信箱,抓虾的在线订阅器的时候,我不禁为他们通信的安全性担心。为什么使用 Google 的服务?一个很重要的原因是:因为它更安全。

目录:

1. 得到抓虾用户名密码的例子
2. 嗅探和可嗅探网络
3. 为什么 Google 更安全?
4. 为什么 163, sina, 抓虾 不安全?
5. 如何使用 Google 提供的安全服务?
6. 使用 Google 提供的安全服务的额外好处

1. 得到抓虾用户名密码的例子

首先,来看一个截图,看看国内某著名在线订阅器网站抓虾网对用户密码的保护有多脆弱:

Wireshark_Zhuaxia

请大家注意截图的最下方,能否看到这一行字:
email=solrex%40gmail.com&password=testtest&persistentCookie=true
solrex@gmail.com 是我在抓虾的注册帐号,而后面的 password 大家应该知道是什么东西吧!(不用试我的帐户,我的密码已经改了。)

有人会好奇这张截图怎么得到的,其实这是我在自己的电脑上用 Wireshark(一款著名的网络数据包分析软件,其前身是 Ethereal) 对通过我网卡的到抓虾网数据包进行监控的截图。Wireshark 实际上就是一款嗅探器,它能记录经过指定网络接口的所有数据包并进行分析。

2. 嗅探和可嗅探网络

为了解释如何才能得到上面的数据包,首先要介绍一下网络嗅探的原理:

嗅探,是一种黑客的窃听手段,一般是指使用嗅探器对数据流的数据截获。由以太网的知识我们知道,在以太网的冲突域中,每台主机的网卡都能接触到所有的数据包,如果数据包的目的地址是自己,网卡就接收数据包,并将包的内容向上层传递;如果数据包的目的地址不是自己,就将该包丢弃。那么如果网卡接收所有的数据包并对其进行分析呢?这就是所谓的“混杂模式”,将网卡设置为混杂模式后,就可以接收所有包,进而对同一网络中的其它主机的通信内容进行监听,这就是 Wireshark 进行嗅探的原理。

需要说明的一点是,在当前的网络下,直接进行嗅探并没有那么容易。上面所说的情况,只在以太网的冲突域中才能实现,而当前交换机的广泛使用,将冲突域限制到交换机和主机两点之间,除了自己没有其它主机,当然也无法直接对其它主机的通信内容进行监听。如果在交换网络下达到嗅探的目的,必须通过其它办法,比如 ARP 欺骗,这超出了本文的讨论范围,就不予介绍了。

虽然在交换网络下无法对其它主机进行直接嗅探,但是我们无法保证在我们的数据包经过的防火墙或者网关时候不会被监听。就比如在实验室的网络环境下,实验室的管理员在网络出口的防火墙处对数据包进行分析是易如反掌的事情。

所以我们总结一下,用户通信的数据包被监听可能发生在几种情形下:一、共享网络,网络用户通过集线器连接到网络;二、交换网络的结点不可信任,比如公司网络的出口防火墙管理员不可信;三、缺乏安全机制的无线网络,比如学校为学生提供的无线网络连接(用 WEP 加密传输的网络可以认为是缺乏安全机制);四、有ARP欺骗的交换网络。

由于很多网站的登录 session 是使用的 http 协议,在此协议下,用户名和密码都是通过明文传输的(抓虾和 sina 就是一个例子),所以当用户处在上述的网络环境下时,很有可能数据包被别人监听到。而数据包一旦被监听和分析,得到用户的信息易如反掌,南京大学小百合 BBS 最近的一篇文章:你还敢在教室中享受无线吗? ,就是一个很生动的例子。

3. 为什么 Google 更安全?

首先,因为 Google 采用了 https 协议来处理用户登录请求。https(Hypertext Transfer Protocol over Secure Socket Layer) 协议是指加强安全的 http 协议,正如它名字所示,它采用 SSL 来保证数据的加密传输。举个很有证明力的事实,如果你有任何一个银行的网上银行帐号,请打开你的网银登录窗口,查看上面的地址栏内容开头是不是:https://xxx.xxx.com/xxxx 。没有任何一家银行采用 http 协议处理网银登录请求,这说明了什么?http 协议不安全。

其次,因为 Google 使用可选的 https 协议来提供内容传输服务。虽然 Google 在其任何服务的登录请求处理中都是使用 https 协议,但是在认证完用户之后,和 Google 服务器的连接就转回到了 http 协议。这样虽然 Google 的用户名和密码不能被窃听到了,可服务的内容,比如 Gmail 邮件的邮件内容就会被恶意用户窃听到。那么如何使整个通信的内容都受到保护呢,就需要使用 Google 提供的可选 https 服务,只需要在你的浏览器地址栏内容的最前面 http:// 换成 https:// 即可。

4. 为什么 163, sina, 抓虾 不安全?

sina 和 抓虾 没有提供任何的帐户信息和内容的安全传输功能,所以在课堂上演示嗅探器工作方式的时候,演示者一般都会首先拿 sina 开刀,原因很简单,它是个大网站。

163 呢,比前面两个好一点儿,它提供了可选的帐户信息的加密传输功能,就是在登录 163 信箱的时候,在登录框下面有一个“增强安全性”的选项,如果勾选了增强安全性选项,163 就会用 https 来处理用户的登录请求。但是 163 仍然没有提供对用户内容的加密传输功能,即 163 的所有邮件在网络上都是明文传输

5. 如何使用 Google 提供的安全服务?

如果用户希望自己的帐户信息和传输内容都受到保护的话,那么就应该使用 Google 提供的 https 连接登录 Google 服务。比如Gmail 的 https 入口是:https://mail.google.com/ ,Google Reader 的 https 入口是:https://www.google.com/reader/ 。在 Google 其它的服务中,用户也可以简单地通过将地址栏的 http:// 换成 https:// 来选择使用安全传输。

6. 使用 Google 提供的安全服务的额外好处

使用安全的加密传输能保证自己传输的信息不被别人获取,这是显而易见的好处,但是使用 Google 的安全服务还有一点额外好处:避免自己的网络访问被关键词过滤。

有过访问敏感站点经验的同志可能都知道,如果网页中包含某些关键词,连接往往会被重置。就比如用户使用 Google Reader 订阅了某个激进的博客的RSS FEED,如果使用传统的 http 连接,当文章中包含敏感关键词时,Google Reader 就会与服务器断开连接。如果使用加密传输的话,传输内容就避免了被关键词过滤,就不会发生类似连接被重置的情况。

在 Ubuntu 上部署 Snort 入侵检测系统

2007年12月4日 Solrex Yang 9 条评论

最后更新时间:2009年7月1日

摘要:

这份文档主要描述了我在 Ubuntu 7.10 上安装部署 Snort 入侵检测系统和 acid 基于 PHP 的网页入侵检测数据库分析控制台的过程。

目录

1. 介绍
2. 安装过程
3. 总结
4. 参考文章

1. 介绍

Snort 是一款非常优秀的开源主机入侵检测系统软件,可以用来对主机的网络状况进行记录、分析和报警,并且支持用户自定义规则库。Snort 在 Windows 平台和 Linux 平台上均可运行,详细介绍请访问 Snort 的官方网站:http://www.snort.org

Snort的默认记录是存放在 log 文本文件中,而为了观察监控方便起见,一般使用 acidbase 这个网页控制台来查看(好像 MySQL 的 phpmyadmin)。所以整个过程需要:安装 snort 和相应包;安装 LAMP(Linux, Apache, MySQL, PHP) 服务器;在MySQL数据库中建立好Snort数据库并配置 Snort 使其将 log 存放在 MySQL 数据库中;为基于 PHP 的入侵检测数据库分析控制台 (acidbase) 配置好数据库连接。

2. 安装过程

[安装LAMP,Snort和一些软件库]

由于 Ubuntu 是 Debian 系的 Linux,安装软件非常简单,而且 Ubuntu 在中国科技大学有镜像,在教育网和科技网下载速度非常快(2~6M/s),就省掉了出国下载安装包的麻烦,只需要一个命令即可在几十秒钟内安装好所有软件。这里使用 Ubuntu 默认命令行软件包管理器 apt 来进行安装。

$ sudo apt-get install libpcap0.8-dev libmysqlclient15-dev mysql-client-5.0 mysql-server-5.0 bison flex apache2 libapache2-mod-php5 php5-gd php5-mysql libphp-adodb php-pear pcregrep snort snort-rules-default

需要注意的是在安装 MySQL 数据库时会弹出设置 MySQL 根用户口令的界面,临时设置其为“test”。

[在 MySQL 数据库中为 Snort 建立数据库]

Ubuntu 软件仓库中有一个默认的软件包 snort-mysql 提供辅助功能,用软件包管理器下载安装这个软件包。

$ sudo apt-get install snort-mysql

安装好之后查看帮助文档:

$ less /usr/share/doc/snort-mysql/README-database.Debian

根据帮助文档中的指令,在 MySQL 中建立 Snort 的数据库用户和数据库。所使用的命令如下:

$ mysql –u root –p

在提示符处输入上面设置的口令 test

mysql> CREATE DATABASE snort;
mysql> grant CREATE, INSERT, SELECT, UPDATE on snort.* to snort@localhost;
mysql> grant CREATE, INSERT, SELECT, UPDATE on snort.* to snort;
mysql> SET PASSWORD FOR snort@localhost=PASSWORD('snort-db');
mysql> exit

以上命令的功能是在 MySQL 数据库中建立一个 snort 数据库,并建立一个 snort 用户来管理这个数据库,设置 snort 用户的口令为 snort-db。

然后根据 README-database.Debian 中的指示建立 snort 数据库的结构。

$ cd /usr/share/doc/snort-mysql
$ zcat create_mysql.gz | mysql -u snort -D snort -psnort-db

这样就为 snort 在 MySQL 中建立了数据库的结构,其中包括各个 snort 需要使用的表。

[设置 snort 把 log 文件输出到 MySQL 数据库中]

修改 Snort 的配置文件:/etc/snort/snort.conf

$ sudo vim /etc/snort/snort.conf

在配置文件中将 HOME_NET 有关项注释掉,然后将 HOME_NET 设置为本机 IP 所在网络,将 EXTERNAL_NET 相关项注释掉,设置其为非本机网络,如下所示:

#var HOME_NET any
var HOME_NET 192.168.0.0/16
#var EXTERNAL_NET any
var EXTERNAL_NET !$HOME_NET

将 output database 相关项注释掉,将日志输出设置到 MySQL 数据库中,如下所示:

output database: log, mysql, user=snort password=snort-db dbname=snort host=localhost
#output database: log, mysql

这样,snort 就不再向 /var/log/snort 目录下的文件写记录了,转而将记录存放在 MySQL 的snort数据库中。这时候可以测试一下 Snort 工作是否正常:

$ sudo snort -c /etc/snort/snort.conf

如果出现一个用 ASCII 字符画出的小猪,那么 Snort 工作就正常了,可以使用 Ctrl-C 退出;如果 Snort 异常退出,就需要查明以上配置的正确性了。

[测试 Web 服务器 Apache 和 PHP 是否工作正常]

配置 apache 的 php 模块,添加 msql 和 gd 的扩展。

$ sudo vim /etc/php5/apache2/php.ini
extension=msql.so
extension=gd.so

重新启动 apache

$ /etc/init.d/apache2 restart

在/var/www/目录下新建一个文本文件test.php

$ sudo vim /var/www/test.php

输入内容:

<?php
phpinfo();
?>

然后在浏览器中输入 http://localhost/test.php,如果配置正确的话,就会出现 PHP INFO 的经典界面,就标志着 LAMP 工作正常。

[安装和配置 acid-base]

安装 acid-base 很简单,使用 Ubuntu 软件包管理器下载安装即可:

$ sudo apt-get install acidbase

安装过程中需要输入 acidbase 选择使用的数据库,这里选 MySQL,根用户口令 test,和 acid-base 的口令(貌似也可以跳过不设置)。

将acidbase从安装目录中拷贝到www目录中,也可以直接在apache中建立一个虚拟目录指向安装目录,这里拷贝过来主要是为了安全性考虑。

sudo cp –R /usr/share/acidbase/ /var/www/

因为 acidbase 目录下的 base_conf.php 原本是一个符号链接指向 /etc/acidbase/ 下的base_conf.php,为了保证权限可控制,我们要删除这个链接并新建 base_conf.php 文件。

$ rm base_conf.php
$ touch base_conf.php

暂时将 /var/www/acidbase/ 目录权限改为所有人可写,主要是为了配置 acidbase 所用。

$ sudo chmod 757 acidbase/

现在就可以开始配置 acid-base 了,在浏览器地址栏中输入 http://localhost/acidbase,就会转入安装界面,然后就点击 continue 一步步地进行安装:

选择语言为 english,adodb 的路径为:/usr/share/php/adodb;选择数据库为 MySQL,数据库名为 snort,数据库主机为 localhost,数据库用户名为 snort 的口令为 snort-db;设置 acidbase 系统管理员用户名和口令,设置系统管理员用户名为 admin,口令为 test。然后一路继续下去,就能安装完成了。

安装完成后就可以进入登录界面,输入用户名和口令,进入 acidbase 系统。

这里需要将 acidbase 目录的权限改回去以确保安全性,然后在后台启动 snort,就表明 snort 入侵检测系统的安装完成并正常启动了:

$ sudo chmod 775 acidbase/
$ sudo snort -c /etc/snort/snort.conf -i eth0 –D

[检查入侵检测系统工作状况,更改入侵检测规则]

正常情况下在一个不安全的网络中,登录 acidbase 后一会儿就能发现网络攻击。如果没有发现网络攻击,可以添加更严格的规则使得正常的网络连接也可能被报攻击,以测试 Snort IDS 的工作正确性,比如在 /etc/snort/rules/web-misc.rules 的最后添加下面的话:

$ sudo vi /etc/snort/rules/web-misc.rules
alert tcp any :1024 -> $HTTP_SERVER 500:

这一行的意思是:对从任何地址小于 1024 端口向本机 500 以上端口发送的 tcp 数据包都报警。杀死 Snort 的后台进程并重新启动,就应该能检测到正常的包也被当作攻击了。

$ sudo kill `pgrep snort`
$ sudo snort –c /etc/snort/snort.conf –i eth0 -D

3. 总结

使用 Ubuntu 部署 Snort 入侵检测系统和网页控制台是相当容易的,因为 Ubuntu 提供了很方便的软件包安装功能,只是有时候定制性能太差,需要用户手动去寻找软件包的安装位置。

4. 参考文章

http://www.howtoforge.com/intrusion-detection-with-snort-mysql-apache2-on-ubuntu-7.10

分类: Linux, Security 标签: , , ,