Challenge Files
WEB
Training Problem: Intro to Web 50
Challenge Description: It's nice to have some training problems. -ProfNinja https://bluehens-webstuff.chals.io/

Solve:
I navigated to the site and received the following.

I viewed the source code, and there was nothing else to tell us where to go, so we needed to use this prompt. It says “version control”, which usually means that /.git is a directory for verison control based on previous CTFs. I navigated to it.

We confirmed there is a /.git directory. I used git-dumper to dump the /.git: https://github.com/arthaud/git-dumper
udctf{marcecko_licenseplate}
OSINT
Intro to OSINT
Challenge Description: A famous person is selling their house...
Solve:
I started by reverse image searching...
udctf{marcecko_licenseplate}
CRYPTO
Nonogram Pt. 1: Simple Enough
Challenge Description: When you get past the puzzle, you now face a classic encryption / old-school stego encoding. Wrap the text you find in `UDCTF{TEXTHERE}`. -Grace

Solve:
In this challenge, we were given a Nonogram Puzzle to solve, then we received a encrypted code.
Encrypted code:
UDDDU UDUUU DUDUD UUDUU UDUDU UUUUU DUUDU UUDUU UUUDD
The challenge information says it’s an old-school cipher, so I thought it might be the Bacon’s cipher invented by Fancis Bacon in 1605. I used dcode to decode this. https://www.dcode.fr/bacon-cipher

UDCTF{PIXELATED}
CRYPTO
XS1: XOR without XOR
Challenge Description: This is how XOR makes me feel. *This series of problems is called the XOR SCHOOL. For whatever reason I just love xor problems and over the years there are many that have charmed my soul. This sequence is an homage to the many many ways that xor shows up in CTFs. I hope you can see some of the beauty that I see through them. -ProfNinja*


Solve:
I created a script in Python to recreate this XOR, and decode the flag for us.
# Given flag string from the image output
flag = "u_cnfrj_sr_b_34}yd1tt{0upt04lbmb"
# Repeat the flag 32 times, then apply the slicing
decoded_flag = (flag * 32)[::17][:32]
# Print the result
print("Decoded flag:", decoded_flag)
Running this script provided us the flag.
┌──(Tux㉿kali-2024v2)-[~/Desktop]
└─$ python test.py
Decoded flag: udctf{just_4_b4by_1ntr0_pr0bl3m}
udctf{just_4_b4by_1ntr0_pr0bl3m}
CRYPTO
ROTOLACTOR
Challenge Description: "Got Milk?" -JayV

Solve:
To start, I was looking at the challenge name and it starts with ROT, so I thought, ROT13. I translated this file they gave us to ROT13 and it came out with “Moo” language.
OOOMoOMoOMoOMoOMoOMoOMoOMoOMMMmoOMMMMMMmoOMMMMOOMOomOoMoOmoOmoomOo
MMMmoOMMMMMMmoOMMMMOOMOomOoMoOmoOmoomOoMMMmoOMMMMMMmoOMMMMOOMOomOo
MoOmoOmooOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOomOoMMMmoO
moOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOo
MMMmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOoMMM
moOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMM
MOOMOomoOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOomoOMoOmOomoomoOMoO
MoOMoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomoOMoOMoO
MoOMoOMoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOo
MMMmoOmoOMMMMOOMOomoOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOomoOMoO
mOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOoMMM
moOMMMMOOMOomoOMoOmOomoomOomOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomoOMoO
MoOMoOMoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOomOoMMMmoOmoOMMMMOOMOomoO
MoOmOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoomOo
OOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOoMMMmoOmoOMMMMOOMOo
moOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoO
MoOMoOMoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOo
mOoMMMmoOmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoO
MoOMoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoo
mOomOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoomOoOOOmoOOOO
mOomOomOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOO
MOomoOMoOmOomoomoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOo
moomOomOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoomOoOOOmoO
OOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOo
moOMoOmOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoomOo
OOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOoMMMmoOmoOMMMMOOMOo
moOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoO
MoOMoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOomOoMMMmoOmoOMMMMOOMOomoOMoO
mOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoomOoOOO
moOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOoMMMmoOmoOMMMMOOMOomoO
MoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoO
MoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOomOoMMMmoO
moOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoO
MoOMoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOoMMM
moOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOo
mOomOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOo
moOMoOmOomoomoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoo
mOomOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoO
MoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOo
mOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOo
mOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOomoOMoO
mOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoomOoOOOmoO
OOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOoMMMmoOmoOMMMMOOMOomoOMoO
mOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoo
mOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoomOomOoMMMmoOmoOMMMMOO
MOomoOMoOmOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOoMMM
moOMMMMOOMOomoOMoOmOomoomOomOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomoOMoO
MoOMoOMoOMoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOomOoMMMmoOmoOMMMMOOMOo
moOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoO
MoOMoOMoomOoOOOmoOOOOmOomOomOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomOomOo
mOoMMMmoOmoOmoOMMMMOOMOomoOMoOmOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoO
MoOMoOMoOMoOMoOMoOMoomOoOOOmoOOOOmOomOoMMMmoOMMMMOOMOomoOMoOmOomoo
mOomOoMMMmoOmoOMMMMOOMOomoOMoOmOomoomOomOomOoMMMmoOmoOmoOMMMMOOMOo
moOMoOmOomoomoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoomOo
I’ve seen this before. I went to https://www.jdoodle.com/execute-cow-online and pasted in the code above and clicked on “execute”, and it gave me the flag.

UDCTF{h0w_d1d_y0u_f1nd_thi5?}
FORENSICS
Hidden Data Extraction
Challenge Description: Steganography in an image...
Solve:
I used steghide to extract hidden information...
udctf{stego_found}
PWN
Buffer Overflow
Challenge Description: Exploit a classic buffer overflow vulnerability...
Solve:
I used GDB to analyze...
udctf{buffer_overflow}
REVERSING
Training Problem: Intro to Reverse
Challenge Description: Just a classic flagchecker. -ProfNinja (Try using dogbolt.org)

Solve:
I loaded the flagchecker file into Ghidra and looked at the main function.
undefined8 main(void)
{
undefined8 uVar1;
long in_FS_OFFSET;
int local_4c;
undefined8 local_48;
undefined8 local_40;
undefined4 local_38;
char local_28 [24];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
local_48 = 0x2c6c766271616375;
local_40 = 0x212352275c642a6e;
local_38 = 0x6c21;
fgets(local_28,0x13,stdin);
local_4c = 0;
do {
if (0x11 < local_4c) {
puts("You got it!");
uVar1 = 0;
LAB_00101246:
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return uVar1;
}
if (local_28[local_4c] - local_4c != (int)*(char *)((long)&local_48 + (long)local_4c)) {
puts("wrong");
uVar1 = 1;
goto LAB_00101246;
}
local_4c = local_4c + 1;
} while( true );
}
local_28[local_4c] - local_4c == (int)*(char *)((long)&local_48 + (long)local_4c)
flag[i] = (char)((int)*(char *)((long)&local_48 + i) + i)
import struct
# Hardcoded values based on `local_48`, `local_40`, and `local_38`
local_48 = 0x2c6c766271616375
local_40 = 0x212352275c642a6e
local_38 = 0x6c21
# Combine the values into a byte array in little-endian format
flag_bytes = struct.pack("
local_48, 40 and 38 are hard coded values in hexadecimal, representing the expected parts of the flag. local_218 is the buffer where the input flag is stored from fgets. The flag checking function loops over each character in the input flag (up to 0x11 or 17 characters). For each character at index local_4c, it checks if:
import struct
# Hardcoded values based on `local_48`, `local_40`, and `local_38`
local_48 = 0x2c6c766271616375
local_40 = 0x212352275c642a6e
local_38 = 0x6c21
# Combine the values into a byte array in little-endian format
flag_bytes = struct.pack("
This means the input character minus its index must much the corresponding byte in local_48, 40 and 38. Since each character flag[i] at position i must satisfy:
flag = ''.join(chr(flag_bytes[i] + i) for i in range(len(flag_bytes)))
print("Calculated flag:", flag)
┌──(rsa_env)─(Tux㉿kali-2024v2)-[~/Desktop]
└─$ python test.py
Calculated flag: udctf{r3v3ng3_101}
udctf{r3v3ng3_101}
MISC
AlgebrarbeglA 100
Challenge Description: 78! - k = k - !87 Solve for k flag format is udctf{k} -ProfNinja Dedicated to Wrath of Math

Solve:
I approached the problem by...
I have tried to perform the math in a calculator. Math error is all I see. wrote the code I first had to work out with what I knew which is the factorial of 78 (78!) I did not know of !87. This brought about syntax error. Did a little bit of google search on this https://en.wikipedia.org/wiki/Glossary_of_mathematical_symbols stumbled apon this for the !87 https://en.wikipedia.org/wiki/Subfactorial Put together some code. AlgebrarbeglA.py

and boom the flag
udctf{387700288526444839185460979130991103610316350951544192244807199359099600806691328655309595021094080317314686982970896828895806969367}
Welcome Letter 50
Challenge Description:Welcome to the CTF. A few notes:
* I made 10 XOR School problems, we're a uni so teaching will always be part of our CTFs. These are made as an ode to the beauty of XOR. * Some Training problems in the main categories: Reverse, PWN, Web, and Crypto just for first-timers. Google the problem title + "CTF Writeup" and you'll find similar problems out there that you can mimic I'm sure. * In playtesting many of the problems were fun puzzles but I can imagine someone calling them "guessy", forgive us now. I killed any that felt egregious and the others I've labelled as "guess school". Behind that label is the idea that deductive reasoning within the meta of CTFing is actuallyy a muscle. Many (very good) teams have a member that specializes in guessy problems. I think that XOR and the guess school problems cultivate a sort of "escape room" sensibility that often is overlooked in CTF training as too frustrating. I think it's valuable as a life skill but consider this a trigger warning, stay away from those ones if you tend to get frustrated. * I tried to make sure the main categories have enough depth to chew on but not all of the main categories are equally as deep. I think PWN and WEB are maybe a little lighter than perfection but we have a ton of challenges and 12 less hours, so your WEB anchor might need to go help someone else after day 1. * We're a student club. Every year students make problems. They are fun and quirky but this year they made a TON of forensics and misc and problems that maybe crawl over several categories. The heavy hitting teams might not love that but our deepest problems tend to get deeper and our n00b problems stay light, just the nature of undergrads. Just have fun with it. * We pride ourselves on customer service, jump in the discord and ask questions and I'll try to teach you stuff without lessening the competitive integrity of the competition. * Some authors used udctf{} others used UDCTF{} so bear that in mind when validating your hypotheses. * We have a long history of a minecraft category, this year we don't. Sorry. I miss it. FSG lives on in ranked.

Solve:
I approached the problem by...
UDCTF{guessy_is_sometimes_deduction_sometimes_awful}