A GitHub repository presented as a Solidity interview exercise concealed commands that could download and execute malware when developers used its custom VS Code terminal profiles, according to a SlowMist analysis published on October 23, 2026, at 18:20 UTC+8.
The repository, Hylance/sol-live, advertised eight exercises, each supposedly taking five to ten minutes. The malicious entry point was not the Solidity code: it was .vscode/settings.json.
SlowMist’s analysis of archived source code and a retained remote payload identified capabilities for collecting browser databases and wallet-extension storage, copying the macOS keychain file, uploading local files, monitoring the clipboard and executing remote commands. The report did not establish the infection scope, successful credential decryption or actual data exfiltration.
How the terminal settings triggered execution
The workspace settings mixed ordinary editor preferences with terminal profiles for macOS, Linux and Windows. The profiles used familiar names such as zsh, bash and powershell. Hundreds of spaces preceded the malicious commands, making them less visible, while a files.exclude rule hid .vscode from VS Code’s file tree. That rule did not delete the directory or prevent VS Code from reading its settings.
On macOS and Linux, the repository did not make its malicious terminal profile the default. Developers had to select the project-defined profile and launch a terminal to trigger the analyzed chain. Merely opening the repository was not the same as executing those commands.
The commands checked for Node.js and npm. If unavailable, they attempted to install nvm using the official nvm-sh/nvm v0.40.3 installer and then install Node.js LTS. They subsequently installed axios, wrote an app.js loader and ran it in the background with output suppressed.
The loader sent a POST request without a request body to a fixed endpoint on www[.]enabledomain[.]app, then passed the returned JavaScript directly to eval without validating it. SlowMist retained an approximately 4 MB obfuscated response. The chain ran with the current user’s permissions and did not require administrator authorization.
A path detail matters for investigation: the command used the quoted string "~/.vscode/cache". Because the tilde was quoted, the shell treated it as a literal directory name rather than expanding it to the user’s home directory. The loader therefore landed at ./~/.vscode/cache/app.js relative to the terminal’s starting working directory—typically the project root—not necessarily in the home directory’s .vscode/cache.
Windows was different. The settings selected PowerShell as the default and attempted to launch a hidden window, but SlowMist found quoting that could produce invalid JavaScript in app.js. The Windows chain was not tested, and successful remote code execution remained unconfirmed.
This also differed from the separate vscode_tasks_command_execute_poc previously published by SlowMist founder Cos: that proof of concept used .vscode/tasks.json and a folder-open task, triggered when automatic tasks were permitted, rather than a manually selected terminal profile.
What the retrieved payload could do
SlowMist reconstructed three principal modules offline. The main program could start them as detached Node.js processes and record their process IDs and start times in the system temporary directory:
| Module | Process-record file |
|---|---|
| Browser-data collection | pid.2.1.lock |
| File scanning and upload | pid.2.2.lock |
| Remote control | pid.2.3.lock |
The analyzed code did not contain a macOS startup service, Windows scheduled task or Linux cron job. Detached processes and process-record files do not, by themselves, establish persistence across a system reboot. Reusing the malicious terminal profile could trigger execution again.
Browser and wallet data collection
The browser module contained path rules for 13 Chromium-based browsers and checked 41 hardcoded extension IDs, including storage associated with MetaMask, Phantom, TronLink and Rabby. It targeted browser login and autofill databases, wallet-extension directories and Brave’s Local Storage/leveldb. On macOS, it could also copy ~/Library/Keychains/login.keychain-db.
However, the analyzed decryptPassword() function immediately returned an empty string, leaving its later decryption branches unreachable. The code could still extract URLs, usernames and encrypted password values, encoding the latter as Base64 for upload.
Copying these files did not demonstrate recovery of plaintext passwords, seed phrases or private keys. Wallet-storage encryption depends on the extension, and a copied macOS keychain remains protected by the user’s login password. Other key-retrieval functions were present, but their effectiveness was not tested.
The browser module uploaded through unencrypted HTTP to port 8085 on 172[.]86[.]112[.]107. Its HMAC-SHA256 check authenticated requests from a party holding the hardcoded key; it did not encrypt the uploaded content.
File scanning and remote access
The file scanner began after approximately one second, despite a code comment saying “10 minutes.” In priority locations—including Desktop, Documents, Downloads, cloud-drive folders and development directories—files could qualify for upload without matching sensitive keywords, provided they passed extension exclusions and were no larger than 5 MiB. Elsewhere under the home directory, paths had to match sensitive-file patterns.
The scanner skipped directories including .ssh, .aws, .gnupg, .kube and .config, but those exclusions did not restrict the separate remote-control module.
That module could execute server-supplied commands, read and upload specified files, provide interactive terminal sessions and check clipboard contents every second. It could also search for .env* files shortly after connecting. Cross-platform terminal implementations were present in the code but were not validated through execution.
What developers should check
SlowMist recommended prioritizing hosts where the malicious terminal profiles had actually been used, while investigating uncertain cases through execution traces. The two file-location checks are separate:
- Loader location: inspect the project directory or terminal’s actual starting working directory for a literal
~directory containing.vscode/cache/app.js—that is,./~/.vscode/cache/app.jsrelative to that working directory. - Process records: inspect the system temporary directory, not the terminal’s starting directory, for
pid.2.1.lock,pid.2.2.lockandpid.2.3.lock. - Processes and network activity: review Node.js processes and connections to
172[.]86[.]112[.]107, alongside proxy, DNS and endpoint-detection logs.
For hosts where execution was confirmed or could not be ruled out, SlowMist advised isolation and preservation of evidence before using a trusted device for wallet migration and credential rotation. Treating wallet secrets as compromised in that situation is a precautionary response—not proof that this investigation established their theft. Changing a macOS login password does not invalidate an older keychain file that may already have been copied.
Before using interview or exercise repositories, review .vscode/settings.json, custom terminal profiles, default-profile settings and startup arguments. The absence of a default malicious profile does not make a repository safe: manually selecting one can still execute its commands.
SlowMist also identified eight other GitHub repositories with similar terminal download-and-execute configurations. Those findings were limited to preliminary configuration checks; the team did not obtain and deeply analyze every remote payload.
Limits of the findings
The investigation used archived source, retained HTTP responses and offline script reconstruction. SlowMist said it did not execute the malicious samples, establish a command-and-control session or access the analysis host’s browser data, keychain or clipboard. The findings describe code capabilities, not confirmed behavior on victims’ machines.
Original SlowMist article, published October 23, 2026, at 18:20 UTC+8.