first commit

This commit is contained in:
2020-06-25 15:12:51 +02:00
commit 40ea05385c
17 changed files with 1064 additions and 0 deletions

View File

@@ -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."
}
}

View File

@@ -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();

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -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;
}
}
})();

View File

@@ -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);

View File

@@ -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:;"
}

View File

@@ -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:;"
}