מימוש התקפה מסוג Man in the Middle (קיצור: MITM) על רשת Zigbee קיימת.
התקפת האדם שבתווך (Man in the middle) היא סוג של ציתות אקטיבי שבו התוקף המאזין לשיחה המתקיימת בין שני מחשבים או ישויות ברשת, מצליח להתחזות לכל אחד מהם בנפרד, להעביר את התמסורת ביניהם ולגרום להם להאמין שהם מתקשרים ביניהם ישירות בערוץ פרטי, בעוד ש למעשה ההתקשרות נשלטת לגמרי בידיו.
תמונה מדגימה:
פירוט המכשירים והתוכניות שהשתמשנו בהם:
התחלנו בחיפוש ב-Zigbee Specification של פרוטוקול ההצטרפות של מכשיר חדש לרשת קיימת, ושל המבנה של ההודעות שנשלחות ע"י המכשיר, על מנת לראות איך המכשיר התוקף יכול להכנס לתמונה. כמו כן ניסינו ללמוד איזה מידע הוא יכול לקבל מההודעות שנשלחות, וכן איזה מידע הוא יכול להעביר כמו שהוא, או שהוא צריך לשנות בתקשורת בין ה-coordinator למכשיר המתחבר.
תרשים פרוטוקול התחברות מתוך zigbee_primer *:
מבנה הודעות Zigbee:
הפרוטוקול שראינו עבור כל מכשיר, גם מאותו סוג (למשל שני השקעים) לא היה עקבי, מה שיקשה על קביעת דרך פעולה אחידה עבור מכשיר תוקף, וידרוש התאמה למכשיר מתחבר ספציפי, או חלוקה למקרים והתמודדות בהתאם. למרות שנראה שהתקשורת לא אחידה בין היחידות השונות, השלב הראשון בפרוטוקול, שבעצם אינו חלק מפרוטוקול Zigbee אלא של פרוטוקול 802.15.4 (beacon request, beacon, association request, association response) מתרחש תמיד, והוא גם החלק היחיד בתקשורת שאינו מוצפן, ולכן התמקדנו בו בהמשך העבודה.
התחברות של מכשירים שונים (מ- wireshark):
ראינו שסדר התדרים שנסרק ע"י המכשיר המתחבר קבוע ומוגדר ב-Zigbee spec, ולכן הכוונה הראשונית שלנו היתה לנסות לתפוס את ניסיון ההתחברות לתדר הראשון (11) ואז להעביר את בקשת ההתחברות לתדר העבודה האמיתי של הרשת, לפני שהמכשיר שולח כזו, ובכך להכנס בינו לבין ה-coordinator.
לצורך נסיונות מימוש ובדיקות שונות כתבנו סקריפטים ב-python שהשתמשו בכלים של killerbee, והתבססו על סקריפטים שמגיעים עם ההתקנה של killerbee (בתיקית tools). כתבנו סקריפטpython שמאזין לערוץ 11, ואז מעביר כל הודעה שמתקבלת בערוץ זה לערוץ 22 (ערוץ העבודה האמיתי של הרשת), וכל הודעה שמתקבלת בערוץ 22 מועברת לערוץ 11. לצורך כך הסקריפט החליף כל הזמן את הערוץ שאליו הוא האזין, וכשקיבל הודעה העביר אותה לערוץ השני. (relay.py).
לאחר מספר נסיונות ראינו שהמכשיר המתחבר תמיד מתחבר לרשת בערוץ האמיתי, ושלמרות שחלק מההודעות אכן הועברו בין הערוצים ע"י הסקריפט שלנו, הם לא הפריעו להתחברות. כמו כן ראינו שבתהליך ההתחברות המכשיר שולח beacon request בכל הערוצים (לפי הסדר המוגדר) ואז מאזין לתשובות בכולם, ולא עובר ערוץ ערוץ שולח request ומחכה לתשובה ואז עובר לערוץ הבא.
גם אם נצליח להכנס בין המכשיר ל-coordinator ולשלוח את הבקשות של המכשיר בערוץ האמיתי לפני שהוא ישלח אותן, מכיוון שהתקשורת היא אלחוטית, התשובה המשודרת ע"י ה-coordinator נקלטת ע"י המכשיר המתחבר, ומכיוון שהוא שלח בקשת התחברות גם בערוץ זה, הוא ממשיך בתהליך ההתחברות ישירות אל ה-coordinator, ולא דרך המכשיר התוקף. בעקבות הבנה זו, חיפשנו דרכים לשבש את התקשורת של המכשיר עם הרשת, על מנת לאלץ אותו לתקשר רק דרך המכשיר התוקף **.
למדנו שניתן לשבש יחסית בקלות תקשורת רדיו בפרוטוקול 802.15.4, וניסינו לעשות זאת ע"י סקריפט שהקשיב לנסיונות התחברות בתדר 11, ואז ברגע ששמע כזה, שידר הודעות אקראיות במרווחים קטנים, כדי להציף את הערוץ בשידורים, ולשבש הודעות שנשלחות, ובכך למנוע את התקשורת הישירה בין המכשיר לרשת. נסיונות עם פרמטרים שונים לא עבדו, ותמיד המכשיר התחבר לרשת. (jam.py).
ניסיון נוסף למנוע את ההתחברות היה שינוי של הביט ב-beacon שאומר שניתן להתחבר לרשת, ושידור של beacon שקרי כזה ברגע שמתקבלת בקשת התחברות. גם ניסיון זה לא עבד, וגם אם שודרו אלפי הודעות שקריות, מספיק שאחת אמיתית התקבלה, והפרוטוקול המשיך בלי הפרעה. (fakebeacon1.py).
הניסיון הבא היה לגרום למכשיר המתחבר לנסות להתחבר לרשת שקרית במקום לרשת האמיתית, ובכך למנוע התחברות. בתור התחלה העתקנו beacon של הרשת האמיתית, כיבינו את ה-coordinator, וכתבנו סקריפט שמאזין לבקשת התחברות, ואז שולח את ה-beacon המועתק. ניסיון זה הצליח, והביא לכך שהמכשיר אכן ניסה להמשיך בפרוטוקול ההתחברות.
השלב הבא בפרוטוקול הוא שליחת מפתח ההצפנה של הרשת, ומעבר לתקשורת מוצפנת, ואת זה כבר לא יכלנו לסמלץ. לאחר מכן חיברנו את ה-coordinator, וניסינו לחזור על הניסוי הקודם, כך ששלחנו beacon עם אישור הצטרפות בערוץ 11 במקום 22, אך במקרה זה המכשיר התחבר לרשת האמיתית בערוץ 22, ולא ניסה להתחבר אלינו בערוץ 11.
הניסיון האחרון היה לשנות את ה-beacon כך שייראה כאילו הוא מגיע מרשת עם PANID אחר ולראות אם המכשיר המתחבר ינסה להתחבר אליה. ניסיון זה הצליח, וברוב הניסויים שעשינו, היה ניסיון להמשך פרוטוקול ההתקשרות בתדר 11 מול הרשת השקרית, ולא ברשת האמיתית, ובכך בעצם הצלחנו למנוע התחברות של המכשיר לרשת, גם אם לא לבצע את ההתקפה המקורית. (fakebeacon2.py).
ניסיון התחברות לרשת השקרית ב-wireshark:
* : התמונה נלקחה מהקובץ שנמצא בקישור פה.
** : הדרך שנסינו לשבש בה את הרשת מצאנו במאמר הנמצא בקישור הבא: Message Denial and Alteration on IEEE
802.15.4 Low-Power Radio Networks.