Table of Contents
Hi Readers! I played UMDCTF 2023 which was happened from 29 Apr to 01 May. I played it with the team Invaders0x1.
These are the writeups for the challenges I solved.
Crypto
CBC-MAC1
Attached Files : cbc-mac1.py
cbc-mac1.py
import socket
import threading
from _thread import *
from Crypto import Random
from Crypto.Cipher import AES
from binascii import hexlify, unhexlify
HOST = '0.0.0.0' # Standard loopback interface address (localhost)
PORT = 60001 # Port to listen on (non-privileged ports are > 1023)
FLAG = open('flag.txt', 'r').read().strip()
MENU = "\nWhat would you like to do?\n\t(1) MAC Query\n\t(2) Forgery\n\t(3) Exit\n\nChoice: "
INITIAL = "Team Rocket told me CBC-MAC with arbitrary-length messages is safe from forgery. If you manage to forge a message you haven't queried using my oracle, I'll give you something in return.\n"
BS = 16 # Block Size
MAX_QUERIES = 10
def cbc_mac(msg, key):
iv = b'\x00'*BS
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
t = cipher.encrypt(msg)[-16:]
return hexlify(t)
def threading(conn):
conn.sendall(INITIAL.encode())
key = Random.get_random_bytes(16)
queries = []
while len(queries) < MAX_QUERIES:
conn.sendall(MENU.encode())
try:
choice = conn.recv(1024).decode().strip()
except ConnectionResetError as cre:
return
# MAC QUERY
if choice == '1':
conn.sendall(b'msg (hex): ')
msg = conn.recv(1024).strip()
try:
msg = unhexlify(msg)
if (len(msg) + BS) % BS != 0:
conn.sendall(f'Invalid msg length. Must be a multiple of BS={BS}\n'.encode())
else:
queries.append(msg)
t = cbc_mac(msg, key)
conn.sendall(f'CBC-MAC(msg): {t.decode()}\n'.encode())
except Exception as e:
conn.sendall(b'Invalid msg format. Must be in hexadecimal\n')
# FORGERY (impossible as I'm told)
elif choice == '2':
conn.sendall(b'msg (hex): ')
msg = conn.recv(1024).strip()
conn.sendall(b'tag (hex): ')
tag = conn.recv(1024).strip()
try:
msg = unhexlify(msg)
if (len(msg) + BS) % BS != 0:
conn.sendall(f'Invalid msg length. Must be a multiple of BS={BS} bytes\n'.encode())
elif len(tag) != BS*2:
conn.sendall(f'Invalid tag length. Must be {BS} bytes\n'.encode())
elif msg in queries:
conn.sendall(f'cheater\n'.encode())
else:
t_ret = cbc_mac(msg, key)
if t_ret == tag:
conn.sendall(f'If you reach this point, I guess we need to find a better MAC (and not trust TR). {FLAG}\n'.encode())
else:
conn.sendall(str(t_ret == tag).encode() + b'\n')
except Exception as e:
conn.sendall(b'Invalid msg format. Must be in hexadecimal\n')
else:
if choice == '3': # EXIT
conn.sendall(b'bye\n')
else: # INVALID CHOICE
conn.sendall(b'invalid menu choice\n')
break
if len(queries) > MAX_QUERIES:
conn.sendall(f'too many queries: {len(queries)}\n'.encode())
conn.close()
if __name__ == "__main__":
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen()
while True:
conn, addr = s.accept()
print(f'new connection: {addr}')
start_new_thread(threading, (conn, ))
s.close()
The remote challenge is at nc 0.cloud.chals.io 12769. The challenges is Generating a Message Authentication Code [Tag] For the given input message. The message should be in hex format and the length of the message has to be multiple of 16.
mj0ln1r@AHLinux:~/cbc0mac1$ nc 0.cloud.chals.io 12769
Team Rocket told me CBC-MAC with arbitrary-length messages is safe from forgery. If you manage to forge a message you haven't queried using my oracle, I'll give you something in return.
What would you like to do?
(1) MAC Query
(2) Forgery
(3) Exit
Choice: 1
msg (hex): 6162636465666768696a6b6c6d6e6f70
CBC-MAC(msg): f670f2abb9159a15a82a5779adbfb7bc
What would you like to do?
(1) MAC Query
(2) Forgery
(3) Exit
Choice: 1
msg (hex): 6162636465666768696a6b6c6d6e6f706162636465666768696a6b6c6d6e6f70
CBC-MAC(msg): 2836413262109e028fe4e00452f60f53
What would you like to do?
(1) MAC Query
(2) Forgery
(3) Exit
Choice:
The program is taking the variable length message as input, this is a flag in cbc-mac.
So, The MAC or Tag is the last encrypted plaintext in the CBC Mode of AES. As the program allowing us to input variable length message we can generate a new message M2
with the same tag t1
which is the tag of M1
. To do this I choosed M2
with 2 blocks of plaintext with 16 characters each. The new_M2 = (last block of M2) xor t1
This new_M2
will have the same tag t1
. This is how we can forge the message. Here is the automated script for the challenge.
from pwn import *
from Crypto.Util.strxor import strxor
conn = remote('0.cloud.chals.io',12769)
conn.recvuntil(b'Choice: ')
conn.sendall(b'1')
conn.recvuntil(b'msg (hex): ')
m1 = "abcdefghijklmnop"
m2 = "abcdefghijklmnopqrstuvwxyz123456"
m1_hex = ''.join(hex(ord(c))[2:] for c in m1)
m2_hex = ''.join(hex(ord(c))[2:] for c in m2)
conn.sendline(m1_hex.encode())
conn.recvuntil(b'(msg): ')
tag1 = conn.recvline().strip()
x = strxor(m2_hex[32:].encode(),tag1)
new_m2 = m2_hex[:32]+x.decode()
conn.recvuntil(b"Choice: ")
conn.sendline(b"2")
conn.recvuntil(b"msg (hex): ")
conn.sendline(new_m2.encode())
conn.recvuntil(b"tag (hex): ")
conn.sendline(tag1)
flag = conn.recv()
print(flag)
Flag : UMDCTF{Th!s_M@C_Sch3M3_1s_0nly_S3cur3_f0r_f!xed_l3ngth_m3ss4g3s_78232813}
Pokecomms
The challenge had this txt file.
CHU! PIKA CHU! PIKA CHU! PIKA CHU! PIKA
CHU! PIKA CHU! CHU! PIKA PIKA CHU! PIKA
CHU! PIKA CHU! CHU! CHU! PIKA CHU! CHU!
CHU! PIKA CHU! CHU! CHU! CHU! PIKA PIKA
CHU! PIKA CHU! PIKA CHU! PIKA CHU! CHU!
CHU! PIKA CHU! CHU! CHU! PIKA PIKA CHU!
CHU! PIKA PIKA PIKA PIKA CHU! PIKA PIKA
CHU! PIKA CHU! PIKA CHU! CHU! CHU! CHU!
CHU! CHU! PIKA PIKA CHU! CHU! CHU! PIKA
CHU! PIKA CHU! CHU! PIKA CHU! PIKA PIKA
CHU! CHU! PIKA PIKA CHU! PIKA CHU! CHU!
.
.
CHU! CHU! PIKA PIKA CHU! PIKA CHU! CHU!
The first thing I did is eliminated the duplicate lines in text file. Then I saw that there are only 8 words in every line. And the The words are only CHU! PIKA with random sequence. So, I changed CHU! to 1 and PIKA to 0. Got the binary bits then converted it to ascii to get the flag.
The solution script is
with open("pokecomms.txt","r") as f:
l = f.readlines()
m = []
for i in l:
m.append(i.strip())
s = list(set(m))
byte=[]
for i in m:
bits=[]
for j in i.split():
if j == "CHU!":
bits.append('0')
elif j == "PIKA":
bits.append('1')
else:
print("else")
oneb = "".join(bits)
byte.append(int(oneb,2))
for i in byte:
print(chr(i),end="")
#UMDCTF{P1K4CHU_Once_upon_a_time,_there_was_a_young_boy_named_Ash_who_dreamed_of_becoming_the_world's_greatest_Pokemon_trainer._He_set_out_on_a_journey_with_his_trusty_Pokemon_partner,_Pikachu,_a_cute_and_powerful_electric-type_Pokemon._As_Ash_and_Pikachu_traveled_through_the_regions,_they_encountered_many_challenges_and_made_many_friends._But_they_also_faced_their_fair_share_of_enemies,_including_the_notorious_Team_Rocket,_who_were_always_trying_to_steal_Pikachu._Despite_the_odds_stacked_against_them,_Ash_and_Pikachu_never_gave_up._They_trained_hard_and_battled_even_harder,_always_looking_for_ways_to_improve_their_skills_and_strengthen_their_bond._And_along_the_way,_they_learned_valuable_lessons_about_friendship,_determination,_and_the_power_of_believing_in_oneself._Eventually,_Ash_and_Pikachu's_hard_work_paid_off._They_defeated_powerful_opponents,_earned_badges_from_Gym_Leaders,_and_even_competed_in_the_prestigious_Pokemon_League_tournaments._But_no_matter_how_many_victories_they_achieved,_Ash_and_Pikachu_never_forgot_where_they_came_from_or_the_importance_of_their_friendship._In_the_end,_Ash_and_Pikachu_became_a_legendary_team,_admired_by_Pokemon_trainers_around_the_world._And_although_their_journey_may_have_had_its_ups_and_downs,_they_always_knew_that_as_long_as_they_had_each_other,_they_could_overcome_any_obstacle_that_stood_in_their_way}
Rev
Welcome to Python
Challenge had this binary file chall
As it is a ELF file I decompiled it to Pyc
then Pyc to py
file. My teammates found that python generated ELF
can be decompiled to pyc with pyinstxtractor. It generated a pyc file then used online pyc decompiler to decompile to the py file.
The decompiled chall.py
is
# Source Generated with Decompyle++
# File: chal.pyc (Python 3.10)
from math import sqrt, sin, cos
from ctypes import c_uint32, c_float
from sys import exit as exit_
source = [
672662614,
741343303,
495239261,
744259788,
722021046,
0xA70AA247,
1053692,
0xA8050035,
0xA982A820,
624689,
0xA90D20BC,
41134,
295340,
0xA0028102,
622681,
576469,
671170814,
0x8041086E,
765,
680595550,
0x80200166,
698368102,
2437137,
0x8042C1EE,
570966112,
4612341,
0x800008D4,
0xA94D02CE,
16484,
2103301,
136226,
9438506,
663820758,
0x8013523B,
8405532,
0xA4000875,
0x80030A78,
136768]
seed = 64
def wandom(x):
return x * x * cos(x) * sin(x) / 1000
def evil_bit_hack(y):
return int(c_uint32.from_buffer(c_float(y)).value)
print('==========================================')
print('Professional flag checker service (v 97.2)')
print('==========================================')
flag = input('Show me the flag: ')
lf = len(flag)
ls = len(source)
l = lf if lf < ls else ls
for i in range(seed, seed + l):
w = wandom(i)
c = ~(~ord(flag[i - seed]) ^ evil_bit_hack(wandom(wandom(w))) & evil_bit_hack(w)) + 1
if source[i - seed] != c:
print("Uh oh! We don't think your flag is correct... :(")
exit_(1)
if lf == ls:
print('Your flag is correct!')
# None('Some of your flag is correct...')
Points I observed
- The seed is 64
- source values are known
c
is generated by XORing flag char with evil_bit_hack(wandom(wandom(w))) & evil_bit_hack(w) and 1 is added at the end.
So, I just need to reverse this line c = ~(~ord(flag[i - seed]) ^ evil_bit_hack(wandom(wandom(w))) & evil_bit_hack(w)) + 1
To print the flag.
Interesting, lets do it
res = (source[i-seed]-1)^ evil_bit_hack(wandom(wandom(w))) & evil_bit_hack(w)
Will be the reversed function.
And here is the solution script to print the flag.
# Source Generated with Decompyle++
# File: chal.pyc (Python 3.10)
from math import sqrt, sin, cos
from ctypes import c_uint32, c_float
from sys import exit as exit_
source = [
672662614,
741343303,
495239261,
744259788,
722021046,
0xA70AA247,
1053692,
0xA8050035,
0xA982A820,
624689,
0xA90D20BC,
41134,
295340,
0xA0028102,
622681,
576469,
671170814,
0x8041086E,
765,
680595550,
0x80200166,
698368102,
2437137,
0x8042C1EE,
570966112,
4612341,
0x800008D4,
0xA94D02CE,
16484,
2103301,
136226,
9438506,
663820758,
0x8013523B,
8405532,
0xA4000875,
0x80030A78,
136768]
seed = 64
def wandom(x):
return x * x * cos(x) * sin(x) / 1000
def evil_bit_hack(y):
return int(c_uint32.from_buffer(c_float(y)).value)
flag = 38 * 'A'
lf = len(flag)
ls = len(source)
l = lf if lf < ls else ls
for i in range(seed, seed + l):
w = wandom(i)
x = evil_bit_hack(wandom(wandom(w))) & evil_bit_hack(w)
c = ~(~ord(flag[i - seed]) ^ evil_bit_hack(wandom(wandom(w))) & evil_bit_hack(w)) + 1
res = (source[i-seed]-1)^x
print(chr(res),end="")
#UMDCTF{0_0+-+eXP-eLLiARm_us_!!!-12345}
Flag : UMDCTF{0_0+-+eXP-eLLiARm_us_!!!-12345}
Hardware
beep1
The attached files are Beep1.circ which is a xml file and a flag.enc file.
Beep1.circ is
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project source="3.8.0" version="1.0">
This file is intended to be loaded by Logisim-evolution v3.8.0(https://github.com/logisim-evolution/).
<lib desc="#Wiring" name="0">
<tool name="Pin">
<a name="appearance" val="classic"/>
</tool>
</lib>
<lib desc="#Gates" name="1"/>
<lib desc="#Plexers" name="2"/>
<lib desc="#Arithmetic" name="3"/>
<lib desc="#Memory" name="4"/>
<lib desc="#I/O" name="5"/>
<lib desc="#TTL" name="6"/>
<lib desc="#TCL" name="7"/>
<lib desc="#Base" name="8"/>
<lib desc="#BFH-Praktika" name="9"/>
<lib desc="#Input/Output-Extra" name="10"/>
<lib desc="#Soc" name="11"/>
<main name="main"/>
<options>
<a name="gateUndefined" val="ignore"/>
<a name="simlimit" val="1000"/>
<a name="simrand" val="0"/>
</options>
<mappings>
<tool lib="8" map="Button2" name="Poke Tool"/>
<tool lib="8" map="Button3" name="Menu Tool"/>
<tool lib="8" map="Ctrl Button1" name="Menu Tool"/>
</mappings>
<toolbar>
<tool lib="8" name="Poke Tool"/>
<tool lib="8" name="Edit Tool"/>
<tool lib="8" name="Wiring Tool"/>
<tool lib="8" name="Text Tool"/>
<sep/>
<tool lib="0" name="Pin"/>
<tool lib="0" name="Pin">
<a name="facing" val="west"/>
<a name="output" val="true"/>
</tool>
<sep/>
<tool lib="1" name="NOT Gate"/>
<tool lib="1" name="AND Gate"/>
<tool lib="1" name="OR Gate"/>
<tool lib="1" name="XOR Gate"/>
<tool lib="1" name="NAND Gate"/>
<tool lib="1" name="NOR Gate"/>
<sep/>
<tool lib="4" name="D Flip-Flop"/>
<tool lib="4" name="Register"/>
</toolbar>
<circuit name="main">
<a name="appearance" val="logisim_evolution"/>
<a name="circuit" val="main"/>
<a name="clabelup" val="north"/>
<a name="simulationFrequency" val="8.0"/>
<comp lib="0" loc="(140,300)" name="Clock">
<a name="label" val="clk"/>
</comp>
<comp lib="0" loc="(350,220)" name="Splitter">
<a name="fanout" val="8"/>
<a name="incoming" val="8"/>
</comp>
<comp lib="0" loc="(440,460)" name="Splitter">
<a name="facing" val="west"/>
<a name="fanout" val="8"/>
<a name="incoming" val="8"/>
<a name="spacing" val="2"/>
</comp>
<comp lib="0" loc="(460,130)" name="Splitter">
<a name="facing" val="west"/>
<a name="fanout" val="8"/>
<a name="incoming" val="8"/>
</comp>
<comp lib="0" loc="(670,190)" name="Bit Extender">
<a name="out_width" val="7"/>
<a name="type" val="one"/>
</comp>
<comp lib="1" loc="(290,380)" name="NOT Gate">
<a name="facing" val="north"/>
</comp>
<comp lib="1" loc="(300,340)" name="Controlled Buffer"/>
<comp lib="1" loc="(320,540)" name="NOR Gate">
<a name="facing" val="west"/>
<a name="inputs" val="8"/>
</comp>
<comp lib="4" loc="(320,300)" name="Counter">
<a name="appearance" val="classic"/>
</comp>
<comp lib="4" loc="(340,290)" name="ROM">
<a name="appearance" val="classic"/>
</comp>
<comp lib="5" loc="(140,370)" name="Button">
<a name="label" val="rst"/>
</comp>
<comp lib="5" loc="(710,200)" name="TTY">
<a name="cols" val="40"/>
</comp>
<comp lib="5" loc="(710,260)" name="Button">
<a name="label" val="tty_rst"/>
</comp>
<wire from="(140,300)" to="(160,300)"/>
<wire from="(140,370)" to="(310,370)"/>
<wire from="(160,300)" to="(160,340)"/>
<wire from="(160,340)" to="(280,340)"/>
<wire from="(290,350)" to="(290,380)"/>
<wire from="(290,410)" to="(290,540)"/>
<wire from="(290,540)" to="(320,540)"/>
<wire from="(300,320)" to="(300,340)"/>
<wire from="(300,340)" to="(330,340)"/>
<wire from="(310,320)" to="(310,370)"/>
<wire from="(320,300)" to="(340,300)"/>
<wire from="(330,230)" to="(330,340)"/>
<wire from="(330,230)" to="(690,230)"/>
<wire from="(350,220)" to="(350,270)"/>
<wire from="(350,270)" to="(590,270)"/>
<wire from="(370,120)" to="(370,140)"/>
<wire from="(370,120)" to="(480,120)"/>
<wire from="(370,150)" to="(420,150)"/>
<wire from="(370,160)" to="(380,160)"/>
<wire from="(370,170)" to="(440,170)"/>
<wire from="(370,180)" to="(390,180)"/>
<wire from="(370,190)" to="(390,190)"/>
<wire from="(370,200)" to="(380,200)"/>
<wire from="(370,210)" to="(370,220)"/>
<wire from="(370,220)" to="(420,220)"/>
<wire from="(380,140)" to="(380,160)"/>
<wire from="(380,140)" to="(430,140)"/>
<wire from="(380,200)" to="(380,210)"/>
<wire from="(380,210)" to="(400,210)"/>
<wire from="(380,500)" to="(390,500)"/>
<wire from="(380,510)" to="(400,510)"/>
<wire from="(380,520)" to="(410,520)"/>
<wire from="(380,530)" to="(420,530)"/>
<wire from="(380,550)" to="(420,550)"/>
<wire from="(380,560)" to="(410,560)"/>
<wire from="(380,570)" to="(400,570)"/>
<wire from="(380,580)" to="(390,580)"/>
<wire from="(390,160)" to="(390,180)"/>
<wire from="(390,160)" to="(440,160)"/>
<wire from="(390,190)" to="(390,200)"/>
<wire from="(390,200)" to="(440,200)"/>
<wire from="(390,470)" to="(390,500)"/>
<wire from="(390,470)" to="(420,470)"/>
<wire from="(390,580)" to="(390,600)"/>
<wire from="(390,600)" to="(420,600)"/>
<wire from="(400,180)" to="(400,210)"/>
<wire from="(400,180)" to="(440,180)"/>
<wire from="(400,490)" to="(400,510)"/>
<wire from="(400,490)" to="(420,490)"/>
<wire from="(400,570)" to="(400,590)"/>
<wire from="(400,590)" to="(420,590)"/>
<wire from="(410,510)" to="(410,520)"/>
<wire from="(410,510)" to="(420,510)"/>
<wire from="(410,560)" to="(410,570)"/>
<wire from="(410,570)" to="(420,570)"/>
<wire from="(420,130)" to="(420,150)"/>
<wire from="(420,130)" to="(440,130)"/>
<wire from="(420,190)" to="(420,220)"/>
<wire from="(420,190)" to="(440,190)"/>
<wire from="(420,600)" to="(420,610)"/>
<wire from="(430,140)" to="(430,150)"/>
<wire from="(430,150)" to="(440,150)"/>
<wire from="(440,130)" to="(440,140)"/>
<wire from="(440,210)" to="(440,220)"/>
<wire from="(440,220)" to="(480,220)"/>
<wire from="(440,460)" to="(590,460)"/>
<wire from="(460,130)" to="(590,130)"/>
<wire from="(480,120)" to="(480,220)"/>
<wire from="(580,350)" to="(590,350)"/>
<wire from="(590,130)" to="(590,190)"/>
<wire from="(590,190)" to="(630,190)"/>
<wire from="(590,270)" to="(590,350)"/>
<wire from="(590,350)" to="(590,460)"/>
<wire from="(670,190)" to="(710,190)"/>
<wire from="(690,200)" to="(690,230)"/>
<wire from="(690,200)" to="(710,200)"/>
<wire from="(710,260)" to="(720,260)"/>
<wire from="(720,230)" to="(720,260)"/>
<wire from="(720,230)" to="(730,230)"/>
<wire from="(730,210)" to="(730,230)"/>
</circuit>
</project>
The solution, the header contains the github link to the logisim software. Downloaded the logisim-evolution-3.8.0-all.jar
file and runned it locally. And Opened the beep1.circ
file in the software and loaded the flag.enc
file in the ROM. And started the simmulation then the flag is displayed in the TTY.
Flag: UMDCTF{w3lc0me_t0_l0g1s1m_yeet}
clutter
The challenge has two files clutter.vsp and a pdf about the installation of VeSP
software.
The clutter.vsp is
2000
0000
2001
0000
2001
0003
2000
0052
0000
315B
0000
2001
0008
2000
0045
0000
3285
0000
...
..
and upto 215 lines
Solution,
Installed and started the VeSP
mj0ln1r@AHLinux:~/clutter$ wget https://user.eng.umd.edu/\~yavuz/teaching/courses/enee350/vesp-source-code/vesp1.1X/main.cpp -o vesp1_1.cpp
mj0ln1r@AHLinux:~/clutter$ cpp vesp1_1.cpp -o vesp1_1
mj0ln1r@AHLinux:~/clutter$ ls
vesp1_1
mj0ln1r@AHLinux:~/clutter$ ./vesp1_1
Welcome to Vesp 1.1
Type
0 to enter a program
1 to display registers
2 to display memory:
Okay, I followed the instructions and loaded the clutter.vsp
file in the vesp1_1 program. After running the program with long trace(in verbose mode). I found some memory storage locations in every instruction execution like this Memory[0001] = 000A
. After observing all the same memory location values I got to know that flag characters are stored in memory locations other than 0000
and 0001
. I couldn't found any way to store the output of the program to a file so I wrote this automated script using pwntools
. Cool, Right!
solve.py
from pwn import *
import re
target = process("vesp/vesp1_1")
target.recv()
target.sendline(b"0")
target.sendline(b"002")
target.sendline(b"1")
target.sendline(b"clutter/clutter.vsp")
target.sendline(b"0")
target.sendline(b"1")
output = target.recvuntil(b"The number of clock cycles used = 396").decode('utf-8')
regex = "Memory\[\w+\] = .{4}"
match = re.findall(regex,output)
for i in match:
if ("0000" not in i) and ("0001" not in i):
x = i[15:]
di = int(x,16)
print(chr(di),end="")
# UMDCTF{Ux13-us3-m3m0ry-w1p3!}
Flag: UMDCTF{Ux13-us3-m3m0ry-w1p3!}
Forensics
Fire Type Pokemons Only
Attached file : fire-type-pokemon-only.pcapng.zip
Without opening the pcap file I know that I had to look for FTP
packets in the file. So I extracted the zip and opened the pcap file in wireshark.
Solution
- Opened the pcap in wireshark
- Filtered FTP packets in wireshark
- Followed the TCP stream of FTP data
- Found a password
piku
- Some Images are transfered over network
So, I just exported the FTP-DATA saved the files. The files are Diglett.png
, secretpic1.png
, hmmmm
and secret.zip
The zip is password protected, I used piku
as the password for the zip. A video file is extracted, the flag is diplayed in the video.
Flag : UMDCTF{its_n0t_p1kachu!!}
No. 352
A hide-n-seek.jpg file is attached
Used Steghide immediately
- First password
kecleon
(from google search) - Second password
timetofindwhatkecleonishiding
mj0ln1r@AHLinux:~/no352$ steghide extract -sf hide-n-seek.jpg
Enter passphrase : kecleon
extracted data kecleon.jpg
mj0ln1r@AHLinux:~/no352$ steghide extract -sf kecleon.jpg
Enter passphrase : timetofindwhatkecleonishiding
extracted data wrote to flag.txt
mj0ln1r@AHLinux:~/no352$ cat flag.txt
UMDCTF{KECLE0NNNNN}
Flag : UMDCTF{KECLE0NNNNN}
Mirror Unknown
The attached image is
Solution,
Did a reverse image search on google images. And found the letters associated with the symbols.
The Alphabets associated with symbols are - HOJNISSNIUR
Reversed the letters as the challenge says it mirror - SINJOHRUINS
Found that Sinjoh ruins is a place, It might be the correct flag and it is.
Flag : UMDCTF{SINJOHRUINS}
OSINT
Gone Missing 1
The link attached hosted this location image
Again did a reverse image search search
Found that it is Royal Palace, Oslo
Selected the Royal palace in the map given at the bottom right corner, got the flag.
Flag : UMDCTF{I_b3t_rainbolt_c0uld_g3t_th1s_!n_thr33_s3c0nd5}
Web
Treps Ticket System
The attached URL hosted a form like this,
Inputed the Test creds name = test email = test@gmail.com
It loaded a ticket with the URL https://tts.chall.lol/ticket?num=12
Tried IDOR
in the URL. changed the num=0
and recieved the flag.
Flag : UMDCTF{d0nt_b3_@n_id0r_@lw@ys_s3cur3_ur_tick3ts}