Kotya security


Channel's geo and language: not specified, not specified
Category: not specified


Channel about web3 security. Author - @grged

Related channels  |  Similar channels

Channel's geo and language
not specified, not specified
Category
not specified
Statistics
Posts filter


Type: #dex #logicFlow

Project: Kyberswap

Date: 17/04/23
Blockchain: Multichain

Problem: Double-adding liquidity because of the incorrect tick handling.

For this hack it's important to understand how CLMM works, visit a link for a full hack description. In short:
* Users provide liquidity at a certain price range.
* The price range is discretely subdivided into ticks.

In Kyberswap the trick was to get the system in a state where currentTick was sitting on a valid tick range boundary and nearestCurrentTick == currentTick - 1. You then mint liquidity in the range (currentTick, currentTick + n) for some n. When a one-for-zero swap is executed in the current state, the nearestCurrentTick == currentTick - 1 (the next tick) will be calculated as currentTick, but it should be calculated as the next initialized tick.

This causes the liquidity just added to be added again:
- Before minting, crossing the tick boundary would have added l0 liquidity.
- Minting adds l1 liquidity, but it also adds liquidity to the tick range. This means crossing the tick boundary will now add l0 + l1 liquidity.
- We then cross the tick boundary with a small one-for-zero swap. In total, l1 + l0 + l1 liquidity has been added by minting and crossing (because two ticks are the same).

The Hacker:
1) Starts with a pool containing 1000 ETH and 2,000,000 USDC. Using a flash loan swaps 5000 ETH for USDC, getting the price down to $1 (tick 0). There are now 6000 ETH tokens in the pool and no USDC.
2) Calculates how much liquidity would need to be in the range (0,n) for some small n in order to completely drain the pool of 6000 ETH (in this tick range).
3) Mints half that liquidity and then performs the double-add exploit. Since the price of ETH is $1 this doesn’t require a whole lot of ETH and USDC.
4) Swaps 6000 USDC for 6000ETH.
5) Pays back the flash loan and keep approximately 1000 ETH as profit as well as the USDC received in step 1.

Discoverer: 100proof
Harm: 100 M $, 1.1 M payout
link


🌟 Welcome on board! 🌟

I'm excited to have each and every one of you here as part of our growing community. I'm very happy to see all new subscribers as well as the very first ones.

🔒 About the Group:
This group focuses on exploring world of web3 security, diving deep into bug bounty reports and recent hacks. Whether you're a newbie in the field or a senior developer/auditor, this group will be useful for you.

🔎 What to Expect:
As a full-time auditor, blockchain researcher, and whitehat, I will be sharing valuable insights, articles, and updates related to the latest hacks and incidents in web3 security. Additionally, I encourage everyone to actively sharing your own findings, asking questions, and engaging in meaningful discussions.

💡Learning and Growing Together:
This group aims to be a platform for continuous learning and professional growth. It's very important for every crypto-anarchist to know what is happening with DeFi in terms of security, this will help to get rid of mistakes which leads to money loss.

🌐 My other resources:

1. LinkedIn
2. Medium

Once again, a warm welcome to all new subscribers! Let's secure web3 world together!


Type: #wallet #blockchain

Project: Near Wallet

Date: 30/05/23
Blockchain: NEAR

Problem: Sentry logged private key of the user to the Near developers.

Sentry.io is a third party service to track errors and monitor performance. The logging event is done poorly, Near Wallet sends users private keys to the cloud version of the app and Sentry administrators and Near Wallet developers with access to Sentry are able to steal users' private keys.

During the auto-import process, the sentry is logging the # part of the URL (with the secret key):
When the user opens https://wallet.testnet.near.org/auto-import-secret-key#kalloc.near/SECREY_KEY_ENCODED_BASE58, the app sends to sentry full URL with # part.

As for now, the finding is accepted by the Near Wallet team, but you should keep in mind that if you used Near Wallet earlier - your private key has already been leaked.

The Hacker:
1) Compromise Near developers sentry address.
2) Collects all private keys of the Near Wallet users (not ledgers).
3) Drains wallets of 20 M + users.

Discoverer: @kalloc
Harm: NaN
link


Type: #proxy

Project: AAVE

Date: 19/05/23
Blockchain: Polygon

Problem: Update was done on address with incorrect interface.

Sometimes it's critical to write proper integration tests, even in case you are sure that the update will be executed as planned, DAO will check all the info and e.t.c. The attack also could be prevented if AAVE devs used ERC-165 checker and the proposed transaction would revert.

The root of the problem is that, for legacy reasons, the v2 version used on Aave v2 Polygon (and Avalanche) is slightly different from Aave v2 Ethereum. So, contracts in Avalanche and Polygon differs from the contract in Ethereum blockchains. You can see difference on the pictures:
* the first pic is the new calculateInterestRates function.
* the second one is calculateInterestRates on the current AAVE V2 implementation.
Devs updated contract in Ethereum, covered the update with tests, and after that they submitted the same code to the Polygon blockchain, but interfaces are different and all deposits and withdrawals from Polygon blockchain were stopped.
Taking into consideration, that Polygon EVM has slight differences with EVM, the update could lead to much more problems

The DAO:
1) Updates contract in Ethereum.
2) Passes the same code in new proposal to Polygon chain.
3) Updates Polygon chain without integration tests, all funds are stuck.

Discoverer: NaN. was rekt
Harm: 120 M $ STUCK
link


Type: #metamorphic

Project: Tornado DAO

Date: 20/05/23
Blockchain: ETH

Problem: Proposal can be updated as a metamorphic contract.

Changing the bytecode of a fixed account in Ethereum is possible using a sequence of CREATE/CREATE2 and SELFDESTRUCT calls.
CREATE, and CREATE2 are unique EVM operations that create new accounts. A contract can only be created if the account is "empty," where "empty" means codesize == 0 and nonce == 0. A newly created smart-contract has codesize > 0 and nonce == 1. Although this information is well-known, it is worth mentioning the following details about CREATE/CREATE2:
* CREATE - calculates address of new contract from keccak256(_deployer_addr, deployer_nonce_)(actually: keccak256(rlp([_deployer_addr, deployer_nonce_]))[12:])
* CREATE2 - calculates address of new contract from keccak256(_0xFF, deployer_addr, salt, bytecode)(actually: keccak256(_0xFF, deployer_addr, salt, bytecode)[12:]).

But how was it possible to deploy different contract at the same address in case of Tornado DAO? The hacker deployed factory contract with CREATE2 opcode, which deployed the proposal with the CREATE opcode. After the hacker deployed a proposal, the nonce of the factory became 1, so if the next proposal is executed with CREATE opcode - the address will differ. BUT: When the contract is selfdesctructed, the nonce of the contract also becomes zero.

The Hacker:
1) Deploys a proposal contract. Tornado governance approves proposal contract.
2) Deletes the proposal contract. Deletes the factory of the proposal contract making nonce = 0.
3) Attacker redeploys a factory, and then deploys different contract at the same address as the proposal contract.
4) Attacker executes malicious code. Since the initial proposal was already passed by voters, the attacker managed to grant himself the fake votes.

Discoverer: NaN. was hacked
Harm: 1 M $
link


Type: #validation

Project: Level finance

Date: 01/05/23
Blockchain: BSC

Problem: claimMultiple allows claim reward for the same epoch multiple times.

Level finance has a contract which grant users with rewards for swaps and has a referral system.

The Hacker:
1) Creates and sets lot's of referrals.
2) Executes swaps using flashloan in order to receive big reward per epoch.
3) Calls claimMultiple function, where all _epochs array is an array of the same epoch with big reward.

Discoverer: NaN. was hacked
Harm: 1 M $
link


Type: #logicFlow #token

Project: Dei

Date: 05/05/23
Blockchain: Multichain

Problem: Upgrade to vulnerable implementation.

During the burnFrom function there is an invocation of _approve function, which grants allowance from the burner address to the msg.sender. The DEI token on BSC was upgraded on Apr-10-2023 so the vulnerability was present for almost a full month.

The Hacker:
1) Approves uint256.max to the address with DEI tokens, in our case the Uniswap LP pair.
2) Call burnFrom function with zero amount for granting allowance yourself.
3) Call transferFrom, after that the hacker calls sync and swaps all tokens.

Discoverer: NaN. was hacked
Harm: 5.4 M $
link


Type: #blockchain

Project: Optimism

Date: 02/02/22
Blockchain: OPTIMISM + METIS

Problem: Selfdestuct doesn't subtract value from the contract.

Optimism is a L2 blockchain. It has it's own EVM which is called OVM - a fork with slight changes.

Optimism modified Geth to apply patches to StateDB to store the native balances in an ERC-20 token storage state. ETH is still represented internally as an ERC-20 token OVM_ETH. It's crucial to understand, that under the hood native balance of tokens is represented in ERC-20, it's also important to understand that since Optimism is a fork it's still has stateObject which represents ETH value and equals to the OVM_ETH.

Solidity compiler has interesting feature: selfdestruct(address) method, which is used for destroying all bytecode from the calling contract address and transfering all Ether held to the target address allows interacting with the destructed contract after the opcode invocation, if called in the same transaction.

The issue in Optimism was that with setting the balance of an account after selfdestruct to 0:
stateObject.data.Balance = new(big.Int)
Optimism client sets the balance to zero directly on the stateObject instead of ERC-20 OVM_ETH contract.

The Hacker could:
1) Creates an exploit contract that contains two internal functions. One with selfdestruct, and a second that withdraws the balance of the contract to the caller. The function with selfdestruct sends the contract’s balance to itself. In this case the contract will double its ERC-20 balance of native token.
2) The attacker deploys the contracts and in the constructor executes calls to the selfdestruct function multiple times in a for loop.
3) After the for loop is finished, the constructor calls the second internal function of the exploit contract to transfer the inflated funds to the attacker.
4) The exploit contract is destroyed at the end of the transaction, hacker takes all the profit.

Discoverer: Saurik
Harm: > 1 B $, 2 M $ whitehat payout
link


Type: #logicFlow #dex

Project: Burger swap

Date: 27/05/21
Blockchain: BSC

Problem: BurgerSwap swapping function had a missing require statement which could let anyone remove any amounts from a pool on the protocol.

The swap() function checks for the x*y ≥ k condition which verifies if the correct amount of tokens were received to do the swap. The code marked in the yellow box is what BurgerSwap is missing from its swap() function. Anyone could call this function to swap 100 token A to 100 token B, and could send only 1 token A and receive back 100 token B. This allows anybody to remove any amount of tokens from the pool without checking the x*y ≥ k. There seems to be no explanation for why this check was removed by the developers of BurgerSwap.

Another difference was an extra modifier onlyPlatform for the swap() function that allowed only the Router to call the swap function.

For the attack, the hackers created a pair with some newly created X tokens and BURGER. Then the Router was called to do a swap, sending in incorrect amounts of tokens. After the X token → BURGER swap, the attacker re-entered and did another swap BURGER → WBNB. Because the attacker re-entered before the updation of reserves after the first swap, the previous values of reserves were used for the next swap from BURGER → WBNB.

The Hacker:
1) Flash swaps 6000 WBNB from PanckakeSwap.
2) Swaps 6000 WBNB ↔ 92000 BURGER.
3) Creates a new token (which we will call X). Creates a new pair with some X tokens and BURGER.
4) Adds 100 X tokens and 45000 BURGER to the pool.
5) Swaps 100 X tokens ↔ 4400 WBNB.
6) Swaps another 45000 BURGER ↔ 4400 WBNB because of re-entrancy.
7) Swaps 493 WBNB ↔ 108800 BURGER
8) Replays the flash swap.


Discoverer: NaN. was hacked
Harm: 7.2 M $
link


Type: #logicFlow

Project: Sheep farm

Date: 16/11/22
Blockchain: BSC

Problem: Users timestamp not updated after registration.

Function register will check the user's timestamp to ensure it is a new user. However, it does not update the timestamp after the registration. In this case, the attacker can invoke the function register for multiple times claiming entry reward. Everytime the function register is invoked, the GEM_BONUS will be assigned to the attacker.

The Hacker:
1) Calls register in for loop multiple time abusing rewards.
2) Withdraw reward and claims profit.

Discoverer: NaN. was hacked
Harm: 1 BNB
link


Type: #logicFlow #dex

Project: Elastic swap

Date: 13/12/22
Blockchain: ETH + AVAX

Problem: Misapplication of two accounting systems.

For the addLiquidity function, the contract uses a constant K value algorithm for internal accounting.
But for removeLiquidity, it uses token-balance-based accounting in which the balance of two tokens (`baseToken` and `quoteToken`) in the current pool is used to calculate the amount.

The Hacker:
1) Adds liquidity to the TIC-USDC pool.
2) Deposits $USDC.e directly into the TIC-USDC pool by transfering tokens.
3) Removes the liquidity, causing the contract’s internal USDC reserve to become unbalanced.
4) Swapes USDC for TIC tokens and takes profit.

Discoverer: NaN. was hacked
Harm: 845 k $
link


Type: #logicFlow #token

Project: Axioma

Date: 24/04/23
Blockchain: BSC

Problem: Presale wasn't ended after the token release.

During the token presale, the deployer set rate for buying initial tokens, but when the token was released the presale contract wasn't stopped.

The Hacker:
1) Takes flashloan.
2) Buys tokens using presale contract at low price rate.
3) Sells tokens using DEX at higher price rate, returns flashloan and keeps profit.

Discoverer: NaN. was hacked
Harm: 21 BNB
link


Type: #reentrancy

Project: Visor Finance

Date: 21/12/21
Blockchain: ETH

Problem: call to arbitrary contract, missing non-reentrant modifier.

This attack exploits two vulnerabilities in the stake mining contract RewardsHypervisor of Visor Finance:

1. The call does not restrict the target contract, and the hacker can call any contract and take over the execution process of the stake mining contract. This is the primary vulnerability, causing the root cause of this exploit.

2. The function is not protected against reentrancy attacks. This is the minor vulnerability, leading to a miscalculation of the amount of staking credentials, which is not the main exploit of this attack, but can also be exploited to launch a separate attack.

The Hacker:
1) Deploys the attack contract with the correct interface.
2) Calls the deposit function of the stake mining contract through the attack contract, and specify the amount of tokens deposited visrDeposit to be 100 million , from the attack contract to the attacker’s address. In line 53 on the pic. 1, the amount of stake certificates shares is calculated as 97,624,975 vVISR.
3) Since from is an attack contract, the deposit function executes the if branch from line 56–59 and calls the specified function of the attack contract, where the hacker reenters the deposit function with the delegatedTransferERC20 function call.
4) When the second execution reaches delegatedTransferERC20 hook, the attack contract will not perform any operations.
5) Due to reentrancy, the stake mining contract issues two staking certificates of 97,624,975 vVISR to the hacker, and the total number of staking certificates is 195,249,950 vVISR. After that hacker withdraws profit.

Discoverer: NaN. was hacked
Harm: 8.2 M $
link


Type: #logicFlow

Project: Levyathan

Date: 28/07/21
Blockchain: BSC

Problem: The Levyathan developers left the private keys to a wallet with minting capability available on Github.

The Levyathan protocol faced two critical issues:

* Lost keys and minting.
* Vulnerable emergencyWithdraw.

1. In Levyathan’s authorization system, a function was added to the MasterChef by the developer to recover the token’s ownership. Presumably, this was done in order to allow to create a v2 of the contract, with enhanced features. Only its owner, the Timelock, had the permission to change it.
On Jul 28th, 2021, the owner of the Timelock, which wasn’t a multisig contract, passed a transaction through the Timelock, scheduling an ownership transfer. And on Jul 30th, 2021, the transaction was executed, the hacker gained control over the LEV token and minted lot's of tokens.

2. Since the Masterchef lost its ownership of the token, it couldn’t mint tokens when users withdrew, which triggered errors. Usually, such problem can be mitigated with the emergencyWithdraw() function, which returns the staked tokens without any rewards. Emergency withdraw returned an amount of tokens equal to rewardDebt and not user.amount rewardDebt is an intermediary variable used by the contract to compute the final rewards owed to the staker, which is usually higher than the real reward.

The Hacker:
1) Visits github, searches for private key leak.
2) Transfers ownership of token from Masterchef to yourself, mint and sell tokens.

After, users starts using emergencyWithdraw and withdraw more tokens that they should receive.

Discoverer: NaN. was hacked
Harm: 1.5 M $
link


Type: #logicFlow

Project: yearn finance

Date: 13/04/23
Blockchain: ETH

Problem: Misconfiguration. Used the Fulcrum iUSDC token instead of the Fulcrum iUSDT token.

The iearn USDT token (yUSDT) has been broken since deploy, which was over 1000 days ago. Because the pool value is computed as the sum of the value of derivatives + USDT contract balance, if the contract withdraws bZxUSDC into USDC, the bZxUSDC value is lost, reducing the pool value.

The Hacker:
1) Buys yUSDT from Curve.
2) Mints bZxUSDC, sends it to the contract, increasing the price per share.
3) Redeems bought yUSDT to USDT. This withdraws everything from Aave first.
4) yUSDT is now fully invested in bzxUSDC.
5) Triggers a rebalance withdrawing bZxUSDC into USDC, reducing the value per yUSDT to literally 0.
6) Sends 1 wei of USDT to the contract and mints yUSDT at 1 wei per yUSDT - the attacker can essentially mint yUSDT for free.
7) Sells unlimited yUSDT back into the Curve pool for profit.

Rebalance decides what to invest in based on the APR of the protocols. Current provider was AaveV1, to rebalance into a different provider attacker had to reduce Aave's APR to 0 by repaying every single borrower.

Discoverer: NaN. was hacked
Harm: 11.6 M $
link


Type: #logicFlow #flashLoan

Project: Hundred finance

Date: 15/04/23
Blockchain: Optimism

Problem: Exchange rate Manipulation & ERC4626 Inflation Attack.

The project setup two wBTC cTokens, one of which was used by the UI, one of which was empty, which led to the price manipulation. Thus, the attacker could inflate the price of the collateral by first depositing a few WBTC, getting 200 hWBTC in return and then depositing 500 WBTC to inflate the price of hWBTC.
Then, because of the inflated price of hWBTC, he could borrow funds from all pools.

The Hacker:
1) Flashloan 500 WBTC -> cBTC WBTC balance: 0.00000378
2) Mint 4 WBTC -> 200 сBTC -> CBTC WBTC balance: 4.00000378
3) Redeem 199.99999998 cBTC
-> CBTC total supply = 2
-> cBTC WBTC balance = 0.00000378
4) Transfer 500.30063816 WBTC to cBTC
-> сBTC total supply = 2
-> cBTC WBTC balance = 500.30064194
5) Enter cBTC market
-> cBTC total supply = 2
-> Hacker cBTC balance = 2
-> сBTC WBTC balance = 500.30064194
-> Exchange rate: 500.30064194 / 2
-> Collateral effective val: 2 * 500.30064194 / 2 = 500.30064194 WBTC
6) Borrow 1021.915074492787011273 ETH
7) Redeem 1 cWBTC
-> Receives back 500.30063815 WBTC
8) Liquidate the attack contract

Discoverer: NaN. was hacked
Harm: 7 M $
link


Type: #logicFlow #dex

Project: Swapos

Date: 16/04/23
Blockchain: ETH

Problem: Inconsistent value in the Uniswap V2 LP, 10000 instead of 1000.

The problem in Swapos contract occured several hours ago, it is the same as the NowSwap platfom had.

The Hacker:
1) Transfers some amount of tokens to LP pair.
2) Calls swap with amountOut 10 times bigger that he sent.
3) Repeat steps 1 and 2 draining the LP pair for other pools.

Discoverer: NaN. was hacked
Harm: 450 k $
link


Type: #accessControl #validation

Project: MetaPoint token

Date: 12/04/23
Blockchain: BSC

Problem: Positions are stored on contract with public approve function.

MetaPoint is a token with staking system. When user creates deposit -> the new contract is created with users funds. These contracts with positions are vulnerable, since everything they have is an uprotected approve function which anyone can call and set allowance to his address.

The Hacker:
1)
Finds all contracts with users positions.
2) Created contract which calls approve to his address in batches.
3) Created contract which transferFrom tokens to his contract and swaps all tokens to USDT.

Discoverer: NaN, was hacked
Harm
: 920 k $
link


Type: #reentrancy

Project: Paribus

Date: 11/04/23
Blockchain: Arbitrum

Problem: State is updated after tokens are sent.

Paribus is a fork of the old version of CompoundV2 protocol with a known reentrancy issue.

The Hacker:
1)
Takes flashloan.
2) Opens position, calls redeem.
3) Reenters after funds were sent to him, borrow more tokens and continues to redeem.

Discoverer: NaN, was hacked
Harm
: 100 k $
link


Type: #validation #arbitraryData

Project: Sushiswap

Date: 09/04/23
Blockchain: Multichain

Problem: Callback address is not validated.

The sushi router doesn't validate that the v3Pool address caller is a v3 pool (Uniswap router does), so anyone could pass any arbitrary contract which can callback sushiRouter.swap3callback() with any from address.

The Hacker:
1)
Creates malicious contract and passes arbitrary data which calls the malicious contract.
2) The malicious Pool calls back the RouteProcessor2 uniswapV3SwapCallback function in its swap function. Since the lastCalledPool variable has been set to Pool, the check for msg.sender in uniswapV3SwapCallback is bypassed.
3) Constructs token transfer parameters when the malicious Pool calls back the uniswapV3SwapCallback function, stealing tokens from other users who have approved RouteProcessor2.

Discoverer: NaN, was hacked
Harm: 3 M $
link

20 last posts shown.

837

subscribers
Channel statistics