Git Product home page Git Product logo

defivulnlabs's Introduction

DeFiVulnLabs

This was an internal Web3 solidity security training in XREX. I want to share these materials with everyone interested in Web3 security and how to find vulnerabilities in code and exploit them. Every vulnerability testing uses Foundry. Faster and easier!

Currently supports 47 types of vulnerabilities. it compiles with Solidity 0.8.18 except the cases like overflow, underflow where we need older solidity to reproduce the bug.

Disclaimer: This content serves solely as a proof of concept showcasing Solidity common bugs. It is strictly intended for educational purposes and should not be interpreted as encouraging or endorsing any form of illegal activities or actual hacking attempts. The provided information is for informational and learning purposes only, and any actions taken based on this content are solely the responsibility of the individual. The usage of this information should adhere to applicable laws, regulations, and ethical standards.

DeFiVulnLabs Solidity Security Testing Guide

Getting Started

  • Follow the instructions to install Foundry.
  • Clone and install dependencies:git submodule update --init --recursive
  • Test vulnerability: forge test --contracts ./src/test/Reentrancy.sol -vvvv

List of vulnerabilities

  • Integer Overflow 1 | Integer Overflow 2 :
    • In previous versions of Solidity (prior Solidity 0.8.x) an integer would automatically roll-over to a lower or higher number.
    • Without SafeMath (prior Solidity 0.8.x)
  • Selfdestruct 1 | Selfdestruct 2 :
    • Due to missing or insufficient access controls, malicious parties can self-destruct the contract.
    • The selfdestruct(address) function removes all bytecode from the contract address and sends all ether stored to the specified address.
  • Unsafe Delegatecall :
    • This allows a smart contract to dynamically load code from a different address at runtime.
  • Reentrancy :
    • One of the major dangers of calling external contracts is that they can take over the control flow.
    • Not following checks-effects-interactions pattern and no ReentrancyGuard.
  • Read Only Reentrancy :
    • An external call from a secure smart contract "A" invokes the fallback() function in the attacker's contract. The attacker executes the code in the fallback() function to run against a target contract "B", which some how indirectly related to contract "A".
    • In the given example, Contract "B" derives the price of the LP token from Contract "A"
  • ERC777 callbacks and reentrancy :
  • Unchecked external call - call injection :
    • Use of low level "call" should be avoided whenever possible. If the call data is controllable, it is easy to cause arbitrary function execution.
  • Private data :
    • Private data ≠ Secure. It's readable from slots of the contract.
    • Because the storage of each smart contract is public and transparent, and the content can be read through the corresponding slot in the specified contract address. Sensitive information is not recommended to be placed in smart contract programs.
  • Unprotected callback - ERC721 SafeMint reentrancy :
    • _safeMint is secure? Attacker can reenter the mint function inside the onERC721Received callback.
  • Hidden Backdoor in Contract :
    • An attacker can manipulate smart contracts as a backdoor by writing inline assembly. Any sensitive parameters can be changed at any time.
  • Bypass iscontract :
    • The attacker only needs to write the code in the constructor of the smart contract to bypass the detection mechanism of whether it is a smart contract.
  • DOS :
    • External calls can fail accidentally or deliberately, which can cause a DoS condition in the contract. For example, contracts that receive Ether do not contain fallback or receive functions. (DoS with unexpected revert)
    • Real case : Charged Particles
  • Randomness :
    • Use of global variables like block hash, block number, block timestamp and other fields is insecure, miner and attacker can control it.
  • Visibility :
  • txorigin - phishing :
    • tx.origin is a global variable in Solidity; using this variable for authentication in a smart contract makes the contract vulnerable to phishing attacks.
  • Uninitialized state variables :
    • Uninitialized local storage variables may contain the value of other storage variables in the contract; this fact can cause unintentional vulnerabilities, or be exploited deliberately.
  • Storage collision 1 | Storage collision 2 (Audius) :
    • If variable’s storage location is fixed and it happens that there is another variable that has the same index/offset of the storage location in the implementation contract, then there will be a storage collision. REF
  • Approval scam :
    • Most current scams use approve or setApprovalForAll to defraud your transfer rights. Be especially careful with this part.
  • Signature replay 1 | Signature replay 2 (NBA):
    • Missing protection against signature replay attacks, Same signature can be used multiple times to execute a function. REF1, REF2, REF3, REF4, REF5
  • Data location - storage vs memory :
    • Incorrect use of storage slot and memory to save variable state can easily cause contracts to use values not updated for calculations. REF1, REF2
  • DirtyBytes :
    • Copying bytes arrays from memory or calldata to storage may result in dirty storage values.
  • Invariants :
    • Assert is used to check invariants. Those are states our contract or variables should never reach, ever. For example, if we decrease a value then it should never get bigger, only smaller.
  • NFT Mint via Exposed Metadata :
    • The contract is vulnerable to CVE-2022-38217, this could lead to the early disclosure of metadata of all NFTs in the project. As a result, attacker can find out valuable NFTs and then target mint of specific NFTs by monitoring mempool and sell the NFTs for a profit in secondary market
    • The issue is the metadata should be visible after the minting is completed
  • Divide before multiply :
    • Performing multiplication before division is generally better to avoid loss of precision because Solidity integer division might truncate.
  • Unchecked return value :
    • Some tokens (like USDT) don't correctly implement the EIP20 standard and their transfer/ transferFrom function return void instead of a success boolean. Calling these functions with the correct EIP20 function signatures will always revert.
  • No Revert on Failure :
    • Some tokens do not revert on failure but instead return false, for example, ZRX.
  • Incompatibility with deflationary / fee-on-transfer tokens :
    • The actual deposited amount might be lower than the specified depositAmount of the function parameter. REF1 ,REF2, REF3
  • Phantom function - Permit Function :
    • Accepts any call to a function that it doesn't actually define, without reverting. For example: WETH. REF1, REF2
    • Attack Vector
      • Token that does not support EIP-2612 permit.
      • Token has a fallback function.
  • First deposit bug :
    • First depositor can break minting of shares: The attack vector and impact is the same as TOB-YEARN-003, where users may not receive shares in exchange for their deposits if the total asset amount has been manipulated through a large “donation”. REF1, REF2, REF3
  • Empty loop :
    • Due to insufficient validation, An attacker can simply pass an empty array to bypass the loop & signature verification. REF
  • Unsafe downcasting :
    • Downcasting from a larger integer type to a smaller one without checks can lead to unexpected behavior if the value of the larger integer is outside the range of the smaller one. This could lead to unexpected results due to overflow. REF1 , REF2
  • Price manipulation :
    • Incorrect price calculation over balanceOf, getReverse may refer to a situation where the price of a token or asset is not accurately calculated based on the balanceOf function. REF
  • ecRecover returns address(0) :
    • If v value isn't 27 or 28. it will return address(0). REF
  • Oracle stale price :
    • Oracle data feed is insufficiently validated. REF
  • Precision Loss - Rounded down to zero :
    • Avoid any situation that if the numerator is smaller than the denominator, the result will be zero. REF
  • Slippage - Incorrect deadline & slippage amount :
    • If both the slippage is set to 0 and there is no deadline, users might potentially lose all their tokens. REF
  • abi.encodePacked() Hash Collisions :
    • Using abi.encodePacked() with multiple variable length arguments can, in certain situations, lead to a hash collision.REF
  • Struct Deletion Oversight :
    • Incomplete struct deletion leaves residual data. If you delete a struct containing a mapping, the mapping won't be deleted.REF
  • Array Deletion Oversight :
    • Incorrect array deletion leads to data inconsistency. REF
  • txGasPrice manipulation :
    • Manipulation of the txGasPrice value, which can result in unintended consequences and potential financial losses. REF
  • Return vs break :
    • Use of return in inner loop iteration leads to unintended termination. REF
  • Incorrect use of payable.transfer() or send() :
    • Fixed 2300 gas, these shortcomings can make it impossible to successfully transfer ETH to the smart contract recipient. REF
  • Unauthorized NFT Transfer in custom ERC721 implementation :
    • Custom transferFrom function in contract VulnerableERC721, does not properly check if msg.sender is the current owner of the token or an approved address. REF
  • Missing Check for Self-Transfer Allows Funds to be Lost :
    • The vulnerability in the code stems from the absence of a check to prevent self-transfers. REF
  • Incorrect implementation of the recoverERC20() function in the StakingRewards :
    • The recoverERC20() function in StakingRewards.sol can potentially serve as a backdoor for the owner to retrieve rewardsToken. REF
  • Missing flash loan initiator check :
    • Missing flash loan initiator check refers to a potential security vulnerability in a flash loan implementation. REF
  • Incorrect sanity checks - Multiple Unlocks Before Lock Time Elapse :
    • This allows tokens to be unlocked multiple times before the lock period has elapsed, potentially leading to significant financial loss. REF

Bug Reproduce

20220714 Sherlock Yield Strategy Bug - Cross-protocol Reentrancy

Bounty: $250K POC | Reference

20220623 Sense Finance - Access control

Missing access control in onSwap()

Bounty: $50,000

Testing

forge test --contracts ./src/test/SenseFinance_exp.sol -vv 

Link reference

https://medium.com/immunefi/sense-finance-access-control-issue-bugfix-review-32e0c806b1a0

Spotthebugchallenge

Link reference

defivulnlabs's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

defivulnlabs's Issues

move test directory to root

how about move test directory to project's root directory . according to this

of course it is also possible to put it in the current src/test directory.

SenseFinance_exp.sol compilation error

Hi,

While experimenting with 20220623 Sense Finance - Access control, I've bumped into the following compilation error.

Any idea what's wrong with my foundary setup or command?

P/S: I've newly cloned this github repository, it shouldn't caused by github cloning.

forge test --contracts ./src/test/SenseFinance_exp.sol -vv
[⠊] Compiling...
[⠰] Compiling 8 files with 0.7.6
[⠔] Solc 0.7.6 finished in 248.22ms
Error:
Compiler run failed
error[4957]: src/test/interface.sol:31:16: TypeError: This type is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
  function ffi(string[] calldata) external returns (bytes memory);
               ^---------------^


error[4957]: src/test/interface.sol:48:74: TypeError: This type is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
  function envString(string calldata, string calldata) external returns (string[] memory);
                                                                         ^-------------^


error[4957]: src/test/interface.sol:49:73: TypeError: This type is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
  function envBytes(string calldata, string calldata) external returns (bytes[] memory);
                                                                        ^------------^


error[4957]: src/test/interface.sol:75:48: TypeError: This type is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
  function getRecordedLogs() external returns (Log[] memory);
                                               ^----------^


error[4957]: src/test/interface.sol:174:39: TypeError: This type is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
  function rpcUrls() external returns(string[2][] memory);
                                      ^----------------^


error[4957]: src/test/SenseFinance_exp.sol:10:5: TypeError: This type is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
    SwapRequest memory request,
    ^------------------------^


error[2443]: src/test/SenseFinance_exp.sol:62:9: TypeError: The type of this parameter, struct ISpace.SwapRequest, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
        aad,
        ^-^


error[2443]: src/test/SenseFinance_exp.sol:69:20: TypeError: The type of this parameter, struct ISpace.SwapRequest, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
      space.onSwap(aad, 2000000000000000000, 2000000000000000000)
                   ^-^

Great Resources

Thank you very much for taking time to create these the learning experience is helpful!

vunerability in bytecode sol

This code contains a vulnerability related to the "isContract" check in the Target contract. The issue arises due to relying on the extcodesize function to determine if an address is a contract. However, this method is not entirely reliable, as it returns 0 for contracts that are still in the construction phase.

To address this vulnerability, a more secure method should be used to check if an address is a contract. One commonly used approach is to check the code.length of the address.

vulnerability in approvescam.sol

The code appears to have a potential vulnerability that could be exploited.

In the testApproveScam function, the contract allows Alice to grant unlimited approval to the address of Eve using the approve function.

This means that Alice is granting permission to Eve to transfer any amount of tokens from Alice's account. This can be problematic if Alice unintentionally grants approval to a malicious or untrusted address, allowing it to drain Alice's funds.

To mitigate this vulnerability, it is recommended to use a more controlled and limited approach when granting approval. For example, Alice can specify the exact amount of tokens to approve or implement a mechanism where approval is granted only for specific trusted addresses or contracts.

Additionally, the code could benefit from better error handling and input validation to prevent potential issues and improve the overall security and robustness of the smart contract.

assign me this @SunWeb3Sec so i can solve issue

Test failed about Uninitialized_variables.sol

When I try to test the Uninitialized_variables.sol,using forge test --contracts ./src/test/Uninitialized_variables.sol -vvvv.
I got the result.

forge test --contracts ./src/test/Uninitialized_variables.sol -vvvv
[⠔] Compiling...
[⠊] Compiling 1 files with 0.8.17
[⠢] Solc 0.8.17 finished in 1.43s
Compiler run successful (with warnings)
Running 1 test for src/test/Uninitialized_variables.sol:ContractTest
[PASS] testSafeMint() (gas: 655369)
Logs:
  Unitialized Upgrader: 0x0000000000000000000000000000000000000000
  Initialized Upgrader: 0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496
  Exploit completed
  Since EngineContract destroyed, next call will fail.

Traces:
  [655369] ContractTest::testSafeMint() 
    ├─ [276918] → new Engine@0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
    │   └─ ← 1383 bytes of code
    ├─ [101370] → new Motorbike@0x2e234DAe75C793f67A35089C9d99245E1C58470b
    │   ├─ [46480] Engine::initialize() [delegatecall]
    │   │   ├─ emit Initialized(version: 1)
    │   │   └─ ← ()
    │   └─ ← 159 bytes of code
    ├─ [21275] → new Attack@0xF62849F9A0B5Bf2913b396098F7c7019b51A820a
    │   └─ ← 106 bytes of code
    ├─ [2392] Engine::upgrader() [staticcall]
    │   └─ ← 0x0000000000000000000000000000000000000000
    ├─ [0] console::log(Unitialized Upgrader:, 0x0000000000000000000000000000000000000000) [staticcall]
    │   └─ ← ()
    ├─ [44480] Engine::initialize() 
    │   ├─ emit Initialized(version: 1)
    │   └─ ← ()
    ├─ [392] Engine::upgrader() [staticcall]
    │   └─ ← ContractTest: [0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496]
    ├─ [0] console::log(Initialized Upgrader:, ContractTest: [0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496]) [staticcall]
    │   └─ ← ()
    ├─ [28641] Engine::upgradeToAndCall(Attack: [0xF62849F9A0B5Bf2913b396098F7c7019b51A820a], 0x9e5faafc) 
    │   ├─ [5103] Attack::attack() [delegatecall]
    │   │   └─ ← ()
    │   └─ ← ()
    ├─ [0] console::log(Exploit completed) [staticcall]
    │   └─ ← ()
    ├─ [0] console::log(Since EngineContract destroyed, next call will fail.) [staticcall]
    │   └─ ← ()
    ├─ [6741] Engine::upgradeToAndCall(Attack: [0xF62849F9A0B5Bf2913b396098F7c7019b51A820a], 0x9e5faafc) 
    │   ├─ [5103] Attack::attack() [delegatecall]
    │   │   └─ ← ()
    │   └─ ← ()
    └─ ← ()

Test result: ok. 1 passed; 0 failed; finished in 1.16ms

Excepting result is the second call to function upgradeToAndCall will fail.

vulnerability in the backdoor assembly.sol

This code contains a vulnerability that could allow the contract admin to manipulate the winner and drain the prize funds. Let me analyze the issue:

In the LotteryGame contract, the pickWinner function uses an assembly block to directly set the winner address using the sstore opcode.
This allows the contract admin to manipulate the winner address and set it to any address of their choice.

The safeCheck modifier checks if the msg.sender is equal to the referee address, and if not, it calls the getkWinner function. However, the getkWinner function doesn't perform any validation or security checks, and it simply returns the current value of winner. This means that anyone can call getkWinner to see the manipulated winner address. assign me this @SunWeb3Sec so i can solve this

Not an issue But want to understand (I am new to foundry)

In Reentrancy.sol
we have contracts EtherStore and EtherStoreRemediated but in tests we have 4 contracts additional two attack and attackRemediated
I cant locate 2 additional contracts . Is there any trick to it. Am I missing something ???

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.