על ייעול משמעותי של חומרת ה-MagSpoof (פרויקט של ההאקר המפורסם סמי קמקר) בעקבות אי-הבנה של שיטת קידוד הביטים בכרטיסי אשראי.
סמי, שעשה לעצמו שם באיתור פרצות אבטחה שונות ומשונות במגוון תחומים, גילה נקודות תורפה מסוימות בכרטיסי אשראי של אמריקן אקספרס ובאופן ההנפקה שלהם. לפני כשלושה חודשים הוא העלה סרטון שבו הסביר במה מדובר, וגם הציג את ה-MagSpoof – מעגל קטן עם סליל נחושת, ג'וק דרייבר למנועי DC, ומיקרו-בקר ATtiny85 עם תוכנה מתאימה – שיוצר שדה אלקטרומגנטי משתנה וגורם לקוראי כרטיסים רגילים לחשוב שהעבירו בהם כרטיס אשראי.
אין לי שום כוונה לנסות לזייף כרטיסי אמריקן אקספרס (או בכלל), אבל אופן הפעולה של חומרת ה-MagSpoof עניין אותי מאד, אז כשהשגתי קורא כרטיסים פשוט (אפשר לקנות מהמזרח הרחוק בעשרה ומשהו דולרים) מיהרתי לאסוף רכיבים, להעלות את הקוד-לדוגמה של סמי לארדואינו ולנסות. זה עבד – אלא שכאשר הסתכלתי בקוד התוכנה, מצאתי משהו שנראה לי משונה.
לפני זה, קצת השכלה כללית. בפס המגנטי של כרטיסי האשראי יש מספר רצועות של מעין "ברקוד" ארוך, עשוי מקווים של חומר מגנטי עם רווחים ביניהם. סמי המחיש זאת יפה כשטבל את הכרטיס שלו באבקת ברזל דקה, שנצמדה לקווים הללו והפכה אותם לגלויים לעין. בקורא הכרטיסים יש חיישן מגנטי רגיש שמזהה את הפסים הללו כשהם עוברים בסמוך לו. ה-MagSpoof מחקה את השפעת הפסים מרחוק, על ידי היפוך הקוטביות של שדה אלקטרומגנטי חזק (=הזרמת זרם בכיוון מתחלף בסליל)
בשורה התחתונה זה עובד, אבל עניין היפוך הקוטביות טרד את מנוחתי, כי חשבתי שקורא הכרטיסים בודק רק "יש חומר מגנטי" (קווים) לעומת "אין חומר מגנטי" (רווחים), ואם כך, למה צריך שינויי קוטביות? לא הגיוני יותר שיהיה שדה בכיוון אחד בלבד, שיידלק ויכבה לסירוגין? אחרי מעט ניסוי וטעייה עם שינויים בקוד, הצלחתי להראות שאכן אין צורך בהיפוך הקוטביות: בעזרת העברה של זרם בכיוון אחד בלבד והפסקה שלו בתזמון נכון, הצלחתי "לשדר" את אותו המידע בדיוק לקורא, מטווח דומה.
כתבתי על כך לסמי, ובזמן שחיכיתי לתשובתו ניסיתי להבין את המשמעות של פרט אחד קטן ומסתורי שעדיין לא "פוצח": גם בקוד של סמי וגם בקוד שלי אנחנו מתעלמים, למעשה, מהרווחים שבין הקווים ומתפעלים את השדה האלקטרומגנטי כאילו היו רק קווים, בלי רווחים. בפועל, ברור שהרווחים משמעותיים ושאין בהם שדה מגנטי (אחרת הם היו אוספים את אבקת הברזל ולא ניתן היה להבחין ב"ברקוד"). אז איך הקורא בכל זאת מסתדר?
אז גיליתי עוד פיסת מידע חשובה, שהוכיחה שטעיתי בגדול: הקווים בפס המגנטי הם לא סתם ממוגנטים, אלא עם קוטביות שמתחלפת בין קו אחד לבא אחריו. מהבחינה הזו, הקוד של סמי היה נכון והגיוני, ואילו הקוד שלי, שלא הפך את כיוון הזרם, לא אמור היה לעבוד. רק שהוא כן עבד…
שתי השאלות הפתוחות נפתרות ביחד אם מניחים שמה שמעניין את הקורא הוא לא הקוטביות כשלעצמה אלא רק שינויים קיצוניים בשדה המגנטי, ושהקורא מחליט מה נחשב "שינוי קיצוני" על סמך הרמות שהתקבלו מהביטים הראשונים שבברקוד (ביטים לסינכרון, שאינם חלק מהמידע).
בתסריט זה, כשמעבירים בקורא כרטיס רגיל, או משתמשים ב-MagSpoof בגרסה של סמי, הקורא לומד מהר מאד את ערכי הקיצון הרלוונטיים, ומתעלם משינויים קטנים יותר, כגון השינוי בין קו לרווח. במילים אחרות, ההתעלמות מרווחים בקוד של סמי לא מפריעה לפעולת ה-MagSpoof – כי הקורא ממילא מתעלם מרווחים גם בכרטיס אמתי. בגרסה שלי, הקורא לומד ערכי קיצון שונים (יש/אין שדה), אבל מתייחס אליהם בדיוק כמו לרגילים, ולכן שוב אין לרווחים משמעות.
ומה החשיבות המעשית של כל זה? ברמת הוכחת ההיתכנות, שעבורה נבנה ה-MagSpoof המקורי, אין לזה שום חשיבות; אבל אם הייתי רוצה לתכנן MagSpoof לייצור המוני, השיטה שלי הרבה יותר טובה מכיוון ש:
- אצלי הזרם עובר בכיוון אחד בלבד, כך שאני יכול להיפטר מג'וק הדרייבר ולשים במקומו טרנזיסטור אחד קטן וזול,
- בזמן השידור, אני מכבה ומדליק את השדה במקום להפוך אותו, וכך צריכת החשמל יורדת בחצי!
שלחתי לסמי עוד מייל עם המידע החדש, והפעם קיבלתי גם תשובה: "הא, נחמד" – נו, יותר טוב מכלום 🙂
הערה פיסיקלית קטנה:
שדה מגנטי לא נוצר כתוצאה מזרם חשמלי, אלא כתוצאה משינוי בזרם החשמלי.
לדעתי זו הסיבה שהקוד עבד גם כשלא הזרים זרם בכיוון הנגדי – הזרמת הזרם החשמלי גרמה לשדה מגנטי להיווצר, וניתוקו יצר שדה מגנטי בכיוון ההפוך.
כתוצאה מכך גם אורך ה\\\"פולס\\\" המגנטי התקצר לחצי – אבל כנראה זה הספיק עבור הקורא.
לפי מה שכתבת, אלקטרומגנטים לא יכולים לעבוד… הרי אלקטרומגנט מושך ברזל ברציפות כל עוד עובר בו זרם.
יש פה בלבול קל, זרם יוצר שדה מגנטי, אבל שדה מגנטי קבוע לא יכול להשרות זרם במוליך אחר. מאוד יתכן שקורא הכרטיסים מרגיש את השינוי הזה בשדה המגנטי ולא את השדה עצמו, כמו ששיערת, ולכן זה עבד גם הפוך. בכל מקרה אפקטיבית מה שעשית (להזרים זרם רק מכיוון אחד- יש זרם ואין זרם) זה בממוצע לשדר אות קבוע + אות של זרם שהולך לשני הכיוונים השונים, שניהם בחצי הזרם המקסימלי שהוצאת. רכיב הDC סתם מבזבז חשמל ורכיב הAC עושה את העבודה אבל הוא חלש יותר, ככה שבעצם אתה סתם שורף ככה אנרגיה שלא עושה כלום וגם משדר בעוצמה נמוכה יותר.… לקרוא עוד »
לא, זרם בכיוון הפוך ("שלילי") צורך בדיוק אותה כמות אנרגיה כמו זרם בכיוון "רגיל", ומכיוון שמדובר כאן בעצם על גל ריבועי, השיטה של סמי צורכת אנרגיה 100% מזמן השידור, ואילו השיטה שלי רק 50%.
זה נכון שטווח "עוצמת השידור" שלי הוא חצי מזה של סמי, אבל אם במבחן התוצאה קורא הכרטיסים מסתדר עם השיטה שלי ממרחק סביר, אז השגתי את היעד הפונקציונלי בחצי מצריכת החשמל.
אני מתכוון ליעילות שידור. אם סמי היה עושה אותו דבר אבל בזרמים קטנים פי 2, הוא היה משדר באותה עוצמה כמוך, אבל בחצי מההספק בו אתה משדר.
אם באמת תרצה לחסוך בחשמל אתה יכול פשוט לקרב את הסליל שלך לקורא ולכתוב עם זרמים חלשים יותר.
אבל מה זה משנה, העיקר שזה עובד 🙂
עדיין לא – אם אתה עובד 100% מהזמן ב-50 מיליאמפר, או ב-50% מהזמן ב-100 מיליאמפר, ההספק הכולל זהה…
אני מצטער אבל זה לא נכון. קח את חוק אוהם V=RI, ותציב אותו בביטוי להספק: P=VI. תקבל P=RI², כאשר R היא ההתנגדות של המוליך (הסליל במקרה הזה) ו-I הוא הזרם העובר בו. כלומר ההספק לא פרופורציוני לזרם, אלא לריבוע שלו. וזה חשוב, כי אם אתה משדר חצי מהזמן ב-100mA, אתה עדיין משתמש בהספק כפול בממוצע ממי שישדר כל הזמן ב-50mA. ההספק הממוצע במקרה הראשון הוא 0.1²R*0.5 וואט, או 5R מיליוואט, כשהחצי מגיע מהממוצע, בעוד שבשיטה השניה ההספק הוא 0.05²R וואטים, או 2.5R מיליוואטים (ההתנגדות באוהמים). אבל רגע, אם שתי האופציות נותנות את אותו השינוי בשדה, שזה הרי מה שחשוב בשביל… לקרוא עוד »
אוקיי, זה הולך ומסתבך ואכן השתמשתי קודם במונח "הספק" בצורה לא מדויקת. אז בוא נחזור למצב הקיים: סמי ואני השתמשנו באותו זרם בדיוק (אצלי כON/OFF, אצלו כפלוס/מינוס). כדי להשתמש בזרם קטן פי שניים (על אותו סליל), צריך היה להוסיף התנגדות או להפחית את המתח של המערכת כולה, מה שהיה משנה כמובן את החישובים… כמו שהמערכת בנויה כרגע, הסוללה שלי תשרוד פי שניים זמן משלו.
על זה כאמור אין ויכוח 🙂
נחמד.
ניסית גם לבנות את הMagspoof ולסליל השתמשתי בחוט שהוצאתי מממיר שהיה ברמקולים, לא שיניתי את הגודל שעליו ליפפתי וזה עדיין עובד.
הייתה בעיה שזה הוציא חצאי מידע ורק אח"כ התברר לי שצרבתי את הATTiny85 על 1 מה"צ במקום 8 מה"צ.
יש לך איזו כוונה לכתוב משהו על RFID?
אחרי שסיימתי את הMagspoof התחלתי לחקור קצת את הProximity Card ומצאתי את AVRfid שמדמה תג RFID עם ATTiny85 וסליל בלבד.
עם RFID עבדתי בינתיים רק ברמה הכי בסיסית (קורא ותגים קנויים) – אולי גם בזה אתעמק מתישהו 🙂
נרשמתי לRSS אז אני מעודכן אם יהיה משהו על RFID 🙂
בנתיים אני מפחד לצרוב את AVRFID על הATTINY85 בגלל שזה מבטל את השעון הפנימי ואז הבנתי שאי אפשר לצרוב אותו שוב ללא ציוד (אני משתמש בארדואינו כדי לצרוב).
יש דרך קלה לאפס את הפיוזים במקרה שטעיתי? או שיש אפשרות להוסיף מתנד ואז לצרוב שוב עם הארדואינו?
אם הקוד מצפה למתנד חיצוני, אז מן הסתם אתה צריך לבנות מעגל עם מתנד חיצוני – ואז יש לך את מקור השעון כבר מוכן אם תצטרך לשנות משהו בעתיד.
הקוד של הAVRFID מתבסס על הRF שנכנס מהקורא כשעון ולכן צריך לבטל את השעון הפנימי.
השאלה היא האם אפשר פשוט לשים מתנד חיצוני ולצרוב שוב או שצריך את השיטה עם 12V וכו'
אוקיי, עכשיו ראיתי את הפרטים. זה עסק מלוכלך מאד, ה-AVRfid הזה. בכל אופן, מכיוון שהוא מסתמך על קלט חיצוני כמקור שעון, במקרה הכי גרוע אתה יכול לתכנת ארדואינו נוסף (או ג'וק 555) לתת גל ריבועי מספיק מהיר, להכניס את זה לאותו פין של הטייני (עם אדמה משותפת כמובן) ויש לך שעון חלופי.
מעניין.
555 אין לי פה אבל מתנד קריסטלי של 16 יש כמה.
ראיתי בכמה מקומות שצריך להוסיף קבלים בין המתנד לאדמה, האם זה יהיה נחוץ גם עם ה555 או הארדואינו?
ובכלל, אם אני משתמש בארדואינו כISP אי אפשר לגרום לו לתת גל ריבועי דרך אחת היציאות? יש איזשהו מקום שאפשר לחקור על זה קצת (הוצאת גל ריבועי דרך ארדואינו). תודה!!
ב-Datasheet… מתנד חיצוני פועל בשיטה אחרת מאשר אות שעון חיצוני, ולא יעזור לך. קרא כאן: https://www.idogendel.com/whitebyte/archives/1773
איזה מגניב! אני בדיוק גם חוקר את זה עכשיו. התגובה הצוננת של סאמי מעאפנה כי הוא בטח חושב שבשלב הבא תשפר לו את הקוד של myspace חח. תגיד, כשרצית לבנות את המעגל איך החלטת איזה נגד לשים לפני הסליל ? כאילו על סמך מה עשית את החישוב של הזרם?
ולמה לא השתמשת בסולונואיד? הרי בתכלס מה שבנית זה סולונואיד לקמצני זרם, לא?
מסקרן אותי ממש לראות את המעגל שלך אבל יותר מסקרן לדעת זה כשאתה רוצה לחבר ציפ וסליל איך אתה יודע לפי חישוב שצריך עוד נגד במעגל?
אה, עידו מתי תתחיל לשחק עם teensy?
סמי באמת בנאדם עסוק, ובהתחשב בעומס המיילים שבטח יש עליו, הוא עשה מעל ומעבר 🙂 (אפרופו, היתה לי איתו פעם התכתבות ארוכה ומשמעותית קצת יותר בנושא אחר).
את הסליל בניתי בשיטה של סמי, כי לא ידעתי אם זה יעבוד בכלל ולא רציתי שתהיה תקלה בגלל סליל לא מתאים – אני לא מומחה לשדות אלקטרומגנטיים…
לגבי הנגד, מכיוון שההתנגדות של הסליל מאד קטנה רציתי להגביל את הזרם, שלא יתחממו לי החוטים ושלא יעבור את הזרם המקסימלי הנקוב של הטרנזיסטור.
ו-Teensy – בשביל מה? כשאתחיל לעבוד עם ARM כמו שצריך, אעשה את זה כמו שצריך 🙂
חחחח לפני שקראתי בויקיפידה לא הייתי מומחה 😉 לפי חוק כלל יד ימין ( אני לא מסתלבט ככה באמת קוראים לזה ) אם אתה לוקח את יד ימין שלך ואוחז חוט חשמל, כאשר הבוהן ( או אגודל?) מצביעה אל כיוון הזרימה שלך הזרם – אתה יוצר שדה מגנטי שהוא בכיוון שאר האצבעות. במקרה שלך – במרכז המעגל הזה שיצרת יש שדה מגנטי אחיד שיוצא ממרכז המעגל – שקיים רק כשיש בחוטים זרם. עכשיו לא סתם אני קודח לך פה, השאלה שלי היא בשביל מה מלכתחילה הלכת וקנית קורא כרטסיים ? אי אפשר להפוך את הפעילות של הסליל שלך ולהשתמש ב… לקרוא עוד »
רציתי לראות את ההשפעה של הסליל על קורא כרטיסים אמתי, לא רק בתיאוריה.
לפרק אותו? רק עכשיו הגיע, לא חבל 🙂
בשביל לדמות עכבר ומקלדת יש לי ארדואינו לאונרדו / מיקרו, זה מספיק בינתיים…
אדיר! הקוד תואם לארדואינו בלי בעיות?
ואפשר תמונה של הגירסה שלך?
יש בקוד המקורי פונקציה למעבר למצב שינה, עם רגיסטרים של ATtiny85 ולא של ארדואינו. לא היה לי צורך במצב שינה, אז פשוט מחקתי אותה.
הגירסה שלי… ראית פעם טרנזיסטור על מטריצה עם נגד וכמה חוטים? ככה זה נראה 🙂 אבל אולי אכין בקרוב סרטון של העסק בפעולה.
בהחלט מגניב, תודה רבה על התגובה ואני יודע שאני אישית אשמח לסרטון הדגמה.
ובכללי נהניתי מהפוסט מכיוון ששני האנשים שאני עוקב אחריהם הכי הרבה בעולם המייקינג הם סאמי קמקר ועידו גנדל 🙂
הצבת לי סטנדרט גבוה… 😀
או שאולי הצבתי לו.
אגב, גם לי הייתה פעם התכתבות איתו בה הוא שלח לי תגובה קרירה. שאלתי אותו איזו שאלה לגבי איזה באג שהיה לי עם הkeysweeper והוא ענה לי שאשאל אותו בעמוד ביוטיוב של הסרטון והוא יענה שם. שאלתי אותו שם והוא מעולם לא ענה לי 🙁
עם זאת אני עדיין מעריץ גדול שלו ועוקב אחרי הפרוייקטים שלו.
אני מבטיח לך שזה לא היה אישי. כשיש לך קהל של עשרות ומאות אלפים, אין לך ברירה – או שאתה מקדיש את כל החיים שלך מעתה והלאה רק לתגובות ואימיילים, או שאתה מתחיל לסנן ולקצר… וגם לשכוח לענות מדי פעם.