איך להימלט מחוזים חכמים ממצמד התקפות החזרה? PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

איך להימלט מחוזים חכמים ממצמד התקפות החוזרות?

זמן קריאה: 6 דקות

אם נסתכל מקרוב על פריצות הקריפטו הגדולות והדמויות מרעישות העין שאבדו להן, הן היו מושרשות עמוקות מפגמי הקידוד.

תופעה שכיחה כזו של פגיעות אבטחה היא התקפת Reentrancy. עם זאת, ההשפעה ההרסנית שנגרמה עקב כניסה חוזרת שלא טופלה עשויה להישמע פשוט כמו הפעלת המתקפה עצמה.

למרות היותו נושא מוכר ומתוקשר, הופעתו של באג ה-Reentrancy בחוזים חכמים היא תמיד בלתי נמנעת. 

באיזו תדירות נוצלה הפגיעות של Reentrancy על ידי האקרים בשנים האחרונות? איך זה עובד? כיצד לרסן חוזים חכמים מהפסד כספים לבאגים של Reentrancy? מצא תשובות לשאלות אלו בבלוג זה.

אז, תוך זמן קצר, בואו נחדש את התקפות הכניסה החוזרת הגדולות ביותר בזיכרון. 

כמה מהפרקים הידועים לשמצה ביותר לכניסה מחדש בזמן אמת 

התקפות כניסה חוזרות שגרמו להשפעות ההרסניות ביותר על הפרויקטים בסופו של דבר ביצעו את אחד משני אלה או אפילו את שניהם. 

  • רוקנו את האתר לחלוטין מהחוזים החכמים
  • האקרים מתגנבים לקוד החוזה החכם

כעת אנו יכולים לראות כמה מקרים של התקפות Reentrancy והשפעתם. 

יוני 2016: התקפת DAO – 3.54 מיליון או 150 מיליון דולר אתר

אפריל 2020: פריצת Uniswap/Lendf.Me - 25 מיליון דולר

2021 מאי: פריצת BurgerSwap - 7.2 מיליון דולר

2021 באוגוסט: פריצת CREAM FINANCE – 18.8 מיליון דולר

מרץ 2022: אולה פיננסים - 3.6 מיליון דולר

2022 ביולי: פרוטוקול OMNI – 1.43 מיליון דולר

ברור כי התקפות Reentrancy מעולם לא יצאו מהסגנון. בואו לקבל תובנות עמוקות לגביו בקטעים הבאים. 

סקירה כללית של התקפת כניסה חוזרת

כמו מהשם "Reentrancy", אשר מרמז על "Reenting שוב ושוב." התקפת כניסה חוזרת כוללת שני חוזים: חוזה הקורבן וחוזה התוקף. 

חוזה התוקף מנצל את הפגיעות של כניסה חוזרת בחוזה הקורבן. הוא משתמש בפונקציית נסיגה כדי להשיג זאת. 

חוזה התוקף קורא לפונקציית המשיכה כדי לנקז את הכספים מחוזה הקורבן על ידי ביצוע שיחות חוזרות לפני שהיתרה בחוזה הקורבן מתעדכנת. חוזה הנפגע יבדוק את היתרה, ישלח כספים ויעדכן את היתרה. 

אבל בתוך מסגרת הזמן של שליחת הכספים ועדכון היתרה בחוזה, חוזה התוקף מבצע את הקריאה המתמשכת למשוך כספים. כתוצאה מכך, היתרה לא מתעדכנת בחוזה הקורבן עד שחוזה התוקף מרוקן את כל הכספים.

החומרה והעלות של ניצול כניסות חוזרות מעוררות את הצורך העז בביצוע ביקורת על חוזים חכמים לשלול אפשרות להתעלם מטעויות כאלה. 

תצוגה המחשה של מתקפת Reentrancy

בואו נבין את הרעיון של התקפת כניסה חוזרת מהאיור הפשוט למטה. 

להלן שני חוזים: החוזה הפגיע וחוזה האקר

חוזה ההאקרים קורא לסגת מהחוזה הפגיע. עם קבלת השיחה, החוזה הפגיע בודק את הכספים בחוזה ההאקר ולאחר מכן מעביר את הכספים להאקר. 

ההאקר מקבל את הכספים ומיישם את פונקציית ה-fallback, שמתקשרת שוב לחוזה הפגיע עוד לפני שהיתרה מתעדכנת בחוזה הפגיע. ובכך חוזר על אותה פעולה, ההאקר מושך את הכספים לחלוטין מהחוזה הפגיע. 

איך להימלט מחוזים חכמים ממצמד התקפות החוזרות?

תכונות של פונקציית Fallback בשימוש התוקף 

  • הם ניתנים להתקשרות חיצונית. כלומר לא ניתן להתקשר אליהם מתוך החוזה שהם כתובים
  • פונקציה ללא שם
  • פונקציית ה-fallback אינה כוללת בתוכה היגיון שרירותי
  • Fallback מופעל כאשר ETH נשלח לחוזה החכם המקיף שלו, ולא מוצהרת פונקציה receive().

ניתוח התקפת כניסה חוזרת מנקודת מבט טכנית 

בואו ניקח חוזה לדוגמה ונבין כיצד מתרחשת התקפת הכניסה החוזרת.

חוזה זדוני

contract Attack {
    DepositFunds public depositFunds;

    constructor(address _depositFundsAddress) {
        depositFunds = DepositFunds(_depositFundsAddress);
    }

    // Fallback is called when DepositFunds sends Ether to this contract.
    fallback() external payable {
        if (address(depositFunds).balance >= 1 ether) {
            depositFunds.withdraw();
        }
    }

    function attack() external payable {
        require(msg.value >= 1 ether);
        depositFunds.deposit{value: 1 ether}();
        depositFunds.withdraw();
    }


}

זהו חוזה התוקף שבו התוקף מפקיד 2ETH. התוקף קורא לפונקציית הנסיגה בחוזה הפגיע. ברגע שהכספים מתקבלים מהחוזה הפגיע, פונקציית החזרה מופעלת. 

לאחר מכן, ה-fallback מבצע את פונקציית המשיכה ומנקז את הקרן מהחוזה הפגיע. מחזור זה נמשך עד שהכספים מוצו לחלוטין מהחוזה הפגיע.

חוזה פגיע

contract DepositFunds {
    mapping(address => uint) public balances;

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function withdraw() public {
        uint bal = balances[msg.sender];
        require(bal > 0);

        (bool sent, ) = msg.sender.call{value: bal}("");
        require(sent, "Failed to send Ether");

        balances[msg.sender] = 0;
    }


}

לחוזה הפגיע יש 30ETH. כאן הפונקציה draw() שולחת את הסכום המבוקש לתוקף. מכיוון שהיתרה לא מתעדכנת, האסימונים מועברים לתוקף שוב ושוב. 

סוגי התקפות כניסה חוזרות

  • כניסה חוזרת לתפקיד יחיד 
function withdraw() external {
   uint256 amount = balances[msg.sender];
   require(msg.sender.call.value(amount)());
   balances[msg.sender] = 0;
}

ה-msg.sender.call.value(amount)() מעביר את הכספים שלאחר מכן קריאות פונקציית ה-fallback של חוזה התוקף recdraw() שוב לפני שהיתרות[msg.sender] = 0 מתעדכנות.

  • כניסה מחדש בין פונקציות
function transfer(address to, uint amount) external {
   if (balances[msg.sender] >= amount) {
       balances[to] += amount;
       balances[msg.sender] -= amount;
   }
}
function withdraw() external {
   uint256 amount = balances[msg.sender];
   require(msg.sender.call.value(amount)());
   balances[msg.sender] = 0;
}

כניסה חוזרת בין פונקציות היא הרבה יותר מורכבת לזיהוי. ההבדל כאן הוא שפונקציית ה-fallback קוראת העברה, שלא כמו ב-reentrancy של פונקציה אחת, שם היא קוראת לנסיגה.

מניעה מפני התקפות כניסה חוזרת

דפוס בדיקות-אפקטים-אינטראקציות: דפוס בדיקות-אפקטים-אינטראקציות עוזר במבנה הפונקציות. 

יש לקודד את התוכנית באופן שבודק תחילה את התנאים. לאחר העברת הבדיקות, יש לפתור את ההשפעות על מצב החוזים, ולאחר מכן ניתן לקרוא לפונקציות החיצוניות. 

function withdraw() external {
   uint256 amount = balances[msg.sender];
   balances[msg.sender] = 0;
   require(msg.sender.call.value(amount)());
}

הקוד המשוכתב כאן עוקב אחר דפוס ה-checks-effects-interactions. כאן האיזון נעשה לאפס לפני ביצוע שיחה חיצונית. 

שימוש במשנה

השינוי noReentrant שהוחל על הפונקציה מבטיח שלא יהיו קריאות חוזרות. 

contract ReEntrancyGuard {
    bool internal locked;

    modifier noReentrant() {
        require(!locked, "No re-entrancy");
        locked = true;
        _;
        locked = false;
    }
}

סוף הסרט /

הצעד היעיל ביותר הוא לקחת ביקורת חוזים חכמים מחברת אבטחה מובילה כמו QuillAudits, שבה המבקרים עוקבים מקרוב אחר מבנה הקוד ובודקים כיצד פועלת פונקציית ה-fallback. בהתבסס על הדפוסים הנלמדים, ניתנות המלצות לארגון מחדש של הקוד אם נראה שיש כאלה התנהגויות פגיעות

בטיחות הכספים מובטחת ממש לפני שנפלה קורבן להפסדים כלשהם. 

שאלות נפוצות

מה זה התקפת כניסה חוזרת?

התקפת כניסה חוזרת מתרחשת כאשר פונקציה בחוזה הפגיע מתקשרת לחוזה לא מהימן. החוזה הלא מהימן יהיה החוזה של התוקף שיבצע שיחות רקורסיביות לחוזה הפגיע עד שהכספים יתרוקנו לחלוטין. 

מה זה נכנס מחדש?

פעולת הכניסה מחדש פירושה הפסקת ביצוע הקוד והתחלת התהליך מחדש, המכונה גם כניסה מחדש.

מהו שומר כניסה חוזר?

Reentrancy guard משתמש במשנה שמונע את הקריאה של הפונקציה שוב ושוב. קרא את הבלוג שלמעלה כדי למצוא את הדוגמה לשומר על כניסה חוזרת.

מהן חלק מההתקפות על חוזים חכמים?

חוזים חכמים חשופים לפגיעויות רבות, כגון כניסה חוזרת, תלות בחותמת זמן, הצפות אריתמטיות, התקפות DoS וכו'. לכן, ביקורת היא חובה כדי לוודא שאין באגים שממוטים את ההיגיון של החוזה.

69 צפיות

בול זמן:

עוד מ קווילהש