This past weekend I played in UTCTF 2023 by myself under flocto solo run. Ended up in 11th place, not too shabby 😎
While there were some infra issues, I still had a lot of fun solving these challenges, so I would consider this one a success. Looking forward to next year, unless hxp takes precedence.
Anyway, here’s a megathread containing mini writeups for the challenges I solved. As always, I don’t do pwn, so none of them are here.
TOC
Misc
Starting off with the simplest category.
Dry Run
Points: 20
Join our Discord server and look in the #announcements channel to find the flag. :-)
Just a sanity check chall, nothing to see here.
utflag{welc0me_to_utctf!}
Half-time Survey
Points: 20
Again, nothing to see here, just a survey.
utflag{hack_hack_hack}
Zipper
Points: 964
NOTE: echo ‘Hello world’ is the only “allowed” command. Do not bruteforce other commands.
One of our spies has stolen documentation relating to a new class of missiles. Can you figure out how to hack them?
“We have developed a new protocol to allow reprogramming missiles in flight. We send a base64 encoded string representing a specifically formatted zip file to control these missiles. The missiles themselves verify each command before executing them to ensure that a hacker cannot manipulate them.”
A sample message has also been stolen by our spy.
By Aadhithya (@aadhi0319 on discord)
nc betta.utctf.live 12748
The first real challenge. The original challenge didn’t release with the Python file, so let’s start with the b64 file. Opening it up, we get:
Very clearly this is base64, so let’s decode it.
Opening up command.txt
, we get:
And README.md
:
After I got to this point in the original challenge, I was stuck for a while. I didn’t really see anywhere to progress or check for “approved commands”.
At some point, I moved on and came back when the verify_hash.py
file was released.
Looking at the Python file, we see:
Very clearly there’s a vulnerability if more than one file has the name commands/command.txt
in the zip file. The get_file
function will only return the first file, meaning when
extractall
is run, it can possibly overwrite the command.txt
file with a malicious one.
So the solve is just a simple zip slip attack. We can create a zip file with a malicious command.txt
file, and then zip it with the original command.txt
file.
This gives us our flag: utflag{https://youtu.be/bZe5J8SVCYQ}
Networking
An interesting category you don’t see in many CTFs.
A Network Problem - Part 1
Points: 100
There are some interesting ports open on betta.utctf.live, particularly port 8080. By Robert Hill (@Rob H on discord)
betta.utctf.live:8080
This challenge is just connecting via netcat.
A Network Problem - Part 2
Points: 614
Update: smb port has been moved to 8445 from 445 on networking-misc-p2
betta.utctf.live has other interesting ports. Lets look at 8445 this time. By Robert Hill (@Rob H on discord)
betta.utctf.live:8445
This time its a Samba share. Trying to connect shows that we don’t even need a specific username or password.
Anyway, after looking around for a while, we come across \WorkShares\shares\IT\Itstuff\notetoIT
:
A Network Problem - Part 3
Points: 935
We’ve gathered a lot of information at this point, let get access through ssh. (ignore port 22, use 8822)
(Use of brute force is permitted for this problem, but please set the wait time in hydra so you don’t overwhelm the server)
By Rob H (@Rob H on discord)
betta.utctf.live:8822
From the not-so-subtle hint that this is ssh
bruteforce, let’s go generate some possible usernames and passwords.
The note in the last challenges tells us that we have 4 people to bruteforce: Crystal Ball, Wade Coldwater, Jay Walker, and Holly Wood.
Their password is also likely to be abracadabra
with some special character appended.
Now we can use hydra
to bruteforce the ssh server (and remembering to set a wait time to be nice to the server).
After a while, we get a hit:
Now we can just connect via ssh and get our flag:
Web
Only did a single web challenge, which was also actually just a Pyjail.
Calculator
Points: 856
Who says guessing games shouldn’t let you do math?
By Alex (@Alex_ on discord)
This challenge is actually just 4 mini pyjails. Each pyjail has the same format, which generally looked like this:
The author unfortunately forgot that solution
and password
were both in the global scope so as long as we can access the main
module, we can get them easily
Passwords were:
Level 0: PuXqj7n4WNZzStnWbtPv
Level 1: Krdi9yQuY8mHoteZDCF5
Level 2: E46Dnqb5enAMgGArbruu
Level 3: 5F4p7aLgQ5Nfn5YM8s68
The last challenge, challenge 3, removed __builtins__
, so we couldn’t use import. Fortunately the old ().__class__.__bases__[0].__subclasses__()
trick still works.
utflag{LGvb7PJXG5JDwhsEW7xp}
Crypto
Many blunders and mistakes…
Affinity
Points: 991
I just found out that the source code for AES is public. How can I trust that my secrets won’t be decrypted if the decryption algorithm is public. Since I’m a genius, I decided to make some modifications and roll my own crypto. Now you’ll never decrypt my secret!
3384f87f781c394b79e331510540a4125a371b057b058d8e793521cd43f2ae94
^^all of that is one line even though it is split into two. I don’t control the line breaks sorry :(. By Aadhithya (@aadhi0319 on Discord)
nc puffer.utctf.live 52584
aes.py
contains a simple AES implementation, with only one major difference.
The Sbox defined is actually equivalent to nothing, making the entire AES encryption process equivalent to an Affine function (see challenge name).
encrypt_pub.py
is the server code, and all it does is encrypt via the broken AES.
This type of challenge has definitely appeared before, so I won’t go into detail. Here’s a helpful link if you want to look into it more.
I also have an exact copy of the challenge solved here.
Actually I wasted about 2 hours on this challenge even though I literally already solved it before, because I thought the master key was the flag 😂.
Anyway here’s the final solve:
Flag is utflag{5O_Th3_5B0x_d035_m4tt3R!}
Looks Wrong tom E
Points: 993
everything about this challenge looks wrong…
there are now 2 flags for this challenge btw so try submitting on the other one if this one doesn’t work
also this does mean that the source is lying to you a little bit ;)
By oops (@oops on discord)
nc puffer.utctf.live 8484
This one is cheese, just feed the server 0s and it will give you the flag.
utflag{mY_l34Rn1Ng_h4s_3rr0rs_2f11a84e}
Provably Insecure
Points: 993
I’m sure nobody remembers the fiasco from DiceCTF when I thought I had proven my cipher was secure. Can you fool this signature service?
By Jeriah (@jyu on Discord)
nc puffer.utctf.live 52548
All we need to do is generate n'
such that we can solve a discrete log easily on s
and m
. I made a mistake and assumed large composite numbers wouldn’t work because
the inverse didn’t exist, but all you had to do was try multiple times.
My final solution ended up being generating a smooth prime and doing dlog that way.
utflag{hey_wait_signature_forgery_is_illegal}
Reversing
Reading List
Points: 100
I created this binary to keep track of some strings that I want to read. I thought I put a CTF flag in it so I’ll remember to make a problem for UTCTF, but I can’t seem to find it…
By Caleb (@eden.caleb.a#6541 on Discord)
Very simple strings challenge
Game
Points: 930
Nostalgic overload, at least for me. Credit due to Carolina.
By Jeriah (@jyu on Discord)
The given game is actually a .swf
file, so let’s throw it into a decompiler like JPEXS.
Inside the file, we can search for the flag via the flag format and find it pretty easily.
utflag{they_kn0w}
Looks Correct to Me
Points: 984
the flag checker looks right to me
oh I guess it doesn’t terminate if your flag is right
By oops (@oops on discord)
Not going to go into the decompilation and analysis, but essentially the program just checks pairs of random indices in the flag to see if they match some values inside a giant matrix with some conditions.
If the pair of indices ever fails to satisfy the conditions, the program will exit. Otherwise, it will continue forever, proving the description.
Here’s the solve with the extracted memory: data
utflag{L0c4l1z3d_Ch1ck3n_M0d1f1c4t10N_g8h91b3h89}
Forensics
Wooo redacted text woooo
”Easy” Volatility
Points: 834
I’ve included the flag in as shell command. Can you retrieve it?
I recommend using the volatility3 software for this challenge.
Here is the memory dump: (debian11.core.zst)[https://utexas.box.com/s/fehluzyox4bbgfjlz061r2k7k2sek3cw] This problem also comes with a free profile! (debian11_5.10.0-21.json.zst)[https://utexas.box.com/s/g64kezqvkqhm6nw79oovcekn9z1w66q0] Both of these files are compressed using zstd.
This challenge’s flag looks like a UUID.
Note: the volatility challenges do not have a flag format to discourage grepping. They all should be possible without guessing. If you have trouble, remember that you can ask for help.
By Daniel Parks (@danielp on discord)
This really is an easy challenge, all we need to do is expand the memory dump and profile, import the profile into volatility3, and finally run the linux.bash.Bash
plugin
08ffea76-b232-4768-a815-3cc1c467e813
(no flag format for these)
What Time is It?
Points: 905
Super Secure Company’s database was recently breached. One of the employees self reported a potential phishing event that could be related. Unfortunately, our Linux email server does not report receiving any emails on March 2, 2023. Can you identify when this email was actually sent? The flag format is
utflag{MM/DD/YYYY-HH:MM}
in UTC time.By Aadhithya (@aadhi0319 on Discord)
Looking at the email, nothing seems too out of place:
MIME-Version: 1.0
Date: Thu, 2 Mar 2023 03:12:42 +0000
Message-ID: <CAODBzaAPrwTP=oDe6fkOv1a7LApXzv1m+YrYG9RHZM7tbBJRbw@mail.gmail.com>
Subject: Critical Security Incident - Action Required ASAP!
From: Security Division <admin-notifications@supersecurecompany.com>
To: Jim Browning <jim.browning@supersecurecompany.com>
Content-Type: multipart/alternative; boundary="00000000000093882205f60cdcdb"
--00000000000093882205f60cdcdb
Content-Type: text/plain; charset="UTF-8"
Jim,
We have reason to believe that your Google account may have been
compromised. Please login as soon as possible at the following link in
order to secure your account. Thank you for your cooperation and swift
action to address this issue. Please feel free to reply to this email if
you have any questions. Do not email IT about this email as they are not in
the loop on account authorization issues.
https://supersecurecompany.gooogle.com/login/
Sincerely,
Security Division
Super Secure Company
--00000000000093882205f60cdcdb
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div di=
r=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div>Jim,</div><div><br></div><=
div>We have reason to believe that your=20
Google account may have been compromised. Please login as soon as=20
possible at the following link in order to secure your account. Thank=20
you for your cooperation and swift action to address this issue. Please=20
feel free to reply to this email if you have any questions. Do not email
IT about this email as they are not in the loop on account=20
authorization issues.</div><div><br></div><div><a href=3D"https://supersecu=
recompany.gooogle.com/login/">https://supersecurecompany.gooogle.com/login/=
</a><br></div><div><br></div><div>Sincerely,</div><div>Security Division</d=
iv><div>Super Secure Company<br></div></div></div></div></div></div></div><=
/div>
--00000000000093882205f60cdcdb--
However, something special about Gmail boundaries is that they actually contain timestamps, so all we need to do is extract them.
If you want more information, read here
utflag{03/04/2023-06:06}
Redacted Text
Points: 1000
Note: there are two accepted flags for Redacted Text, of which you only need to find one.
Well, I recently found out that people actually put in the effort to reverse engineer blured text… Want to try it?
This now has three versions, in order of decreasing difficulty:
- redacted.png (the original)
- redacted-no-subpixel-aa.png (disabled subpixel anti-aliasing, changed font size)
- redacted-aligned.png (integer pixel aligned text, alternate flag)
By Alex (@Alex_ on discord)
(I only solved for one so I’m only including the download for this image) redacted-aligned.png
I’m preparing to write a full writeup for this challenge here so this will stay empty for now. Click that link to read the full thing when it comes out.