在一切的嘟囔之前,让我先说一句,【直接使用】任何开放式网络都是十分危险的!开放式网络主要指的是学校、机场、咖啡厅等公共场合的开放Wi-Fi以及有线网络。公司的网络同样也不值得相信。所有不可控的网络都应该被划分到"开放式网络"中。
在开放式网络中,中间人劫持是极有可能存在的。一点技术含量都没有,一部root的Android手机就足够了。
序
话说六七年前呐,人们上网,还是通过插着网线的台式机;随后的2011、2012智能设备的兴起,越来越多的人开始使用可以连接到Wi-Fi的智能手机,越来越多的家庭开始有了"无线路由器"。
到现在,2016年,Wi-Fi已经遍地可见了——肯德基、必胜客、公园游乐场等餐饮娱乐场所,银行、学校、医院、火车站、机场等服务场所。
在空中飞着的无线电波啊,是不是给人一种飘渺虚无的没有安全感的感觉?其实有线网络也没安全到哪里去。
在兴致勃勃的连接上公共Wi-Fi时,你是否想过一个很严肃的问题:你的通信,是安全的吗?"安全"这二字虽然简单,但是却意味着四件事情:我的通信内容无法被第三者看到(隐私性)、我的通信即使被第三者看到也无法被解密(保密性)、我的通信发送给了正确的接受者(通信正确性、真实性)、我的通信内容没有被篡改(内容正确性、完整性)。
什么是"开放式网络"
提到"开放式网络",很多人可能就想到那些公共场合的无密码的Wi-Fi,其实这样的想法是不准确的、错误的。在进一步说明什么是"开放式网络"之前,我们先想一想自己新安装的Windows第一次联网的时候的情景:
Windows将网络分为专用网络和公用网络,在此我同样建议这样分类,但是很明显工作网络也是很难信任的(参见《如何防范网络审计》)。所以,靠谱的分类是这样子滴:
开放网络:公共场合的Wi-Fi(无论是否有密码保护)、工作网络、学校网络
专用网络:家庭网络
开放网络包括但不限制于公共场合的Wi-Fi、公司网络、学校网络以及所有被你认定为不信任的网络。
在此我们将网络分成两部分,一部分是"外部网络",你不可以控制的那部分网络;一部分称为"内部网络",你的路由器的那个网段对你来说就属于内部网络,你可能有权控制、也可能只是众多客户之一。
一句话总结,所有不可控的网络都应该被划分到"开放式网络"中。
小提示:Wi-Fi和WLAN的区别 WLAN是Wireless LAN的缩写,即无线局域网;而Wi-Fi是Wireless Fidelity,意为"无线保真",是指能将电脑、手机等以无线方式互联的技术。Wi-Fi是WLAN的一个"子集"
为什么"开放式网络"很危险
在"开放式网络中",我们的定义是:我们无法信任处于同一网络的其他设备。在继续讨论为何"开放式网络"危险之前,我们先想想小时候的一个游戏。
20岁以上的小盆友可能小时候玩过"土电话",就像下图所示一样。
一个发送端,一个接收端,通过一条线路"链接"到一起,这就是最简单的通信模式。下面我对这个图稍作改动
假设一个不怀好意的"滑稽"在双方不知情的情况接入通信链路,那么他就极有可能监听到这两者的通信内容。
在真实的网络中,直接通过一条线连接并通信的情况是很罕见的,通常一条通信线路都需要很多设备来"中转"。
如果在你的这个通信线路中同样存在一个不怀好意的"设备"记录你的通信,而且这个设备不是网关,这就叫"旁路"——而且通常是你无法察觉的。或者我们称之为"嗅探"更容易理解。这个现象其实很常见的,在《网络审计》中我们会重提这个问题。
在开放式网络中,任何人都可以接入这个网络,并且一般来说,任何一个设备均可以通过"ARP欺骗"来阻断数据包、中转数据包甚至是篡改数据包——这也就是说,开放式网络中,你看到的大部分东西,都不一定是它本来的面貌。其中"中转数据包"便是攻击者加载客户和网关之间充当“翻译”,具体模式大概如下:
1. 对目标主机A进行ARP欺骗,声称自己是网关; 2. 转发目标主机A的数据到网关,维持目标主机A的外出数据; 3. 对网关进行ARP欺骗,声称自己是目标主机A; 4. 转发网关的数据到目标主机A,维持目标主机A的接收数据; 5. 监听劫持或者修改目标主机A的进入和外出数据,从而实现攻击。
这种攻击也就是MITM(Man In the Middle attack,中间人攻击)的一种实施模式,在目标主机A和网关之间充当中间人,同理,攻击者也同样可以在目标主机A和目标主机B之间充当中间人。攻击者可以选择默默的监听,也可以选择篡改数据,甚至是丢弃数据来达到阻止通信的目的。
中间人攻击之所以能成功,是因为通信双方缺乏有效的身份认证机制。
盗用随想的一张图:
需要注意的是,ARP欺骗只是中间人攻击的一种模式而已,在内网中存在中间人攻击,在外部网络也同样存在中间人攻击,由政府、黑客操纵发动的中间人攻击也不是没有。
在开放式网络中,大部分情况下接入者是有能力进行ARP欺骗的,而凑巧的是互联网发展之初很多应用层协议都是【明文】传输的——你的通信内容已经不再具有隐私性。
你还能信任开放式网络吗?
不信,那就让我攻击一次来给你看。在淘宝、QQ邮箱登录还不是HTTPS的年代,我就干过这样的事情,真的一点技术含量都没有,只需要耐心而已。
这是我在自己的网络中使用ARP欺骗进行MITM之后的结果,捕捉到了一些提交的表单中的账号密码。
由于cain内置的表单内容不够多,所以没能看到一部分明文登录表单,可以通过wireshark自己查看下登录表单名,再添加到cain中。
在"开放式网络"之中的危险因素分析和应对措施
危险的原因
互联网的发展,大概可以这样说:设计者们把互联网设计成了一个漏水的瓶子,后人们就负责堵住漏水的洞。
在想要在网络中保证安全之前, 我们首先要理解为什么会不安全(如果你实在懒得看,就跳过这一部分吧)
-
隐私性
我的通信内容无法被第三者窃取。当第三者窃取的时候,我会注意到。
-
保密性
我的通信即使被第三者看到也无法被解密,这也就等同于"我的通信内容无法被第三者看到"。
-
通信正确性、真实性
我的通信发送给了正确的接受者,而不是冒充的"中间人",想要保证这一点,我们需要一种有效的身份认证机制。
-
内容正确性、完整性
我的通信内容没有被篡改,我能够识别篡改。举个例子,你怎么知道你看的网页和我的服务器想要发送给你的网页是一样的?
如何应对这四个危险因素
-
保证隐私性
想要单纯的保证通信的隐私性,很抱歉这是不可能的。在现有的网络之中,任何中间设备都有可能记录下你的通信内容。
-
保证保密性
值得庆幸的是,随着现代密码学的发展,这一点已经成为可能。使用一种安全的加密算法来加密通信内容。然而如何配送加密密钥又成了一个问题,幸好人们发明了一些行之有效的密钥交换算法。
-
保证通信正确性、真实性
我们需要一种身份认证机制,通常都是客户认证服务器的身份(双向认证的情况也有,比如说4G网络的双向鉴权)。我们可以让服务器颁发证书/指纹给客户,以后每次连接的时候客户都会验证证书/指纹,之后如果有人进行中间人劫持,证书/指纹是必然要变化的。SSH便是采取这种模式的(然而SSH的第一次连接是无法避免中间人劫持的)。这一点往往也是SSL/TLS设计中最困难的、理论与实际差距最大的一部分,通常我们会引入第三方认证机构,并对认证机构分层级管理——所谓PKI体系
-
保证内容正确性、完整性
单向散列函数似乎是个很好的选择——哪怕原始信息发生1 bit的变化,散列结果都会变得完全不同。
单向散列函数是个啥捏?下一个系列见
说了这么堆废话,那么我们该如何保证在"开放式网络"中的安全性呢?
解决方案一:选择加密的网络协议
显而易见的是,在开放式网络之中,选择完善的加密通信协议,比如说HTTPS, SSH而不是HTTP, telnet。于是问题来了,国内很多门户网站、社交网站都没有采取全站HTTPS,包括新浪、搜狐、贴吧、微博……嗷呜满脸悲伤,本以为找到了个解决方案呢,是不?哎,每一个解决方案都是下一个问题的来源。那我们就想办法解决下一个问题吧。
通常来说,一般人针对HTTPS进行的MITM会导致浏览器警告错误的证书。无论何时,看到“证书错误”的警告,一定不要盲目点继续。12306那个SB当我没说
解决方案二:将非加密协议承载在加密隧道协议之上
以HTTP为例,HTTP是一个典型的应用层协议,它的运作需要传输层的TCP、网络层的IP等等的配合。如果我们给HTTP的下层协议"打个补丁"使其增加安全性,那么我们的目的不就达到了吗?是啊……SSL/TLS就是酱紫的,但是为了避免篇幅太长,SSL/TLS我们要留到以后再说。
1. 使用加密的VPN协议
这标题看起来很难懂是不是,但是如果我说"挂个VPN"是不是就秒懂了?不要提到VPN就想到翻墙哦。
VPN全称是Virtual Private Network,虚拟专用网。这东西,最开始呐,有一群懒虫们想在家里访问公司的内部网络。扯一条专线过去吧,太费钱了,不如发明一种协议虚拟个"隧道"?没错这就是VPN的最初思想。通常VPN是加密的,它利用已加密的通道协议(Tunneling Protocol)来达到保密、发送端认证、消息准确性等私人消息安全效果。这种技术可以利用不安全的网络来发送可靠、安全的消息。
当你成功连接VPN时,VPN程序会修改系统的路由表,使得所有数据,无论是你聊的QQ还是看的视频或是刷的微博都从加密的隧道转发出去(OpenVPN则将数据从虚拟的TAP网卡发送、接收),也就是所谓的"全局"。在这里"所有"画了删除线,比如说WebRTC就会直接无视路由表。
VPN根据不同的协议,可以有很多分类,常见的有PPTP、L2TP、OpenVPN、SSTP等
其中PPTP已经不再安全(使用iOS的用户应该记得那个警告吧)
L2TP是未加密的,通常搭配IPSec、IKE2等来达到加密、认证的目的。
OpenVPN使用OpenSSL库来加密数据与控制信息,而且对服务器也有证书认证、并且是跨平台的。
2. 使用加密的SOCKS5协议
在这里比较有名的恐怕是Clowwindy的shadowsocks了吧——shadowsocks是一款安全的加密的SOCKS5代理、附带有流量混淆功能。然而SOCKS5却不够"全局",有些软件无法设置代理,有些设置了代理,其自带的自动更新也常常会绕过代理。包括可恶的Flash都会无视代理设置。
关于HTTP与HTTPS
HTTP发明于上个世纪的八十年代,那个时候互联网先驱们们还没有想到如此复杂、险象环生的网络。随着网络的不断发展,HTTP也从1.0变成了广泛应用的1.1,最终2015年发布了全新的HTTP/2(这么前卫的我当然启用了HTTP/2的支持,只要你使用Google Chrome、Mozilla Firefox、Microsoft Edge或Opera中任意一款即可,一部分套牌浏览器的内核也应该高于支持HTTP/2的Chromium版本号)
然而尽管到了HTTP/2,可是HTTP/2依旧没有强制加密连接。
随着斯诺登把NSA大规模监听计划棱镜曝光之后,人们越来越关注隐私,越来越反对政府对个人权利的肆意侵犯(但是有很多天朝人民却在跪着,还想让别人也都跟着一起跪着);各大公司纷纷加强安全基础设施,开启透明度报告并启用全站HTTPS——在HTTPS这事上大概只有Google做的最激进了,不仅改变了搜索引擎的算法提升了HTTPS网站的权重,甚至打算在Chrome 56中正式将HTTP页面标记为不安全。
在HTTP的时代,任何网页都可能不是你想看的真正的网页,任何内容都可能是被篡改过的,你输入的任何信息都可能被第三方窃取,一切隐私都是不可能的!
为什么我们要启用全站HTTPS
尽管HTTPS会对性能造成一定程度的影响,但是随着HTTP/2的逐渐普及、HTTPS性能调优和人们对隐私关注的提高,HTTPS不应该只是为了保护用户的账号密码,用户所浏览的任何网页都应该得到加密。
同时,不是全站HTTPS也存在一些缺点,比如说cookie泄露、跳转时降级攻击。
早就应该到了全站HTTPS的时代了!HTTP已死!纸都别烧了。
结束语
在开放式网络中啊,要么搜索下周杰伦多少岁(一些无关紧要的事情),要么挂上一个VPN来保证通信安全!个人信息是可以拿来交易的,知道嘛。
在写目录的时候,我把一些密码学的概念、HTTPS/SSL/TLS放到了这一部分,但是写着写着就发现这会使篇幅严重加长并且和题目《从开放式网络中想到的》毫无关系。所以只好以后再单独写一篇HTTPS/SSL/TLS了(如果我能写好的话)。
感谢那些鼓励我写此系列文章的朋友们!
弱弱地问一下:有没有什么方法可以进行自动尝试加密,如果不行自动退回 HTTP 连接?(除了 HTTPS Everywhere)