DEF CON DFIR CTF 2018 Write-up Part 1 - HR Server Basic Challenges

6 minute read Published:

A writeup for the 2018 DEF CON DFIR CTF - Part 1
Table of Contents

Introduction

I’m heading to DEF CON in Vegas this year and thinking about participating in the DFIR CTF that runs at the Blue Team Village. As a bit of a warm-up, I thought I’d give last year’s DFIR CTF a crack, which is still available to play online at the time of writing - you can find details for how to sign-up and obtain the images here. Without further ado, here’s a write-up of the challenges that I’ve managed to complete so far, which I’m writing mainly so I can remember the tools and commands for next time…

I used the SANS SIFT Workstation for the challenge tasks. If you're not familiar with it, it's an excellent distribution for doing DFIRy things - check it out at the SANS DFIR website.

HR Server - Basic Challenges

While there are three images to download, they’re all encrypted and only the password for one image is provided initially: the “HR Server”.

The HR Server image is an Expert Witness compresion Format (EWF) file, which I mounted using the following commands (you can find these on the SIFT Workstation cheat sheet):

$ sudo ewfmount HRServer_Disk0.e01 /mnt/ewf
$ mount –o loop,ro,show_sys_files,streams_interface=windows,offset=525336576 /mnt/ewf/ewf1 /mnt/windows_mount

The offset in the mount command above was calculated by multiplying the starting sector of the target partition by 512 (the number of bytes in a sector for this hard drive). The starting sector of the partition (1026048) was recovered with the mmls command:

# mmls /mnt/ewf/ewf1 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0001026047   0001026048   Unallocated
002:  000:000   0001026048   0104857599   0103831552   NTFS / exFAT (0x07)

Acquisition Software Name and Version

The first two questions ask you to recoved the name and version of the acquisition software that was used to obtain the image. You can find this information with the ewfinfo command:

# ewfinfo /home/sansforensics/defcon/HRServer_Disk0.e01
ewfinfo 20140806

Acquiry information
	Description:		HRServer_Disk0
	Examiner name:		Professor Frink
	Acquisition date:	Wed Aug  8 14:32:43 2018
	System date:		Wed Aug  8 14:32:43 2018
	Operating system used:	Win 10 (64 bit)
	Software version used:	XWF 19.6     <-- acquisition software
...

MFT Entry Name

The next question asks you for the file name that represents MFT entry 168043. Note that the answer for this question also required knowledge of the partition’s starting offset (this time expressed in sectors instead of bytes).

# istat -o 1026048 ewf1 168043 
MFT Entry Header Values:
Entry: 168043        Sequence: 1
$LogFile Sequence Number: 195192139
Allocated File
Links: 2

...

$FILE_NAME Attribute Values:
Flags: Archive
Name: pip3.7.exe
Parent MFT Entry: 167052 	Sequence: 1
Allocated Size: 0   	Actual Size: 0
Created:	2018-07-23 13:39:41.412153100 (UTC)
File Modified:	2018-07-23 13:39:41.412153100 (UTC)
MFT Modified:	2018-07-23 13:39:41.412153100 (UTC)
Accessed:	2018-07-23 13:39:41.412153100 (UTC)

MFT Entry Number

Next up, we need to find the MFT entry number for a specific file. Seeing as we’ve mounted the filesystem, we can simply use ls:

# ls -ial /mnt/windows_mount/xampp/mysql/bin/mysql.exe 
115322 -rwxrwxrwx 1 root root 3770280 Mar 26  2018 /mnt/windows_mount/xampp/mysql/bin/mysql.exe

The MFT entry is shown at the beginning of the line - 115322.

MFT Attribute ID

We now need to find the “MFT Attribute ID” of the “named $J” data attribute for the MFT entry with a file name of $UsnJrnl. OK then!

# find -name '$UsnJrnl'
./$Extend/$UsnJrnl
# ls -ial /mnt/windows_mount/\$Extend/\$UsnJrnl 
108606 ---------- 1 root root 0 May  1  2018 /mnt/windows_mount/$Extend/$UsnJrnl
# istat -o 1026048 /mnt/ewf/ewf1 108606
...
Attributes: 
Type: $STANDARD_INFORMATION (16-0)   Name: N/A   Resident   size: 72
Type: $FILE_NAME (48-1)   Name: N/A   Resident   size: 82
Type: $DATA (128-3)   Name: $J   Non-Resident, Sparse   size: 368717664  init_size: 368717664
...

In the brackets for the $J data attribute above, 3 is the attribute ID (I think 128 is probably the attribute flags, although I haven’t confirmed this - I was just inferring it from this blog post).

SMB

Things changed up a bit with this question - what IP address attempted an anonymous SMB logon at 2018-08-08 18:10:38.554 (UTC)?

I went to the event logs for the answer here, using Willi Ballenthin’s excellent python-evtx library to parse the logs to XML, then just searched for the timestamp:

# evtx_dump.py /mnt/windows_mount/Windows/System32/winevt/Logs/Microsoft-Windows-SMBServer%4Security.evtx >SMBSecurityEvents.xml
# grep -B7 -A23 "18:10:38.554" SMBSecurityEvents.xml 
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"><System><Provider Name="Microsoft-Windows-SMBServer" Guid="{d48ce617-33a2-4bc3-a5c7-11aa4f29619e}"></Provider>
<EventID Qualifiers="">551</EventID>
<Version>2</Version>
<Level>2</Level>
<Task>551</Task>
<Opcode>0</Opcode>
<Keywords>0x0810000000000008</Keywords>
<TimeCreated SystemTime="2018-08-08 18:10:38.554293"></TimeCreated>
<EventRecordID>4517</EventRecordID>
<Correlation ActivityID="" RelatedActivityID=""></Correlation>
<Execution ProcessID="4" ThreadID="1940"></Execution>
<Channel>Microsoft-Windows-SMBServer/Security</Channel>
<Computer>WIN-29U41M70JCO</Computer>
<Security UserID="S-1-5-18"></Security>
</System>
<UserData><EventData xmlns="Smb2Namespace"><SessionGUID>{00000000-0000-0000-0000-000000000000}</SessionGUID>
<ConnectionGUID>{00000000-0000-0000-0000-000000000000}</ConnectionGUID>
<Status>0xc0000022</Status>
<TranslatedStatus>0xc0000022</TranslatedStatus>
<ClientAddressLength>128</ClientAddressLength>
<ClientAddress>AgAhgVBRbjIAAAAAAAAAAAAA//9QUW4yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</ClientAddress>
<SessionId>0x0000000000000000</SessionId>
<UserNameLength>15</UserNameLength>
<UserName>ANONYMOUS LOGON</UserName>
<ClientNameLength>14</ClientNameLength>
<ClientName>\\80.81.110.50</ClientName>
<SPN>session setup failed before the SPN could be queried</SPN>
<SPNValidationPolicy>0</SPNValidationPolicy>
</EventData>
</UserData>
</Event>

You can see the IP address in the ClientName element above.

Saved Batch File

The next requirement is to supply the name of a batch file saved by the mpowers user. At this point, I thought I’d construct a super timeline with the venerable log2timeline and import it into an ELK stack to assist further analysis.

For my own future reference, these are the commands I used to create the super timeline and export them into Elasticsearch:

# log2timeline.py -f filter timeline.plaso /mnt/ewf/ewf1 
# psort.py -o elastic --server $ELK_IP --port 9200 --raw_fields --index_name hrserver timeline.plaso

I used Mark Hallman’s Windows Plaso filters, which you can find my fork of here.

Once all the data was ingested, I ran a query to search for entries in user registry hives (i.e. ntuser.dat) that contained the string “bat”, as there are several places in the user registry where evidence of recent files gets left lying around. The search revealed the presence of a file called C:\Production\update_app.bat (as shown below), which was the correct answer.

HR Management Application

The next question asks for the name of the HR management applcation that hosts a webserver. While one valid way of solving this question would be simply to inspect the contents of the Program Files folder on the filesystem, there are some clues in the Windows Firewall logs too, as shown below:

OrangeHRM… sounds juicy! (Sorry.)

There’s a follow-up question then, which is to find the public URL for the HR system’s portal. This can be found by diving through the Apache access logs at C:\Program Files\OrangeHRM\4.1\apache\logs\access.log.

...
74.118.139.108 - - [11/Jul/2018:13:25:31 -0700] "GET /symfony/web/webres_5acde3dbd3adc6.90334155/js/jquery/validate/jquery.validate.js HTTP/1.1" 200 39131 "http://74.118.139.108/symfony/web/index.php/auth/login" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
7
...

File Changes

This batch of questions ends on some more disk forensics. Firstly, we’re asksed to name the file that had a change recorded with an update sequence number of 368701440. Plaso had already nicely ingested the USN Journal for me, so I just searched for the number in Kibana and found it straight away:

The final question asked for the deleted file with a “reference number” of 12947848928752043. I was a bit unsure about this one, and ended up consulting another write-up for a nudge.

First thing to do is to convert the number into a hex value, which is 0x2E00000000F1AB. This looks a lot more meaningful and parsable. Next thing I did was to find the specification for what an NTFS “reference number” is. I found the MS docs on the topic to be fairly verbose… being impatient, I looked for something more succinct and came across this link. As per the layout, the FILE record number is 0x00000000F1AB (61867), and the sequence number is 0x002E (46).

This info is once again available from Plaso, which reveals the filename to be _MEI78882, and indeed suggests that the file was deleted:

Phew… that’s it for the “basic” questions on the HR Server. I’ll be back with anoher post if I manage to crack the “Advanced” ones!

MOAR