פגיעויות חילופין מבוזרות

בחודש האחרון, ההפסדים כתוצאה מהתקפות האקרים על קהילת הקריפטו עלו ל-1.019 מיליארד דולר (24.10), מעבר לחודשים האחרונים (בהשמטת תקרית טרה לונה)

על ידי מבט מקרוב, אנו יכולים לראות שהמנצלים העיקריים בוצעו בפלטפורמות DEX (Decentralized Exchange), המסכמות של כמעט 15% מסך ההפסדים באוקטובר בלבד.

עם זאת בחשבון, בואו נצלול עמוק יותר לתוך שלושה מקרים בעולם של ניצול DEX וננסה לענות על השאלות האלה:

  • מהן הסיבות העיקריות לפגיעויות DEX?
  • כיצד נוכל להימנע מאלה בעתיד?

החלפת בננה

ב-28 באוגוסט החלפת האסימונים של $DDC, החלפת בננה, הותקף. התוקף הצליח לתמרן את מחיר המטבע, על ידי שבירת ההיגיון הפנימי של חישוב המחיר, וכתוצאה מכך החליף 23 $ DDC תמורת 110,105 $ BUSD.

הפגיעות הייתה פשוטה למדי, אך להשפעה הייתה פוטנציאל רווח עצום:

  1. המתקפה החלה בעסקה של 26$ DDC לחשבון התוקף
  2. לאחר מכן החל חיפוש אחר ארנק של קורבן במטרה למצוא ארנק המכיל כמות גדולה של האסימונים
  3. [ניצול] כאשר נמצא חשבון מתאים התוקף התקשר handleDeductFee אשר ביצע א ניכוי כמעט כל האסימונים מיתרת הנפגע
  4. על מנת לסיים את מניפולציית המחיר, הפונקציה sync נקרא לעדכן את הערך/מחיר של $DDC

כתוצאה מכך, יתרת ה-$DDC במאגר הצטמצמה ל-0.0003 $DDCs, לאחר עדכון הערך/מחיר, עולה משמעותית המחיר של $USD המקביל ל-$DDC, וניתן להחליף סכום גדול של $USD באמצעות כמות קטנה של $DDC. ההאקר השתמש ב-23 $ DDC כדי להחליף תמורת 104,600 דולר.

אז איך יכול היה לתוקף לתמרן את יתרת החשבון של הקורבן? מה היה ה handleDeductFee ביצוע פונקציה?

בואו נסתכל על הקוד:

function handleDeductFee (ActionType actionType, uint256 feeAmount, address from, address user) external override {
	distributeFee(actionType, feeAmount, from, user);
}
// deduct the config fee and transfer to handle fee address which config.
// parameter from
function distributeFee (ActionType actionType, uint feeAmount, address from, address user) internal { 
	_balances [from] = _balances[from].sub(feeAmount);
	...
}

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

התוקף העביר את כתובת הקורבן בתור from פרמטר ואת feeAmount היה מעט פחות מהתוצאה של balanceOf של כתובת זו.

זהו זה! לא אימות אחד על הנתונים הנכנסים. אין תיאוריה מורכבת מאחורי זה בכלל.

Cyber אבטחה 101: לעולם אל תבטח בנתונים הנשלטים על ידי המשתמש.

מידע נוסף ניתן למצוא בפוסט הטוויטר של Beosin Alert כאן.

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

חילופי תחבורה ציבורית

חילופי תחבורה ציבורית היא פלטפורמת אגרגטור DEX מרובת שרשרת הפועלת ברשתות Ethereum ו-Binance. ב-1 באוקטובר, הפלטפורמה הייתה קורבן למתקפה שהוציאה נכסים בשווי של כמעט 29 מיליון דולר מהארנקים של משתמשי הפרוטוקול.

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

גרסה פשוטה של ​​זרימת הנתונים נראית בערך כך:

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

"הסיבה העיקרית להתקפה זו היא שפרוטוקול Transit Swap אינו מאמת בקפדנות את הנתונים המועברים על ידי המשתמש במהלך חילופי האסימונים, מה שמוביל לשיחה חיצונית שרירותית." – הניתוח של SlowMist

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

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

Maiar Exchange – רשת אלרונד

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

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

כדי להמחיש זאת נמחיש חוזים א', ב' ו-ג'. חוזה א' קורא foo זה בתוך ב'. foo שיחות executeOnDestByCaller מה שמאפשר ל-B לבצע את הפונקציה bar של חוזה ג' כמתחזה של א'.

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

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

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

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

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

עונה על השאלות

בידיעה של מה שאנחנו יודעים עכשיו אנחנו יכולים להתייחס לשאלות האלה.

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

  1. קוד פתוח – כפי שכולנו יודעים ה-'D' ב-DEX מייצג Decentralized, כלומר המוצר מונע על ידי המשתמשים, וזה הופך את הקוד לנגיש לעולם. זה מקל על איתור הפגיעות.
  2. קשה לעדכן - העלות של איתור ועדכון של פגיעות גבוהה בהרבה מאשר באפליקציה מחוץ לרשת. ככל שהחוזים מועלים בשרשרת, תיקון של פגיעות פירושו העלאת עותק חדש של החוזה והפניית כל הכתובות מהישן לחדש אם אין חוזה פרוקסי בשימוש.

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

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

סיכום

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

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

נכתב על ידי
איתי צ'רדמן

איתי הוא חוקר אבטחה ב-Sayfer. הוא נלהב להבין ולחקור וקטורים תוקפים והגנתיים המופיעים בטכנולוגיות מתפתחות חדשות.

עבור לתוכן