commit 40ea05385cc12b425f2e773371f055906b8a7f0a Author: Josef Fröhle Date: Thu Jun 25 15:12:51 2020 +0200 first commit diff --git a/hw_datacollector - Kopie/_locales/en/messages.json b/hw_datacollector - Kopie/_locales/en/messages.json new file mode 100644 index 0000000..16a4bd2 --- /dev/null +++ b/hw_datacollector - Kopie/_locales/en/messages.json @@ -0,0 +1,10 @@ +{ + "appName": { + "message": "HW Sniffer", + "description": "The title of the application, displayed in the web store." + }, + "appDesc": { + "message": "Make HW Tools better, and share your data with us.", + "description":"The description of the application, displayed in the web store." + } + } \ No newline at end of file diff --git a/hw_datacollector - Kopie/background.js b/hw_datacollector - Kopie/background.js new file mode 100644 index 0000000..fb53fa4 --- /dev/null +++ b/hw_datacollector - Kopie/background.js @@ -0,0 +1,74 @@ +/* global chrome */ + +// List of tabIds where CSP headers are disabled +var disabledTabIds = []; + +var isCSPDisabled = function (tabId) { + return disabledTabIds.includes(tabId); +}; + +var toggleDisableCSP = function (tabId) { + if (isCSPDisabled(tabId)) { + // remove this tabId from disabledTabIds + disabledTabIds = disabledTabIds.filter(function (val) { + return val !== tabId; + }); + } else { + disabledTabIds.push(tabId); + + // Sites that use Application Cache to cache their HTML document means this + // extension is not able to alter HTTP response headers (as there is no HTTP + // request when serving documents from the cache). + // + // An example page that this fixes is https://web.whatsapp.com + chrome.browsingData.remove({}, { serviceWorkers: true }, function () { }); + } + updateUI(tabId); +}; + +var onHeadersReceived = function (details) { + if (!isCSPDisabled(details.tabId)) { + return; + } + + for (var i = 0; i < details.responseHeaders.length; i++) { + if (details.responseHeaders[i].name.toLowerCase() === 'content-security-policy') { + details.responseHeaders[i].value = ''; + } + } + + return { + responseHeaders: details.responseHeaders + }; +}; + +var updateUI = function (tabId) { + var isDisabled = isCSPDisabled(tabId); + var iconName = isDisabled ? 'off' : 'on'; + var title = isDisabled ? 'disabled' : 'enabled'; + + chrome.browserAction.setIcon({ path: 'hero_' + iconName + '.png' }); + chrome.browserAction.setTitle({ title: 'HW Collector are ' + title }); +}; + +var init = function () { + // When Chrome recieves some headers + var onHeaderFilter = { urls: ['*://*/*'], types: ['main_frame', 'sub_frame', "script", "object", "xmlhttprequest", "other"] }; + chrome.webRequest.onHeadersReceived.addListener( + onHeadersReceived, onHeaderFilter, ['blocking', 'responseHeaders'] + ); + + // When the user clicks the plugin icon + //chrome.browserAction.onClicked.addListener(function (tab) { + // toggleDisableCSP(tab.id); + //}); + + // When the user changes tab + chrome.tabs.onActivated.addListener(function (activeInfo) { + updateUI(activeInfo.tabId); + }); + + // onAttached +}; + +init(); \ No newline at end of file diff --git a/hw_datacollector - Kopie/hero_off.png b/hw_datacollector - Kopie/hero_off.png new file mode 100644 index 0000000..3a1e98e Binary files /dev/null and b/hw_datacollector - Kopie/hero_off.png differ diff --git a/hw_datacollector - Kopie/hero_on.png b/hw_datacollector - Kopie/hero_on.png new file mode 100644 index 0000000..478076e Binary files /dev/null and b/hw_datacollector - Kopie/hero_on.png differ diff --git a/hw_datacollector - Kopie/injected.js b/hw_datacollector - Kopie/injected.js new file mode 100644 index 0000000..5eb25ec --- /dev/null +++ b/hw_datacollector - Kopie/injected.js @@ -0,0 +1,388 @@ +const getCircularReplacer = () => { + const seen = new WeakSet(); + return (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; +}; + +/** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ +function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; +} + +function ab2str(buf) { + return String.fromCharCode.apply(null, new Uint8Array(buf)); +} +function str2ab(str) { + var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char + var bufView = new Uint8Array(buf); + for (var i = 0, strLen = str.length; i < strLen; i++) { + bufView[i] = str.charCodeAt(i); + } + return buf; +} +(function () { + + var xml_type; + // branch for native XMLHttpRequest object + if (window.XMLHttpRequest && !(window.ActiveXObject)) { + + xml_type = 'XMLHttpRequest'; + + // branch for IE/Windows ActiveX version + } else if (window.ActiveXObject) { + try { + + a = new ActiveXObject('Msxml2.XMLHTTP'); + + xml_type = 'Msxml2.XMLHTTP'; + + } catch (e) { + + a = new ActiveXObject('Microsoft.XMLHTTP'); + + xml_type = 'Microsoft.XMLHTTP'; + + } + + } + + var ActualActiveXObject = window.ActiveXObject; + var ActiveXObject; + + if (xml_type == 'XMLHttpRequest') { + + (function (open) { + XMLHttpRequest.prototype.open = function (method, url, async, user, password) { + this._method = method; + this._url = url; + this._requestHeaders = {}; + this._startTime = (new Date()).toISOString(); + if (this._url.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + //console.log('Intercept'); + //console.log(this, arguments); + //console.log("start here logging") + } + return open.apply(this, arguments); + }; + })(XMLHttpRequest.prototype.open); + + (function (setRequestHeader) { + XMLHttpRequest.prototype.setRequestHeader = function (header, value) { + if (this._url.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + this._requestHeaders[header] = value; + } + return setRequestHeader.apply(this, arguments); + }; + })(XMLHttpRequest.prototype.setRequestHeader); + + (function (send) { + XMLHttpRequest.prototype.send = function (postData) { + this.addEventListener('load', function () { + var endTime = (new Date()).toISOString(); + if (postData && postData.length == 0 || postData == '') { + return + } + if (this._url.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + + var requestModel = { + 'uri': this._url, + 'verb': this._method, + 'time': this._startTime, + 'headers': this._requestHeaders + }; + var dataX = undefined; + var abData = ab2str(postData) + try { + dataX = JSON.parse(abData, getCircularReplacer()); + } catch (e) { + console.error(e); + console.log(typeof postData); + console.log(postData); + console.log(typeof abData); + console.log(abData); + } + + if ( + dataX == undefined || + ( + dataX.calls.some(e => ( + e.name === 'stashClient' || + e.name === 'chatSendText' + )) && dataX.calls.length == 1 + ) + || + ( + dataX.calls.some(e => ( + e.name === 'registration' // only if it is internal used, else get it and connect with all data + )) + && dataX.calls.length > 1 + ) + ) { + return + } + requestModel['body'] = dataX + //console.log('request post abData is ???'); + //console.log(typeof abData); + //console.log(abData); + //if (postData) { + // //console.log('request post data is ???'); + // //console.log(typeof postData); + // //console.log(postData); + // if (typeof postData === 'string') { + // //console.log('request post data is string'); + // //console.log(postData); + // try { + // requestModel['body'] = JSON.parse(abData); + // } catch (err) { + // //console.log('JSON decode failed'); + // //console.log(err); + // requestModel['transfer_encoding'] = 'base64'; + // requestModel['body'] = window.btoa(postData); + // } + // } else if (typeof postData === 'object' || typeof postData === 'array' || typeof postData === 'number' || typeof postData === 'boolean') { + // requestModel['body'] = postData; + // } else if (typeof postData === 'function') { + // requestModel['body'] = abData; + // } + //} + + var responseHeaders = parseResponseHeaders(this.getAllResponseHeaders()); + + var responseModel = { + 'status': this.status, + 'time': endTime, + 'headers': responseHeaders + }; + + //console.log(this.responseType); + //try { + // //console.log(this.responseText); + //} catch (err) { } + //console.log(this.response); + + try { + if (this.response) { + // responseText is string or null + try { + responseModel['body'] = JSON.parse(this.response); + } catch (err) { + responseModel['transfer_encoding'] = 'base64'; + responseModel['body'] = window.btoa(this.response); + } + } + } catch (err) { } + + var event = { + 'request': requestModel, + 'response': responseModel + }; + // Example POST method implementation: + async function postDataFn(data = {}) { + // Default options are marked with * + var response = await fetch("https://hwcollector.derhost.com", { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + mode: 'cors', // no-cors, *cors, same-origin + cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached + credentials: 'omit', // include, *same-origin, omit + headers: { + 'Content-Type': 'application/json' + // 'Content-Type': 'application/x-www-form-urlencoded', + }, + redirect: 'follow', // manual, *follow, error + referrerPolicy: 'origin', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + body: JSON.stringify(data, getCircularReplacer()) // body data type must match "Content-Type" header + }); + return response.json() + } + + // ignore empty responses... + if (event.response && event.response.body && event.response.body.results && event.response.body.results[0].result && event.response.body.results[0].result.response == null) { + return + } + postDataFn(event); + } + + }); + return send.apply(this, arguments); + }; + })(XMLHttpRequest.prototype.send); + } else { + + ActiveXObject = function (progid) { + var ax = new ActualActiveXObject(progid); + + if (progid.toLowerCase() == "microsoft.xmlhttp") { + var o = { + _ax: ax, + _status: "fake", + responseText: "", + responseXml: null, + readyState: 0, + dataType: 'plain', + status: 0, + statusText: 0, + onReadyStateChange: null, + onreadystatechange: null + }; + o._onReadyStateChange = function () { + var self = o; + return function () { + self.readyState = self._ax.readyState; + if (self.readyState == 4) { + + self.responseText = self._ax.responseText; + self.responseXml = self._ax.responseXml; + self.status = self._ax.status; + self.statusText = self._ax.statusText; + + } + if (self.onReadyStateChange) { + self.onReadyStateChange(); + } + if (self.onreadystatechange) { + self.onreadystatechange(); + } + } + }(); + o.open = function (bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword) { + this._ax.onReadyStateChange = this._onReadyStateChange; + this._ax.onreadystatechange = this._onReadyStateChange; + if (bstrUrl.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + + //console.log('Intercept'); + //console.log(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword); + //console.log("start here logging windows?!") + } + return this._ax.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword); + }; + o.send = function (varBody) { + return this._ax.send(varBody); + }; + o.abort = function () { + return this._ax.abort(); + } + o.setRequestHeader = function (k, v) { + return this._ax.setRequestHeader(k, v) + } + o.setrequestheader = function (k, v) { + return this._ax.setRequestHeader(k, v) + } + o.getResponseHeader = function (k) { + return this._ax.getResponseHeader(k) + } + o.getresponseheader = function (k) { + return this._ax.getResponseHeader(k) + } + + } else if (progid.toLowerCase() == "msxml2.xmlhttp") { + var o = { + _ax: ax, + _status: "fake", + responseText: "", + responseXml: null, + readyState: 0, + dataType: 'plain', + status: 0, + statusText: 0, + onReadyStateChange: null, + onreadystatechange: null + }; + o._onReadyStateChange = function () { + var self = o; + return function () { + self.readyState = self._ax.readyState; + if (self.readyState == 4) { + + self.responseText = self._ax.responseText; + self.responseXml = self._ax.responseXml; + self.status = self._ax.status; + self.statusText = self._ax.statusText; + + } + if (self.onReadyStateChange) { + self.onReadyStateChange(); + } + if (self.onreadystatechange) { + self.onreadystatechange(); + } + } + }(); + o.open = function (bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword) { + this._ax.onReadyStateChange = this._onReadyStateChange; + this._ax.onreadystatechange = this._onReadyStateChange; + if (bstrUrl.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + + //console.log('Intercept'); + //console.log(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword); + //console.log("start here logging windows?!") + } + return this._ax.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword); + }; + o.send = function (varBody) { + return this._ax.send(varBody); + }; + o.abort = function () { + return this._ax.abort(); + } + o.setRequestHeader = function (k, v) { + return this._ax.setRequestHeader(k, v) + } + o.setrequestheader = function (k, v) { + return this._ax.setRequestHeader(k, v) + } + o.getResponseHeader = function (k) { + return this._ax.getResponseHeader(k) + } + o.getresponseheader = function (k) { + return this._ax.getResponseHeader(k) + } + + } else { + var o = ax; + } + + return o; + } + + } + +})(); \ No newline at end of file diff --git a/hw_datacollector - Kopie/injector.js b/hw_datacollector - Kopie/injector.js new file mode 100644 index 0000000..01cf1fc --- /dev/null +++ b/hw_datacollector - Kopie/injector.js @@ -0,0 +1,6 @@ +var s = document.createElement('script'); +s.src = chrome.extension.getURL('injected.js'); +s.onload = function () { + this.remove(); +}; +(document.head || document.documentElement).appendChild(s); \ No newline at end of file diff --git a/hw_datacollector - Kopie/manifest copy.json b/hw_datacollector - Kopie/manifest copy.json new file mode 100644 index 0000000..476d159 --- /dev/null +++ b/hw_datacollector - Kopie/manifest copy.json @@ -0,0 +1,47 @@ +{ + "manifest_version": 2, + + "name": "HW Sniffer", + "description": "Make HW Tools better, and share your data with us.", + "version": "1.0.0", + "default_locale": "en", + + "icons": { + "128": "hero_on.png" + }, + + "permissions": [ + "tabs", + "webRequest", + "webRequestBlocking", + "browsingData", + "https://i-heroes-fb.nextersglobal.com/*" + ], + + + // "browser_action": { + // "default_icon": "hero_on.png", + // "default_title": "HW Sniffer" + // }, + + + "background": { + "scripts": ["background.js"], + "persistent": true + }, + + "content_scripts": [{ + "matches": [ + "https://i-heroes-fb.nextersglobal.com/*" + ], + "js": [ "injector.js" ], + "run_at": "document_start", + "all_frames": true, + "persistent": true + }], + "web_accessible_resources": [ + "injected.js" + ], + "content_security_policy": "default-src 'self'; script-src 'self'; style-src * 'unsafe-inline'; img-src 'self' data:;" + +} \ No newline at end of file diff --git a/hw_datacollector - Kopie/manifest.json b/hw_datacollector - Kopie/manifest.json new file mode 100644 index 0000000..c013930 --- /dev/null +++ b/hw_datacollector - Kopie/manifest.json @@ -0,0 +1,37 @@ +{ + "manifest_version": 2, + + "name": "HW Sniffer", + "description": "Make HW Tools better, and share your data with us.", + "version": "1.0.0", + "default_locale": "en", + + "icons": { + "128": "hero_on.png" + }, + + "permissions": [ + "https://i-heroes-fb.nextersglobal.com/*" + ], + + + "browser_action": { + "default_icon": "hero_on.png", + "default_title": "HW Sniffer" + }, + + "content_scripts": [{ + "matches": [ + "https://i-heroes-fb.nextersglobal.com/*" + ], + "js": [ "injector.js" ], + "run_at": "document_start", + "all_frames": true, + "persistent": true + }], + "web_accessible_resources": [ + "injected.js" + ], + "content_security_policy": "default-src 'self'; script-src 'self'; style-src * 'unsafe-inline'; img-src 'self' data:;" + +} \ No newline at end of file diff --git a/hw_datacollector.crx b/hw_datacollector.crx new file mode 100644 index 0000000..b90321a Binary files /dev/null and b/hw_datacollector.crx differ diff --git a/hw_datacollector.pem b/hw_datacollector.pem new file mode 100644 index 0000000..d89f86c --- /dev/null +++ b/hw_datacollector.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCvs/olB8tJ11SE +YllTVc19QyX0C/CiPzgb9P74FcmfjPGBRyYHqCN+g/L2deNTNBJY0OpEV8fGvEnc +eWXOpevxJrqKTv2gH2zL0HO0IQDTnDSDzytJX1gv0ZP//Zk+n3eWttGm9p2HJyni +Z/EB8mcJQZkRX57Pccr1ZBwICROag2M7zacvo8UNjqSx9VXF43qaDee2LmX0BVGX +Hp4FA2N0rLKV/6GeBnb9INQP+X9ENMHDhqs02oK4Z3QoMgoA7BbsD2SxKwc/V/5F +79POnV/DXnYu6u0VWUQ7vtRIWc+dCyLANQCTMKxqEbdFSqjgQfGCg0aRvOvWc5H8 +H3OxcSppAgMBAAECggEAJMl4aq9mk0fH1M3oqOeSlhLsi9vCHp5A562UgqnBJKw0 +Vl5oqnq8L719rbeCCIYi/0CChBui4svCZSxvseQQcdWrgdDHDnL16vhyeTjdvPB8 +GErUY9DYHG7zX0of/zoRJleRrrT8x3LeNJ6RmdhAVXJME5SjIgjPtzAmJFKOLa/S +upxI8z5g+odtYYQLyimyIhNrXI8yJQLb/pnrKPJj5IDjcPobYapfPAd5392q1CfD +HEIpnrjnO+TlRjapADOpcmjQTyaZOxO/wXw6mFww33He+I97KxLPPQWn0TWyFJdm +GtgVQaqkY5BZyBHoGuAwx/wRU/pwvL9rXPfjngElRwKBgQDeZSv9xzbEUtgJe4QX +DBozwP9VW+/Q16YkK5R3NZJU6rA13hY8ztLue869R1Xamr0qXWbItK2g3+6ANkNh +pLYTM4rwhcsLBg7QgKrca1CEia5/B+0L1ZxuM1uWt6vgOQpue6kPq015iwmplkmk +ufAPfY95HxT7WKKn0UM0yQGkcwKBgQDKQKFQwmRvabA3z11Xf4Vqj7Te5ugfcC2k +tBHdslYERTig6ksq6+Go1HrKbJhJcU7u480k1ldwdlztW228HG30TxLGBIh5C05x +caZQ+fe2Igtp3+QvZGYV0Hmc8QXvH8QE44luCFyUQ/XnOVdNBwR5AYgZmrKsI3oH +Fm+KPKqaswKBgDXmt37Opct3eLzzntQnLsKUaE479ifb3Hyvw1ARP+Is74Bez2z1 +g9IhV74wZ/KPxoFaGetTPzHalGemvzYPQcHtoCMjik6lrTmDteWubNlytUQ8m4te +vodHE0+4PIQfzxNwDU2q6yAmPrVHo5m1JyXZ/MgSbHduyB18bpmAjlFZAoGAD1ja +JNOrZVzit0lv7szJZe2jrupcoM4VWJMla+o1ZruN8X/11jrx86qz6ppU7/W+JJh6 +n5n4JpuEr6opaIXLvicl6Iq9hFncSPVzxl9BcbuhnBYWLZZzvKIGKGeNqLiDWk+d +xRCzXbjOdw491qV6rGf2WOMJPdCvWMxWCGpUE8sCgYBz7x0LlVyY5Yd7LfqNePM5 ++NQDzdcGasEcAHBhrmAHaeG/Rmf9JHjF3z4fFwg8YdOf7QfQP2gGKao1RkLTKFEH +8d5l6uc9hBJszy2E9hikOL+GlxnFWYiT22L3yXJN6djBqm6gVPvRvTog2tQHg4Iw +rBo2B8+rYWr+xwZWraOXPg== +-----END PRIVATE KEY----- diff --git a/hw_datacollector/_locales/en/messages.json b/hw_datacollector/_locales/en/messages.json new file mode 100644 index 0000000..16a4bd2 --- /dev/null +++ b/hw_datacollector/_locales/en/messages.json @@ -0,0 +1,10 @@ +{ + "appName": { + "message": "HW Sniffer", + "description": "The title of the application, displayed in the web store." + }, + "appDesc": { + "message": "Make HW Tools better, and share your data with us.", + "description":"The description of the application, displayed in the web store." + } + } \ No newline at end of file diff --git a/hw_datacollector/bg.js b/hw_datacollector/bg.js new file mode 100644 index 0000000..7b3ed87 --- /dev/null +++ b/hw_datacollector/bg.js @@ -0,0 +1,27 @@ +/* global chrome */ + +var onHeadersReceived = function (details) { + + for (var i = 0; i < details.responseHeaders.length; i++) { + if (details.responseHeaders[i].name.toLowerCase() === 'content-security-policy') { + details.responseHeaders[i].value = ''; + } + } + + return { + responseHeaders: details.responseHeaders + }; +}; + + +var init = function () { + // When Chrome recieves some headers + var onHeaderFilter = { urls: ['*://*/*'], types: ['main_frame', 'sub_frame', "script", "object", "xmlhttprequest", "other"] }; + chrome.webRequest.onHeadersReceived.addListener( + onHeadersReceived, onHeaderFilter, ['blocking', 'responseHeaders'] + ); + + // onAttached +}; + +init(); \ No newline at end of file diff --git a/hw_datacollector/hero_off.png b/hw_datacollector/hero_off.png new file mode 100644 index 0000000..3a1e98e Binary files /dev/null and b/hw_datacollector/hero_off.png differ diff --git a/hw_datacollector/hero_on.png b/hw_datacollector/hero_on.png new file mode 100644 index 0000000..478076e Binary files /dev/null and b/hw_datacollector/hero_on.png differ diff --git a/hw_datacollector/injected.js b/hw_datacollector/injected.js new file mode 100644 index 0000000..5eb25ec --- /dev/null +++ b/hw_datacollector/injected.js @@ -0,0 +1,388 @@ +const getCircularReplacer = () => { + const seen = new WeakSet(); + return (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; +}; + +/** + * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into + * a dictionary. + * + * @exports parseResponseHeaders + * + * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method + * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * is that header's value. + * + * @private + */ +function parseResponseHeaders(headerString) { + var headers = {}; + + if (!headerString) { + return headers; + } + + var headerPairs = headerString.split('\u000d\u000a'); + + for (var i = 0; i < headerPairs.length; ++i) { + var headerPair = headerPairs[i]; + // Can't use split() here because it does the wrong thing + // if the header value has the string ": " in it. + var index = headerPair.indexOf('\u003a\u0020'); + if (index > 0) { + var key = headerPair.substring(0, index); + var val = headerPair.substring(index + 2); + headers[key] = val; + } + } + + return headers; +} + +function ab2str(buf) { + return String.fromCharCode.apply(null, new Uint8Array(buf)); +} +function str2ab(str) { + var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char + var bufView = new Uint8Array(buf); + for (var i = 0, strLen = str.length; i < strLen; i++) { + bufView[i] = str.charCodeAt(i); + } + return buf; +} +(function () { + + var xml_type; + // branch for native XMLHttpRequest object + if (window.XMLHttpRequest && !(window.ActiveXObject)) { + + xml_type = 'XMLHttpRequest'; + + // branch for IE/Windows ActiveX version + } else if (window.ActiveXObject) { + try { + + a = new ActiveXObject('Msxml2.XMLHTTP'); + + xml_type = 'Msxml2.XMLHTTP'; + + } catch (e) { + + a = new ActiveXObject('Microsoft.XMLHTTP'); + + xml_type = 'Microsoft.XMLHTTP'; + + } + + } + + var ActualActiveXObject = window.ActiveXObject; + var ActiveXObject; + + if (xml_type == 'XMLHttpRequest') { + + (function (open) { + XMLHttpRequest.prototype.open = function (method, url, async, user, password) { + this._method = method; + this._url = url; + this._requestHeaders = {}; + this._startTime = (new Date()).toISOString(); + if (this._url.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + //console.log('Intercept'); + //console.log(this, arguments); + //console.log("start here logging") + } + return open.apply(this, arguments); + }; + })(XMLHttpRequest.prototype.open); + + (function (setRequestHeader) { + XMLHttpRequest.prototype.setRequestHeader = function (header, value) { + if (this._url.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + this._requestHeaders[header] = value; + } + return setRequestHeader.apply(this, arguments); + }; + })(XMLHttpRequest.prototype.setRequestHeader); + + (function (send) { + XMLHttpRequest.prototype.send = function (postData) { + this.addEventListener('load', function () { + var endTime = (new Date()).toISOString(); + if (postData && postData.length == 0 || postData == '') { + return + } + if (this._url.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + + var requestModel = { + 'uri': this._url, + 'verb': this._method, + 'time': this._startTime, + 'headers': this._requestHeaders + }; + var dataX = undefined; + var abData = ab2str(postData) + try { + dataX = JSON.parse(abData, getCircularReplacer()); + } catch (e) { + console.error(e); + console.log(typeof postData); + console.log(postData); + console.log(typeof abData); + console.log(abData); + } + + if ( + dataX == undefined || + ( + dataX.calls.some(e => ( + e.name === 'stashClient' || + e.name === 'chatSendText' + )) && dataX.calls.length == 1 + ) + || + ( + dataX.calls.some(e => ( + e.name === 'registration' // only if it is internal used, else get it and connect with all data + )) + && dataX.calls.length > 1 + ) + ) { + return + } + requestModel['body'] = dataX + //console.log('request post abData is ???'); + //console.log(typeof abData); + //console.log(abData); + //if (postData) { + // //console.log('request post data is ???'); + // //console.log(typeof postData); + // //console.log(postData); + // if (typeof postData === 'string') { + // //console.log('request post data is string'); + // //console.log(postData); + // try { + // requestModel['body'] = JSON.parse(abData); + // } catch (err) { + // //console.log('JSON decode failed'); + // //console.log(err); + // requestModel['transfer_encoding'] = 'base64'; + // requestModel['body'] = window.btoa(postData); + // } + // } else if (typeof postData === 'object' || typeof postData === 'array' || typeof postData === 'number' || typeof postData === 'boolean') { + // requestModel['body'] = postData; + // } else if (typeof postData === 'function') { + // requestModel['body'] = abData; + // } + //} + + var responseHeaders = parseResponseHeaders(this.getAllResponseHeaders()); + + var responseModel = { + 'status': this.status, + 'time': endTime, + 'headers': responseHeaders + }; + + //console.log(this.responseType); + //try { + // //console.log(this.responseText); + //} catch (err) { } + //console.log(this.response); + + try { + if (this.response) { + // responseText is string or null + try { + responseModel['body'] = JSON.parse(this.response); + } catch (err) { + responseModel['transfer_encoding'] = 'base64'; + responseModel['body'] = window.btoa(this.response); + } + } + } catch (err) { } + + var event = { + 'request': requestModel, + 'response': responseModel + }; + // Example POST method implementation: + async function postDataFn(data = {}) { + // Default options are marked with * + var response = await fetch("https://hwcollector.derhost.com", { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + mode: 'cors', // no-cors, *cors, same-origin + cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached + credentials: 'omit', // include, *same-origin, omit + headers: { + 'Content-Type': 'application/json' + // 'Content-Type': 'application/x-www-form-urlencoded', + }, + redirect: 'follow', // manual, *follow, error + referrerPolicy: 'origin', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + body: JSON.stringify(data, getCircularReplacer()) // body data type must match "Content-Type" header + }); + return response.json() + } + + // ignore empty responses... + if (event.response && event.response.body && event.response.body.results && event.response.body.results[0].result && event.response.body.results[0].result.response == null) { + return + } + postDataFn(event); + } + + }); + return send.apply(this, arguments); + }; + })(XMLHttpRequest.prototype.send); + } else { + + ActiveXObject = function (progid) { + var ax = new ActualActiveXObject(progid); + + if (progid.toLowerCase() == "microsoft.xmlhttp") { + var o = { + _ax: ax, + _status: "fake", + responseText: "", + responseXml: null, + readyState: 0, + dataType: 'plain', + status: 0, + statusText: 0, + onReadyStateChange: null, + onreadystatechange: null + }; + o._onReadyStateChange = function () { + var self = o; + return function () { + self.readyState = self._ax.readyState; + if (self.readyState == 4) { + + self.responseText = self._ax.responseText; + self.responseXml = self._ax.responseXml; + self.status = self._ax.status; + self.statusText = self._ax.statusText; + + } + if (self.onReadyStateChange) { + self.onReadyStateChange(); + } + if (self.onreadystatechange) { + self.onreadystatechange(); + } + } + }(); + o.open = function (bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword) { + this._ax.onReadyStateChange = this._onReadyStateChange; + this._ax.onreadystatechange = this._onReadyStateChange; + if (bstrUrl.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + + //console.log('Intercept'); + //console.log(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword); + //console.log("start here logging windows?!") + } + return this._ax.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword); + }; + o.send = function (varBody) { + return this._ax.send(varBody); + }; + o.abort = function () { + return this._ax.abort(); + } + o.setRequestHeader = function (k, v) { + return this._ax.setRequestHeader(k, v) + } + o.setrequestheader = function (k, v) { + return this._ax.setRequestHeader(k, v) + } + o.getResponseHeader = function (k) { + return this._ax.getResponseHeader(k) + } + o.getresponseheader = function (k) { + return this._ax.getResponseHeader(k) + } + + } else if (progid.toLowerCase() == "msxml2.xmlhttp") { + var o = { + _ax: ax, + _status: "fake", + responseText: "", + responseXml: null, + readyState: 0, + dataType: 'plain', + status: 0, + statusText: 0, + onReadyStateChange: null, + onreadystatechange: null + }; + o._onReadyStateChange = function () { + var self = o; + return function () { + self.readyState = self._ax.readyState; + if (self.readyState == 4) { + + self.responseText = self._ax.responseText; + self.responseXml = self._ax.responseXml; + self.status = self._ax.status; + self.statusText = self._ax.statusText; + + } + if (self.onReadyStateChange) { + self.onReadyStateChange(); + } + if (self.onreadystatechange) { + self.onreadystatechange(); + } + } + }(); + o.open = function (bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword) { + this._ax.onReadyStateChange = this._onReadyStateChange; + this._ax.onreadystatechange = this._onReadyStateChange; + if (bstrUrl.startsWith("https://heroes-fb.nextersglobal.com/api/")) { + + //console.log('Intercept'); + //console.log(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword); + //console.log("start here logging windows?!") + } + return this._ax.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword); + }; + o.send = function (varBody) { + return this._ax.send(varBody); + }; + o.abort = function () { + return this._ax.abort(); + } + o.setRequestHeader = function (k, v) { + return this._ax.setRequestHeader(k, v) + } + o.setrequestheader = function (k, v) { + return this._ax.setRequestHeader(k, v) + } + o.getResponseHeader = function (k) { + return this._ax.getResponseHeader(k) + } + o.getresponseheader = function (k) { + return this._ax.getResponseHeader(k) + } + + } else { + var o = ax; + } + + return o; + } + + } + +})(); \ No newline at end of file diff --git a/hw_datacollector/injector.js b/hw_datacollector/injector.js new file mode 100644 index 0000000..01cf1fc --- /dev/null +++ b/hw_datacollector/injector.js @@ -0,0 +1,6 @@ +var s = document.createElement('script'); +s.src = chrome.extension.getURL('injected.js'); +s.onload = function () { + this.remove(); +}; +(document.head || document.documentElement).appendChild(s); \ No newline at end of file diff --git a/hw_datacollector/manifest.json b/hw_datacollector/manifest.json new file mode 100644 index 0000000..79a1b73 --- /dev/null +++ b/hw_datacollector/manifest.json @@ -0,0 +1,43 @@ +{ + "manifest_version": 2, + + "name": "HW Sniffer", + "description": "Make HW Tools better, and share your data with us.", + "version": "1.0.0", + "default_locale": "en", + + "icons": { + "128": "hero_on.png" + }, + + "permissions": [ + "webRequest", + "webRequestBlocking", + "https://i-heroes-fb.nextersglobal.com/*" + ], + + "browser_action": { + "default_icon": "hero_on.png", + "default_title": "HW Sniffer" + }, + + "background": { + "scripts": ["bg.js"], + "persistent": true + }, + + "content_scripts": [{ + "matches": [ + "https://i-heroes-fb.nextersglobal.com/*" + ], + "js": [ "injector.js" ], + "run_at": "document_start", + "all_frames": true, + "persistent": true + }], + "web_accessible_resources": [ + "injected.js" + ], + "content_security_policy": "default-src 'self'; script-src 'self'; style-src * 'unsafe-inline'; img-src 'self' data:;" + +} \ No newline at end of file