RED
50 points
Author: Shuailin Pan (LeConjuror)
Description
RED, RED, RED, RED
Download the image: red.png [link expunged]
Write-up
This is an introductory steganography challenge. The flag is hidden inside the image, somehow.
Typical hiding places include inside the metadata tags, but in this case is least-significant bit steganography.
Taking advantage of what digital images are, people can encode messages inside images by changing the least-significant bits (remember that each character has an equivalent value in hex; see an ASCII table). This encodes information without causing visual disruption (i.e. garbage pixels)
Try playing with this tool by comparing two identical colors, and then change the last bit with values from 0 to F. Notice how the changes are extremely subtle... In a complete image, it wouldn't be perceptible at all.
Download the image and simply run zsteg.
$ zsteg red.png
The output contains the flag, encoded in base64.
meta Poem .. text: "Crimson heart, vibrant and bold,\nHearts flutter at your sight.\nEvenings glow softly red,\nCherries burst with sweet life.\nKisses linger with your warmth.\nLove deep as merlot.\nScarlet leaves falling softly,\nBold in every stroke."
b1,rgba,lsb,xy .. text: "cGljb0NURntyM2RfMXNfdGgzX3VsdDFtNHQzX2N1cjNfZjByXzU0ZG4zNTVffQ==cGljb0NURntyM2RfMXNfdGgzX3VsdDFtNHQzX2N1cjNfZjByXzU0ZG4zNTVffQ==cGljb0NURntyM2RfMXNfdGgzX3VsdDFtNHQzX2N1cjNfZjByXzU0ZG4zNTVffQ==cGljb0NURntyM2RfMXNfdGgzX3VsdDFtNHQzX2N1cjNfZjByXzU0ZG4zNTVffQ=="
The poem, by the way, is hidden in the metadata. We could've uncovered it with exiftools, but alas that's not the flag. Note how zsteg notes the base64 string is hidden in the least significant bits (lsb).
Decode it with CyberChef and get your flag. This time around, it doesn't seem to have the usual 8 character hash...
picoCTF{r3d_1s_th3_ult1m4t3_cur3_f0r_54dn355_}
Ph4nt0m 1ntrud3r
50 points
Author: Prince Niyonshuti N.
Description
A digital ghost has breached my defenses, and my sensitive data has been stolen! 😱💻 Your mission is to uncover how this phantom intruder infiltrated my system and retrieve the hidden flag.
To solve this challenge, you'll need to analyze the provided PCAP file and track down the attack method. The attacker has cleverly concealed his moves in well timely manner. Dive into the network traffic, apply the right filters and show off your forensic prowess and unmask the digital intruder!
Find the PCAP file here [link expunged] and try to get the flag.
Write-up
This time we're given a PCAP (Packet Capture) file, which we must investigate to find the flag.
I will assume you have some basic familiarity with Wireshark (for this challenge, that practically only implies "can launch the program").
However, before doing that, let's run the strings command against the PCAP file. It kinda goes against the spirit of the exercise, but maybe the flag is in plain sight.
$ strings myNetworkTraffic.pcap
ezF0X3c0cw==
cGljb0NURg==
bnRfdGg0dA==
Yt8ksMM=
3psv5C4=
YQEFzIU=
YmhfNHJfOQ==
a23/UbI=
TOGSGg4=
bpzQ0R8=
fQ==
nfu4Vww=
J4auZMY=
ePRXDio=
fjIzQwk=
XThGxuE=
ckBkZLk=
CJr4oDk=
BgJLB0c=
XzM0c3lfdA==
NTlmNTBkMw==
dgV9v0s=
At least looking at the output, it sure looks like base64. Dumping this into CyberChef reveals that among the base64-encoded gibberish are chunks of the flag. While we could try to reconstruct it, perhaps it's better to investigate with Wireshark.
After opening the packet capture, I noticed a few things:
- This is a very tiny file. appropriate for this beginner's challenge, but I did a double-take at first!
- All the connections are TCP; most of them (suspected) retransmissions.
- Most have negative time. I don't quite understand the significance even after some research (something about delta time?), but it does hint that something is afoot, and that the default ordering by Wireshark is not necessarily correct or useful to us.
If you sort the packets by time it becomes clear that most of the packets have a content length of 8 (Len=8); the gibberish base64-encoded strings we uncovered earlier are all 8 characters long.
The ones with a length of 12 (Len=12) correspond to the flag chunks, as seen in the payload pane; and the sole packet with a length of 4 is a single character in base64 (the closing curly bracket).
Join together these base64-encoded chunks and you get the flag.
picoCTF{1t_w4snt_th4y_34sy_tbh_4r_XXXXXXXX}
Bitlocker-1
200 points
Author: Venax
This problem cannot be solved in the webshell.
Description
Jacky is not very knowledgable about the best security passwords and used a simple password to encrypt their BitLocker drive. See if you can break through the encryption! Download the disk image here [link expunged]
Write-up
Players are given a disk image of a Bitlocker-encrypted disk (bitlocker-1.dd)
This challenge requires of quite a few steps to solve. With Bitlocker encryption it's impossible to do most of anything from the get-go; we must use specialized tools for the task.
Note that I use Kali Linux, so my instructions are geared towards that (or similar Linux systems).
After downloading our bitlocker-1.dd image, we must get the password hashes for this encrypted drive with John The Ripper's bitlocker2john
bitlocker2john -i bitlocker-1.dd > bitlocker-1-hash.txt
Feel free to look at the file to check it's correct. You should have hashes starting with $bitlocker$. You may name your .txt file anything you want, of course.
Now we must use these hashes paired with our RockYou password list.
hashcat --hash-type 22100 --attack-mode 0 bitlocker-1-hash.txt /usr/share/wordlists/rockyou.txt
22100 is Bitlocker; attack mode 0 is a dictionary attack; first we provide the file with the hashes we want to check against the wordlist we want to use.
Check the docs for other ways to use it.
Run the program and wait for it to finish; feel free to read the outputs as it goes.
I did not have any issues and it did not take very long on a not-very-good laptop, though obviously more advanced and sophisticated uses of hashcat will really benefit (if not actually need) much better hardware.
The final output might be a bit unintuitive (it was for me, at any rate).
It outputs the hash that had a match, like so:
$bitlocker$[very long hash]:[cracked password]
In this case, the password was jacqueline. (Jacky...)
And below that line is information on the cracking process, such as time started and ended (mine took 27 seconds) among other things. Don't get confused by the "Candidates" row.
Now, we have a password. But what do we do? We can't mmls the file, or even mount it ('unknown filesystem type Bitlocker')... This is where dislocker comes in.
First, make the folders where we'll mount things. The way dislocker works is that it decrypts the Bitlocker disk image at a specified mountpoint, where it drops dislocker-file. This is a flat file that can be mounted as a NTFS partition. You cannot just open or browse dislocker-file; you must mount it elsewhere.
$ sudo mkdir /media/bitlockermnt
$ sudo mkdir /media/bitlockerdecrypt
These are the names I used; use the ones you please.
I struggled quite a bit using dislocker -- the program itself is not too difficult, but you may run into issues regarding file and mounting permissions (as I did for an embarrassingly long time). So, as recommended in a dislocker issue, do this:
$ sudo su -
Now you're root. Be careful! Now do:
# dislocker -ujacqueline /home/kali/Downloads/bitlocker-1.dd /media/bitlockerdecrypt
Obviously replacing my filepaths with your own. As previously explained, this will place a file called dislocker-file in /media/bitlockerdecrypt
And finally, do:
# mount -o loop,ro /media/bitlockerdecrypt/dislocker-file /media/bitlockermnt
(if you don't specify -o loop,ro it will complain about unclean filesystems and will try to open it as read-only. Might as well skip that, no?)
And it's mounted. At least in my case, it doesn't appear mounted in the file manager (unlike bitlockerdecrypt), so you must go to /media/bitlockermnt manually (preferably from the CLI).
# ls /media/bitlockermnt
'$RECYCLE.BIN' flag.txt 'System Volume Information'
Read the file in the way you prefer, and you'll get your flag.
# cat /media/bitlockermnt/flag.txt
picoCTF{us3_b3tt3r_p4ssw0rd5_pl5!_XXXXXXXX}
Unmount the folders we used, and don't forget to exit root.
Event-Viewing
200 points
Author: Venax
Description
One of the employees at your company has their computer infected by malware! Turns out every time they try to switch on the computer, it shuts down right after they log in. The story given by the employee is as follows:
- They installed software using an installer they downloaded online
- They ran the installed software but it seemed to do nothing
Now every time they bootup and login to their computer, a black command prompt screen quickly opens and closes and their computer shuts down instantly.
See if you can find evidence for the each of these events and retrieve the flag (split into 3 pieces) from the correct logs! Download the Windows Log file here [link expunged]
Write-up
Players are provided with a Windows XML EventLog (.evxt) file, which they must analyze to find the flag, which has been split into 3 parts and located in events that are evidence of the alleged malware.
$ evtxexport Windows_Logs.evtx > winlog.txt
Used without redirecting, it spits the entire log to the console, which is not at all practical.
Now, ideally, competitors would look for evidence of malware... But I sort of jumped the gun to looking for pieces of the flag. Oops.
$ grep "pico" winlog.txt
This didn't work. Knowing CTF challenges, it might be encoded in some way.
$ grep "==" winlog.txt
This did work, returning two strings. The = is a padding character in base64 encoding, so it's quite common for strings of a certain size to get padded with one or two of these when encoded in base64.
String: 5 : cGljb0NURntFdjNudF92aTN3djNyXw==
String: 6 : Immediate Shutdown (MXNfYV9wcjN0dHlfdXMzZnVsXw==)
Decoding with CyberChef gives us:
picoCTF{Ev3nt_vi3wv3r_1s_a_pr3tty_us3ful_t00l
We're missing the final chunk, which is a hash unique to each competitor (from what I understand). Grepping for "=" is very impractical, as evxt logs are full of those (by virtue of being some form of XML). However, we know the flag always ends with a curly brace, and that the hash is always 8 characters long.
Encoding a dummy string such as ABCDABCD} to base64 in CyberChef shows that the curly bracket becomes 0=
$ grep "0=" winlog.txt
String: 6 : [base64]0=
String: 6 : [base64]0=
And appending this and going back to CyberChef gives us:
picoCTF{Ev3nt_vi3wv3r_1s_a_pr3tty_us3ful_t00l_XXXXXXXX}
Now, what if my idea to look for a base64 encoded string didn't work, or that it was a string that didn't get padded (and thus wouldn't have been revealed by these crude methods)?
Well. We're looking at an event log, and the description of what is going on mentions: installers off the Internet, installer executed but seemingly does nothing, and sudden shutdowns.
Rather than grep, we could've used a text editor and searched for incriminating strings, such as "Shutdown". Just with that one, we'd get our first chunk of the flag, in the Immediate Shutdown string, and also learn the name of the program installed: Totally_Legit_Program
Searching for that name and looking at the associated events, we'd eventually find the other two pieces of the flag.
Maybe there is an even better way, but this is what I thought of at the time.
Bitlocker-2
300 points
Author: Venax
This problem cannot be solved in the webshell.
Description
Jacky has learnt about the importance of strong passwords and made sure to encrypt the BitLocker drive with a very long and complex password. We managed to capture the RAM while this drive was opened however. See if you can break through the encryption! Download the disk image here [link expunged] and the RAM dump here [link expunged]
Write-up
We're given a Bitlocker-encrypted disk image (.dd) once again; we must decrypt it and find the flag. This time around, Jacqueline "Jacky" (allegedly) learned the lesson from Bitlocker-1 and has an (allegedly) much better password.
I found this quite challenging, but unfortunately less because of any merits of its design and more because I (once again) had to wrangle with the tools necessary to complete this challenge for an absurdly long time. Oh, to be a greenhorn is to suffer.
One could manually sift through the RAM dump with a hex viewer, as some people have done (1) (2). I am not bright enough to find the encryption key doing that (I did try, for what is worth).
And as my mother often says about things like household appliances, some engineer busted their head designing these wondrous tools to make our lives easier; it's only fair that we benefit from them, no?
So let's use volatility. It's pretty easy to get the hang of it, at least for basic CTF usage.
I ran these commands from the folder volatility was installed to after following the above guide. I assume you already have everything set up, as noted in the tools section.
$ python2 vol.py -f "/home/kali/Downloads/bitlocker-2/memdump.mem" imageinfo
This will work for a few seconds and eventually give us some information on our image dump, such as when it was dumped, and most importantly for our purposes the recommended profile to use with future operations in volatility.
Volatility Foundation Volatility Framework 2.6.1
INFO : volatility.debug : Determining profile based on KDBG search...
Suggested Profile(s) : Win10x64_19041
AS Layer1 : SkipDuplicatesAMD64PagedMemory (Kernel AS)
AS Layer2 : FileAddressSpace (/home/kali/Downloads/bitlocker-2/memdump.mem)
PAE type : No PAE
DTB : 0x1ad000L
KDBG : 0xf80251217b20L
Number of Processors : 2
Image Type (Service Pack) : 0
KPCR for CPU 0 : 0xfffff8024f52f000L
KPCR for CPU 1 : 0xffffc301a8c67000L
KUSER_SHARED_DATA : 0xfffff78000000000L
Image date and time : 2024-07-15 19:24:38 UTC+0000
Image local date and time : 2024-07-15 12:24:38 -0700
Let's check what FVEKs volatility-bitlocker can find on the system, if any.
$ python2 vol.py -f "/home/kali/Downloads/bitlocker-2/memdump.mem" bitlocker --profile=Win10x64_19041
It finds four candidates. Interestingly enough, one of my crude first attempts at solving involved running the strings command on the memory dump and saving that to a text file for analysis. Looking for "Recovery Key" would lead to four distinct character sequences (either files or registry keys, I'm not sure), but I couldn't find a way to use them effectively with dislocker.
Moving on... Let's dump these candidates.
$ python2 vol.py -f "/home/kali/Downloads/bitlocker-2/memdump.mem" bitlocker --profile=Win10x64_19041 --dislocker /home/kali/Downloads/bitlocker-2
--dislocker is one of the options available in the volatility-bitlocker plugin, and dumps the keys in a format dislocker can use. I chose to dump them into the folder with the memdump.mem and bitlocker-2.dd files, to keep things tidy.
Feel free to check the files are there; you should have 4 66-bytes .fvek files.
Now, it's time to use dislocker, similarly to how we did back in Bitlocker-1. Create your mountpoints:
$ sudo mkdir /media/bitlockermnt
$ sudo mkdir /media/bitlockerdecrypt
These are the names I used; use the ones you please. Now, to avoid any problems with FUSE permissions, do:
$ sudo su -
Now you're root. Be careful! Now, we must use dislocker with the -k flag, pointing to where our .fvek files are. How do we know which one is it?
...I won't reproduce it here, but I just did it one by one. You know you got it right when the mount command works without problems; any sort of error (wrong fs etc.) is sign that the FVEK used did not work, and the resulting dislocker-file is useless.
Perhaps someone with the chops would find a way to automate it. This is the one that works:
# dislocker -k /home/kali/Downloads/bitlocker-2/0x9e8879926a50-Dislocker.fvek /home/kali/Downloads/bitlocker-2/bitlocker-2.dd /media/bitlockerdecrypt
Obviously replacing my filepaths with your own. As explained in Bitlocker-1, this will place a file called dislocker-file in /media/bitlockerdecrypt
And finally, do:
# mount -o loop,ro /media/bitlockerdecrypt/dislocker-file /media/bitlockermnt
As noted previously, if you got any sort of error while mounting then the FVEK file used with dislocker is incorrect and you should try a different one. If you get wrong fs and add -t ntfs-3g to the mount command all that's gonna do is show a different error that hints that the dislocker-file generated by dislocker is bad.
Now that we got a working dislocker-file, we can now explore /media/bitlockermnt
# ls /media/bitlockermnt
'$RECYCLE.BIN' flag.txt 'System Volume Information'
Retrieve the flag as you prefer:
# cat /media/bitlockermnt/flag.txt
picoCTF{B1tl0ck3r_dr1v3_d3crypt3d_XXXXXXXX}
And we're done.