Sergei ShevchenkoThreatResearchManager
NeverBeforeHadStierlitzBeenSoCloseToFailure
macOSThreatReports
PotentiallyUnwantedApplications(PUA):94%ofallinfections
Malware:6%ofallinfections
macOSPotentialThreatExposureRatePercentageofusersacrossourmacOSCustomerBasethatwereattackedwithmalwareorPUA.100%ofattacksweredetectedandblocked.
1.06%werepreventedfrombeinginfectedwithmacOSmalware
16.04%werepreventedfrombeinginfectedwithmacOSPUA
macOSCurrentThreatMap
macOSTopMalwareThreats
vSearch(82.4%)
Keygen(5.8%)
FkCodec(5.2%)
Spynion(2.3%)Other(4.3%)
macOSTopPUAThreats
MacKeeper(32.8%)
Genieo(25.4%)
AdvancedMacCleaner(11.1%)
InstallCore(6.4%)
Bundlore(5.9%)
AdvancedMacCleanerDownloader(5.2%)
CoinHiveJavaScriptCryptocoinMiner(4.5%)
PsExec(3.1%)
Mughthesec(2.8%)
InstallCoreInstaller(2.8%)
InstallerisbundledwithvariousformsofPUAForthedeveloperswhowanttomonetizetheirwork
MainExecutable:randomname/signer
• fatherless• senectitude• sphenobasilic• tryhouse• entailment• coconsecrator• …
Filenameexamples:
Various/randomsigners
MainExecutable:Entropy
DisassemblingMainExecutable
__text:000000010000115004startdb4__text:00000001000011514Adb4Ah;J__text:00000001000011523Edb3Eh;>
Mach-Obinary,reliesonObjective-Cruntimelibobjc.dylib.
EPstartswith‘garbage’,novalidcodetoexecute:
Howisitexecutedwithoutcrashing?
Non-lazy('eager')andlazy('on-demand')implementationofObjective-Cclasses:• Non-lazyclassesarerealisedwhentheprogramstartsup.Theseclasseswillalwaysimplement
+loadmethod• Lazyclasses(classeswithout+loadmethod)donothavetoberealisedimmediately,butonly
whentheyreceiveamessageforthefirsttime
Objective-CRuntimerealizesnon-lazyclassesobjc-runtime-new.mm
//Realizenon-lazyclasses(for+loadmethodsandstaticinstances)for(EACH_HEADER){classref_t*classlist=_getObjc2NonlazyClassList(hi,&count);for(i=0;i<count;i++){realizeClass(remapClass(classlist[i]));}}
objc-file.mm
_getObjc2NonlazyClassList()collectsnon-lazyclassesfromthe__objc_nlclslistdatasection
//functionname|contenttype|sectionnameGETSECT(_getObjc2NonlazyClassList,classref_t,"__objc_nlclslist");
__objc_nlclslist:0001000692C8__objc_nlclslistsegmentparapublic'DATA'use64__objc_nlclslist:0001000692C8dqoffset_OBJC_CLASS_$_ListedUpaithric__objc_nlclslist:0001000692D0dqoffset_OBJC_CLASS_$___ARCLite____objc_nlclslist:0001000692D0__objc_nlclslistends
Jumpinginto__objc_nlclslistsegment
v
+[ListedUpaithricload]moval,'c'mov[rbx+8],almovbyteptr[rbx+2],'_'movbyteptr[rbx+5],'o'movbyteptr[rbx+0Ah],0movbyteptr[rbx+4],'r'movr13b,'m'mov[rbx+1],r13bmoval,'t'mov[rbx+6],almovbyteptr[rbx],'v'moval,[rbx+6]mov[rbx+9],almoval,'e'mov[rbx+7],almovbyteptr[rbx+3],'p'movrdi,0FFFFFFFFFFFFFFFFh;handlemovrsi,rbx;symbolcall_dlsym;vm_protect()
rbx
1 2 3 4 5 6 7 8 9 A0
c_ 0orm t tep
vm_protect(mach_task_self(),//owntask(char*)&anchor–2976,//0x100001150–>startofthe__textsection14322,//sizeoftheentire__textsection0,//maximumprotection=FALSEVM_PROT_ALL)//assignread,write,andexecuteaccessrights
0x100001150
14,322bytes
anchor
2,976__text:000100001CF023anchordb23h;#__text:000100001CF12Bdb2Bh;#__text:000100001CF20Edb0Eh__text:000100001CF30Edb0Eh
0x100001CF0
__textsectionnJvgccZUbkJMUaoapqPGcgEjPyGay6xx
Decryptwith32-byteXORkey:
Decrypting__textcodesection
Decrypting__textcodesection
__text:000100001CF0anchordb'MaximMaximovichIsayev',0
__text:000100001CF0anchordb23h;#__text:000100001CF1db2Bh;+__text:000100001CF2db0Eh__text:000100001CF3db0Eh
Anchorwithinencryptedsection:
Anchorwithindecryptedsection:
__text:000100001150publicstart__text:000100001150startprocnear__text:000100001150push0__text:000100001152movrbp,rsp__text:000100001155andrsp,0FFFFFFFFFFFFFFF0h__text:000100001159movrdi,[rbp+8]
Decryptedcodesection:
Decrypted__textcodesection
?
HiddenMarker
MaximMaximovichIsayev(МаксимМаксимовичИсаев)isarealnameofMaxOttovonStierlitz,theleadcharacterinapopularRussianbookserieswritteninthe1960s.ASovietJamesBond,StierlitztakesakeyroleinSSReichMainSecurityOfficeinBerlinduringWorldWarII.
WorkingasadeepundercoveragentwithinSS,hedivertstheGermannuclear"VengeanceWeapon"researchprogramintoafruitlessdead-end.
NeverBeforeHadStierlitzBeenSoCloseToFailure
String/APIEncryption
Allthestringdecodingfunctionsusedifferentkeys,buttheyimplementoneofthefollowing3algorithms:
• simpleXORkey• simplekeysubtraction• auto-incrementedXORkey
1,228encodedstrings,decodedwith1,055differentfunctions
chardecrypt(charch,intindex){returnch^(index+0x13);}
*(OWORD*)buf=xmmword_100065BE0;*(WORD*)(buf+16)=0x244D;buf[0]=decrypt(0x5D,0);index=1;do{buf[index]=decrypt(buf[index],index);++index;}while(index!=17);
__const:0000000100065BE0xmmword_100065BE0xmmword'K@mqqthzyptgfTG]'
00007FFEEFBFFBE04E534170706C69636174696F6E4D6169NSApplicationMai00007FFEEFBFFBF06E2400000E0000000000000000000000n$..............
get_6procnearpushrbpmovrbp,rspmoval,3;al=3shlal,2;al=12movsxecx,al;ecx=12moveax,65;eax=65xoredx,edx;edx=0idivecx;65/12,eax=5mulcl;eax=60movcl,65;cl=65subcl,al;cl=65-60=5inccl;cl=6movsxeax,cl;result=6poprbpretnget_6endp
NewStringObfuscationfromApril2019
signed__int64get_6(){return6;}
Eachintnumberisencodedwithaseparatefunction,e.g.number6isencodedas:
Hex-RaysDecompiler’soutput:
(lldb)imagelist…[222]FABB97BC-...
DynamicModuleLoadingEncrypteddatastub(>300KB)storedinaseparatesectionoftheexecutable.
Dataisread,validated(CRC32),decryptedanddecompressedwithuncompress()APIfromtheloadedlibz.1.dylib.Theuncompresseddata(>800KB)isdataisloadedfrommemoryasapluginmodulewiththehelpofNSCreateObjectFileImageFromMemory()andNSLinkModule()APIs.
[223]C5F8F084-D151-3D02-9058-905A19117A900x0000000101a00000image(0x0000000101a00000)…[265]B16080FC…
(lldb)memread0x0000000101a000000x101a00000:cffaedfe070000010300000008000000????............0x101a00010:1e000000581200008580010000000000....X...........
->0x100001ac6<+1020>:callq*%r13 R13->pointertoNSLinkModule()
DecompressedPlugin(Engine)
TheEngineTheloadedmodulerepresentsitselfanenginedrivenbytheJavaScriptfiles.
Non-lazyClass+loadmethod
Encrypted__textsection•EntryPoint
CompressedBLOB
EncryptedSDK
Dynamiclinkercalls+loadmethodofObjective-CclassbeforeEntryPoint
Decrypted__textsection•EntryPoint Encrypted
API/stringsSDK
(JavaScript)
DownloadedTasks
(JavaScript)
RemoteServer
ptrace=0x515D5A5D;//encrypted‘ptrace’string:5D5A5D51ptrace_plus_4=0x5752;//5257ptrace_plus_6=0x33;//33ptrace[0]=add_2D_xor(0x5D,0);//decrypt1stchar(5D^(2D+0))i=1;//startloopfromthe2ndchardo{//decrypttherestptrace[i]=add_2D_xor(ptrace[i],i);//ptrace[i]^=2D+ii++;}while(i!=6);//6charsfromthe2ndchar,incl/0fn_ptrace=dlsym(RTLD_NEXT,&ptrace);//getprocaddrfromthelinkeddylibsreturnfn_ptrace(PT_DENY_ATTACH,0,0,0);//callptrace()bypointer,denytracing
Anti-DebuggingTheanti-debuggingdefenceisprovidedwithptrace()requestnamedPT_DENY_ATTACH(0x1F),calledfrom:
Iftheprocessisbeingdebugged,itwillexitwiththeexitstatusofENOTSUP(45),‘error,notsupported’.Otherwise,itsetsaflagthatdeniesfuturetraces–anattempttodebugitwiththisflagsetwillresultinasegmentationviolationexception.
Anti-Debuggingmac:/user$sudolldb/Users/user/Installer/Installer.app(lldb)targetcreate"/Users/user/Installer/Installer.app"Currentexecutablesetto'/Users/user/Installer/Installer.app'(x86_64).(lldb)rProcess1280launched:'/Users/user/Installer/Installer.app/Contents/MacOS/radiosurgical'(x86_64)Process1280exitedwithstatus=45(0x0000002d)
->0x103dd1ff5<+25>:callq0x103e30cd3;callthefunctionwithptrace()0x103dd1ffa<+30>:callq0x103de03aa;ICCrashLogger::sharedLogger()0x103dd1fff<+35>:movq%rax,%rdi(lldb)rewpc`$pc+5`;stepoverdeny_attach()byadding5bytesto$pc(lldb)x/2i$pc;now$pc(pseudo-nameforRIP)pointstonextinstr->0x103dd1ffa:e8abe30000callq0x103de03aa;ICCrashLogger::sharedLogger()0x103dd1fff:4889c7movq%rax,%rdi
Bysteppingoverthedeny_attach()call(orNOP-ingthe5bytesofthecall),theanti-debuggingtrickabovecanbeeasilycircumvented:
VMDetectionTheengineisabletodetectthepresenceofVMthroughthemethodcheckPossibleFraud().ThismethodisexposedtoJavaScript,whereitcanbecalledas:
varisVm=system.checkPossibleFraud()>0?1:0;
Theenginecompilessocalled'fraud'reportthatconsistsofthefollowingdetails:
vmVendor CheckiftheMACaddressstartsfromanaddressthatiscommonforagivenVMmanufacturer.Forexample,“00:1C:42*”isforParallelsVM.Recognisesover35VMsbyknownMACprefixes:
• ParallelsID.• Egenera,Inc.• FirstVirtualCorporation• linuxkernalvirtualmachine(kvm)• VirtualIronSoftware,Inc.(was:KatanaTechnology)• ParavirtualCorporation(was:Accenia,Inc.)• VirtualConexions• VirtualComputerInc.• virtualaccess,ltd.• VirtualInstruments
• Virtualtek.Co.Ltd• VMware,Inc.• MicrosoftCorporation(was:Connectix)• MicrosoftCorp.• MicrosoftNetworkLoadBalancingServiceHeartbeat• MicrosoftXCG• OracleCorporation(was:VirtualIronSoftware)• OracleCorporation(was:XsigoSystems,Inc.)• OracleCorporation(was:SunMicrosystems,Inc)• CADMUSCOMPUTERSYSTEMS
HostUUID
VMDetection
hddName DADiskCreateFromBSDName()for'/dev/disk0'device
usbFraud ioreg-l|grep-e'USBVendorName'
dispRats
lastMove
lastRbt
dmgLoc
fromDMG
wndPos
msePos
gethostuuid()
MAC_L MACandIPaddressesforallnetworkinterfaces
displayratio
mousepositionsincethelastmousemovementevent
systemup-time,sincelastreboot
fullpathfilenameoftheDMGfile,incaseit'sexecutedbyasandboxunderagenericname,i.e.afilehash
positionandsizeoftheapp’swindow
mouseposition,toseeifmouseisinuse
torecognisefingerprintsofthecommonsandboxes
CrashLogs
ThecrashloggersendsGETrequesttoaremotescript,disguisedasaPNGfile:
ThestatsitsubmitstotheremotescriptareencodedasURLparameters:
• crash=1• os=mac• appkit=%APP_KIT%• ver=%VERSION%• ldebug=%LIVE_DEBUG%• backtrace=%CALL_BACKTRACE%
http[://][removed].us-west-2.compute.amazonaws[.]com/black.png
ConfigFiles:1/2Theinstalleruses2configurationfiles.
Thefirstoneisdynamicallyextractedfromitsownbody.
ThisconfigurationisencryptedwithAES-128algorithm.Tolocatetheencryptedconfig,theinstallermoduleparsesthecontentsofthefile.
Foreachpairofbytes,itsubtractsonebytefromanother,untiliflocatesaspecificsignaturethatconsistsof764-bitintegers.
DecryptedconfigspecifiestheURLofanapplicationtodownloadandinstall:
PRODUCT_TITLE=[removed]PRODUCT_DESCRIPTION=[removed]DOWNLOAD_URL=http%3A%2F%2F[removed]-Installer.dmgPRODUCT_LOGO_URL=http%3A%2F%2F[removed].pngROOT_IF_INSTALLED=[removed]
if(ptr!=(_BYTE*)&FEEDFACF+1){found=0LL;do{prev=ptr[(_QWORD)index-2];curr=ptr[(_QWORD)index-1]-prev;if(curr<0)curr=ptr[(_QWORD)index-1]-prev+256;if(curr==signature[found]){if(++found==7)gotofound_inj;}else{found=0LL;}--ptr;}while(ptr!=(_BYTE*)&FEEDFACF+1);}ptr=(_BYTE*)(&FEEDFACF+1);
ConfigFiles:1/2
HEADER:0000000000000000FEEDFACFdd0FEEDFACFh
__const:00000000000B7430signaturedq0Fh,9,3Eh,23h,7,86h,0Ch,0
ConfigFiles:2/2The2ndconfigurationfileisprovidedasaJavaScriptfile,andisdecryptedwiththeotherSDKfilesfromtheapp’sResourcesdirectory.Thisconfigurationdefinesmultipleoperationalparameters,suchasreportandadservers:
varappInfo={report:'http://rp.[removed].com',ad_url:'http://os.[removed].com/[removed]',requires_root:false,root_if_installed:[''],skip_vm_check:false,...
ReportServerThereportserverfromtheconfigurationisusedtoreceivepostedreports.
Forexample,anexamplebelowdemonstrateswhatdataispostedtothereportserver:
PROD_TITLE=[REMOVED]schemeName=MacDarwenDLMOSName=OSXOSVer=10.12OSLang=en_makeDate=201811091722BRW=SafariOSPlat=2MAC_L=[REMOVED]000000000000%3A127.0.0.1%3A24%3A0hddSize=107374182400_makerver=total20181107115116Isuseradmin=1isVmDef=1inst_flv=no_injection_106.1712QuitPage=welcomePage
Thecollecteddataisassembledintoatext,thenencryptedwithAES-128,andpostedtotheserver
RemoteTasks
POSThttp://[removed].com/[removed]USER-AGENT:ICMACResponse:Header:X-ICSCT-SERVER-NAME:[removed]Data:85,368bytesbinary[6cec6c99...]
Remotetasksarereceivedencryptedfromtheadserver:
varnamestartstr='<!--SECTIONNAME="';varnameendstr='"-->';varsectionendstr='<!--/SECTION-->';
Whenthereceivedtaskisdecrypted,itsdataissplitintonamedsections.Eachsectionissurroundedwiththefollowingcomments:
TheparserextractsJavaScriptcodefromthosesections.ThatcodewillthenrelyonAPIsexposedbytheSDK,todrivetheenginethatexposesitsownAPIinterfacetotheSDK.
Ananalysisofthetasksreceivedfromtheadserverrevealsnomaliciousactivity.
EngineCapabilitiesThebundleware’sengineconsistsoftheseveralcomponents,capableofdoingthefollowing:
• Browsermanagero terminatebrowserprocesso setnewhomepage
• Screenshotcontrollero takefullscreensnapshotwiththemouselocation
• Taskmanagero downloadandexecutenewtaskso createauthorizationfortasks,usinggivencreds
• Systemcontrollero collectsystemOSversiono collectallcookiesfrombrowserso collectthelistofallinstalled/runningapplicationso checkthepresenceofVMo add/removeapplicationsto/fromdocko getinfoaboutconnectediOSdevices:
deviceclass,ID,serialnumber(iPod/iPad/iPhone)
o searchforfilesinthespecifieddirectoryo terminatespecifiedapplicationso readkeyvaluesfromuserdefaultso addanapptodockaspersistentitemo readtextfileso copygivendirectorytoanewlocationo deletethespecifieddirectoryo runspecifiedscriptwith'/bin/sh',asrooto getdetailedHDDinformationo collectnetworkinformationo downloadfileso displayalertso launchtasks/applicationsasrooto copy/movefileso savedatatofileso create/deletedirectories
Conclusions
• Apopularbundlewareproductconcealsaverypowerfulengine
• Theengineresemblesabackdoorasitunlocksfullaccesstothesystem
• Memoryinjectionisdescribedinthe“TheMacHacker'sHandbook”
• Theengineisdrivenbysymmetricallyencryptedremotetasks
• Adisturbingtrendwe’rewitnessing–thecontinued‘spill’ofthetraditionalWindowsmalicioustechniques,suchasrun-timepacking,strings/APIobfuscation,memoryinjectionintotheworldofMac