What happened
According to Pluto Security, a new wave of a campaign it calls EtherDuck, part of SleepyDuck, put fake Solidity and Hardhat extensions on Open VSX, the extension store used by editors such as Cursor, Windsurf and VSCodium. Pluto ties it to the same actor behind earlier SleepyDuck and ScreenConnect campaigns. As far as the sources we have show, Pluto is the only researcher to have published on these waves.
Pluto says the listings imitated legitimate tooling and inflated their download counts to outrank genuine extensions in search. Displayed download numbers on these listings are not real install counts. The four extension IDs Pluto lists are alejandroaranda.solidity-languini, alejandroaranda.solidity-langsupport, juanfranblanco.solidity-vscode and Nomic-ETH.hardhat-solidity.
Pluto says that when the extension activates, it starts a hidden Node process that runs a bundled video file. A custom archive appended after the video data holds payloads for each platform. On macOS and Linux the payload is a Go backdoor that reads its server address from an Ethereum smart contract. On a Mac, Pluto says, it removes its own quarantine flag so Gatekeeper never warns, and adds a LaunchAgent so it starts at every login. It checks for virtual machines, debuggers and sandboxes and exits silently if it finds them. On Windows, Pluto says victims get a ScreenConnect remote access client.
Pluto says Open VSX removed each malicious wave after about 19 hours, but the operator came back within hours under a new publisher account with the same payloads and added anti-VM and anti-debugger checks. Pluto says uninstalling the extension does not remove the malware; the installed background process keeps running.
Timeline
Pluto says the Ethereum contract the backdoor later reads its server address from was deployed.[1]
The first two fake listings appeared under the publisher janeykomit.[1]
Open VSX confirmed both listings removed, about 19 hours after they appeared.[1]
Re-uploaded fake listings reached their final versions under a new publisher, dbolovetoa.[1]
Open VSX confirmed the re-uploaded listings removed.[1]
Pluto Security published its report on the campaign.[1]
Who is affected
- Solidity developers who installed any of the four listed extensions from Open VSX, in Cursor, Windsurf, VSCodium or other editors that use that store.
- Anyone who has or ever had these extensions installed should treat the machine as compromised, since Pluto says a compromised workstation can expose credentials and deployment authority.
- Developers who relied on displayed download counts to judge which Solidity extension was genuine.
How to check
- Look in your editor's extensions list for the four IDs: alejandroaranda.solidity-languini, alejandroaranda.solidity-langsupport, juanfranblanco.solidity-vscode and Nomic-ETH.hardhat-solidity, including past installs.
- On a Mac, look for a hidden .solidity folder in your home directory and for a related LaunchAgent in your user Library.
- Check network logs for connections to the command-and-control addresses Pluto lists, and for repeated Ethereum calls to the config contract from a process that is not a wallet.
What to do
- Disconnect the machine from the network first to cut the active command channel.
- Do not rely on uninstalling the extension; it does not remove the backdoor.
- Remove the payload folder and the LaunchAgent, or better, rebuild the Mac.
- Rotate every credential the machine could reach: SSH keys, cloud sessions, publishing tokens and above all wallet keys and contract deployment keys.
- Install Solidity tooling only from the real publishers and block by publisher account and payload hash, not extension name alone.
Affected packages
The package versions named in this report.
| Ecosystem | Package | Versions |
|---|---|---|
| Open VSX | alejandroaranda.solidity-languini | 0.9.2 |
| Open VSX | alejandroaranda.solidity-langsupport | 0.0.6 |
| Open VSX | juanfranblanco.solidity-vscode | 0.0.1890.0.1900.0.191 |
| Open VSX | Nomic-ETH.hardhat-solidity | 0.9.20.9.3 |
Indicators of compromise
Shown defanged so they can't be clicked. Copy copies the real value. Every indicator appears in the cited source.
| Type | Indicator | Note | Copy |
|---|---|---|---|
| Extension ID | alejandroaranda.solidity-languini | Malicious Open VSX extension (0.9.2)[1] | |
| Extension ID | alejandroaranda.solidity-langsupport | Malicious Open VSX extension (0.0.6)[1] | |
| Extension ID | juanfranblanco.solidity-vscode | Malicious Open VSX extension (0.0.189 to 0.0.191)[1] | |
| Extension ID | Nomic-ETH.hardhat-solidity | Malicious Open VSX extension (0.9.2 and 0.9.3)[1] | |
| IP and port | 185[.]232[.]84[.]169:8041 | ScreenConnect relay (Windows)[1] | |
| IP and port | 193[.]57[.]9[.]17:4912 | Go backdoor C2 (macOS/Linux)[1] | |
| URL | hxxp://107[.]189[.]27[.]46:3000/app.js | Staging URL in contract param2 (unreferenced, not serving during analysis)[1] | |
| Wallet | 0xf8a900Db50b3331be6B768bA460BB59f3E40C344 | Ethereum config contract (EtherHiding-style)[1] | |
| Wallet | 0xfd3fc58bcbd8ccc77b6000201438edfc636e7ca7 | Owner EOA (only account that can rotate C2)[1] | |
| SHA-256 | 7527e86d70e7c9493db4356f1c3775380431b310000f2602c1e993cf435d01da | app.msi (ScreenConnect installer)[1] | |
| SHA-256 | 37d14bff30762ca701e9c1f8bc6c57c065bb20ae3a2208cb7411a6530610f08e | invoke.ps1 (loader)[1] | |
| SHA-256 | 80d2672e2599732d3c0ae2a4cd0d1e3fe4d555a60273ce33feb99db3f34d250f | darwin_amd64 backdoor[1] | |
| SHA-256 | fae61f31f00988fdc5cc9e7272b51e08af2e245d81003237875415930fd27358 | darwin_arm64 backdoor[1] | |
| SHA-256 | 9b73e7cd4e1425e770392549d8df46c706139ef476f4f7b9ac405165dc8d9696 | linux_amd64 backdoor[1] | |
| SHA-256 | b601776817363b96295119f7221338a122d5247a35a77a64b04f286e1bbcc565 | linux_arm64 backdoor[1] | |
| SHA-256 | 683ad81cdc028c538ee66da8e6b60f2a5ab070bfd900da80175df317a73886d8 | note.txt (taunt)[1] | |
| File path | ~/.solidity/ | macOS/Linux payload and wrapper[1] | |
| File path | ~/Library/LaunchAgents/com.solidity.langsupport.runner.plist | macOS LaunchAgent persistence[1] | |
| File path | ~/.config/systemd/user/solidity-langsupport-runner.service | Linux systemd persistence[1] | |
| File path | C:\Program Files (x86)\ScreenConnect Client (5cbe79c9c25524df)\ | ScreenConnect client folder[1] | |
| File path | %TEMP%\solidity-langsupport-debug.log | debug log[1] | |
| Other | __JAWBRK_EC__ | shell markers[1] | |
| Other | __JAWBRK_DONE__ | shell markers[1] | |
| Other | NYANSTEG | archive magics[1] | |
| Other | NYANARCH | archive magics[1] | |
| Other | NYANB64X | archive magics[1] |
Sources
Changelog
- First published.