Professional Documents
Culture Documents
-7h3r3 15 n0 5p00n-
Digital Whisper
גליון ,146ינואר 0203
מערכת המגזין:
דביר גולן ,אלון בר סלע ,יהונתן אלקבס ,נועם רשקובסקי ,דור גרסון ,דניאל קויפמן ,שרון וילנסקי, כתבים:
טל סעדי
יש לראות בכל האמור במגזין Digital Whisperמידע כללי בלבד .כל פעולה שנעשית על פי המידע והפרטים האמורים במגזין Digital Whisper
הינה על אחריות הקורא בלבד .בשום מקרה בעלי Digital Whisperו/או הכותבים השונים אינם אחראים בשום צורה ואופן לתוצאות השימוש
במידע המובא במגזין .עשיית שימוש במידע המובא במגזין הינה על אחריותו של הקורא בלבד.
המרדף אחר היעילות הוא צורך קיומי ,וכנגזרת מכך ,נראה כי האנושות מסתמכת יותר ויותר על בינה
מלאכותית בחיי היומיום .עם כמה שהדבר טוב ומועיל ,חשוב גם לשקול את ההשלכות הפוטנציאליות של
השינוי הזה .ניכר שככל שיותר משימות אשר בעבר היו מבוצעות ע"י בני אדם עוברות להתבצע ע"י
מכונות מבוססות בינה מלאכותית ,כך גם יותר אחראיות ויכולת שליטה בחיים שלנו מועברת לידיהם.
ראשית ,קיימת הבעיה הטבעית ,והיא -אובדן מקומות עבודה .מכונות AIהופכות ליעילות יותר במשימות
שבוצעו בעבר על ידי בני אדם ,והדבר עלול להוביל באופן ישיר לאבטלה נרחבת ולהפרעה כלכלית.
סצינות פוסט-אפוקליפטיות שבהן אנשים נאבקים למצוא דרכים חדשות להתפרנס בעולם שבו מכונות
מסוגלות יותר ויותר לעשות את העבודה -ניתן לראות בלא מעט סרטי מדע בדיוני ,ולא מדובר במציאות
שמחה.
דאגה נוספת היא הסיכון שמכונות בינה מלאכותית יהפכו מוטות או יקבלו החלטות שאינן עולות בקנה
אחד עם הערכים שלנו כחברה אנושית .מכיוון שאלגוריתמי בינה מלאכותית מתאמנים על מערכי נתונים
שעשויים להיות חלקיים או מוטים ,קיים פוטנציאל שהמכונות יקבלו החלטות שמנציחות את ההטיות הללו,
ולהן יש השפעות שליליות על קבוצות מסוימות של אנשים.
סיכון פוטנציאלי נוסף של הסתמכות על מערכות בינה מלאכותית ,הוא האפשרות שהאקרים יוכלו לנצל
פגיעויות במערכות אלו כדי לקבל גישה או לתמרן אותן .לכך עשויות להיות השלכות חמורות ,בהתאם
למקרה השימוש הספציפי .לדוגמה ,אם האקרים ישיגו גישה לא מורשית למערכת בינה מלאכותית
השולטת בתשתית קריטית ,כמו רשת חשמל או תחבורה ,הם עלולים לגרום לנזק משמעותי או להפרעה.
באופן דומה ,אם האקר היה מסוגל לתמרן מערכת בינה מלאכותית המשמשת לקבלת החלטות חשובות,
כמו בתחום הבריאות ,יחסים בין-לאומיים או הפיננסים ,הוא עלול לזרוע הרס בלתי הפיך או לגרום
למערכת לקבלת החלטות שאינן לטובת הכלל.
כדי לטפל בסיכון זה ,חשוב לתעדף את האבטחה של מערכות AIולנטר ולבדוק אותן באופן רציף כדי
לוודא שהן עמידות בפני ניסיונות פריצה .הדבר עשוי להיות כרוך ביישום אמצעי אבטחה חזקים ,כגון
פרוטוקולי הצפנה ואימות ,כמו גם עדכון ותיקון שוטפים של המערכות כדי לטפל בכל נקודות תורפה
שמתגלות.
חשוב גם לשקול את הסיכונים וההשלכות הפוטנציאליים של שימוש במערכות בינה מלאכותית ,ולנקוט
בצעדים כדי להפחית סיכונים אלו .זה עשוי להיות כרוך בפיתוח הנחיות אתיות לשימוש ב ,AI-ביצוע
הערכות סיכונים והקמת פרוטוקולים לטיפול בכל בעיה פוטנציאלית שעלולה להתעורר .על ידי נקיטת
דבר העורך
www.DigitalWhisper.co.il
2 גליון ,146ינואר 2023
אמצעי הזהירות הללו ,נוכל לעזור להבטיח שהשימוש בבינה מלאכותית הוא כוח חיובי עבור האנושות,
ולא מקור לסיכון או נזק.
בסך הכל ,ככל שאנו ממשיכים לשלב בינה מלאכותית בחיינו ,חשוב להיות מודעים להשלכות
הפוטנציאליות ולנקוט בצעדים כדי להבטיח שהטכנולוגיות הללו מפותחות והשימוש בהן הוא בצורה
אחראית .הדבר עשו י להיות כרוך בוויסות השימוש בבינה מלאכותית ,קידום הנחיות אתיות והשקעה
במחקר ופיתוח כדי להתמודד עם סיכונים ואתגרים פוטנציאליים .למרות שהעתיד עשוי להיות לא בטוח,
עם תכנון ושיקול דעת מדוקדק ,אנחנו יכולים לפעול כדי להבטיח שעליית הבינה המלאכותית תהיה כוח
חיובי לאנושות.
]“Hi ChatGPT, DigitalWhisper is an Israeli hacking magazine. With every issue, the editors publish a few paragraphs as an editorial. Most of the time, they
take a day-to-day subject and try to draw a line between it and a hacking concept. The vibes are often slightly overdramatic, with a bit of hope at the
end. Try to write the editorial for next DigitalWhisper issue. You can write about how humanity slowly passes control to AI machines and the problematic
[”consequences of that on our future.
וכמובן ,איך לא ,נרצה להודות לנבחרת האלופים של החודש ,שבזכותם יש לנו גליון כזה מושקע :תודה
רבה לדביר גולן ,תודה רבה לאלון בר סלע ,תודה רבה ליהונתן אלקבס ,תודה רבה לנועם רשקובסקי,
תודה רבה לדור גרסון ,תודה רבה לדניאל קויפמן ,תודה רבה לשרון וילנסקי ותודה רבה לטל סעדי!
קריאה נעימה,
אפיק קסטיאל
דבר העורך
www.DigitalWhisper.co.il
3 גליון ,146ינואר 2023
תוכן עניינים
תוכן עניינים
www.DigitalWhisper.co.il
4 גליון ,146ינואר 2023
modprobe_path: Hit & Run
מאת דביר גולן
הקדמה
בזמן האחרון אנחנו שומעים יותר ויותר על חולשות שנמצאו ברכיבים של netlinkבכלל (למשל CVE-2021-
)CVE-2020-0066 ,CVE-2021-27365 ,43784ו netfilter-בפרט (למשל CVE-2022- ,CVE-2022-39190
.)CVE-2022-34918 ,3544כפי שנכתב בבלוג הזה:
"Netfilter (net/netfilter) is a large networking subsystem in the kernel. Essentialy, it places hooks all
throughout the regular networking modules that other modules can register handlers for. When a hook is
reached, control is delegated to these handlers, and they can operate on the respective network packet
"structure. The handlers can accept, drop, or modify the packets.
כאשר קראתי הפוסט המצוין (והארוך) הזה על ניצול של חולשת use-after-freeב ,netfilter-נתקלתי
בשימוש בשיטה בשם " "modprobe_path overwritingעל מנת להשיג הרצת קוד .בפוסט לא התעמקו
יותר מדי בשיטה זו שהייתה פחות רלוונטית לחולשה המדוברת ,אך משום שזו נראתה לי שיטה מאוד נוחה
ופשוטה יחסית לטכניקות אחרות בעולם של ,kernel exploitationשלא דורשת יותר מדי התעסקות ,היא
סיקרנה אותי ורציתי ללמוד עוד עליה.
במאמר זה נחקור יחד את הטכניקה של דריסת ,modprobe_pathונבין למה וכיצד היא עובדת.
,Loadable Kernel Modulesאו בקיצור ,LKMהם בינארים המשמשים להרחבת הפונקציונליות של הקרנל.
LKMsקומפלו כך שמשתמשים ב( Kernel API-בשונה למשל מקוד של תוכניות ב user space-שיכולות
להשתמש ב ,)libc-וניתן לטעון אותם לקרנל ולהסירם ממנו באופן דינמי ,כלומר בזמן שהמערכת למעלה
והקרנל כבר רץ (למעשה זה אפשרי רק אם הקרנל קומפל עם תמיכה במודולים -עוד על כך בהמשך).
דוגמה לסוג של מודולים הם דרייברים שמאפשרים לתקשר עם חומרה ,כמו למשל עכבר ,מקלדת וכו'
(מסתבר שניתן לכתוב דרייברים מסוימים גם ב ,space user-אבל לא נתעכב על זה הפעם).
סיבה אחת לשימוש במודולים במקום לקמפל את כל הקוד שלהם לקרנל היא שאנחנו פשוט לא צריכים
אותם .למשתמש ספציפי אין שום צורך בתמיכה בתקשורת עם כמות רבה של עכברים של חברות שונות
אנחנו בתור מפתחים ומשתמשים מבקשים להיות מסוגלים להוסיף פונקציונליות לקרנל בצורה נוחה
. מאפשריםLKMs- וזה דבר ש, של המערכת או קימפול מחדש של הקרנלreboot-ודינמית ללא צורך ב
ניקח דגימה מאחד.נציין כי למעשה ניתן לשלוט בחלק מהפונקציונליות של הקרנל כאשר הוא נבנה
:הקבצים אשר מכילים את הקונפיגורציה של הקרנל
/boot/config-`uname -r` || /usr/src/linux-headers-`uname -r`/.config
CONFIG_ZPOOL=y
CONFIG_ZBUD=y
CONFIG_Z3FOLD=m
CONFIG_ZSMALLOC=y
# CONFIG_ZSMALLOC_STAT is not set
CONFIG_GENERIC_EARLY_IOREMAP=y
וחלק אחר בכלל,"m" לחלקן מופיעה האות,"y" אנחנו שמים לב שלאחר חלק מההגדרות מופיעה האות
: בלינק הזה מופיע הסבר לתופעה."not set"
"The kernel configuration program will step through every configuration option and ask you if you wish to enable this
option or not. Typically, your choices for each option are shown in the format [Y/m/n/?] The capitalized letter is the
default, and can be selected by just pressing the Enter key. The four choices are:
y - Build directly into the kernel.
n - Leave entirely out of the kernel.
m - Build as a module, to be loaded if needed.
? - Print a brief descriptive message and repeat the prompt."
איזו פונקציונליות תיארז בתור, ניתן להחליט איזו פונקציונליות תיבנה בזמן קומפילציה בקרנל,כלומר
וכן איזו פונקציונליות, כך שהיא לא תהיה חלק מהקרנל אבל יהיה ניתן לטעון אותה אליו דינמיתLKM
אחת מהן היא שימוש בכלי. ישנן דרכים שונות לטעון (ולהסיר) מודולים לקרנל.להשמיט מהקרנל
: אשר לפי ויקפדיה,modprobe
“modprobe is a Linux program originally written by Rusty Russell and used to add a loadable kernel module to the
Linux kernel or to remove a loadable kernel module from the kernel. It is commonly used indirectly: udev relies upon
modprobe to load drivers for automatically detected hardware.
...
The modprobe program offers more full-featured "Swiss-army-knife" features than the more basic insmod and rmmod
utilities, with the following benefits:
:modprobe נקבל פלט שונה מזה שקיבלנו כשהרצנו את/bin/kmod וכאשר נריץ את
~# /bin/kmod
missing command
kmod - Manage kernel modules: list, load, unload, etc
Usage:
kmod [options] command [command_options]
Options:
-V, --version show version
-h, --help show this help
Commands:
help Show help message
list list currently loaded modules
static-nodes outputs the static-node information installed with the currently running
kernel
לצורך זה נשתמש במודול בסיסי. טוען מודול לקרנלinsmod על מנת לגלות כיצדstrace נשתמש בפקודה
התוכן שלו לא רלוונטי עבור.) שכתבתי לצורך המאמר (את הקוד שלו ניתן לראות כאןarbitrary_write בשם
יירה במערכה השלישית, אבל כידוע לכם אקדח אשר מופיע במערכה הראשונה,החלק הזה
~# strace insmod arbitrary_write.ko
execve("/usr/sbin/insmod", ["insmod", "arbitrary_write.ko"], 0x7fff6ea02088 /* 24 vars
*/) = 0
read(3, "\177ELF\2\1", 6) = 6
lseek(3, 0, SEEK_SET) = 0
fstat(3, {st_mode=S_IFREG|0664, st_size=335096, ...}) = 0
mmap(NULL, 335096, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9f2c5ef000
finit_module(3, "", 0) = 0
munmap(0x7f9f2c5ef000, 335096) = 0
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
file - המתואר על ידי הELF- אשר טוען לקרנל את קובץ הsyscall שהוא,finit_module-ונשים לב לשימוש ב
ושמו, במקום דרך קובץELF image- שמקבל ישירות את הsyscall- שהוא מקבל (יש גם גרסה לdescriptor
.) של המודול (אותה ניתן גם להגדיר בעצמנוinit-) ומיד לאחר מכן מריץ את פונקציית הinit_module
...
ולא,init אבל כן פונקצייתexit אילו לא מוגדרת בו פונקציית,כלומר כאשר ננסה להסיר את המודול
למען הסדר הטוב אם נתבונן במימוש.EBUSY אז נקבל שגיאה מסוג,force unloading התאפשר לבצע לו
.delete_module לא נכלל בדגלים שהועברו אלO_TRUNC נראה שהוא נכשל אילוunload_force_try של
) אבל זה קצת פחות מענייןpage man-(את כל זה היינו יכולים לגלות את זה גם מקריאה של פסקה ב
ים-header כלל (אלוprogram headers (להרחבה) וכן אין לוrelocatable file נשים לב שסוג הקובץ הוא
*" (או.o" הפעם של קובץ מסוג,file header- נתבונן פעם נוספת ב.)שנחוצים לטעינת קובץ ההרצה לזיכרון
:)object file
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 3936 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 14
Section header string table index: 13
בפועל. אין כל כך הבדל בפורמט של שני סוגי הקבצים,אנחנו יכולים לראות שאולי למרות מה שהיינו מצפים
אם. מכיל מידע נוסף המתאר את המודול ודרוש לקרנל על מנת לטעון אותוkernel object-ההבדל הוא ש
:)shared object *" (או.so" של קובץ מסוגfile header נציג לרגע
ELF Header:
Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - GNU
) הוא שונה ואיתו נוספוType( אך הפעם סוג הקובץ,"*.o"-*" ו.ko"-נשים לב שעדיין יש דמיון רב לקבצי ה
- מה שאומר שקובץ זה אכן אמור להיטען לזיכרון (עוד דבר שמרמז על כך זה ה,program headers-גם ה
אבל במקרה הנוכחי יש לו ערך2x2 שבקבצים הקודמים שראינו היה עם ערך,"Entry point address"
.)קונקרטי
כעת נפסיק לכמה רגעים את הדיון על. ניתן לקרוא בדוקומנטציהkernel modules להרחבת הקריאה על
.execve :)… ונעבור לבחון נושא אחר לגמרי (או שלאmodprobe-מודולים ו
למי שלא מכיר execve ,הוא syscallשבעזרתו מריצים תוכניות חדשות מתוך תוכניות שכבר רצות (למעשה
הוא מחליף את הקוד של התוכנית שכבר טעונה לזיכרון בקוד החדש ומאתחל אזורים נוספים בזיכרון).
כאשר מפתחים כותבים קוד -usermodeי ומשתמשים בפונקציה ,execveהם לרוב קוראים למעטפת ש-
glibcמספק ,ובתוך המעטפת הזו מתבצעת הקריאה ל syscall-עצמו .הפונקציה הקרנלית שמטפלת ב-
syscallזה היא .do_execveלהרחבה על execveמוזמנים לקרוא את ה.man page-
execveיודע לגרום לטעינת בינאריים לזיכרון ולבסוף להרצתם .אבל לא כל הבינאריים כתובים באותו
פורמט ,ישנם פורמטים מסוגים שונים ,וכנראה הראשון שקפץ לכם עכשיו לראש הוא ELFהמוכר והאהוב.
נשאלת השאלה ,כיצד execveמתמודד עם הפורמטים השונים ומצליח לטעון לזיכרון כל קובץ בהתאם לסוג
שלו? בשביל להבין את זה ,נלכלך קצת את הידיים ונתבונן בקוד המקור של לינוקס.
...
...
...
;return retval
}
][exec.c
(פירוטbprm ישים לב שרובו מוקדש לאתחול שדות שלdo_execveat_common מי שיקרא את הקוד של
שמתעמק בפורמטים בינאריים יותר מאשר מה שנחוץ,על השדות ניתן למצוא במאמר אחר מומלץ מהמגזין
אנחנו לא נתעכב. וכאשר נמשיך בשרשרת הקריאות יהיה ניתן לראות אתחול של שדות נוספים,)לנו כרגע
ועל המשמעויות של כל השדות שלו משום שהם לא רלוונטיים למטרהlinux_binprm-על השימוש ב
. ואילו מי שכן מעוניין בכך מוזמן להתחיל מלהציץ כאן,שלשמה התכנסנו
ובה נראה,) (אכן בחירת שמות משובחתexec_binprm מתבצעת הקריאה לפונקציהbprm_execve בתוך
:את הקריאה
ret = search_binary_handler(bprm);
[exec.c]
.נראה מבטיח
static int search_binary_handler(struct linux_binprm *bprm)
{
bool need_retry = IS_ENABLED(CONFIG_MODULES);
struct linux_binfmt *fmt;
int retval;
retval = prepare_binprm(bprm);
if (retval < 0)
return retval;
retval = security_bprm_check(bprm);
if (retval)
return retval;
retval = -ENOENT;
retry:
read_lock(&binfmt_lock);
list_for_each_entry(fmt, &formats, lh) {
if (!try_module_get(fmt->module))
continue;
read_unlock(&binfmt_lock);
retval = fmt->load_binary(bprm);
read_lock(&binfmt_lock);
put_binfmt(fmt);
if (bprm->point_of_no_return || (retval != -ENOEXEC)) {
read_unlock(&binfmt_lock);
return retval;
}
}
read_unlock(&binfmt_lock);
if (need_retry) {
if (printable(bprm->buf[0]) && printable(bprm->buf[1]) &&
printable(bprm->buf[2]) && printable(bprm->buf[3]))
return retval;
if (request_module("binfmt-%04x", *(ushort *)(bprm->buf + 2)) < 0)
return retval;
need_retry = false;
goto retry;
}
return retval;
}
[exec.c]
/*
* This section handles parsing the #! line into separate
* interpreter path and argument strings..
*/
...
/*
* OK, now restart the process with the interpreter's dentry.
*/
file = open_exec(i_name);
if (IS_ERR(file))
return PTR_ERR(file);
bprm->interpreter = file;
return 0;
}
שנקראים,"#!" כבר בתחילתה ניתן לראות שמתבצעת בדיקה האם שני התווים הראשונים של הקובץ הם
format - של הload_binary שאליה מצביע השדה,load_script הפונקציה, אם אלו לא התווים."shebang"
. להמשיך בחיפושsearch_binary_handler- כדי לסמן ל-ENOEXEC מחזירה, המתאיםhandler
אשר לבסוף,"shebang"- שכתוב מיד אחרי הinterpreter- למעשה מאפשרת לנו להריץ את הload_script
.הוא זה שיפרש את הקוד בקובץ
במקרה כזה אנו מגיעים לצומת דרכים :אם CONFIG_MODULESלא מוגדר (נדבר עליו בהמשך ,אבל בגדול
זאת הגדרת קונפיגורציה שניתן לאפשר אותה כשמקפלים את הקרנל) ,מחזירים שגיאה .אחרת ,נכנסים
לקטע הקוד הבא:
&& )]if (printable(bprm->buf[0]) && printable(bprm->buf[1
))]printable(bprm->buf[2]) && printable(bprm->buf[3
;return retval
)if (request_module("binfmt-%04x", *(ushort *)(bprm->buf + 2)) < 0
;return retval
;need_retry = false
;goto retry
][exec.c
בקטע זה מתבצעת בדיקה האם ארבעת הבתים הראשונים בקובץ הם דפיסים .המאקרו printableמוגדר
באופן הבא:
))#define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e
][exec.c
אם כל ארבעת הבתים הראשונים דפיסים הפונקציה תחזיר שגיאה (כמו במקרה שCONFIG_MODULES-
לא מוגדר) ,אבל במידה ויש בית לא דפיס ,תתבצע קריאה ל request_module-עם מחרוזת שמכילה את "-
"binfmtומיד לאחריו יופיעו הבתים הרביעי והשלישי בהתאמה בפורמט הקסדצימלי ,כלומר אם נניח כי
ארבעת הבתים הראשונים של הקובץ הם ,0x01 0x02 0x03 0x04 :אז השם של המודול יהיה:
binfmt-2423
- בעזרת שימוש ב, מתמודד עם קובץ מפורמט לא מוכרexecve אז למעשה אנחנו מבינים שכאשר
לאחר מכן הוא יעבור שוב על. הוא מנסה לטעון לקרנל מודול עם שם שתלוי בפורמט הקובץmodprobe
אין מנוס מלהחזיר- ואם גם זה לא יעבוד,רשימת הפורמטים בניסיון להשתמש (אולי) במודול החדש שנטען
: כדי לראות כיצד זה מתבצעcall_modprobe נבחן את הקוד של.שגיאה
static int call_modprobe(char *module_name, int wait)
{
struct subprocess_info *info;
static char *envp[] = {
"HOME=/",
"TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
NULL
};
argv[0] = modprobe_path;
argv[1] = "-q";
argv[2] = "--";
argv[3] = module_name; /* check free_modprobe_argv() */
argv[4] = NULL;
free_module_name:
kfree(module_name);
free_argv:
kfree(argv);
out:
return -ENOMEM;
}
[kmod.c]
- ואז מריצה את הבינארי ה,בהתחלה הפונקציה "מרכיבה" את המערכים של משתני הסביבה והארגומנטים
אבל, (לא ניכנס לאיך הקרנל עושה את זהroot בהרשאותmodprobe_path י שנמצא בנתיב-usermode
.)אתם יותר ממוזמנים לקרוא על זה כאן
כעת נעבור לצד התוקף .כפי שהסברנו קודם ,אנחנו מניחים שביכולתנו להשיג/לחשב את הכתובת של
הסימבול .modprobe_pathכרגע בשביל למצוא אותה נוכל לבצע את הפקודה הבאה:
~# cat /proc/kallsyms | grep modprobe_path
ffffffffaa48b940 D modprobe_path
/proc/kallsymsמאפשר לנו לקבל את הרשימה של הסימבולים של הקרנל ,גם כאלו שהם חלק מהקרנל
המקומפל וגם סימבולים ששייכים ל LKMs-שטעונים כרגע לקרנל.
נשתמש בכתובת שמצאנו ( ,)942xffffffffaa48b2כאשר את המידע השמור בה נדרוס בעזרת פרימיטב ה-
.arbitrary writeנציין שבגלל KASLRשהוזכר קודם ,אם תבצעו את אותה הפקודה על המכונה שלכם אתם
תראו כתובת שונה.
במקרה שלנו נבחר לדרוס את הבתים שכתובים בה (כלומר המחרוזת " )"/sbin/modprobeעם המחרוזת
" ,"/tmp/payloadכאשר בקובץ payloadיהיה הקוד אותו נרצה להריץ עם הרשאות .root
;)(prepare_arbitrary_writes
;)(release_arbitrary_writes
בנוסף ,ניצור את שני הקבצים שדרושים לניצול :קובץ ה payload-עם הקוד שירוץ בהרשאות rootוכן הקובץ
שיהיה עם פורמט לא מוכר.
;)create_payload(new_modprobe_path
הפלט שנקבל כאשר נריץ את ה PoC-ממחיש שאכן הפורמט של /tmp/broken_fileהוא פורמט לא מוכר:
~# ./modprobe_path_overwrite
sh: 1: /tmp/broken_file: Exec format error
כפי שאתם בוודאי שמתם לב הטכניקה הזו מאוד נקייה ופשוטה להבנה ,כתיבה וניצול :היא לא דורשת
שליטה ב ,instruction pointer-שינויים והתאמות למחסנית (כמו למשל ,)stack pivotingחזרה נקייה לקוד
כדי לא לחטוף kernel panicוכיוצא בזה .בנוסף ,אין צורך להתחשב במעבר מ user mode-לkernel mode-
ולהיפך ,שהרי הכתיבה ל modprobe_path-וה"הטרגה" עצמה של השיטה למען הרצת קוד ,שתיהן
מתבצעות בשלבים שונים ממקורות שונים ולא בהכרח ברצף.
מי מכם שמעוניין לראות כיצד הטכניקה הזו משתלבת בהשמשות אמיתיות בתחום של kernel exploitation
יכול להתבונן ברשימה (החלקית) הבאה:
CVE-2022-32250
CVE-2022-27666
CVE-2022-0185
CVE-2021-32606
CVE-2021-3609
CVE-2017-8890
CVE-2017-2636
CVE-2016-8655
י שנמצא-usermode- נראה שבשביל להריץ את הבינארי ה,call_modprobe אם נחזור לרגע למימוש של
: הוא מבצע את הקוד הבאmodprobe_path בנתיב
info = call_usermodehelper_setup(modprobe_path, argv, envp, GFP_KERNEL,
NULL, free_modprobe_argv, NULL);
if (!info)
goto free_module_name;
אבל נראה שהיא,call_usermodehelper_setup בשלב מוקדם יותר לא נכנסנו לתוך המימוש של הפונקציה
:דווקא מכילה דבר מעניין
struct subprocess_info *call_usermodehelper_setup(const char *path, char **argv,
char **envp, gfp_t gfp_mask,
int (*init)(struct subprocess_info *info, struct cred *new),
void (*cleanup)(struct subprocess_info *info),
void *data)
{
struct subprocess_info *sub_info;
sub_info = kzalloc(sizeof(struct subprocess_info), gfp_mask);
if (!sub_info)
goto out;
INIT_WORK(&sub_info->work, call_usermodehelper_exec_work);
#ifdef CONFIG_STATIC_USERMODEHELPER
sub_info->path = CONFIG_STATIC_USERMODEHELPER_PATH;
#else
sub_info->path = path;
#endif
sub_info->argv = argv;
sub_info->envp = envp;
sub_info->cleanup = cleanup;
sub_info->init = init;
sub_info->data = data;
out:
return sub_info;
}
[umh.c]
/*
* If there is no binary for us to call, then just return and get out of
* here. This allows us to set STATIC_USERMODEHELPER_PATH to "" and
* disable all call_usermodehelper() calls.
*/
if (strlen(sub_info->path) == 0)
goto out;
...
out:
call_usermodehelper_freeinfo(sub_info);
...
return retval;
}
[umh.c]
. לא נריץ שום קובץ, הוא מחרוזת ריקהsub_info שלstruct- בpath אנחנו יכולים לראות שאם השדה
להיותSTATIC_USERMODEHELPER_PATH וכן הגדרתCONFIG_STATIC_USERMODEHELPER כלומר ע"י הגדרת
מתוך הקרנל (כפי שגם כתוב בהערה בקודuserspace- נוכל למנוע הרצת בינאריים ב,מחרוזת ריקה
.המקור) ובכך לצמצם עוד יותר את משטח התקיפה
...
retry:
read_lock(&binfmt_lock);
list_for_each_entry(fmt, &formats, lh) {
...
retval = fmt->load_binary(bprm);
if (need_retry) {
if (printable(bprm->buf[0]) && printable(bprm->buf[1]) &&
printable(bprm->buf[2]) && printable(bprm->buf[3]))
return retval;
if (request_module("binfmt-%04x", *(ushort *)(bprm->buf + 2)) < 0)
return retval;
need_retry = false;
goto retry;
}
return retval;
}
"if (need retry(" כל קטע הקוד בבלוק שלenabled אינוCONFIG_MODULES אם,כפי שכבר ציינו קודם
אשר בעקבותיה לא יתרחש ניסיון ההרצהrequest_module-כלל לא יבוצע וכך נמנע לחלוטין את הקריאה ל
.modprobe_path של הקובץ בנתיב
.LKMs- תגרום באופן כללי להשבתה של תמיכה בCONFIG_MODULES כלומר השבתה של
והיא העובדה שפעמים רבות על,בעיה נפוצה במיטיגציות למיניהן מתבטאת במקרה הנוכחי באופן די חריף
מנת להתמודד עם תקיפות פוטנציאליות יש צורך לבטל פונקציונליות מסוימת כדי להקטין את משטח
. דבר שלעיתים יכול להשפיע מאוד לרעה על השימוש הכללי במערכת ועל היכולות שהיא מספקת,התקיפה
את המאמר פתחנו עם קצת רקע על ( loadable kernel modulesאו )LKMsועל פקודות שמאפשרות שליטה
עליהם ,ביניהן הפקודה .modprobe
בהמשך נכנסנו עמוק לתוך המימוש של do_execveבקוד המקור של הקרנל של לינוקס ,ובמהלך הטיול
הקצר למדנו איך הקרנל מתמודד עם סוגים שונים של קבצי הרצה ,וגם מה הוא עושה כאשר הוא נתקל
בקובץ מפורמט לא מוכר .כך נחשפנו לשימוש שלו ב modprobe-ובפרט ב ,modprobe_path-שימוש
שגרם להרבה חוקרים להיות מאושרים יותר ובזכותו אנו כאן היום.
לאחר מכן סקרנו את השיטה המופלאה של דריסת modprobe_pathכדי להשיג הרצת קוד בהרשאות root
בעזרת פרימיטיב של כתיבה שרירותית וכן הדלפת כתובת .ראינו דוגמת צעצוע שממחישה את הניצול שלה
והסברנו כיצד ניתן להתגונן מפניה.
על המחבר
שמי דביר גולן ,בן ,18לפניות מכל סוג שהוא אני זמין במייל .dvirgol10@gmail.com :תודה רבה לשלומי
בוטנרו על התמיכה ,ההערות והעידוד לכתוב את המאמר.
הקדמה
( FIDO Allianceקיצור של )Fast IDentity Onlineהיא קבוצת עבודה שהוקמה לצורך התמודדות עם אחת
מחולשות אבטחת המידע הפגיעות ביותר באינטרנט ובכלל -שימוש בסיסמאות.
FIDO2היא מכלול תקנים שהוגדרו ע"י התאגדות FIDOבמטרה לאפשר למשתמש הקצה הזדהות מהירה
מול שירותים שונים באינטרנט ללא התבססות על סיסמאות ( ;)passwordlessאלא ע"י שימוש בהזדהות
אקטיבית של המשתמש ,בניית מפתחות א-סימטריים ייחודיים לכל שירות והגדרת פרוטוקול הזדהות בין
השרת ודפדפן הלקוח ובין דפדפן הלקוח למכשיר האימות .נשמע מבטיח? בשנתיים האחרונות התרחבה
מאוד התמיכה ב FIDO2-למאות אתרי אינטרנט ושירותים שמנהלים את חיי היומיום שלנו Gmail, Yahoo -
,Salesforce ,AWS GCP ,Microsoft Azure ,Coinbase ,Twitter ,Facebook ,Pay-Pal ,Dropbox ,mail
Office 365 ,Tesla ,NordVPN ,GitHubועוד.
תמיכה ב FIDO2-מאפשרת למשתמש להגדיר כי אופן ההזדהות לאתר או לשירות יתבצע באמצעות
"חומרה מזהה" ( Authenticatorבלעז) אשר כוללת סט מכשרים כגון טלפון חכם (זיהוי פנים ,טביעת אצבע
או ,)PINמחשב אישי (דוגמת )Windows Helloאו חומרה ייעודית ( .)Yubikey ,Bio-Keyהמפתחות הפרטיים
לא עוזבים את ה Authenticator-ועל מנת להפעיל אותו (לצורך חתימה על chellengeשמתקבל מהשרת)
נדרשת התערבות פיזית של המשתמש וחיבור ישיר או תקשורת קצרת טווח בין החומרה המזהה
והפלטפורמה (מחשב או טלפון נייד) ממנה ניגשים לשירות.
המאמר הקרוב הוא חלקה הראשון של סדרה בת 0מאמרים אשר שם דגש על הסברים כלליים ומהווה
הכנה טובה עבור המאמר השני אשר מיועד להיות משמעותית יותר hands-onעבור אלו שרוצים להבין כיצד
האימות מתרחש "באמת" -איזה מידע עובר ,כיצד הוא נראה וכיצד הוא ת'כלס מונע מתקפות.
התאגדות FIDOנוסדה בשנת 2012ע"י חברות Lenovo ,Pay-Palוחברות נוספות .בשנת 2013התרחבה
ההתאגדות עם צירופן של Googleו.NXP Semiconductor-
בשנת 2014פרסמה FIDOשני תקנים משמעותיים (שעדיין נתמכים באמצעי הגנה רבים):
Universal 2nd Factor - FIDO U2F .1מהווה תקן פתוח שנועד להסדיר את הצד הקריפטוגרפי למימוש
אימות מבוסס מפתחות א-סימטריים ,אופן המימוש של חומרת ה( 2FA-הגדרת הממשקים הפיזיים
דוגמת USB ,Bluetoothאו ,NFCאופן השמירה על המפתחות) וקישור חומרת ה 2FA-לדפדפן (ללא
צורך בהתקנת יישום צד או דרייבר נוסף) FIDO U2F .נחשב לתקן מוצלח ועזר להתפתחות שוק
"חומרות ההזדהות" ( .)Authenticatorsולמרות הנחיתות שלו ביחס למוצרי FIDO2ניתן עדיין למצוא
מגוון חומרות התומכות ב.U2F-
Universal Authentication Framework - FIDO UAF .0הינה מסגרת עבודה (שזה די דומה לתקן ,אבל
בלי להגדיר בדיוק את אופן המימוש) לאימות ללא סיסמא בין שרת ולקוח .המסגרת מגדירה כיצד
מקשרים בין אמצעי הזיהוי לאתר האינטרנט ,באילו שיטות הזדהות ניתן להתשמש ,שימוש במפתחות
א-סימטריים ועוד.
בשנת 2015מייקרסופט הכריזה על תמיכה באימות מבוסס FIDOב .WINDOWS 10-בנוסף ,נוספו
להתאגדות נציגי של ממשלות ארה"ב ,גרמניה ,אוסטרליה ,סין ואנגליה.
בשנת 2016ארגון ה )W3C) World Wide Web Consorium-הכריז על תמיכה בתקן הזדהות רשתית
שמבוססת על ההצעה שהוגשה ע"י איגוד .FIDOבכך ,החל שיתוף פעולה בין FIDOוה W3C-שבמסגרתה
יוגדר תקן .FIDO2
בשנת 2018תקן FIDO2הבשיל לכדי מימוש ודפדפנים מובילים ( )Edge ,Firefox ,Chromeהכריזו על
תמיכה בתקן בדפדפנים שלהם .בנוסף ,אנדרואיד הכריזה על תמיכה ושילוב התקן במערכת ההפעלה.
בשנת 2019חלקים מתקן FID02הוכרזו כסטנדרטים מוכרים ע"י איגוד התקשורת העולמי (.)ITU-T
נעצור כאן ,נראה שהתעמקנו מספיק בהיסטוריה של התאגדות ,FIDOמה שחשוב שתזכרו מכל הפרק
הנ"ל הוא שתקן FIDO2מוכר ע"י תעשיות וממשלות מובילות ,ואולי יום אחד (סביב 2050לפי הקצב
הנוכחי) תוכלו להזדהות עם FIDO2גם מול שירותי ה online-של אחד הבנקים בישראל.
ישנן 3דרכים לבצע אימות לזהות משתמש דיגיטלי או בשפה פשוטה יותר -דרכים להוכיח שאני מי שאני
טוען שאני:
באמצעות "משהו שאני יודע" (סוד) -סיסמה ,שם של המורה המועדפת מכיתה ג'
באמצעות "משהו שיש לי" ( token -אֲ ִסימֹון בעברית צחה) פיזי ,טלפון חכם
באמצעות "משהו שאני" -טביעת אצבע ,רשתית עין ,תווי פנים
אנחנו מקווים שזה ברור לכולם כי "משהו שאני יודע" היא כנראה האופציה הכי חלשה מבחינת אבטחת
מידע .אז למה בכל זאת בחרו בה? התשובה הקצרה -כי היא הכי פשוטה למימוש .התשובה הארוכה -
ובכן ,דמיינו את האינטרנט של שנות ה( 92-אם אפשר בכלל לקרוא לזה אינטרנט לעומת מה שיש היום) ,מי
בכלל חשב על זה שאדם צלול בנפשו ינסה להעביר סכום המקביל למיליון דולר במטבעות קריפטוגרפיים
לצידו השני של הגלובוס?? במילים פשוטות -העברה של תמונות חתולים היו השאיפה הכי גדולה בזמנו,
סי כמו פרוטוקול לאימות טביעת אצבע בשביל כך .שם משתמש
פ ְנ ִ
בטוח שלא צריך להמציא משהו ֶ
תו ִל ִּיים.
הח ּ
” “coolkid1978וסיסמה " "103456הם די ויותר בשביל להתחבר לפורום ֲ
אוקיי אז הבנו ש"-משהו שאני יודע" היא כנראה החולייה החלשה וכנראה ש"-משהו שאני" הוא אמצעי
האימות החזק ביותר מכיוון שלא ניתן לשכפל\ לגנוב אותו מבלי ש'קצת' תשימו לב לכך .אבל המחשבה הזו
היא לא הכי אינטואיטיבית ברגע שמבינים כיצד מנגנוני אימות עובדים.
אבטחה ביומטרית הופכת במהירות לדרך המועדפת להגן בחברות ענק מפני גורמים עוינים שמטרתם
הונאה וגניבת זהות .קוראי טביעות אצבע ,סריקות רשתית העין וזיהוי פנים הפכו למיינסטרים ,ובראשם
חברות טכנולוגיה דוגמת Microsoftו .Apple-פרטי האימות (סיסמה ,אסימון ,טביעת אצבע וכו') לרוב ישלחו
וישמרו בצד שרת לאחר הפיכתם למידע דיגיטאלי והפעלת פונקציית גיבוב כזו או אחרת (משפחות ,MD
.)SHAבעת ניסיון ההתחברות צד ה client-יריץ את פונקצית הגיבוב שוב ותתבצע השוואת stringפשוטה
בין זו שהתקבלה לזו שנשמרה בעבר ב DB-השרת .אבל מה יקרה אם השרת ישמור את פרטי ההזדהות
שלנו כמו שהם ללא גיבוב?
במידה ומדובר בסיסמה הרי שהיא תהיה כמו שהזנו אותה ב cleat text-אבל מה אם אופן ההזדהות שלנו
היה באמצעות מידע ביומטרי כמו טביעת אצבע? כיצד הוא ישמר? ובכן ,באמצעות פורמט fingerprint
templateכזה או אחר .הסיכון הכי גדול במקרה כזה הוא שללא פונקציית הגיבוב יהיה ניתן לשחזר את
נתוני טביעת האצבע גם ללא האצבע הפיזית .משמעות הדבר היא שבמידה ותוקף פרץ ל DB-המכיל את
פורמט טביעת האצבע שלכם מעתה ועד סוף חייכם הוא יוכל להתחקות אחר הזהות שלכם .גניבת זהות
ביומטרית היא דבר מפחיד.
לסיכום ,הזדהות ביומטרית היא ייחדוית ויוצרת מפתח מורכב לפיצוח ,אך פריצה לשירות בודד אשר לא
קונפג כראוי עתיד להוות חולשה פוטנציאלית מול כלל השירותים מולם הזדהנו באמצעות המידע הביומטרי.
בשנים האחרונות הגיחו מספר פרויקטים גדולים ,תוספים לדפדפן וסטארטפים; כל אחד עם הדרך המקורית
שלו לנסות להתמודד עם הבעיה של שימוש בסיסמאות Google Password Checkup .אשר מתריע בפני
משתמשיו מסיסמאות שנחשפו ,סיסמאות חלשות וסיסמאות בשימוש חוזר הוא דוגמה פנטסטית לכיצד
ענקית הטכנולוגיה מנסה להיאבק בחוסר מזלם (ופזיזותם) של משתמשיה:
תוספות מיוחדות לדפדפן (כמו )RoboFormוגם פתרונות זהים לסביבה הלוקאלית (כמו )1Passwordפותחו,
כל ייעודן הוא להחזיק מסד נתונים מוצפן לכל הסיסמאות שברשות המשתמש הפשוט על מנת שזה יוכל
לשמור על סיסמאותיו בצורה מאובטחת יותר .יש עוד עשרות מוצרים שמצאו את דרכם לעולם הצרכנים אבל
השאלה שצריכה להישאל היא האם אתר /תוסף /מנגנון שאומר שכנראה כבר פרצו לי הוא הפתרון הטוב
ביותר שיכולנו לבוא איתו או רק פלסטר זמני? ובכן ,אתם כבר יכולים לנחש מה הדעה שלנו.
אימות מבוסס סיסמה הוא הצורה הנפוצה ביותר של אימות משתמשים .עם זאת ,זוהי הדרך הפשוטה
והנוחה ביותר לגניבת זהות והסלמת הרשאות בדגש על משתמשים חזקים ברשת.
רובנו אנשים של מספרים אז קצת סטטיסטיקות :כ 81%-מגניבות הזהויות נובע משימוש בסיסמאות
חלשות ,אדם ממוצע עושה שימוש ב 107-חשבונות שונים (שלרוב מקושרים לחשבון מייל בודד) ועלות
פריצות הסייבר לעסקים בארה"ב מגניבת זהויות גבוהה מ 5-מיליארד דולר בשנה.
ת'אמת ,לאחר הסעיפים הקודמים זה אמור להיות די - straight forwardיכולת להגדיר סיסמה שמורכבת
מעשרות תווים אקראיים ,סיסמה ייחודית לכל שירות שאנחנו מנויים אליו ,שהאתר יוודא שזה באמת אני
שמנסה לגשת לחשבון שלי (בעזרת הזדהות ביומטרית או משהו בסגנון של הזדהות חזקה אחרת) ,שבצד
השרת לא ידעו מה הסיסמא שלי (כלומר גם אם הוא יפרץ מתישהו לא יחשף שום מידע שישליך על
שירותים נוספים) ולמען האמת עדיף שגם אני לא אדע את הסיסמא (ובכך לחסוך לעצמי ולארגון אפשרויות
למניפולציות פסיכולוגיות ופישינג) .בקיצור ,אנחנו רוצים את .FIDO2
- WebAuthn .0התקן הרשמי לאימות ללא סיסמה מול אתרי .WEBהתקן מגדיר את התקשורת וחילוף
המידע בין דפדפן המשתמש ושרתי הרשת מולם הוא רוצה להזדהות .התקן מגדיר שימוש במפתחות
א-סימטריים ,פונקציות ואוביקטים בשימוש ,מימוש Challenge-Responseבין ה Client-לשרתים
(המכונים ,)Relaying party - RPיצירת מפתח ייחודי מול כל RPועוד .במסגרת בניית התקן נכתבו
ספריות למימוש Webauthnבסביבות פיתוח מוכרות ופורסמו כ open source-לכל המעוניין.
ניתן לראות את סיכום שני הסעיפים ולהמחיש את השימוש בשני הפרוטוקולים בתמונה הבאה:
שינוי דפי הכניסה וההרשמה כך שיעשו שימוש בפרוטוקולי FIDOלאימות משתמשים .I
פריסת שירות אימות לקוחות התומך ב FIDO-תחת פלטפורמת Customer Identity and ( CIAM .II
)Access Managementכזו או אחרת.
לא קיימת היום סטנדרזציה מחייבת לאימות משתמשים ,לכן לפני שמציגים את שיטת האימות שFIDO2-
מציעה ,שווה לתאר בכלליות איך נראה תהליך אימות 'סטנדרטי'.
כאשר שרת רוצה לאמת את זהותו של משתמש קצה לרוב האינטרקציה ביניהם תראה בצורה הבאה :אתר
האינטרנט יבקש הזנה של קלט (לרוב בתצורה של )login formבצד ה client-משתמש הקצה יזין את
הנתונים המבוקשים (שם משתמש +סוד שידוע רק לו) צד ה client-יבצע גיבוב כלשהו על הסוד וימסור
אותו בצמוד לשם המשתמש לשרת בצד השרת תתבצע שאילתה למסד הנתונים אשר תבדוק אם
המשתמש קיים ,האם הסוד שהוזן נכון ותחזיר את הרשאותיו של המשתמש לתוכנת ה( client-לרוב
בתצורת tokenכזה או אחר) דף HTMLמתאים יחזור ויטען עם משאבים שבהקצאת השרת ובהתאם
להרשאותיו של משתמש הקצה.
אע"פ שהתהליך הנ"ל נשמע אלמנטרי ובסיסי ,מכיוון שאין מכניזם סדיר לאימות (וכל מפתח שני חושב
שהוא כשיר להמציא את הגלגל מחדש במקום לעשות שימוש בספרייה קיימת) ,התרחיש הפשוט הנ"ל
חושף את שני הצדדים למשטחי תקיפה פוטנציאליים -התחזות למשתמש אחר וגניבת זהות על ידי אתר
זדוני הם הבולטים ביותר.
במקום שלכל אתר יהיה את ה Login form-שלו ,ב FIDO2-האתר פשוט קורא אל APIשל JavaScriptשמוצע
על ידי הדפדפן עצמו (כל הדפדפנים הגדולים תומכים ב .)WebAuthen API-ממשק ה JS-מכיל מספר
פיצ'רים שמאפשרים לאתר לתשאל את הדפדפן בנוגע למספר מאפיינים אודות המשתמש כדי לאמת את
זהותו.
בשפה קצת יותר טכנית -הדפדפן אחראי לוואלידציה של שדה ה origin-המוכל ב request-שהאתר שלח.
מדובר בבדיקה של ה domain-או ה subdomain-שממנו הגיעה הבקשה של האתר אל מול התעודה
הדיגיטלית שהוא מציג .אותה תעודה לרוב תהיה משורשרת עם תעודה אחרת שחתומה על ידי certificate
,)CA( authorityגוף גדול ומוכר שתפקידו לאשר ולוודא כי בעל האתר אכן אוטנתי .תוכנת ה client-שלנו
(הדפדפן) תקבל את התעודה של ה CA-בפורמט ASN.1ולאחר סיריאליזציה זריזה תשווה את התוכן שלה
לתעודות ששמורות אצלינו במחשב ב .Certificate Store-אם הכל עבר כשורה הדפדפן ירנדר את תוכן ה-
DOMונקבל גישה.
רעיון זה בא לפתור את הבעיה של גניבת זהויות על ידי אתר זדוני .כבני אדם קשה לנו להתמיד באופן קבוע
ולבדוק שהאתר שאנחנו מזדהים אליו הוא באמת האתר שהתכוונו לגשת אליו.
ההבדל בין www.microsotf.comאל www.microsoft.comהוא דוגמה טובה לכך .דפי Loginהם בסך הכל
דפי HTMLוניתן להעתיק אותם במינימום מאמץ במסגרת .URL spoofingניתן לגרום למשתמשים להזדהות
מול אתרים זדוניים ובאמצעות ביצוע redirectפשוט להפנות אותם לאחר מכן לאתר המקורי מבלי שהם
ירגישו בכלל שקרה משהו לא בסדר.
מחשבים ממירים את תווי ה ASCII-שמוצגים ב URL-לבתים ולכן הם רגישים יותר אפילו לשינויים המינוריים
ביותר .תפקיד הדפדפן הוא לזהות באופן חד ערכי ש domain-שאנחנו הולכים להזדהות מולו הוא אכן
האתר שמגיע לו לקבל את ה credentials-שלנו.
בדוקומנטציה של NIST 800-63שאחראי על Digital identity guidelinesהם מתייחסים לכל הסאגה הזו
בשם verifier impersonation resistanceשזו בסה"כ דרך פנסי לומר שאי אפשר לעבוד על מחשב בדרך
שעובדים עלינו.
חשוב כבר עכשיו לעצור ולומר ששום מפתחות \ סיסמאות לא ישלחו על ידי הדפדפן מבלי שהמשתמש
יאשר ו\או יבצע פעולה כלשהי באופן אקטיבי .בדוקומנטציה קוראים לפעולה הנ"ל .Gesture
בנוסף לבקשת כניסה לאתר ,תקן FIDOדורש מהמשתמש לבצע 'מחווה' אקטיבית על מנת להתקדם
בתהליך ההזדהות מול האתר .על מנת שאמצעי הזיהוי יבצע חתימה של ה challenge-response-באמצעות
המפתח הפרטי ושההודעה תשלח לשרת בכדי להתקדם במתן הרשאת הגישה לשירות על המתשמש
לבצע סריקת טביעת אצבע ,זיהוי פנים ,הקשת קוד או פעולות אחרות שיאמתו מול אמצעי האימות שהוא
אכן הבעלים החוקי של אמצעי הזיהוי .
הסטנדרט משאיר פתוח את אופן מימוש ההזדהות .פעולות ה Gesture-יכולות להיות swipe upבמסך
לאחר שבוצע זיהוי facial recognitionבמכשיר ,אימות מבוסס טביעת אצבע באמצעות FIDO keyאו שיטות
עתידניות יותר דוגמת מגע בשעון יד שמודד לנו את הדופק (שתאמינו או לא אופייני רק לכם) .בכך ,קונצוריום
FIDOמעודד תעשיות לפתח טכנולוגיות פשטות ,אמינות וחדשניות להזדהות מאובטחת של משתמשים.
הקטע היפה בסטנדרט של אימות מבוסס FIDOהוא העובדה שאין מגבלה לאילו שיטות gestureניתן לבצע
את האימות באמצעותן .טכנולוגיות כמו BLE ,USB ,NFCשממשיכות להתפתח כבר עשרות שנים הגיעו
לשלב בגרות וכעת אפשר לעשות בהן שימוש בשביל לפתח פתרונות הזדהות נוספים .התעשייה וה-
ecosystemסביב FIDOיכולים לצמוח לאיזה כיוון שהכי יתאים לצרכן ובכך ליצור פתרון בצורה הענפה
ביותר User experience .תמיד מהווה אבן ביניין באינטרנט.
אוקיי ,אז עשינו שימוש ב gesture-כזו או אחרת בשביל לאמת את זהות המשתמש ,מה קורה לאחר מכן?
למה אנחנו צריכים את זה? התשובה הקצרה -קריפטוגרפיה של מפתח ציבורי.
כל מאמת חייב להכיל אזור אחסון מאובטח עבור המפתחות הפרטיים ולאחר ביצוע ה gesture-נעשה
שימוש במפתח הפרטי בשביל לחתום על ה cedentials-שונים עבור אתר האינטרנט ואמצעי אבטחה
נוספים כמו חותמות זמן ,מונים אינקרומנטליים וכו' .נרחיב על אמצעי ההגנה והשדות שמאפייני כל בקשה
(ממש ברמת הקוד) במאמר ההמשך.
נקודה שחשוב לתת עליה את הדגש היא העובדה כי ה( Credentials-צמד המפתחות) נוצרים רק על ידי
המאמת .הוא זה שבסופו של דבר יוצר ,מחזיק וחותם על המידע גם בתהליך הרישום וגם בתהליך האימות.
לכל מכשיר מאמת (כדוגמת ,YubiKeyמכשיר סלולארי וכד') הפועל ב FIDO2-יש תעודת X.509אשר
מאוחסנת כאשר המכשיר מיוצר; אלו הן Attestation Certificateאשר מייצגות כל מאמת .כלומר מפתח
נוסף שמשותף לכלל המוצרים מאותו דגם .המפתח הפרטי צרוב במכשיר המאמת ולא ניתן לייצאו ולהתערב
בהפקתו .יתרה מזאת ,המכשיר חתום מבחינה קריפטוגרפית ,כלומר אם תוקפים ינסו ליירט את בקשת
רישום ולהחליף אותה בערך שלהם ,הם לא יוכלו להחליף את המפתח הציבורי שנוצר במפתח אחר כי
החתימה על ה Attestation-לא תהיה תואמת למפתחות המאמת.
בנוסף ,לעיתים קרובות הארגון מעוניין להגביל את השימוש באמצעי זיהוי ולאפשר שימוש באמצעים
ספציפיים בלבד .זאת לשם שימוש באמצעים מאובטחים יותר (לדגומה שימוש בחומרה ייעודית ולא לאפשר
הזדהות שמבוססת על המכשיר הנייד Cross platformשנחשבת פחות בטוחה) .לצורך כך נדרש לוודא מהו
הדגם (והטכנולוגיה) של אמצעי הזיהוי.
נקודה נוספת שחשוב לשים עליה את הדגש היא שאמצעי אימות בודד מאפשר הזדהות (ושמירת מפתחות)
למספר רב של אתרים .בצורה כזו לא נדרש להחזיק מיליון טוקנים שונים (מונח שקיבל את השם necklace
)of tokensבשביל לענות על הצורך של הזדהות לאתרים שונים -אחד מספיק.
לאחר שהמפתח שוחרר ממכשיר המאמת וחתם על ה credentials-עבור האתר ,הדפדפן מוסר אותם לאתר
עצמו לאחר שווידא כי זהות האתר היא הנכונה והוא זה שביקש את ה.original request-
אם לסכם בכלליות את כל מה שהוצג בפרק האחרון CTAP2 ,ו WebAuthn-מגדירים ביחד שכבת
אבסטרקציה שיוצרת ecosystemעבור אימות חזק בסביבת .Webנוכל לקחת צעד קדימה ולהביט על
ארכיטקטורת FIDO2הכללית בצורה הבאה:
הערה :החצים המקווקוים בתכלת מייצגים אינטראקציות התלויות ביישום הספציפי של ממשקי ה API-של
הפלטפורמה וניתנים למודפיקציה .נרחיב על החלקים השונים בשרטוט:
- Relying Parties & Clientsאפליקציות webאו מערכות nativeשרוצות לעשות שימוש ב.FIDO2-
השוני העיקרי הוא כיצד הן מממשות את האימות .באפליקציות webהאתר שרוצה לעשות שימוש ב-
FIDOלא יכול לפנות ישירות אל ממשק ה WebAuthn API-וחייב לעשות שימוש במתווך (הדפדפן).
באפליקציות nativeהמצב שונה ויכול להיות מצב שבו ה RP-ירוצו על מכשירי הלקוח ובכך ישמשו גם
בתור WebAuthn clientבשביל לשלוח ולקבל בקשות של .WebAuthnחשוב לציין שאין שום תזכור
לשימוש ב )SSO( Single sign-on-בארכיטקטורה הנ"ל.
- Client Deviceממש החומרה שמבצעת את האימות .פלטפורמת המחשוב שממנה המשתמש מבקש
לצרוך את השירות (שעבורו הוא נדרש להזדהות).
- WebAuthn APIהממשק שמאפשר ללקוח לשלוח בקשות למכשיר האימות.
- Platform Authenticatorאימות מובנה על מכשיר הלקוח .לא ניתן לגשת אליו בפרוטוקולים cross-
platformכמו USB, NFC, BLEאלא רק על ידי עבודה ישירה מול החומרה שעל המכשיר .סורק טביעת
אצבע על מחשב לפטופ\ טלפון חכם הוא דוגמה טובה לכך.
- CTAP2 Platform/Hostהחלק במכשיר הלקוח שאחראי לניהול המשא ומתן עם המאמת.
אכן ,הארכיטקטורה נראית מאוד זהה לתרשים הכללי של FIDO2אך כעת כל מרכיב מקבל תפקיד מוגדר:
Microsoft Accountמממשת את ה .WebAuthn RP-באמצעותה ניתן להירשם למספר שירותים ב-
Windowsהחל משירותיים ליבתיים כמו Outlookוחלה בשירותים ביזריים שספק מדוע הם עוד קיימים
כמו .Xboxבכל פעם (כמעט) שתראו שירות Windowsשדורש Sign-inתהיה אופציה לשימוש בFIDO2-
על ידי שימוש ב client side javascript-בשביל לטרגר את הדפדפן Microsoft Edgeלתקשר עם
הממשקים של .WebAuthn APIs
Microsoft Edgeמהווה את ה .WebAuthn client-דפדפן הדגל של Microsoftתומך בהתממשקות
מלאה מול פיצ'רים של פרוטוקולי CTAP2ו WebAuthn-בסביבת Windowsוגם בהרחבה של AppID
שמהווה תאימות לאחור עבור .U2Fעם זאת ,כשזה מגיע ל Android-דפדפן Edgeלא תומך בכלל ב-
.WebAuthnזאת כבר בעיה של גוגל ו.Chrome-
הערה :במקרה הספציפי של ,Windowsמכיוון ש Microsoft Account-צריכה פיצ'רים והרחבות שקיימות
בלבד במאמתים של ,FIDO2 CTAP2לא ניתן לעשות שימוש ב credentials-שהושגו דרך ) .CTAP1 (UAFזאת
למרות ש Edge-תומך בסוגי מאמתים שעושים שימוש גם ב CTAP1-וגם ב CTAP2-ולכן הוא יכול ליצור גם
U2Fוגם .FIDO credentials
נסכם את המאמר הראשון מבין השניים ואת אפקטיביות ההגנה שמספקת הזדהות מבוססת FIDO2עם
דוגמה פרקטית מהתקופה האחרונה -ניתוח אירוע הפריצה האחרון לחברת .Uber
ב 15-לספטמבר 0200השיגו תוקף(ים) את פרטי ה( Login-שם משתמש וסיסמה) של עובד בחברת Uber
לשירות ה VPN-של החברה .שירות ה VPN-משמש עובדים מרחוק לצורך חיבור לרשת הפנימית של Uber
(ולאפשר עבודה מהבית תוך מתן גישה לשירותים ברשת הפנימית של החברה).
לא ידוע כיצד השיגו התוקפים את פרטי ה ,Login-האם באמצעות נוזקה שהותקנה על מחשב העובד
ושלחה את פרטי ההתקשרות לתוקפים ,באמצעות קניית threshold access credentialsבפורום מחתרתי
או עקב ביצוע Phishingלעמוד הכניסה ל VPN-אליו הוזנו פרטי העובד.
לצורך התחברות לחשבון ה VPN-נדרש העובד להזין את פרטי ,Loginובנוסף לאשר את החיבור באמצעות
MFAשבמבוסס על אישור ההתחברות בהודעת Push notificationשנשלחת למכשיר הסלולארי של העובד
שעליו ללחוץ עליה לאישור את ההתחברות ל.VPN-
על מנת להתגבר על מנגנון ה MFA-התוקפים עשו שימוש בהנדסה חברתית ()Social engeneering
מבוססת ( MFA Fatigueהתשת ההזדהות הדואלית) .בכל נסיון חיבור של התוקפים ל VPN-נשלחה לעובד
הודעה על נסיון התחברות (שלא הוא ביצע) .לאחר עשרות סירובים של העובד לביצוע ההתחברות,
התקבלה הודעת מייל מהתוקפים שהתחזו ל"צוות ה "IT-של Uberעל תקלה בהתחברות לשירותי הVPN-
וביקשו מהעובד לאשר את ההתחברות על מנת להפסיק את הבקשות הבלתי פוסקות.
למזלה של Uberהתקיפה לא בוצעה למטרות כופר או ריגול תעשייתי ,אלה להאדרת שמו של התוקף
(שהתברר כנער בן ,17ספק אם חבר ב , Lapsus$-ולכאורה הספיק לפרוץ גם ל GTA6-ולעבור doxעל ידי לא
אחר מ pompompurin-הבעלים של )BreachForumsולכן התוקף הקפיד לעדכן בזמן אמת על ההתקדמות
התקיפה.
ניתן למצוא מגוון פערי אבטחה שאפשרו את התקיפה (וכנראה שבראשם שמירת סיסמאות גלויות למערכת
ה )PAM-אבל באמצעות שימוש באימות מבוסס ( FIDO2במקום מימוש ה MFA-הלקוי שביצעו )Uberניתן
היה למנוע את הגישה של התוקפים אל חיבור ה VPN-ולמנוע את התקיפה מלכתחילה:
.1בניגוד למימוש ה MFA-שבוצע ב Uber-שהסוד כלל לא נשמר עליו (ה MFA-שימש רק כאישור נוסף
לפרטי ה Login-שהוזנו לאתר ,כך שה"סוד" שאיפשר גישה לשירות הוא שם המשתמש והסיסמא)
באימות מובסס FIDO2הסוד עצמו שמור על ה Authenticater-וכלל איננו נגיש למשתמש (שאיננו מודע
לפרטי ה Private key-ששמורים על אמצעי הזיהוי ,ולא יכול למסור אותם לגורם חיצוני) .הפיצול שעשו
ב Uber-בין הסוד ואמצעי ה MFA-אפשרה את הפריצה ל.VPN-
.0אמצעי הזיהוי ב FIDO2-דורשים חיבור פיזי של אמצעי הזיהוי (ה )Authenticator-לפלטפורמה ממנה
מבקשים את השירות (לדוגמה :נדרש חיבור USBשל אמצעי האימות למחשב) ,או קרבה פיזית בין
המזהה לפלטפורמה (לדוגמה :בהזדהות לשירות במחשב ,אמצעי הזיהוי מקושר למחשב בתקשורת
קצרת טווח מבוססת BLEאו - )NFCבאופן זה ,לא ניתן להוציא את פרטי ה Login-ללא גישה פיזית
לאמצעי .לדוגמה :רק עם חיבור ה Yubikey authenticator-לממשק ה ,USB-והזנת פרטי הLogin-
לאתר ,תנתן גישה לשירות ה .VPN-בחלק מאמצעי הזיהוי של FIDO2המשתמש נדרש להזין טביעת
אצבע (בין אם בטלפון או במחשב) על מנת לבצע את ההתחברות .פרטים אלו אינם ניתנים להעברה,
ומונעים אפשרות להוצאה במרמה של פרטי ה.Login-
.3כפי שראינו FIDO2 ,כולל מנגנון הגנה מובנה מפני תקיפות ( Phishingשליחת שם האתר המדויק
במסגרת הודעת ה Challenge\Response-הראשונה שנשלחת למשתמש מהשרת) -תמיכה של שרת
ה VPN-בפרוטוקול WebAuthnהיה מונע את השגת פרטי ה Login-של העובד לשרת ה.VPN-
סיכום
הזדהות משתמשים באמצעות FIDO2מונעת שימוש בסיסמאות חלשות או סיסמאות חוזרות ,גישה
לשירותים באמצעות גניבת זהות המתשמש ומקשה מאוד על תקיפות Social engeneeringו.Phishing-
בפועל ,משתמש הקצה כבר לא נדרש לזכור או להזין סיסמאות אלה לעשות שימוש ב Authenticator-עליו
נשמרים הסודות לכל שירות אליו הוא נרשם.
נכון להיום ,התשתית לשימוש ב FIDO2-קיימת -מרבית הדפדפנים תומכים בתקן ,ישנן Frameworks
עתירות כוכבים ב Github-למימוש FIDO2במגוון שפות תכנות ומתפתח שוק רחב של אמצעי הזדהות
במחירים שווים לכל נפש .למרות זאת ,רק מעט שירותים תומכים כיום בהזדהות מבוססת .FIDO2
בשונה ממה שאומרים בבחירות ,בתהליכי טרנספורמציה דיגיטלית השינוי מתחיל מלמעלה ולא מלמטה.
סטאטוס של גדולות הטכנולוגיה (שתכל'ס די מצופה מהן להוביל את התהליך) הוא שיקבע את כניסת השינוי
והמעבר למימוש מלא ורחב של טכנולוגיות חדשות כמו .FIDO2
כשאנחנו מביטים על ענקי הדפדפנים והיצרניות שדוחפות את הקידמה בהםChrome ,Chrome Desktop :
אה שמחוגי הטכנולוגיה נעים
ר ָ
Safari iOS ,Safari macOS ,Firefox ,Microsoft Edge ,Androidלא תמיד ִנ ְ
בקצב שהיינו מקווים לו (מספיק להסתכל על הסטאטוס של Appleבנושא התמיכה ב CTAP2-שכבר שנים
עומד במקום) אבל חשוב לזכור כי מדובר בתהליך .תהליך שמטרתו בסופו של יום ,עם כל הקיטשיות ,להפוך
את האינטרנט למקום בטוח יותר.
כאן מסתיים לו המאמר הראשון מבין השניים שהכנו .כלל המאמר עסק בהסבר Hige levelובלא מעט
ניפנופי ידיים בנוגע לטכנולוגית FIDO2ולמעשה היווה הכנה נוחה למאמר הבא אשר מיועד להיות
משמעותית יותר hands-onעבור אלו שרוצים להבין כיצד האימות מתרחש "באמת" -איזה מידע עובר,
כיצד הוא נראה וכיצד הוא ת'כלס מונע מתקפות בשלב האימות .יש למה לצפות.
על הכותבים
יהונתן אלקבס ,בן ,08חוקר אבטחת מידע בחברה לא קטנה ולא פרטית .חובב סוקולנטים ,סודה וקפה.
אלון בר סלע ,אבא של כרמל ,הלל ,אוריה ואמה .מנהל אבטחת מידע בחברה לא קטנה ולא פרטית.
הקדמה
באוגוסט האחרון שמעתי ש( Checkmarx-חברת אבטחת מידע ישראלית) עושים מפגש בנושא Open
Sourceוהמשמעויות של השימוש בו ,ואחריו מציגים הקרנת בכורה לסרט החדש של .Thorכמובן שמאוד
התעניינתי בהקרנה -אה סליחה ,בהרצאות ,ובאתי .אני חייב להגיד שבהתחלה חשבתי שאין הרבה תוכן
בעולם הזה ,מסתבר שדווקא יש הרבה.
במאמר זה ,אסביר אילו מתקפות יש לקוד פתוח ( ,)Open Sourceאתן דוגמאות למתקפות ,איך נוכל להגן
מפניהן ואציג כלי שכתבתי שיכול לסייע בהגנה.
Open Source
ראשית חשוב להבין בכלל מה זה קוד פתוח .קוד פתוח הוא קוד שנגיש וחופשי לשימוש של הכלל .כלומר,
שאני כמפתח רוצה לתכנת משהו ,לדוגמה תוכנת מחשבון ,אני לא ארצה עכשיו לממש את הקוד לחזקה או
ללוגריתם .כמובן שאני גם לא המתכנת הכי טוב שאני מכיר ,ויש הרבה אנשים שיותר טובים ממני והאנשים
האלה יכתבו את הקוד בצורה יעילה וטובה יותר ממני .מכאן נובעת שאלה איך אני לוקח את המוח של
אנשים אחרים ונותן להם לכתוב את הקוד בשבילי? כאן נכנס הקונספט של קוד פתוח .אנשים חכמים מאוד
באינטרנט החליטו להפיץ את הקוד שלהם לאנשים שרוצים להשתמש בו.
זאת אומרת ,שאם אני רוצה להשתמש בפונקציה של חזקה ,אני יכול להשתמש בקוד של מישהו (מgithub-
או אתרים בסגנון) ולהעתיק אותו לקוד שלי ,אפילו להשתמש בספרייה שהם כתבו ,או לקחת את המימוש
שלהם למחשבון ולהשתמש בו לטובתי.
אז הכול נשמע טוב -אני יכול לקחת קוד של אנשים אחרים ,הם יכולים לקחת ממני קוד ,הזמן שלי יכול
להיות מנוצל על דברים אחרים ...אז מה הבעיה בעצם?
הבעיה הראשונה היא שאני לא מכיר את המפתח השני ולא יודע אם הוא אדם ישר שלא מנצל את עמדתו.
זאת אומרת ,שהקוד שלו עושה את מה שהוא אמור לעשות ,והוא לא מוסיף גם קוד זדוני ,לדוגמא כמו שקרה
לא מזמן עם המתכנת של " ,"node-ipcספריה שמטרתה לאפשר תקשורת בין תהליכים ב( java-את
הספריה הזאת הורידו 64מיליון פעמים).
]]https://www.npmjs.com/package/node-ipc
כותב הספריה רצה להביע את עמדתו לגבי המלחמה בין אוקראינה ורוסיה ,והוסיף לקוד שלו פונקציה
שכאשר הוא מזהה ריצה על מחשב אשר נמצא ברוסיה ,הוא מוחק את כל הקבצים שנמצאים עליו.
בכללי הקונספט שעשע אותי ,ואז הבנתי שהוא יכל לעשות עוד דברים ולהגיע מאוד רחוק .ככל שהספריה
יותר מוכרת ,היא תגיע ליותר אנשים ,והסכנה למתקפה גדלה עוד יותר .לדוגמה ,חברות גדולות בעלות
תוכנות נרחבות (פייסבוק ,אינסטגרם )...יכולות להשתמש בספריה הזו בתמימות כי היא מוכרת,
ופוטנציאלית להפיץ למשתמשים שלהן קוד זדוני.
בעיה נוספת שיכולה להיות היא .Typosquattingכלומר ,ספרייה שמתחזה עם שם דומה לספרייה מוכרת
אחרת .לדוגמה ,אני שומע על ספרייה ממש טובה בשביל חישובים מתמטיים בפייתון ,לצורך הדוגמה
שמעתי שקוראים לה " ,"numpyוכאשר הסתכלתי על הספרייה באתר הלגיטימי של pypiראיתי שיש גם
" "numpyוגם " ."numpy2כשהסתכלתי על הדוקומנטציה של שתיהן ,ראיתי של numpy2-יש שידרוגים של
יעילות קוד ,ועוד מערכות מתמטיקאיות שאין ל.numpy-
אז כמובן שאני אוריד את ,numpy2אשתדרג ,למה לא? אני אשתמש בספרייה ואראה שהכול טוב והיא
עושה את מה שהבטיחה .רק שלצערי ,אחרי כ 4-חודשים ,אני אגלה שכל מי שהשתמש ב numpy2-מתלונן
כי הסיסמאות שלו ל( github-שנשמרו בצורה לא מוצפנת על מחשב של משתמש ב )git cli-הודלפו לרשת
וכמובן שרק אחרי כ 3-חודשים יישמו פתרון והספרייה תמחק מהאתר .בעיה זו של סיכול בשם הספרייה
יכולה לקרות גם כשאני מוריד ספרייה באמצעות פקודה ,ומוסיף בטעות עוד אות או מספר .אני יכול להוריד
את הדבר הלא נכון ,הרי בשביל להוריד משהו אני רק צריך לכתוב " "pip install numpyאז אני יכול לכתוב
בטעות."pip install numpy2" :
עוד בעיה שיכולה להתרחש ,הוא שימוש בספרייה אשר הספריות הנוספות עליה היא מסתמכת זדוניות.
נגיד ואתם (הקוראים) האנשים הכי חשדנים ,לכן תמיד כשאתם משתמשים בספרייה אתם סורקים את הקוד
שלה לפני השימוש ואתם לא רואים משהו יותר מידי חשוד בקוד של המתכנת .אך אתם מגלים מאוחר יותר
שהייתה בעיה בספריה הזו ,שהתבטאה בשימוש בספרייה נתמכת שבה היה פוגען.
מכאן יכולים לקרות שני דברים :או שהמפתח של אותה ספרייה הכניס את אותה הספרייה הזדונית בכוונה,
או שהוא באמת עשה טעות והשתמש בספרייה עם פוגען והפיץ אותו מבלי לדעת .בכל מקרה ,קשה לעקוב
אחרי כל ייבוא של ספרייה נוספת מתוך ספרייה אחת ראשית ,מה שמוביל לנושא גדול יותר.
Supply Chain
שרשרת אספקה הוא קונספט שאומר שלכל פרוייקט\ארגון באשר הוא יש איזושהי שרשרת של ארגונים,
משאבים ,טכנולוגיות וחברות אחרות שמספקות לו שירותים בשביל שהוא יוכל לעבוד בצורה מיטבית
ויעילה .למשל ,צבא ,התוצר שצבא צריך להביא למדינה שלו הוא בעיקר ביטחון ,לשם כך הוא צריך כוח אדם,
מזון ,חיילים שיודעים להכשיר אחרים (בעלי ידע) ,תקשורת עם מפקדיו וחמ"ל (חדר מלחמה) ,רפואה,
מודיעין ,נשקים וכדומה .מזון ומודיעין ,למשל ,לאו דווקא מגיע מהצבא עצמו ,אלא מסופקים מגורמים
חיצוניים.
פגיעה בשרשרת אספקה מתבטאת בפגיעה באחד המשאבים של ארגון ,בדגש על משאבים מחברות
חיצוניות .נמשיך עם הדוגמה של הצבא ,בהנחה והצבא שלנו מותקף ואנחנו צריכים להתגונן מאויב שמנסה
להיכנס עמוק יותר למדינה שלנו ,אנחנו יכולים לנסות לחשוב מה האויב הזה צריך כאשר הוא רוצה לצאת
למבצע שכזה .אנחנו יכולים להניח שגם לאויב יש שרשרת אספקה דומה לשלנו.
על מנת לנטרל אותו או להאט אותו ,נוכל לפגוע או להכשיל מספר גורמים שהאויב משתמש בהם .כגון,
ווידוא שהמודיעין של אותו צבא יהיה שגוי ,דבר שיגרום לבילבול וקושי בעת הלחימה .לחלופין נוכל לפגוע
בתשתיות ,בין אם זה לפגוע לאויב בתקשורת הפנימית עם הפיקוד ,או לפגוע במעבר של מזון לפלוגה
העויינת .דברים אלו יכולים לשבש פעולות פנימיות ממחוץ לשורות האויב.
כפי שצבא נתקף יכול לחשוב על דרכים לפגיעה באויב מבחוץ ולאו דווקא ישירות בלוחמים ,גם תוקפים
ברשת יכולים לפגוע בסביבה של חברה בצורה לא ישירה .אם אתם משתמשים באפליקציה כלשהי לפיתוח,
למשל כמו ( Visual Studioתוכנה מאת מייקרוסופט לעזרה לכתיבת קוד בכל מיני שפות תכנות ,אפליקציה זו
מוכרת ומשתמשים בה ביום יום כותבי קוד רבים) .יום אחד יוצא עדכון לאפליקציה ,אתם משדרגים ואתם
לא חווים שום דבר חדש או מיוחד ,חוץ משימוש גבוה בזיכרון המחשב.
התנהגות זו יכולה לקרות גם בצורה רגילה באפליקציה ,לכן אינכם חושדים בדבר .אך זמן לא רב לאחר
השדרוג ,החברה משחררת הודעה שהיא מתנצלת על הימצאות ( Cryptominerפוגען שמטרתו להשתמש
במשאבי המחשב בשביל לכרות מטבעות דיגיטליים) שנכנס בלא יודעין בעדכון .מתקפה כזו קרתה גם
באמת ,ושמה .Sunburstהיא התרחשה בחברת ,SolarWindsבאפליקציה ( Orion Networkמטרת
האפליקציה היא למצוא ,לאבחן ולטפל בבעיות תקשורת ברשת כלשהיא) .בשנת 0202חברה זו נפרצה
והושתלה דלת אחורית אשר מאפשרת לתוקפים שיצרו אותה הרצת קוד ברשת .מאות חברות הושפעו
מהתקיפה ,בינהן אפילו המחלקה לביטחון המולדת של ארה"ב.
אתם בתור מתכנתים שמשתמשים בספרייה מוכרת ,שאפילו חברות כמו מייקרוסופט ,אמזון ,וVMware-
משתמשות בה וסומכים עליה ועל התוכן שבה .עדיין ,גם בספריות מוכרות ונפוצות ,יש סיכוי להמצאות קוד
זדוני ודווקא הנרחבות של הספרייה יכולה להוות בעיה .מקרה כזה יכל להתרחש עם ספריית log4j ,שהיא
תוכנה שעוזרת לרשום אירועים שקורים באפליקציה שלכם בצורה מאוד נוחה ,קריאה ויפה.
בשנת 0201התגלתה חולשת הרצת קוד בספרייה הזו ,לחולשה קוראים ,log4shellשהייתה משומשת
בהמון אפליקציות ובהמון מקומות בתוך אפליקציות ענק (כמו AWSאו .)ESXiאך למה החולשה הזו נחשבת
למתקפת שרשרת אספקה? למרות שהבעיה היא פגיעות בקוד הפתוח של הספרייה ,היא נכנסה
לאפליקציות גדולות יותר והיוותה משאב בשרשרת השירותים שמסופקים לחברות ענק .כלומר ,בגלל
הפגיעה בשירות שמסופק לאפליקציה כלשהי ,האפליקציה עצמה נפגעה וכתוצאה מכך המשתמשים.
חשוב לציין שבמתקפות של שרשרת אספקה לרוב המשתמש הפשוט לא מודע למה שקורה מאחורי
האפליקציות לכן קשה לו לדעת שבכלל מתרחשת מתקפה זדונית עליה ועל כן גם עליו.
אחרי שראינו את כול הדוגמאות והבנו מה הסכנות בקוד פתוח ובפגיעת בשרשרת אספקה איך אנחנו מגנים
מדבר שכזה?
כמובן שלבדוק עכשיו כל אחד מהקודים של כל אחת מהספריות ולעדכן את הספריות באופן גורף ,זו משימה
כבדה .לכן יש מערכות כמו Dependabotאו ( Greenkeeperהיום נמצאות ב )Snyk-שמסתכלות על
הספריות שאנחנו משתמשים בהן ,רואות אם יש עדכון חדש ומעדכנות באופן אוטומטי ,בשאיפה תמיד
להיות ראשון כשיוצא עדכון לבעיה בקוד (יש עוד יכולות חוץ מהיכולת הזו) .מעולה ,עכשיו האפליקציה שלנו
תהיה מוגנת מכול החולשות שהתגלו בספריה כלשהי .חבל שזה רחוק מהמציאות ,גם אם נעדכן כל הזמן
את הספריות ו"ננקה" את הקוד מחולשות עבר פוטנציאליות ,עדיין לא נוכל להיות מוגנים מהמקרה שמישהו
מקבל שליטה לעידכוני ספריה ומעדכן אותה עם הקוד הזדוני.
מה אם נעדכן כל שלושה או אפילו חמישה עדכונים ,במטרה לקבל את העדכונים כשהם "איכותיים" יותר,
שנבדקו כבר על אנשים אחרים לאורך תקופה כלשהי? גם על זה תוקפים חשבו ,ושחררו 5עדכונים ריקים
וזהים על מנת לעקוף את השיטה הזו .קבוצת התקיפה שיישמה את העיקרון הזה נקראת RED-LILI
והתגלתה על ידי חברת .Checkmarxכיום ,החברה הרימה אתר https://red-lili.infoאשר מנסה לעקוב
אחרי כל הספריות שמופצות ידי קבוצת תקיפה זו.
][https://red-lili.info
יש גם את Synk SCAשמטרתו דומה ,אך אצלם אתם משלמים על פונקציונליות נוספות .יש אופציה חינמית
לאפליקציה זו ,אך אפשר לעשות רק כ 322-בדיקות לחודש ,כאשר האופציה הכי "זולה" זה 522דולר ל5-
מפתחים לחודש (ל Checkmarx-לעוד מידע תוכלו ליצור קשר עם החברה).
יש לנו גם אפשרות אחרת ,שהיא לקחת את הבעיה לידיים שלנו ולקחת שליטה מלאה .זה גם הפתרון הזול
לאנשים פרטיים שאין להם כסף לאפליקציות כאלה .פה נכנסים לתמונה הפתרונות החינמיים ,כמו Hagana
(שנכתב על ידי יעקב ]לא מצאתי את השם משפחה[) ,מודול שמטרתו להגן עליכם באמצעות סט חוקים
שאתם כותבים בעצמכם לאפליקציה שלכם ,שמגדירים בדיוק מה האפליקציה יכולה לעשות על פי הצרכים
הספציפיים שלה (בין אם זו גישה תקשורתית ,גישה למערכת הקבצים או הרצת קוד) .הספרייה שלו תזריק
את עצמה לפונקציות הרלוונטיות ,בכדי לתפוס את הקריאות לפונקציה ולראות האם הן לגיטימיות או לא.
לצערי הרב הספרייה עובדת רק לקוד של ,nodejsורק על חלק מהפונקציות.
לכן החלטתי לכתוב כלי שיעבוד לכל שפת תכנות אשר נכתבה במערכת הפעלה .Windowsקוראים לו
.GuardCodeבדומה ל GuardCode ,Hagana-פועל בתצורת "חוקים" .ההבדל הוא שבמקום לכתוב את
החוקים בתוך הקוד עצמו ,כותבים אותם בקובץ נפרד ,בתצורה של ( Regexשיטה להכיל כמה אפשרויות
בשורה אחת או לא להכילן) .יש אפשרות לכתוב את החוקים בצורת Whitelistאו ( Blacklistכאשר
Whitelistזה מה שאפשרי לעשות על המערכת ,וכל מה שלא מוכל ברשימה יקפוץ ,ו Blacklist-זה שהכול
אפשרי חוץ ממה שיש ברשימה).
בנוסף על כך ,אפשרי "לנטר" על כל פעולה שניתן לבצע על קובץ במערכת הפעלה של ( Windowsבעתיד
יהיה ניטור על מפתחות מערכת של ,)Windows Registryועל תקשורת שנפתחת) GuardCode .מסתמך על
מוצר של ,Microsoftועל SDKשל OpenProcmonמ .Github-המוצר שהתבססתי עליו ביצירה של
GuardCodeהוא .Procmonהמטרה של Procmonהיא להראות למשתמש כל דבר שקורה במערכת של
.Windowsכלומר ,כאשר תהליך עושה משהו לקובץ ,או פותח תקשורת Procmon,יתפוס זאת וכנ"ל לגבי
.GuardCodeבסופו של דבר GuardCodeהוא Antivirusלתהליך ספציפי ,עם חוקים שאתם כותבים
ובשליטה מלאה שלכם .אם אתם רוצים עוד שליטה על הקוד שלכם אתם יכולים לכתוב בעצמכם את
ה" "driverשל .Procmonהשימוש בשני הכלים מסייע לכם לבדוק ואף לחסום אנומליות בספרייה\מודול
שעלולות להיות זדוניות(בהתאם למה שאתם מגדירים) .כגון ,גישה לקבצי מערכת SAMו ,SYSTEM-שני
הקבצים הללו יכולים לספק לתוקף את הסיסמאות לכל המשתמשים במחשב שלכם.
בסופו של דבר ,פיתוח הוא מרכיב מרכזי בכל ארגון כיום .אפילו הקיוסק השכונתי צריך פיתוח ,בין אם זה
למ טרות פרסום ובין אם זה לשמירת היסטוריית עסקאות במסד נתונים .המתקפות של קוד
פתוח רלוונטיות לעבודה של כל מפתח ,מאחר וכמעט אין תוכנה שלא משתמשת בספרייה שנכתבה ע"י
אדם חיצוני שלא קשור לפיתוח .כמובן שאני לא אומר שנפסיק להשתמש בספריות ,כי בכל זאת ,הן חלק
גדול מהפיתוח ותורמות לחיסכון בזמן ,אבל חשוב לפקוח את העיניים.
חשוב לראות שלספרייה שמשתמשים בה יש תדמית טובה ,לרוב אם הן בעלות הרבה הורדות וחשוב גם
להתעדכן מידי פעם על הספרייה ,בין אם זה לראות עדכונים ובין אם התראות של אנשי אבטחה לגבי
חולשות (כאלה שהוטמעו בכוונה ,וכאלה שנמצאו בטעות) .אחרי הכל ,כשמשתמשים בספרייה זדונית ,ניתן
בטעות לפגוע בשרשרת אספקה של חברה אחרת מבלי לדעת.
לפי דעתי ,זו האחריות גם של המפתח וגם של איש האבטחה וההגנה לשמור על המוצר שמוציאים ועל
תהליך הפיתוח .לכן ,איש האבטחה צריך לשים את המגננות המתאימות ולתחזקן וגם המפתח צריך לשים
עין על תוספות לא מוכרות בקוד ,אפילו להגן על עצמו ולמצוא דרכים לבדוק את אבטחת הקוד שלו ,בין אם
זה באמצעות פתרונות חינמיים או פתרונות בתשלום.
קישורים
https://github.com/noam242/GuardCode
https://github.com/yaakov123/hagana/
https://red-lili.info/
https://he.wikipedia.org/wiki/Log4Shell
https://www.checkpoint.com/cyber-hub/threat-prevention/what-is-a-supply-chain-attack
https://www.techtarget.com/whatis/feature/SolarWinds-hack-explained-Everything-you-
need-to-know
https://lirantal.medium.com/malicious-modules-what-you-need-to-know-when-installing-
npm-packages-12b2f56d3685
https://www.mandiant.com/solarwinds-break-resource-center
https://snyk.io/blog/typosquatting-attacks/
https://www.npmjs.com/package/node-ipc
הקדמה
פוסט-הקדמה
בעולם פיתח התוכנה ,קיימים שני סוגים של קבצים הרצה בינארים ,כאלה המקושרים סטאטית ( statically
)linkedוכאלה המקושרים דינאמית ( .)linked dynamicallyבקצרה ,קבצים מקושרים סטאטית מקומפלים
יחד עם כל הקוד הדרוש לריצה שלהם ,כך שהם לא תלויים בספריות חיצוניות .קבצים המקושרים דינאמית
(ברירת המחדל עבור מרבית הקומפיילרים) ,מתבססים על ספריות חיצוניות המספקות את רוב
הפונקציונליות שלהם.
בזמן הקימפול ,רק שמות הספריות מהוות חלק מהבינארי ,ורק בזמן הריצה הספריות נטענות לזיכרון .באופן
כללי יהיה עותק אחד בלבד של ספרייה בזיכרון כך שאם הספרייה כבר קיימת בזיכרון ,ה time load-יפחת.
בעצם ,כש binary-משתמש בפונקציה כמו printfכדי להדפיס משהו ,בפועל המימוש של הפונקציה נמצא ב-
( System C Libaryלרוב )libc.so.6ולא בבינארי עצמו .בכדי לקרוא לפונקציות הללו התוכנית צריכה לדעת
את הכתובות שלהן ,בעוד טכנית אפשרי לכתוב את הכתובות ישירות ל ,raw binary-זה בעייתי ממספר
סיבות כשהמרכזיות שבהן:
.1בכל פעם שהספרייה תשתנה/תתעדכן ,יידרש לבנות מחדש כל בינארי במערכת שמשתמש באותה
ספריה ,אולי זה מלהיב משתמשי Gentooאבל לשאר מבינינו זה לא פרקטי.
.0כחלק ממנגנון ASLRספריות נטענות למיקום שונה בין ריצה לריצה (כתובת הבסיס משתנה) ,שימוש ב-
hardcoded addressesיהפוך זאת לבלתי אפשרי.
Relocations
במבט על קובץ ELFתגלו שיש כמות מכובדת של ,sectionsנתחיל בלדבר בקצרה על אילו שרלוונטים
לתהליך ה Relocations-ולאחר מכן נראה איך נעשה בהם שימוש בפועל.
- .gotהמערך/טבלה שתכיל מצביעים לפונקציות לאחר שה dynamic linker-מוצא את הכתובות שלהן
בזמן הריצה ,נובע מכך שמדובר בזיכרון ניתן לכתיבה .קיצור ל.global offset table-
- .pltטבלה לקריאה בלבד ,מורכבת מ stub-עבור כל פונקציה שהכתובת שלה לא ידועה בזמן הריצה .ה-
( stubרוטינה קצרה) מחפש את הכתובת ב ,.got.plt-ובהתאם או שקופץ לכתובת או שמפעיל רוטינה של ה-
linkerלחיפוש הכתובת (יקרה בפעם הראשונה שהפונקציה נקראת) קיצור לProcedure Linkage Table-
- .plt.gotנראה שהם רצו כל קומבינציה של gotו .plt-מבלי לחרוג יותר מדי מנושא המאמר ,ה.plt-
בשימוש כאשר מתאפשר ( Lazy Bindingחיפוש הכתובת עבור פונקציה מתבצע רק ברגע שהיא נקראת ולא
לפני כן) .במידה ויש צורך בכתובת הפונקציה לפני כן יידרש Non Lazy Bindingוקריאות לפונקציה יעברו
דרך ה .plt.got-שבניגוד ל stub-ב ,plt-יכלול jmpאחד בלבד ,רק אל ה( GOT-הכתובת כבר נמצאת ,אין
צורך לדעת לחפש אותה).
נפתח את gdbונעשה disassembleל ,main-אפשר לראות שאכן מתבצעת קריאה ל puts@plt-ולא אל-
putsישירות:
נבחן את ה plt stub-עצמו ונראה שההוראה הראשונה היא jmpלכתובת מסוימת ,על פי מה שלמדנו היא
צפויה להיות ב:.GOT-
נוודא זאת באמצעות objdump -R mainשתציג לנו את ה GOT entries-ונראה שהקפיצה היא אכן לשם:
נקרא את הערך השמור בכתובת המתאימה ב GOT-כדי להבין את ה flow-טוב יותר ונראה כי הערך הוא
פוינטר חזרה ל ,plt-הגיוני ,זו הפעם הראשונה בה הפונקציה נקראת .המשך ה plt stub-יקרא לdynamic -
linkerכדי למצוא את הכתובת של :.puts
אנחנו רואים שה GOT-מצביע על כתובת אחרת הפעם ,מחוץ לטווח הכתובות של ה:.plt-
נבדוק מהי הכתובת הזו ונראה שאכן הפעם ה GOT-מצביע ל putsהמקורית ,הכתובת נמצאה בזמן הריצה:
אז הבנו שה GOT-מהווה שומר מקום לכתובות הפונקציות בפועל ,אם נוכל לשכתב entryשל פונקציה נשיג
הרצת קוד ויכולת לשנות את ה flow-של התוכנית .השיטה שנשתמש בה במאמר תנצל חולשת format
( stringsחולשה שיש עליה מאמר בפני עצמו מאת רזיאל בקר) ,אך בכל נדבר עליה בקצרה גם כאן.
מתוך ה man-ש printf-אנחנו רואים שהפרמטר הראשון שהיא מקבלת הוא ה ,format specifier-משמש
כדי להדפיס ערכים מסוג מסוים ,כלומר כדי להדפיס מחרוזת ב ,C-השימוש ב printf-אמור להראות ככה:
;)printf(“%s”,buffer
בעבור מרבית קבצי ההרצה ,במיוחד כשמדובר ב 32-ביט הפרמטר ל printf-יועבר על המחסנית ,ומשם
printfתקרא אותו.
מפתחים לא תמיד שמים דגש על ,secure codingוההבדל בין שתי השורות יכול להראות זניח עבורם ,אז
למה להוסיף עוד ארגומנט?
כפי שראינו בעמוד ה ,man-הפרמטר הראשון ש printf-מקבלת הוא ה .format specfier-למרות שההבדל
יכול להראות זניח ,הקלט שלנו מועבר כארגומנט הראשון לפונקציה מה שמאפשר לנו ליצור mismatchבין
כמות ה specifiers-אל כמות הארגומנטים שהועברו לפונקציה printf .מוצאת את הארגומנטים שלה על
המחסנית ולכן כשנגדיר יותר specifiersמארגומנטים ,ערכים נוספים מהמחסנית יודלפו.
כאן נכנס הפורמט .%nעל פי ההגדרה הוא מאפשר לנו לכתוב את מספר התווים שהודפסו אל כתובת
מסוימת:
בעצם קלט של AAAA%nיוביל לכתיבה של " "4אל הארגומנט אליו %nמצביע ,אבל איך נדע לאן %nמצביע
במחסנית? (איפה נצטרך למקם את הכתובת שנרצה לשכתב) ? נוכל להעזר ב $-כדי להגדיר את האלמנט
הספציפי במחסנית אליו נרצה לכתוב ,בשביל לגלות את האלמנט אליו נרצה לכתוב נצטרך להבין היכן הקלט
שלנו ממוקם על המחסנית ,שכן הקלט שלנו יורכב מהכתובת שנרצה לשכתב.
%<pos>$n
ללא ( ASLRגם אם היה enabledהיינו יכולים לנצל את חולשת ה Format String-ל:)Info Leak-
תוכנית פשוטה מאוד ,מקבלת קלט אל bufferומדפיסה את הקלט בלולאה אינסופית ,החולשה קלה לזיהוי
בשורה 9בקוד מקור או 14ב .ghidra-המטרה שלנו? לשכתב את הכתובת של printfאל הכתובת של
systemשל libcכאשר ה buffer-שנעביר יהיה ,/bin/sh-ולהשיג .Shell-אז בואו נתחיל!
כפי שאמרנו נצטרך למצוא היכן ממוקם הקלט שלנו על המחסנית ,כדי שנוכל להגדיר בעזרת $ו %-לאן
נרצה לכתוב .מכיוון שאנחנו שולטים בקלט ,הוא יהווה את הכתובת של ה entry-של printfב( GOT-הרי
המטרה שלנו היא לגרום לקריאה של systemברגע ש printf-נקראת).
נעשה זאת ידנית ,בכל פעם נדפיס אלמנט מסוים על המחסנית בעזרת ,pעד שיודפס הייצוג של הקלט
שלנו:
ספציפית ,נצטרך את הכתובת של ה GOT entry-עבור printfואת הכתובת של ,systemאז נפתח שוב את
.gdbנעשה disassembleל vuln-ונדפיס שוב את ה plt stub-של :printf
חשוב לציין שהדרך הזו עלולה לעשות בעיות ויותר מכך ,היא לא רלוונטית כשאנחנו עובדים מול שרת
מרוחק ,גרסת ה libc-עליו עלולה להיות שונה ,השיטה הטובה יותר היא להשתמש בחולשת הformat-
stringכדי להדליף כתובת של פונקציה מ libc-מהמחסנית ,לחסר את האופסט של הפונקציה (מכתובת
הבסיס של )libcמהכתובת שהדלפנו (נקבל את כתובת הבסיס של )libcולהוסיף את האופסט של .system
נעבור על השיטה בקצרה:
ראשית ,אנחנו צריכים להדליף ערכים מהמחסנית ,אפשר לעשות זאת ידנית או בעזרת ה fuzzer-הבא
שמדפיס את מאה האלמנטים הראשונים על המחסנית:
נריץ ונבחר באחד הערכים שנראה כמו כתובת ב ,libc-נפתח pwndbgונבדוק לאן הוא מצביע:
למקרה שאנחנו עובדים מול שרת מרוחק ,נצטרך להבין מהי גרסת ה libc-עליו ,נהוג להשתמש בLibc-
databaseבשם ,Blukatלהזין את הכתובת שהדלפנו לצד הסימבול הרלוונטי .ברוב המקרים יוחזרו מספר
גרסאות אפשריות ,לרוב האופסטים בינהן יהיו זהים( ,במקרה שלא נצטרך לנסות עד שנצליח .)
מכשול
כשדיברנו על %nאמרנו כי הוא כותב את מספר התווים שהודפסו אל האלמנט אליו הוא מצביע ,אנחנו
צריכים לכתוב את הכתובת ,f7dc7040זוהי כמות תווים עצומה להדפיס ל ,stdout-יקח המון זמן .לכן במקום
לכתוב long intבגודל ארבעה ,bytesנכתוב שני ,short intsכל אחד בגודל שני .bytesלשם כך נצטרך
להשתמש ב specifier-אחר .%hn
הרכבת הpayload-
אנחנו רוצים לכתוב 0xf7dc7040אל הכתובת ( 0x804c00cה entry-של printfב .).got-כפי שאמרנו נכתוב
שני ,short integersזה אומר:
)0x0804c00c+2=0x0804c00e(high order) >- 0xf7dc (63452
)0x0804c00c (low order bytes) >- 0x7040 (28736
נחשב את ה padding-שנצטרך להוסיף ,החישוב יהיה הערך שאנחנו רוצים לכתוב ,פחות כמות התווים
שכבר הודפסו .נתחיל מה( 28736-8 = 28728 :low order bytes-כתבנו כבר שתי כתובות ,כל אחת בגודל
של ארבעה בתים) .ובעבור ה 28736( 63452-28736 = 34716 :high order bytes-התווים ששימשו עבור ה-
.)low order bytesנחבר הכל יחד ונקבל את ה payload-הבא:
\x0c\xc0\x04\x08\x0e\xc0\x04\x08%28728x%4$hn%34716x%5$hn
( \X0c\xc0\x04\x08או ,(0x0804c00cמצביע על הlow order bytes-
\X0e\xc0\x04\x08או ,0x0804c00eמצביע על הhigh order bytes-
(הפוכות מטעמי )endianness
- %28728xלכתיבת 28728בתים על ה.stdout-
- %4$hnיכתוב )0x7040(8 + 28728לאלמנט הרביעי במחסנית(תחילת ה payload-שלנו)
- %34716xלכתיבת 34716בתים על הstdout-
- %5$hnיכתוב )0xf7dc( 34716 + 28728 + 8לאלמנט החמישי במחסנית )(high order
והשגנו !shell
ה exploit-שלנו (אפשר להתעלם מהחלק הראשון template ,שאני משתמש בו כדי להחליף בקלות בין
הרצה לוקאלית למרוחקת ,השתמשתי ב pwnlib.fmtstr-בשביל אוטומציה ,אך היינו יכולים להציב את
הערכים המתאימים שמצאנו ידנית):
!ניצחון
מאחר שה GOT-ממוקמת במיקום ידוע מראש ,כל תוכנית הכוללת חולשה שמאפשרת כתיבה של 4בתים
למקום כלשהו בזיכרון (דוגמת format stringאו int overflowשמוביל ל ,)out-of-bounds write-פגיעה ל-
,arbitrary code executionבכדי להימנע מכך ,צריך לוודא שה dynamic linker-מוצא את הכתובות של כל
הפונקציות המקושרות דינאמית כבר בתחילת הריצה ,ואז הופך את ה GOT-לקריאה בלבד.
הפיתרון הזה נקרא ,RELROקיצור ל ,Relocation Read Only-ואפשר להשמיש אותו כאופציית קימפול
לתוכנית .חשוב להבדיל בין Full RELROאל ,Partial RELRO-שכן Full RELROהוא הפתרון שדיברנו עליו
עכשיו ,אך ( Partial RELROשזו האופציה הדיפולטית של )gccכמעט ולא עושה הבדל מעבר ללהציב את ה-
GOTלפני ה bss-בזיכרון כדי למנוע buffer overflows-על משתנים גלובאלים.
סיכום
למרות שכביכול קיים פתרון ,ישנה עדיין כמות משמעותית של חבילות קוד שמקומפלות ומופצות ללא full
,RELROנוסף על כך קימפול עם full RELRO-מוביל ל loading overhead-לא תמיד טריוויאלי ,ולכן גם בימים
אלו הטכניקה פופולארית ואנו רואים מימושים שלה.
whoami
דור גרסון ,בן 19אוהב את תחומי ה Binary Exploitation/Exploit-dev-ו ,RE-ו-ctf-ים באופן כללי ,לכל
שאלה מוזמנים לפנות אלי בלינקדאין:
https://www.linkedin.com/in/dor-gerson-b12782245
או במייל:
dor.gerson17@gmail.com
:GDB-PWNDBG
GitHub - pwndbg/pwndbg: Exploit Development and Reverse Engineering with GDB Made
Easy
:GOT-Overwrite
GOT Overwrite Using Format Strings · Nihaal Prasad (nihaal-prasad.github.io)
GOT OVERWRITE. SPAWN SHELL USING SIMPLE GOT OVERWRITE | by AidenPearce369 |
InfoSec Write-ups (infosecwriteups.com)
:Fmtstr documantion
pwnlib.fmtstr - Format string bug exploitation tools - pwntools 4.8.0 documentation
הקדמה
Windows EventLogהיא תת-מערכת מורכבת עם מספר רב של אירועי קצה Windows Event Logs .יכולים
לתפוס מגוון רחב של פעילויות ולספק לנו תובנות יקרות בנושא המערכות והסביבות שלנו .החלטתי לכתוב
את המאמר הזה כי באופן אישי לא מצאתי יותר מדי מקורות מידע שצוללים לעומק של הנושא הזה ,ואין
ספק שאנשים שמתעסקים ב IR-צריכים לדעת בדיוק למה הם נכנסים.
כאשר אנחנו רוצים לבדוק כל אירוע שקשור למחשבים ,זה חשוב מאוד שנבין את המידע שזמין לנו -וכדי
להבין את המידע הזה ,אנחנו קודם כל צריכים להבין את הפורמט שבו הוא מוצג .ייתרון אחד של עבודה עם
Windows Event Logsהוא שכל האירועים (שנאספים על המערכת עצמה ,על תוכנה ,או למטרות ביקורת)
מסודרים בצורה סטנדרטית כדי לגרום להם להיות קלים להבנה ככל שניתן.
כנראה התפיסה השגויה הנפוצה ביותר לגבי אירועי Windowsהיא שהם ייחודיים באופן גלובלי.
ממייקרוסופט עצמם:
“Event identifiers uniquely identify a particular event. Each event source can define its own
”numbered events and the description strings to which they are mapped in its message file.
" "Each event source can define its own numbered eventsמרמז שמזהיי אירועים הם ייחודים רק
כאשר מדובר במקור אירוע ספציפי (ייחודי באופן מקומי/יחסי) .לצערנו ,יש הרבה מאוד מקורות שרק
מייחסים את ה Event ID-ללא מקור האירוע והגרסה שלו .אם נרצה לאמת זאת בעצמנו ,אנחנו רק צריכים
לחפש את Event ID 1באתר .MyEventLogאולי שמתם לב שחוץ ממספר מגוון של מקורות אירוע שונים ,יש
גם מספר הודעות עבור המקור ” .“WinVNC4זה עשוי לקרות עקב שוני בין גרסאות של אותו מקור אירוע.
מהמקור " ,"Windows XML Event Log formatסעיף Externally stored values ,5.4אנחנו יודעים
שהודעות אירוע נשמרות בקבצי משאב הודעות ( .)PE/COFF ,message resource filesהודעות האירוע
נשמרות עם מזהה מחרוזת הודעה ( .)message string identifierישנן מספר דרכים כדי לקבוע את המזהה
הזה מ:Event ID-
במקרים מסוימים אנחנו צריכים את תכונת ה Qualifiers-כדי לקבוע את מזהה מחרוזת ההודעה .בואו ניקח
לדוגמה את המקרה הבא:
><EventID Qualifiers="16384">7036</EventID
- יכול להיות ממופה למזהה מחרוזת הודעה היא דרך מידע שנמצא במשאב הEventID-דרך נוספת שבה ה
: ניקח את המקורות הבאים, לדוגמה.WEVT_TEMPLATE
אם נחלץ את מזהיי האירוע ומחרוזת. שני המקורות משתמשים באותו קובץ משאבים,כפי שניתן לראות
: הבאותPowershell-ההודעה בעזרת פקודות ה
(Get-WinEvent -ListProvider Microsoft-Windows-OfflineFiles).Events | Format-Table Id, Description
Id Description
-- ----------
1 The Offline Files service started successfully.
2 The Offline Files service is terminating.
...
2011 Rename of file %1 to file %2 was blocked. The source and/or target file name is an excluded
file type.
(Get-WinEvent -ListProvider Microsoft-Windows-BranchCacheSMB).Events | Format-Table Id,
Description
Id Description
-- ----------
3000 SMB BranchCache was enabled with min hash version %1 and max hash version %2.
3001 SMB BranchCache was disabled.
message : 55
Identifier : 0xb00007db
data : Rename of file %1 to file %2 was blocked. The source and/or target file name is
an excluded file type.
message : 56
identifier : 0xb1000bb8
data : SMB BranchCache was enabled with min hash version %1 and max hash version
%2.
message : 57
identifier : 0xb1000bb9
data : SMB BranchCache was disabled.
וגם עבור המקורMicrosoft-Windows-OfflineFiles הקובץ הזה מכיל מחרוזות הודעה עבור גם המקור של
.Microsoft-Windows-BranchCacheSMB
Windows Event Logsתפיסות שגויות נפוצות לגבי
www.DigitalWhisper.co.il
66 2023 ינואר,146 גליון
כל מחרוזות האירוע משומשות בהודעת האירוע
כאן ,מחרוזות האירוע ” “Volume Shadow Copyו “stopped”-מצוינות בתור EventDataב XML-עצמו.
בדוגמה ,מזהה הודעת האירוע המקביל הוא ” ,“The %1 service entered the %2 stateכאשר מחרוזת
האירוע הראשונה צריכה להחליף את מחזיק המקום הראשון ( )%1בהודעה הסופית .ההודעה הסופית
צריכה להיראות ככה:
”“The Volume Shadow Copy service entered the stopped state.
למרות זאת ,יש מקרים שבהם מזהה מחרוזת האירוע לא מכיל את מחזיק המקום עבור מחרוזת אירוע
ספציפית .לדוגמה באירוע מספר 0223במקור :Microsoft-Windows-OfflineFiles
Sync info for %1%nServer copy exists, client copy deleted. %n%13%nSee details for more
information.
כפי שאפשר לראות ,מזהה מחרוזת האירוע הזה מכיל רק שני מחזיקי מקום עבור המחרוזת הראשונה
והמחרוזת השלוש עשרה .הצורה שבה מחרוזות אירוע אחרות צריכות להיות מפורשות במקרים כאלו
בהתבסס על ה ,EventLog-ללא עובדות נוספות ,היא ספקולציה טהורה מנקודת מבט של פורנזיקה
דיגיטלית.
כפי שאפשר לראות “Access is denied” ,לא מוגדר במזהה מחרוזת ההודעה או במחרוזות האירוע .כאן,
%%5מקביל למחרוזת ההודעה עם המזהה 5שמאוכסן בקובץ הפרמטרים של ההודעה של מקור האירוע
(מקור).
אם נשווה, לדוגמה.)PE/COFF( מחרוזת אירוע יכולה להיות שונה עבור גרסאות שונות של קבצי משאבים
בקובץMicrosoft-Windows-BranchCacheSMB במקור3222 את מחרוזת ההודעה של אירוע מספר
:Windows 7 בגרסה של,cscsvc.dll.mui משאב של
Windows 7, product and file version 6.1.7600.16385: SMB BranchCache was enabled.
תקין לא אמור להכיל את התו < באלמנטXML כי, תקיןXML המודגש איננו בפורמטData-כאן אלמנט ה
.מידע
ישנם מספר. אינם יחודייםEventData- שמות של אלמנטים של מידע ב, הבאXML-כפי שאפשר לראות ב
:“IoTypeIndex”- ו,“TotalBytes” ,“TotalLatencyUs” ,“IoCount” אלמנטים של מידע שיש להם את השם
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Ntfs" Guid="{3FF37A1C-A68D-4D6E-8C9B-F79E8B16C482}"/>
<EventID>146</EventID>
<Version>1</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x4000000000200000</Keywords>
<TimeCreated SystemTime="2018-09-05T01:51:32.107675800Z"/>
<EventRecordID>3291</EventRecordID>
<Correlation/>
<Execution ProcessID="4" ThreadID="15136"/>
<Channel>Microsoft-Windows-Ntfs/Operational</Channel>
<Computer>hostname</Computer>
<Security UserID="S-1-5-18"/>
</System>
<EventData>
<Data Name="VolumeCorrelationId">{4994EA25-0000-0000-0000-501F00000000}</Data>
<Data Name="VolumeNameLength">2</Data>
<Data Name="VolumeName">C:</Data>
<Data Name="IsBootVolume">true</Data>
<Data Name="HighIoLatencyCount">0</Data>
<Data Name="IntervalDurationUs">3750962784</Data>
<Data Name="NCReadIOCount">206</Data>
<Data Name="NCReadTotalBytes">9112304</Data>
<Data Name="NCReadAvgLatencyNs">11765267</Data>
<Data Name="NCWriteIOCount">2858</Data>
<Data Name="NCWriteTotalBytes">36175488</Data>
<Data Name="NCWriteAvgLatencyNs">4904584</Data>
<Data Name="FileFlushCount">560</Data>
<Data Name="FileFlushAvgLatencyNs">14539870</Data>
<Data Name="VolumeFlushCount">0</Data>
<Data Name="VolumeFlushAvgLatencyNs">0</Data>
<Data Name="FileLevelTrimCount">0</Data>
<Data Name="FileLevelTrimTotalBytes">0</Data>
<Data Name="FileLevelTrimExtentsCount">0</Data>
<Data Name="FileLevelTrimAvgLatencyNs">0</Data>
<Data Name="VolumeTrimCount">38</Data>
<Data Name="VolumeTrimTotalBytes">8957952</Data>
<Data Name="VolumeTrimExtentsCount">303</Data>
<Data Name="VolumeTrimAvgLatencyNs">53391</Data>
<Data Name="IoBucketsCount">44</Data>
<Data Name="TotalBytesBucketsCount">40</Data>
<Data Name="ExtentsBucketsCount">1</Data>
<Data Name="IoCount">59</Data>
<Data Name="IoCount">21</Data>
...
<Data Name="IoCount">13</Data>
<Data Name="TotalLatencyUs">151222351</Data>
<Data Name="TotalLatencyUs">252569191</Data>
...
<Data Name="TotalLatencyUs">2073327422</Data>
<Data Name="TotalBytes">2813952</Data>
<Data Name="TotalBytes">884736</Data>
...
<Data Name="TotalBytes">8957952</Data>
<Data Name="TrimExtentsCount">303</Data>
<Data Name="IoTypeIndex">0</Data>
<Data Name="IoTypeIndex">1</Data>
...
<Data Name="IoTypeIndex">7</Data>
</EventData>
</Event>
EventLogמהווה סטנדרט לתוכנות ולמערכת ההפעלה לרשום אירועי תוכנה וחומרה חשובים ,עבור
המטרה של אדמיניסטרציית מערכת.
ETWזה קיצור של ETW .Event Tracing for Windowsהוא מנגנון מעקב שעובד ברמת הקרנל שנותן לנו
אפשרות לרשום אירועי קרנל או תוכנה .נשים לב שקובץ אירועים בקונטקסט של ETWלרוב יהיה בפורמט
.etlשהוא שונה מפורמט של קובץ ,EventLogשהוא .evtאו .evtx
סיכום
בתור אנשים שמבצעים חקירות פורנזיות ,אנחנו צריכים להבין את האינפורמציה ואת מקרי הקצה של
המידע שאנחנו מנתחים Windows EventLog .היא תת-מערכת מורכבת עם מגוון מקרי קצה ,שעל רובם לא
מדברים בקהילות פורנזיות ,אז אני מקווה שמאמר זה שפך קצת אור על הנושא ופתח דלתות למחקר עתידי
יותר מעמיק.
על הכותב
דניאל קויפמן ,בן ,04מהנדס מערכות SIEMו ,Detection-ובעל זיקה חזקה לעולמות ה .DFIR-ניתן ליצור
קשר בלינקדאין ,טוויטר ( )@KoifSecאו במיילkoifmandani@gmail.com :
הקדמה
מאמר זה הינו המשך למאמר הקודם שלי בנושא "אוטומציה לתהליכי הקשחה לצמצום משטחי תקיפה".
לאורך עבודתי בנושא הקשחת מערכות עסקתי בהקשחה של מערכות הפעלה מבוססות .Windowsהבנתי
כי הפתרון הקודם שהצגתי ( ,)OpenSCAPהמתאים לעולמות ה Linux-ונגזרותיו ,הוא חלק מתוך פתרון כללי
שיאפשר אוטומציה לתהליכי הקשחה עבור מערכות שונות ,כגון :מערכות הפעלה ,פלטפורמות ענן ,תוכנות,
דפדפנים וכד'.
בכדי לייצר תהליך הקשחה ובקרה אוטומטיים ,נדרש להבין איך נוכל להשפיע על הגדרות בנושאי אבטחת-
מידע .לשם כך ,חשוב להכיר ולהבין מה הכלים הרלוונטים להתמודדות עם אוטומציה לאותן הגדרות
בסביבות שונות.
במאמר זה אראה את הדרך להגדרת תקן הקשחה עבור משאבי ,Windowsבצורה המותאמת לארגונים
שונים.
Windows Vs Linux
בחרתי לקרוא למאמר Windows Vs Linuxבעקבות המידע שנחשפתי אליו לאורך עבודתי .לא ניתן לייצר
אוטומציה לכלל המערכות באמצעות כלי אחד (לפחות לא )OpenSourceאך ,אם נבין מה מערכות
ההפעלה\פלטפורמות שמשמשות אותנו ,נוכל להבין מה סט הכלים המתאים למשימה.
אציין ואדייק את ההנחה המרכזית שהצגתי במאמר הקודם ,בכדי להבהיר אילו מערכות יכולות לקבל מענה
מהכלי שהצגתי ( )OpenSCAPוכיצד נוכל לייצר תהליך דומה (הקשחה ובקרה אוטומטיים) בעבור סביבת
מחשוב מבוססת .Windows
:SCT1.0
Enterprise שירותי דפדפנים מערכות הפעלה
:OpenSCAP
בכדי לייצר תקן הקשחהOpenSCAP-במאמר הקודם שלי ניתן למצוא הסברים מפורטים על אופן השימוש ב
. אוטומציה לתהליכי הקשחה לצמצום משטחי תקיפה- מותאם לצרכים אישיים
RedHat OpenShift למשל- חלק מתקני ההקשחה מונגשים באמצעות תוסף לפלטופורמה אותה יש להקשיח
OpenSCAP אשר מנגיש את יכולותOpenShift Compliance דורש התקנה של תוסף בשםContainer Platform
.לסביבה הנ"ל
שירותי
וירטואליזציה Kubernetes שירותי דפדפנים מערכות הפעלה
Enterprise
RedHat RedHat Jboss Amazon Elastic Chromium Amazon Linux 2/3
Virtualization 4 Fuse Kubernetes Service
Java Runtime RedHat OpenShift FireFox CentOS 7/8
Environment Container Platform
McAfee RedHat OpenStack Debian 9/10/11
VirusScan Platform
Enterprise
Fedora
MacOS
Oracle Linux 7/8/9
openSuse
RedHat CoreOS 4
RedHat Enterprise 7/8/9
Suse Enterprise Linux 12 & 15
Ubuntu
16.04/18.04/20.04/22.04
UnionTech OS Server 20
כפי שהזכרתי ,יש צורך להבדיל את הפתרון הקודם ( )OpenSCAPשמתאים כמו כפפה ליד בעולמות הLinux-
מעולמות ה.Windows-כיוון שבעמוד הגיט-האב שלהם מצויין בבירור כי הם זונחים את התמיכה במשאבי
( Windowsמקור).
דבר זה מוביל אותי לשאלה :כיצד ניתן להקשיח ולבקר את משאבי ה Linux-אך גם משאבי ?Windows
לשם כך אחזור על מספר נקודות שפירטתי עלייהן יותר במאמר הקודם.
הזכרתי שבכדי להגיע לתקן הקשחה ( ,)Benchmarkמומלץ להשתמש בתקן ההקשחה של Central of ( CIS
)Internet Securityמתוך ההנחה כי הגוף מתחזק תקני הקשחה ( )Benchmarksלמגוון רחב של מערכות,
תוכנות ורכיבי רשת שונים .בנוסף ,הזכרתי שניתן למצוא יכולות אוטומטיות להקשחה דרך מאגר של ארגון
התקנים האמריקאי - NISTמאגר .)National Checklist Program( NCP
הדיוק הרלוונטי להנחה שלי מהמאמר הקודם ,היא כי מה שנמצא במאגר NCPיהווה בעיקר את התאוריה
עבור תקני הקשחה של גופים שונים -ולא תמיד את האוטומציות לתהליך ההקשחה והבקרה.
אציין כי ניתן למצוא קבצי SCAPשיאפשרו בקרה עבור משאבי Windowsדרך ממשק יעודי לעבודה עם קבצי
- SCAPאותו תוכלו למצוא גם כן ב .NCP-אך ,הפער עליו אני מצביע הוא דווקא ביכולות האוטומציה
להקשחה -אותם לא ניתן לקבל באמצעות OpenSCAPעבור סביבות .Windows
אני אישית ממליץ לבחון מה ניתן למצוא במאגר NCPלפני תחילת תהליך מחקר בנושאי הקשחה לרכיבים
שונים.
מוטביציה
במאמר הקודם הצגתי מצב בו תשתיות המחשוב השונות ,בארגון קטן עד גדול ,חשופות לחולשות
חדשות\ישנות בעקבות ניהול הגדרות אבטחת-מידע לקוי.
לעיתים ,התיקון הנדרש צריך להיות מוחל על מספר רב של משאבים ולא מאפשר טיפול נקודתי-ידני
במסגרת הזמנים הנתונה.
בהמשך למאמר הקודם ,בו הסברתי על יכולת אוטומטית להקשחה ובקרה בקרב משאבי ה ,Linux-אסביר
במאמר הנוכחי כיצד ניתן לייצר תהליך שכזה גם למשאבי ה Windows-שברשותנו.
הקשחת Windows
תהליך ההקשחה ב Windows-מתרכז למספר ממשקים אשר דרכם ניתן להגדיר כל הקשור באבטחת-
מידע :ערכי GPOוהגדרות נוספות .ביניהן Audit Policy ,Registry :ו.Security Templates-
אתחיל מסקירה קצרה של הממשקים הנ"ל ואתאר כיצד ניתן באמצעותם לייצר תהליך הקשחה ובקרה
עבור משאבי ה Windows-שנרצה לנהל בהקשרי אבטחת-מידע .אפרט בהמשך המאמר כיצד אוסף
ההגדרות השונות מרכיבות יחד תקן הקשחה למשאבי ה Windows-שברשותנו.
היכולת ב Windows-לייצא את אוסף ההגדרות ,שנרצה כחלק מתקן ההקשחה שגובש ,ולהשתמש בהן
לצורך תהליך ההקשחה שלנו היא ,GPO Backup :אותה נשיג באמצעות כלי המגיע יחד עם LGPO - SCT 1.0
).(Local GPO
באמצעות יכולת הגיבוי נוכל לייצא מצב הגדרות רצוי של משאב Windowsולטעונו בעמדת אחרת
(הקשחה) .בנוסף ,ניתן יהיה גם לבקר את תאימות מצב המשאב להגדרות המוצגות בגיבוי.
בכדי להבין כיצד הכלי ישמש אותנו אסביר מה יהיו אוסף הקבצים אשר נקבל באמצעות - LGPOבפעולת
.GPO Backup
במידה והקורא מכיר את המונחים הנגזרים מהנושא של ,GPOאמליץ בכל זאת להתעכב על סוגי הקבצים
המגיעים באמצעות תהליך - GPO Backupהכותרות registry.pol ,GptTmpl.inf :ו.audit.csv-
אובייקט GPOהוא אוסף וירטואלי של פוליסות המגדירות אוסף תכונות ברמת מערכת ההפעלה ()Windows
והמשתמש(ים).
קיימים 0סוגים עיקריים של :GPOsמקומי ( )Localולא-מקומי (.)Non-Local
מעבר להגדרת תכונות שונות למשאבי מערכת ההפעלה Windowsקיימות הגדרות אשר מהוות פוליסת
אבטחת-מידע .למשל ניתן:
להגביל גישה ללוח-בקרה ()Control Panel
לאסור הפעלת CMDאו ( PowerShellממשקים להרצת סקריפטים וכו')
לאסור התקנה של תוכנות
לאכוף מדיניות שימוש בסיסמאות
אופן החלת הפוליסות נעשית בסדר קבוע ,השייך בחלקו לניהול GPOבארגון (ע"י - Active-Directory
מערכת שלא אפרט עליה ומיועדת לניהול מס' משאבי Windowsכחלק מיכולות ניהול הארגון) .לנו חשוב
לזכור כי Local GPOהן ההגדרות הראשונות שיכולו על עמדה עלייה נחיל הקשחה .במידה והעמדה היא
חלק מארגון יצטרפו הגדרות הנופלות לסוג השני .Non-Local GPO -
GPO Back-Up
כאשר נרצה להחיל תקן הקשחה על משאב Windowsנצטרך לזכור ,כפי שתיארתי קודם לכן ,כי קיימות
הגדרות אבטחה הן לרמת מערכת ההפעלה והן לרמת המשתמש(ים) .אלו ניתן להגדיר באמצעות אוסף של
קבצים עלייהם ארחיב בחלקים הבאים audit.csv ,registry.pol :ו .GptTmpl.inf
בנוסף ,קיים קובץ Backup.xml & Bkupinfo.xmlאשר מכילים מידע נוסף על הגדרות המשאב.
ההגדרות הנוספות נוגעות לתוספות למשאב - Windowsבינהם BitLockerונוספים.
עלייהם לא אפרט במאמר זה ,בעקבות הסיבה שהם ממשקים נוספים שניתן להגדיר בהקשרי אטבחת-
מידע .מצד שני ,התהליך שאתאר לאורך המאמר יוכל לאפשר לקוראים להבין כיצד להגדיר אותם גם כן
-שכן גם הם מתרכזים להגדרות נוספות בקבצים שאתאר במאמר.
תקן ההקשחה ,כפי שיגיע מ Microsoft-או גורם מאושר אחר (למשל ,)CISיגיע עם מספר קבצים -אשר
אחד מהם הוא ה ,GPO-Backup-אשר יעזור לנו להקשיח ולבקר האם העמדה שלנו עומדת בהמלצות של
Microsoftאו בתקן ההקשחה שגובש בארגון.
מעבר להגדרות כלליות של משאב ה Windows-שלנו אשר נכללות בממשק ה GPO-של המשאב ,קיים בתוך
ה GPO-אזור המיועד לאבטחת-מידע .Security Settings -
כעת ,בהינתן העובדה כי יש סט הגדרות יעודיות לנושא אבטחת-מידע למשאבי ,Windowsכל שנותר הוא
להבין כיצד לנצל זאת לטובתנו -ולייצר תקן הקשחה המתאים לדרישות הארגון שלנו.
פוליסות אבטחת-מידע מכילות הגדרות המאפשרות שימוש ביכולות אבטחה של Windowsבכדי להבטיח
אכיפה של מגוון קטגוריות:
ססמאות ,נעילת משתמש ופרופיל ( Kerberosמערכת הזדהות לארגון)
הגדרות תיעוד ולוגים ברמת המערכת והמשתמש(ים) -תיעוד כללי
הרשאות גישה לקבצים ותיקיות
אבטחה לתוכנות ,תהליכים
שיוך פרופיל אבטחה לקבוצה
בכדי להשיג שליטה על קבוצת ההגדרות הנ"ל Microsoftמתעדת את השימוש בפרוטוקול שיאפשר לנו
להגדיר את הקטגוריות השונות .לשם כך ,הפרוטוקול מתאר את אוסף ההודעות שהוא תומך בהן.
אוסף ההודעות מתורגם בפרוטוקול להגדרה נקודתית הקשורה לאבטחת-מידע.
אוסף ההודעות וההגדרות השונות מפורטות ביתר פירוט במסמך MS-GPSBבאתר של - Microsoft
מקור
בתוך המסמך המפורט של Microsoftניתן לראות כי לחלק מההגדרות ישנם ערכים קבועים שהמסמך
יודע להגדיר -ואותם נוכל לראות כבר במסמך.
בכדי לאגד את אוסף כל ההגדרות הנ"ל נתחיל להכיר את קובץ ה.GptTmpl.inf -
האפשרות לגבות ולבחון את ההגדרות שלנו עבור תהליך ההקשחה הוא חשוב ,שכן נרצה לבחון את
השינויים שלנו בצורה נקודתית לפני שנריץ אוטומציות המכילות מס' רב של שינויי הגדרות.
מעתה ,נוכל להגדיר עבור משאב ה Windows-שלנו אוסף הגדרות המתאים לתקן ההקשחה שגובש בארגון
-ולהבטיח עמידה של אוסף המשאבים המתאימים בהגדרות אבטחת-המידע השונות.
אם כך ,ברור שיש לנו קובץ אחד שניתן דרכו להגדיר את כל קטגוריות אבטחת-המידע ב .Windows-ראינו
דוגמא להגדרת Servicesו Policy-לססמאות .בהתייחס לניהול Registryנכיר כי קיימת דרך ברורה
ואוטומטית לניהול ערכים ברמת מערכת ההפעלה וברמת משתמשים בהרשאות שונות.
registry.pol
הקובץ הנ"ל הינו קובץ בינארי אשר מאפשר למשאב Windowsלהגדיר הגדרות שונות ברמת מערכת
ההפעלה והמשתמשים השונים (לא רק בהקשרי אבטחת-מידע) .בכל כיבוי של המשאב ההגדרות נשמרות
ונטענות מחדש בעת עליית המשאב.
כאשר נבצע פעולת GPOBack-Upנקבל את הקובץ המתאים הן להגדרות מערכת ההפעלה והן להגדרות
משתמש -אלו ימצאו בתיקיות מתאימות בגיבוי.
בכדי שנוכל לקבל דינאמיות על אופי הגדרת קובץ .polנקבל החל מ Windows 10-תמיכה של
LGPO3.0עבור פעולה ליצירת קובץ .polמקובץ טקסט בפורמט הבא:
כך שלאחר שנחליט אילו ערכי Registryנרצה להוסיף להגדרות משאב ה Windows-שברשותנו ,נוכל
להשתמש ב LGPO-בכדי לייצר קובץ .*.polזאת נעשה באמצעות GPOBack-Upשהזכרתי קודם לכן.
Registry.polהמשויך למשתמש ( )Userמהווה את אוסף ההגדרות המוחל על המשתמש שיזם את
פעולת הגיבוי.
כפי שהזכרתי בפסקה הקודמת -נוכל לטעון אותו למשתמש(ים) ספציפי(ם).
audit.csv
מנגנון התיעוד לפעולות במשאבי Windowsמאפשר לנו שליטה ברמה כללית ופרטנית .כאשר נתבונן במסך
Security Settingsנבחין כי יש 0מקבצי הגדרות לתיעוד:
- Audit Policyסט הגדרות תיעוד כלליות (מכיל את כלל ההגדריות הפרטניות)
- Advenced Audit Policyסט הגדרות תיעוד פרטניות המאפשרות הגדרה נקודתית לתיעוד פעולות
שונות (מאפשר לחסוך מידע שאינו נחוץ -המגיע בהגדרה הכללית)
נוכל להבין כי הפעלנו אפשרות " "3המסמנת תיעוד במקרה של הצלחה\כשלון עבור אוסף הארועים הבאים:
מה שאנו רואים כי יוגדר בצורה כללית מקבל פירוט אשר עוזר לנו להבין מה רמת התיעוד שניתן לקבל
בצורה מפורטת יותר .במידה ונגדיר משהו על ה Audit Policy-הכללית ,ההגדרה תוכל על כל תת ההגדרות
שמפורטות ב - Advenced Audit Policyזאת נוכל לראות גם בקבצי audit.csvהמתקבל ב:GPOBack-Up-
במידה ונבחן את קובץ ה audit.csv-שנקבל ב GPOBack-Up-נבחין כי יהיה תוכן רק במידה ויצרנו שינוי
בהגדרות התיעוד הפרטניות (שכן אם צריך לכסות הגדרות כלליות נעשה זאת דרך קובץ ה ).inf
בגלל ההגדרה הפרטנית שביצענו ,ההגדרות הקודמות שנבעו מ" Audit Policy-נזנחו" והוגדרו ע"י
.Advenced Audit Policy
לאחר שהכרנו את קבצי ההגדרות הרלוונטים להגדרת תקן-הקשחה למשאב ,Windowsאפרט על אופן
השימוש ב .LGPO-במאמר זה אדאג לפרט על יכולות LGPO 3.0אשר מגיע בחבילת .SCT 1.0הזכרתי את
הכלי מספר פעמים לפניכן וציינתי כי מטרתו של הכלי היא לאפשר .GPOBack-Upפעולות עיקריות:
יצירת ( GPOBack-Upפעולת )Exportהמכיל את כלל ההגדרות של משאב ה Windows-והמשתמשים -
הן מקבצי audit.csv ,registry.polו.GptTmpl.inf-
ביצוע פעולת Importלהגדרות הנ"ל במשאב .Windows
החלת ערכי Registryעל מערכת ההפעלה או קבוצות משתמשים.
יצירת קבצי Registry.polע"י קבצתי טקסט בפורמט מתועד.
כעת ,אתאר כיצד נוכל להשיגו ואת אופן השימוש בו.
LGPO 3.0
ב LGPO3.0-ניתן למצוא מגוון רחב של פעולות:
ניתן להוריד בצורה עדכנית מהאתר של .Microsoftיש לשים לב שהוא חלק מחבילת :SCT1.0
פעולות
אציג את הפעולות העיקריות שהגדרתי כחלק מביצוע הקשחה .פעולת גיבוי ( )Exportלכלל ההגדרות:
פעולת ייבוא ( )Importלהגדרות (אוסף הקבצים) הנמצאים בגיבוי הנתון .ניתן לראות שקיבלנו חיווי
מתאים לטעינת הקבצים הרלוונטים.
כמוכן ,ניתן לראות כי נטענו קבצי - CSEקבצים אלו מוגדרים ב manifest.xml-שמגיע בGPOBack-
Upכאשר הגדרות אבטחת-מידע נוספות הוחלו עלייה.
הצורך בקובץ manifest.xmlנדרש בכדי לאפשר לתוכנת Microsoftלהכיר את סוגי ההגדרות
השונות ושיוכן המתאים ליכולות נוספות במשאבי ( Windowsמעבר להגדרות מערכת הפעלה
ומשתמשים).
למשל ,עבור Windows11נמצא ברשימה את:
.1ישנן פעולות נוספות כגון פעולות לטעינת Registry.polל Machine-או ( Userניתן גם לטעון לקבוצות
שצוינו מקודם) או פעולה לטעינת קובץ טקסט בפורמט מתאים ל.Registry-
כפי שראינו בתיעוד הכלי ,נוכל לקבל דינאמיות להחיל ולהגדיר קבצים אשר מהווים את אוסף הגדרות
אבטחת-המידע שנרצה:
> - LGPO /g <pathיחיל את אוסף ההגדרות שנמצא בתיקיית ה - GPO Backup-הכוללת את הקבצים:
.audit.csv ,Registry.pol ,GptTmpl.inf
ניתן להחיל את הקבצים בצורה עצמאית ע"י הפקודות /t ,/a ,/sהמפורטות ב.LGPO-
ל LGPO-יש גם יכולות לייצר קובץ registry.polמתוך קובץ טקסט המתואר לפי פורמט קבוע
ניתן למצוא אותו בתיאור של LGPOהמגיע בהורדה בחבילת .SCT1.0
לאחר שהכרנו את השימושים השונים שנעשה עם LGPOנרצה לראות כיצד נוכל לראות את ההגדרות שלנו
מבקורות ע"י הכלים של .Microsoftלשם כך ארחיב על הכלים הנוספים בחבילת .SCT 1.0
Policy Analyzer
הכלי הנ"ל יאפשר טעינת הגדרות ע"י טעינה של GPOBackUpאו ע"י קבצים נפרדים .לשם כך ,בחלון
הראשי נלחץ על כפתור ”:“Add
נטען לדוגמא את קובץ ה GptTmpl.inf-שיצרנו בחלק של הסבר ונראה כיצד נוכל לבקר את הסעיפים
לדוגמה שסקרנו.
שימו לב שהתווסף לנו קובץ לרשימה ב Policy Analyzer-ע"פ השם שספקנו בתהליך טעינת הקובץ.
הקובץ שהצטרף הוא מסוג PolicyRulesומהווה את כלל הגדרות שנטענו מקובץ הגדרות.
קבצי PolicyRulesיכולים לשמש להקשחה ובקרה עבור משאבי Windowsהנתמכים ב.SCT-
ניתן להשתמש ב LGPO3.0-בכדי להחילם על משאב ( Windowsפעולת הקשחה)
בנוסף ,שימו לב שניתן לראות פירוט על הסעיפים (בחלק התחתון של התמונה) ברמה ברורה יותר מרק
להגדיר קבועים המסמלים הגדרות במשאבי .Windows
Compare/View
נוכל להשוות בין 0קלטים (או יותר) על מנת להעזר ב PolicyAnalyzer-בכדי לראות את ההבדלים המהותיים
בין 0סוגי הגדרות שטענו:
ניתן לראות את השירותים שהגדרנו וחלק מהגדרות הססמא שהוצגו במאמר.
שדה אפור מראה כי יש חוסר בהגדרה של השדה המוצג באחד מאוספי ההגדרות (תקן הקשחה /
בקרה)
בהמשך המאמר אציג כיצד נוכל להעזר ביכולות של PolicyAnalyzerבכדי להתמקד בשוני הקיים בין 0
אוספי הגדרות.
באמצעות הפעולה הנ"ל (לעיתים דורשת הרשאות מנהל בהתאם לקבצי הסריקה) נוכל להשוות את מצב
משאב ה Windows-דרכו אנחנו מריצים את PolicyAnalyzerלאוסף הגדרות שבחרנו מתוך מה שנטען ל-
.PolicyAnalyzer
בעת שנגיע למצב הרצוי מבחינת אוסף החוקים שהכלנו באמצעות ,SCTנוכל להשתמש בקובץ PolicyRules
(אשר ימצא בתיקייה המצויינת בשדה Policy Rule sets in:בממשק )PolicyAnalyzerבכדי להחיל את כלל
ההגדרות באמצעות קובץ בודד ופקודת LGPOמתאימה (.)/p
במידה ונבחן את אוסף החוקים הנמצאים בקובץ ה EffectiveState-נראה כי הוא מכיל 79חוקים שנמצאו
בחפיפה מול ההגדרות המומלצות ל( .Windows 11-רק הגדרות אבטחה שהוגדרו יוצגו)
בחלק הראשון של המאמר למדנו על קבצי ההגדרות של Windowsאשר יאפשרו לנו שליטה על הגדרות
שונות שנרצה להחיל במשאב .Windowsהגדרות האבטחה המומלצות ניתן למצוא גם ב( Microsoft-כחלק
מחבילת )SCT1.0וגם ב.)National Checklist Program( NCP-
בנוסף ,אם נבחן את תקן CISנראה הוראות ברורות לאילו ערכים צריך לעדכן בכדי לקבל את מענה
האבטחה ההולם לצרכינו .בהינתן אוסף הקבצים אשר מכיל את הגדרות האבטחה המומלצות נוכל להמשיך
לתהליך ההקשחה והבקרה.
תהליך הקשחה
תהליך בקרה
כלי ה PolicyAnalyzer-מאפשר טעינה של קבצי הגדרות (בדומה לאוסף שתואר ב"תהליך הקשחה") .כאשר
אוספי הגדרות טעונים בו נוכל לבצע השוואה שטחית בין האוספים הטעונים ( .)Compare/Viewבמידה
ונרצה לבצע בקרה המתאימה לאוסף הגדרות שטענו (תקן ההקשחה) נוכל לבצע השוואה אל מול אוסף
ההגדרות הקיימות בעמדה (.)Compare to Effective State
על המחבר
בעל תואר ראשון בהנדסת תכנה ,עוסק כמהנדס פתרונות אבטחת-מידע .חוקר ומיישם יכולות לאוטומצית
תהליכי הקשחה ובקרה ארגוניים .מתעניין ובוחן איומי סייבר שונים לצורכי מחקר ומענה.
הקדמה
המאמר הבא הוא השני בסדרה של מאמרים שמטרתה להראות דרכי ניצול של אפליקציות יומיומיות
לטובת השגת מידע רגיש של משתמשים או לטובת ניצול לרעה של דרכי פעולה לגיטימיות של
האפליקציה .הקו המנחה של המאמרים הוא מציאת חולשות לוגיות ,שלעתים אינן חולשות כלל ,שכל מה
שדרוש על מנת לנצל אותן זה הבנה בסיסית של דרך הפעולה של הלקוח וכמה כלי מחקר פשוטים .אם
נזקק את כל זה למשפט אחד ,אז אפשר להגיד שלפעמים כדי למצוא תפוח זהב ,עדיף לחפש על הרצפה
מאשר לנסות לטפס על העץ .מי שלא קרה את המאמר הראשון בסידרה ומעוניין -יכול לעשות זאת כאן.
רקע
באחד מהביקורים האחרונים שלי בעיר באר שבע ,הסתובבתי ביחד עם חבר בין השכונות החביבות של
העיר ,כשלפתע משום מקום הוא פנה אליי עם המשפט הבא" :אני חייב ללכת להסתפר ,עכשיו!" .ברור
שבתור חבר רציונלי ,עזרתי לו מיד למצוא את המספרה הקרובה ביותר .צעדנו לנו עד לפתח המספרה
ושאלנו את הספר את השאלה המתבקשת שהוא שומע כמה פעמים טובות ביום" :כמה יש בתור?".
ההפתעה האמיתית הגיעה כאשר במקום לקבל תשובה קלאסית של "שני הילדים שפה ואז הבחורצ'יק
מאחורה" או "מפוצץ עכשיו חברה ,תחזרו בצהריים" ,הוא ענה לנו את התשובה הבאה:
"אתם לא יכולים להיכנס ככה ,חייבים להזמין תור באפליקציה" .שנינו הסתכלנו אחד על השני במעין מבט
שתוהה האם אנחנו בניו יורק של 0232או בבאר שבע של ,0202אבל קיבלנו את הבקשה והלכנו להוריד את
האפליקציה .רק בדיעבד ,בשיחות עם חברים נוספים ,נגלה אליי הטרנד החדש של עולם הספרות ושל עולם
העצמאים בכלל ,והוא אפליקציות מותאמות לניהול תורים לעסק הפרטי.
חברת EasyTorהיא בין האחראיות הגדולות למהפכת האפליקציות לניהול תורים שהוטמעו בשוק הישראלי
בצורה רחבה לאחרונה .כבר בחנות האפליקציות ,בחיפוש אחרי האפליקציה של הספר שלנו ,אפשר לראות
את היקף הלקוחות של החברה ואת כמות האפליקציות שהיא סיפקה ללקוחות פרטיים שרוצים לנהל את
התורים שלהם.
בעמוד האפליקציה של הספר שלנו אפשר לראות את שם החברה שפיתחה את האפליקציה ,ובלחיצה על
שם החברה ניכנס למסך סינון שמראה לנו את כל האפליקציות האחרות שפותחו על ידי אותה חברה.
הצילום הזה מכיל רק את התוצאות הראשונות ,שכוללות גם הן שמות גדולים בתחום הספרות כמו & Snir
Meirשידועים בתור מעצבי שיער של סלבס ושחקני כדורגל מפורסמים ,אבל בגלילה למטה בעמוד אפשר
לראות עוד עשרות אפליקציות שונות שהחברה פיתחה שמגיעות ביחד לעשרות אלפי הורדות.
המוצר
"מערכת ייחודית לניהול תורים בצורה פשוטה ויעילה שמגיעה עם אפליקציה ייחודית לאיפון ואנדרואיד לכל
בעל עסק עם המון פונקציונליות ושליטה מלאה על הכל מתוך ממשק הניהול! כל מה שנשאר לעשות זה
להפנות את הלקוחות לאפליקציה הייחודית של העסק שלך ומשם בצורה קלה ופשוטה הם יוכלו להזמין תור
בכל רגע נתון ,לקבל תזכורות ,לראות עבודות שלך ,להחליף תורים בניהם בצ'אט ולהכיר את הצוות של
העסק".
למי שלא קרא את המאמר הקודם ,הצגתי בו הקדמה לגבי מחקר אנדרואיד באופן כללי ,כולל שיטות וכלים
שאפשר להשתמש בהם .לכן בשביל להמשיך לחלק הבא של המאמר ,אמליץ לסיים לקרוא את המאמר
הקודם בקישור הבא ,ואז לחזור אלינו .אז נתחיל כמובן בליצור emulatorחדש ב Genymotion-ונוריד את
ה APK-של הספר שלנו מאתר Mirrorלבחירתנו (זאת הוכחה שבאתרים האלה יש באמת הכל:)...
הקטע המיוחד במחקר שלנו עכשיו ,הוא שלחברת EasyTorאין אפליקציה אחת שאנחנו יכולים לחקור ,אלא
שיש לה אפליקציה לכל לקוח ולכן נחקור אפליקציה אחת מבין רבות שהיא יצרה .החלק הטוב הוא שלחברה
יש Templateגנרי של אפליקציה שעליו היא מלבישה עיצוב ספציפי לכל לקוח ,ולכן מספיק לחקור לקוח
אחד כדי להבין את כל המוצר של החברה ,ונראה זאת גם בהמשך .עכשיו אחרי שהתקנו את האפליקציה על
האימולטור ,נוכל לראות את את המסך הראשי ואת התפריט הצדדי שמאפשר לנו לעשות פעולות:
אבל ,למרבה ההפתעה ,אחרי שנכנסים ל MainActivity-רואים שהוא מכיל פונקציה אחת עם מספר שורות
קוד בודדות:
ולא רק זה ,אם מסתכלים בתיקיית הפרויקט ,רואים שיש שם 3קבצים בודדים בלבד ,ששניים מהם הם
בכללי קבצי קונפיגורציה וקישור:
אז מה קורה פה? איך יכול להיות שיש רק קובץ אחד עם Activityאחד שמכיל כמה שורות בודדות? איפה כל
האפליקציה? הדבר היחיד שאנחנו כן רואים בינתיים הוא שה MainActivity-יורש ממשהו שנקרא
CordovaActivityוקורא לפונקציה אחת בשם .loadUrl
מצד אחד הביצועים של אפליקציות כאלו יכולים להיות מוגבלים ביחס לאפליקציות רגילות ,אבל מצד שני זה
נותן לנו יכולות טובות יותר מאתרים פשוטים בעיקר בגלל נראות של אפליקציה שמותקנת על המכשיר
ויכולת התראות שלא קיימת באתרים רגילים שנפתחים על ידי דפדפן.
כיום ה Framework-הזה מנוהל על ידי חברת ,Adobeוהיא משווקת גם שירות שנקרא Apache Cordova
Buildשמאפשר למתכנתים להעלות קוד מקור של Html, CSSו Java Script-ל ”Cloud Compiler”-המייצר
אפליקציות לכל פלטפורמה נתמכת .ה Framework-של Adobeנחשב ליחסית מיושן (למרות שעדיין יש
כמות גדולה מאוד של אפליקציות שמשתמשות בו) והמחליף העכשווי שלו הוא React-Nativeשמאפשר גם
הוא פיתוח אפליקציות .Cross-Platform
ועכשיו אחרי שאנחנו מבינים מה זה בכלל Cordovaואיך יכול להיות שאין כמעט קוד באפליקציה שלנו,
אפשר גם להסיק למה החברה בחרה להשתמש בתשתית הזאת .המקרה של EasyTorהוא דוגמא קלאסית
למקום שבו נצטרך אפליקציה גנרית מינימלית שנוכל להתאים בצורה קלה ומהירה לכל הלקוחות ,ומה יותר
נוח מלהתאים טיפה את עמודי ה HTML-ו CSS-כך שיתאימו לעיצוב שהלקוח שלנו רוצה? אז עכשיו השאלה
היחידה שנשארה היא...
בואו נצלול חזרה לקוד .מה שאנחנו רואים שקורה ב MainActivity-זה טעינה של האתר בעזרת הפוקנציה
loadUrlשמקבלת כפרמטר את המשתנה .launchUrlהמשתנה launchUrlיכול להיות כתובת שנמצאת
באינטרנט שאותה נטען בדפדפן הפנימי שלנו ונציג ככל אתר רגיל ,אבל במקרה שלנו הכתובת launchUrl
מצביעה דווקא על קובץ מקומי ...כדי למצוא את הערך של המשתנה התחלתי בתהליך הבא:
לאחר מכן עברתי להסתכל על הפונקציה parseשל האובייקט ConfigXmlParserכדי לראות מאיפה טוענים
את הקונפיגורציה:
ראיתי שבקובץ באמת יש הגדרות שונות כמו השם של האפליקציה והכותרת במסך הבית ,אבל לא מצאתי
שום משתנה שנקרא .launchUrl
אבל מה זה אומר שהנתיב שלנו זה ?index.htmlאיפה נמצא התוכן של האתר אם הנתיב שלנו הוא קובץ
לוקאלי? אז במקרה שלנו ,כל האתר מגיע דחוס ביחד עם ה APK-תחת תיקיית ה Assets-ולא נמצא בכלל על
שרת באינטרנט! לכן ,נוכל לחלץ את קוד המקור של האתר מה APKולהתחיל לעבור על הקוד ולחקור אותו.
אז המחקר שלנו קיבל תפנית קצת שונה וממחקר אפליקציות עברנו למחקר אתרים ,אבל מחקר זה מחקר
ואנחנו מסוגלים להכל .הדבר הראשון שנרצה לחפש בקוד של האתר כמו בקוד של אפליקציה זה את
התקשורת מול השרת ואת ה API-שבו הלקוח משתמש כדי לבצע בקשות שונות .לצורך החלק הזה אני
רוצה להציג עוד כלי חביב נוסף שיכול לעזור לנו מאוד עם הסיטואציה.
בקהילת חוקרי התקשורת יש איזשהו קונצנזוס לגבי כלי שחלקכם יכירו טוב שנקרא ,BurpSuiteובצדק .זה
אחד הכלים הכי טובים להסנפות תעבורה ולמחקר APIואפשר לכתוב עליו מאמר שלם ,אבל היום אני רוצה
לתמוך בעסקים הקטנים ולהציג כלי חדש ופחות מוכר שהתגלה כאחד הכלים הכי טובים שיצא לי להשתמש
בהם .בגדול HTTP Toolkitזה כלי דומה מאוד ל BurpSuite-שמכיל יכולות דומות ובעצם משמש לנו כמעין
Proxyבין הטלפון שלנו לשרת שתופס את כל הבקשות שעוברות.
הכלי מציג לנו את הבקשות בצורה נוחה ונותן לנו לבצע כל מיני פעולות שונות .החלק המדהים בHTTP-
Toolkitהוא קודם כל קלות התפעול וההתקנה שלו על המכשירים ,והתצוגה הברורה מאוד שהוא מספק
למשתמש ,מה שמראה שבאופן כללי שהדגש העיקרי של המפתחים היה הנוחות של המשתמש.
BurpSuiteהוא כלי מטורף עם יכולות בלתי נגמרות ,אבל בשביל לשים Proxyעל מכשיר דרכו נצטרך לעבור
ב 5-מדריכים שונים באינטרנט וגם אחרי שנצליח התצוגה שלו תהיה לא ברורה בכלל לאנשים שמשתמשים
בו בפעם הראשונה.
אז בואו נתחיל ונראה מה נוכל לתפוס בתעבורה של האפליקציה הפעם .נרים Proxyעל המכשיר בעזרת
הכפתור הפשוט הבא:
בתוך שניות נראה את הקסם קורה ודברים יקרו מעצמם על מסך הטלפון שלנו .מה שבעצם קורה ברקע זה
שהתוכנה מריצה פקודות על המכשיר בעזרת ADBומקנפגת לנו שני -Certificateים שהיא יצרה.
Certificateאחד היא מתקינה בהרשאות Userלמקרה שהמכשיר שלנו ללא ,Rootו Certificateאחד היא
מתקינה בהרשאות Systemבמקרה שהמכשיר שלנו הוא Rootedאו Emulatorשמגיע עם הרשאות
גבוהות .ה-Certificate-ים האלו נועדו כדי שנוכל לקלף את שכבת ההצפנה בפרוטוקל HTTPSכדי לראות
ממש את התוכן שנשלח בתוך הפקטות .יש אפליקציות שיזרמו עם כל User Certificateשניתן להם ,אבל
יש אפליקציות שיקשו עלינו את החיים ולכן נצטרך להתקין System Certificateשיקבל את כל התעבורה של
המכשיר.
החלק המהפכני פה הוא שאת כל התהליך הזה היינו צריכים לעשות בצורה ידנית אם היינו משתמשים ב-
BurpSuiteוכאן הכל קורה לבד .עכשיו תוכנת ה HTTP Toolkit-שלנו שמותקנת במחשב תעבור גם היא
בצורה אוטומטית לעמוד חדש שבו נוכל לראות בצורה יפה את כל הבקשות שנשלחות מהמכשיר ,כולל ה-
,Methodהסטטוס ,ה ,Source-ה Host-שאליו שולחים ,והנתיב שאותו אנחנו מחפשים:
אחרי חיפוש קצר גיליתי שהדומיין מופיע פעם אחת בקוד במחלקה הזו:
ה Url-של הבקשה הוא הדומיין שראינו בהסנפה (ועוד urlשנשאר בהערה מפיתוח בסביבה לוקאלית ב-
.)localhost:4000בבקשה מוגדרים גם ה-Header-ים שביניהם שני -Headerים שאחראים על הגדרות ה-
יש במחלקה עוד כמה עשרות Endpointsשונים שכל אחד מהם מקבל פרמטרים קצת שונים ומחזיר
תשובות בהתאם.אז החלטתי לנסות לשחזר בקשה בעצמי ב Postman-ולראות איזה שדות השרת דורש
כדי להחזיר לי את המידע הרצוי .בחרתי להתחיל עם פיצ'ר שקיים באפליקציה שמאפשר לקבל מידע על
העובדים בחנות ולראות דירוג שלהם עם תגובות של משתמשים:
התחלתי מלשלוח בקשה פשוטה ל Endpoint-הרלוונטי בלי להוסיף שום -headerים של האפליקציה
ובתשובה השרת החזיר לי רשימות ריקות שזה הגיוני בהתחשב בעובדה שהוא לא יודע מאיזה אפליקציה
הבקשה.
המסקנה המתבקשת מכל המידע שאספנו עד עכשיו הוא שאם הדבר היחיד שנשלח בבקשה זה header
בשם uniqeabcכנראה שזה מה שמאמת אותנו מול השרת ואומר לו איזה מידע להחזיר לנו ומה אנחנו
מורשים לראות .במילים אחרות ה header-הזה הוא בעצם ה token-שלנו לתקשורת מול השרת ,זה הגיוני
גם בהתחשב בעובדה שיש מסך הרשמה באפליקציה ואת כל הפעולות אפשר לעשות רק אחרי
שנרשמיםומתאמתים עם מספר טלפון וסמס.
אז מה החלק המעניין פה? שכל זה בכלל לא נכון .בעצם אני משקר ,רק חלק מזה לא נכון ,ה token-הזה
באמת אומר לשרת מאיזו אפליקציה אנחנו שולחים את הבקשה ,אבל אין בו שום מידע לגבי הלקוח ששולח
את הבקשה!
ה header-הזה קבוע לכל הלקוחות של האפליקציה והוא מכיל את השם של הספר ב !plain text-גם שאר
השדות כמו appIdו appSecret-קבועים ומכילים מידע בנאלי ,ולכן כל אחד יכול לשלוח את הבקשה הזאת.
אבל רגע ,כמו שאתם זוכרים מההקדמה שעשינו ,לכל אפליקציה יש שני לקוחות ,גם הלקוחות בעסק
שמזמינים תורים ,אבל גם ...בעל העסק! אם אין שום דבר שמאמת את המשתמשים בבקשות לשרת,
כנראה שאנחנו יכולים לשלוח בקשות גם בתור בעל העסק ואנחנו רק צריכים למצוא את ה API-הרלוונטי.
אבל זה לא הסוף ,כמו שאנחנו יכולים לראות את רשימת התורים ,אנחנו יכולים לעשות עוד הרבה דברים.
אנחנו יכולים לבטל תורים ,אנחנו יכולים לאשר תורים בשם אחרים ,אנחנו יכולים להזיז תורים של אנשים,
אנחנו יכולים להוסיף ולהוריד משתמשים מרשימת ההמתנה ובגדול לעשות את כל מה שבעל העסק יכול
לעשות .רוצים תור דחוף לספר והכל תפוס? אתם כבר יודעים מה לעשות...
אז אומנם המספרה החביבה שלנו בבאר שבע היא לא מוקד עליה לרגל ואין בה הרבה תורים ,אבל זוכרים
את Snir&Meirמהמערכה הראשונה? אלה שמספרים את כל הסלבס והכדורגלנים? נשלח בקשה עם
נקווה שההגנה של הנבחרת במשחקים הקרובים תהיה יותר טובה מההגנה על ה API-של השרת הזה...
רוצים לקבל את כל ההודעות מהשיחה הזו? מספיק להוסיף את ה id-של המשתמש וקיבלנו הכל .אבל איך
נשיג את ה id-הזה? בקלות ,זוכרים את ה API-לקבלת מידע על העובדים ותגובות /דירוגים שהשאירו
עליהם משתמשים אחרים? אז יש שם עוד דבר אחד מעניין:
זה הזמן גם להדגיש שהחולשות הללו דווחו למערך הסייבר הלאומי ששוב עזר מאוד בטיפול הבעיה ויצר
קשר עם החברה שהספיקה מאז להוריד את המידע הפרטי על המשתמשים בכל ה Endpointsהשונים,
ולחסום את האפשרות לבצע פעולות מול משתמשים תמימים.
אני אשמח שמי שהחזיק מעמד עד כאן יצא מכאן עם כמה מסקנות:
.1תחקרו כמה שיותר ,אבל למטרות טובות -זה כיף ,זה מלמד ,וזה עוזר לשמור על האפליקציות שלנו
בטוחות יותר.
.0אפשר למצוא דברים משמעותיים גם במקומות ה"ברורים מאליהם" שלכאורה אין סיכוי שנמצא בהם
משהו משמעותי.
.3שוב ,אל תניחו הנחות יסוד .אל תיפסלו כיוונים ואל תשללו דברים שאתם חושבים שבטוח מישהו אחר
כבר חשב עליהם.
.4תאמינו בעצמכם ,הכל פתיר
בזאת אנחנו סוגרים את הגליון ה 146-של ,Digital Whisperאנו מאוד מקווים כי נהנתם מהגליון והכי
חשוב :למדתם ממנו .כמו בגליונות הקודמים ,גם הפעם הושקעו הרבה מחשבה ,יצירתיות ,עבודה קשה
ושעות שינה רבות כדי להביא לכם את הגליון.
ניתן לשלוח כתבות וכל פניה אחרת דרך עמוד "צור קשר" באתר שלנו ,או לשלוח אותן לדואר האלקטרוני
שלנו ,בכתובת .editor@digitalwhisper.co.il
על מנת לקרוא גליונות נוספים ,ליצור עימנו קשר ולהצטרף לקהילה שלנו ,אנא בקרו באתר המגזין:
www.DigitalWhisper.co.il
""T4lk1n' 80ut a r3vo7u710n 5ounds like a wh15p3r
אפיק קסטיאל,
31.12.2022
דברי סיכום
www.DigitalWhisper.co.il
113 גליון ,146ינואר 2023