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

  1. Pluto says the Ethereum contract the backdoor later reads its server address from was deployed.[1]

  2. The first two fake listings appeared under the publisher janeykomit.[1]

  3. Open VSX confirmed both listings removed, about 19 hours after they appeared.[1]

  4. Re-uploaded fake listings reached their final versions under a new publisher, dbolovetoa.[1]

  5. Open VSX confirmed the re-uploaded listings removed.[1]

  6. 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

  1. 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.
  2. On a Mac, look for a hidden .solidity folder in your home directory and for a related LaunchAgent in your user Library.
  3. 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

  1. Disconnect the machine from the network first to cut the active command channel.
  2. Do not rely on uninstalling the extension; it does not remove the backdoor.
  3. Remove the payload folder and the LaunchAgent, or better, rebuild the Mac.
  4. Rotate every credential the machine could reach: SSH keys, cloud sessions, publishing tokens and above all wallet keys and contract deployment keys.
  5. 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.

EcosystemPackageVersions
Open VSXalejandroaranda.solidity-languini0.9.2
Open VSXalejandroaranda.solidity-langsupport0.0.6
Open VSXjuanfranblanco.solidity-vscode0.0.1890.0.1900.0.191
Open VSXNomic-ETH.hardhat-solidity0.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.

TypeIndicatorNoteCopy
Extension IDalejandroaranda.solidity-languiniMalicious Open VSX extension (0.9.2)[1]
Extension IDalejandroaranda.solidity-langsupportMalicious Open VSX extension (0.0.6)[1]
Extension IDjuanfranblanco.solidity-vscodeMalicious Open VSX extension (0.0.189 to 0.0.191)[1]
Extension IDNomic-ETH.hardhat-solidityMalicious Open VSX extension (0.9.2 and 0.9.3)[1]
IP and port185[.]232[.]84[.]169:8041ScreenConnect relay (Windows)[1]
IP and port193[.]57[.]9[.]17:4912Go backdoor C2 (macOS/Linux)[1]
URLhxxp://107[.]189[.]27[.]46:3000/app.jsStaging URL in contract param2 (unreferenced, not serving during analysis)[1]
Wallet0xf8a900Db50b3331be6B768bA460BB59f3E40C344Ethereum config contract (EtherHiding-style)[1]
Wallet0xfd3fc58bcbd8ccc77b6000201438edfc636e7ca7Owner EOA (only account that can rotate C2)[1]
SHA-2567527e86d70e7c9493db4356f1c3775380431b310000f2602c1e993cf435d01daapp.msi (ScreenConnect installer)[1]
SHA-25637d14bff30762ca701e9c1f8bc6c57c065bb20ae3a2208cb7411a6530610f08einvoke.ps1 (loader)[1]
SHA-25680d2672e2599732d3c0ae2a4cd0d1e3fe4d555a60273ce33feb99db3f34d250fdarwin_amd64 backdoor[1]
SHA-256fae61f31f00988fdc5cc9e7272b51e08af2e245d81003237875415930fd27358darwin_arm64 backdoor[1]
SHA-2569b73e7cd4e1425e770392549d8df46c706139ef476f4f7b9ac405165dc8d9696linux_amd64 backdoor[1]
SHA-256b601776817363b96295119f7221338a122d5247a35a77a64b04f286e1bbcc565linux_arm64 backdoor[1]
SHA-256683ad81cdc028c538ee66da8e6b60f2a5ab070bfd900da80175df317a73886d8note.txt (taunt)[1]
File path~/.solidity/macOS/Linux payload and wrapper[1]
File path~/Library/LaunchAgents/com.solidity.langsupport.runner.plistmacOS LaunchAgent persistence[1]
File path~/.config/systemd/user/solidity-langsupport-runner.serviceLinux systemd persistence[1]
File pathC:\Program Files (x86)\ScreenConnect Client (5cbe79c9c25524df)\ScreenConnect client folder[1]
File path%TEMP%\solidity-langsupport-debug.logdebug log[1]
Other__JAWBRK_EC__shell markers[1]
Other__JAWBRK_DONE__shell markers[1]
OtherNYANSTEGarchive magics[1]
OtherNYANARCHarchive magics[1]
OtherNYANB64Xarchive magics[1]

Sources

Changelog

  1. First published.