תנועה רוחבית בחשבונות וזיהוי עם שאילתות KQL

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

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

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

מהי תנועה רוחבית

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

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

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

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

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

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

טכניקות שניתן לממש בתנועה רוחבית הם מגוונות, ובמבט על הסיווג של MITRE ניתן להבין כי ישנם טכניקות רבות שניתן לממש, החל מתחנה, דרך זהויות משתמש ועד Session Cookie. מידע נוסף לגבי הטכניקות Lateral Movement, Tactic TA0008 – Enterprise | MITRE ATT&CK.

מהי תנועה רוחבית

זיהוי תנועה רוחבית

ישנם מצבים בהם ניתן לזהות תנועה רוחבית, וישנם מצבים בהם זיהוי וגילוי של תנועה רוחבית היא בעייתית ואף בלתי אפשרית. ישנם כלים שונים שיכולים לזהות תנועה רוחבית החל ברמת זהויות, כמו לוגים של Azure AD או Active Directory, או למשל זיהוי בתחנות קצה ע"י כלי EDR שונים, וכמובן תנועה רוחבית בספקי ענן ואפליקציות SaaS עם כלי CASB למינהם.

הכלים, מערכות אבטחה ובקרות מפצות יכולות להיות גורם מכריע בזיהוי תנועה רוחבית, למשל, זיהוי פעולות חשודות מול תשתית Active Directory שיכולה להיעשות ע"י בקרות של Microsoft Defender for Identity או Javelin. זיהוי של תנועה חשודה והרצת פעולות בתחנת קצה ע"י Microsoft Defender for Identity, ומשם אפשר להמשיך בזיהוי פעולות חריגות בענן באמצעות Cloud App Security.

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

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

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

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

  • אירועים מסוג 4624, 4625 ,4768 ,4776, 4672 לזיהוי ניסיונות כושלים ולאחר מכן הצלחה וכן מימוש הרשאות
  • אירוע מסוג 4648 לזיהוי ניסיונות והצלחות של כניסת חשבונות באמצעות SMB
  • אירוע מסוג 4697 שיעיד על התקנת service בתחנה, למשל מימוש PsExec

לאחר מכן, התוקפים בדרך כלל ינסו לכסות את עקבותיהם במספר שיטות. לעיתים, זה יכול להיות רועש ברשת, למשל פעולת "sdelete" שמוחק קבצים לאחר שהם הוחלפו מספר פעמים, או למשל, "timestamp" שמשנה חותמות זמן של קבצים עם אינדיקטור לאירוע 4663 שהוא למעשה נעשה ניסיון לגשת לאובייקט שבו "WriteAttributes" עם טוקן כולל Audit Success. וכן, ניצול wevtutil המשמש למחיקת אירועים של Windows עם אינדיקטור לאירוע 104.

מידע נוסף לגבי זיהוי תנועות רוחביות על גבי Event Logs בקישור הבא JPCERT Report.

זיהוי אירוע באמצעות Azure Sentinel

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

בכדי לעבוד עם האירועים והאינדיקטורים השונים בתוך Event Viewer אנו צריכים לוודא שהגדרות Advanced Audit בשרתים/תחנות וכמובן ברמת כל Domain Controller מוגדרים בהתאם לאירועים וכן האינדיקטורים הנדרשים שאנו רוצים לזהות בכל אירוע. בעקרון מומלץ להגדיר ולרשום את רוב האפשרויות, שכן עם מערכות כמו Azure Sentinel ניתן לבצע מניפולציות ונורמליזציה על הלוגים, הנתונים, האירועים והאינדיקציות במטרה לתת זיהוי מיטבי.

בכדי לזהות בעיות עם Azure Sentinel אנו צריכים לוודא שישנם Agentים מותקנים ומוגדרים בכל שרת וכן Data Connector מוגדר בתוך Azure Sentinel וכן לוודא שישנה הזרמת לוגים אל Azure Sentinel בצורה רציפה.

זיהוי פוטנציאלי

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

ניתן להריץ אינספור מניפולציות על גבי Azure Sentinel בכדי לזהיות אירועים או בעיות פוטנציאליות, או לחלופין לעלות על גבי תנועה רוחבית שמתרחשת ברמת האובייקט. השאילתה הבאה ממחישה במעט על ניסיונות כושלים והצלחות שמתבססות על אירועים 4625 + 4624 מתוך Event Viewer. מטרת השאילתה היא לתת תמונה כללית, שכן, המטרה היא להבין מי ניסה לבצע לוגין מספר פעמים, ולאחר מספר כשלונות מצליח לבצע לוגין, ולאחר מכן מבצע פעולה.

טיפ: אפשר להוסיף לשאילתה תנאי או הצגה של ערכים ומזהים נוספים, כגון פעולות שמתבססות על explicit credentials כמו זה של לוג 4648

תנועה רוחבית בחשבונות וזיהוי עם שאילתות KQL

שאילתה באירוע Explicit Credentials

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

טיפים באירוע מסוג 4648 – A logon was attempted using explicit credentials

  • מזהה הכניסה הוא ייחודי (באתחול מחדש) שמזהה הפעלת כניסה וכל אירוע נרשם לאחר מכן במהלך הלוגין
  • לוגים נוספים שיכולים להיות חלק מהאירוע הם 4634 וכן 4647
  • באירוע כזה מתייחסים גם לפעולות ברמת Network + Process + Target
  • משתמש אשר השתמשו במזהים שלו
  • לרוב נרצה לדגום חשבונות פריבלגים

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

זיהוי פוטנציאלי

Let timeFrame = 1h
ערך של זמן הבדיקה שאנו מבצעים ברמת השאילתה או לחלופין בזמן הגדרת Analytics Rule

let ignoredAccounts = dynamic([“IgnoredAccountName”])
ערך השימוש בחשבונות שמתמקד בשלילת חשבונות שאינם רלוונטיים לגילוי וזיהוי

let knownTargets = datatable (user:string)
ערך שמסייע נקודתית מול חשבונות שאינם מספקים ערך אבטחה. למשל, פעילות סטנדרטית שבה חשבון אחד מנסה לעבור לחשבון אחר. ניתן להרחיב את הטבחה באופן דינמי או בהתאם לחשבונות בארגון. (מוריד false positive בצורה ניכרת)

let allChanges = SecurityEvent
ערך שמציין טבלה מותאמת אישית ואת הערך הזה נוכל להשוות לאובייקטים המוכרים ומול חריגות בטבלת SecurityEvent

where TimeGenerated >= ago(timeFrame)
ערך שמספק את הבדיקה מול האירועים בטבלת SecurityEvent.

extend SubjectUserName = tolower(SubjectUserName), TargetUserName = tolower(TargetUserName)
ערך נוסף שמספק דיוק ע"י נירמול של שדות SubjectUserName וכן TargetUserName בכדי למנוע התאמות שאינן מדויקות. (מוריד false positive בצורה ניכרת)

where EventID == 4648 and SubjectUserName !endswith “$” and TargetUserName !endswith “$” and SubjectUserName != TargetUserName and SubjectUserName !in (ignoredAccounts) and TargetUserName !in (ignoredAccounts)
ערך שמציין את החיפוש מול מזהי אירוע מסוג 4648, כאשר אף אחד מהחשבונות אינו חשבון תחנה, ולצד זה, שם המשתמש הנבדק אינו שווה למשתמש היעד, ובנוסף לוקח בחישוב שהנושא ומשתמש היעד אינם רשומים ברשימת החשבונות שהוגדרו מראש

where SubjectUserName != “-” and TargetUserName != “-” and isnotempty(SubjectUserName) and isnotempty(TargetUserName)
ערך שמוודא שהנושא ומשתמש היעד אינם רשומים כאובייקטים ריקים ברמת השדות, כך שאנו מקבלים רק נתונים מדויקים לגבי חשבונות אחרים

extend user = strcat(SubjectUserName, ” , “, TargetUserName) | distinct user
משלב את השדות לעמודה יחידה לטובת השוואה ולאחר מכן מציג את הערכים היחודיים

allChanges | join kind = leftanti knownTargets on user
הערך מצטרף לטבלת knownTargets ולכן יציג רק ערכים יחודיים שאינם קיימים בתוך האירוע עצמו ולא ערכים חסרי ערך

רפרנסים וקישורים נוספים

4648(S) A logon was attempted using explicit credentials. Windows security | Microsoft Docs

Azure-Sentinel-4-SecOps/Hunting at master · eshlomo1/Azure-Sentinel-4-SecOps (github.com)

Azure Sentinel – Elli Shlomo (eshlomo.us)

Become an Azure Sentinel Ninja: The complete level 400 training – Microsoft Tech Community

מאמרים נוספים בנושאי אבטחה מידע

1 Response

  1. 11/09/2021

    […] תנועה רוחבית בחשבונות, אינדיקטורים ושאילתת KQL (eshlomo.blog) […]

מה דעתך?

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

%d בלוגרים אהבו את זה: