UMDCTF 2022 writeup
about
3/4~6に開催されていたUniversity of Marylandのチームが主催するCTFです.
チームDCDCとして参加し,1pt以上獲得した552チーム中16位でした.
以下,自分が解いた問題で覚えている物のwriteupです
Pwn
Legacy
なんかガチャガチャやってると,
Traceback (most recent call last):
File "/home/ctf/legacy.py", line 15, in <module>
if (input(str(3-i) + " chances left! \n") == secret):
File "<string>", line 1, in <module>
NameError: name 'hoge' is not defined
って言われるのでsecret
って入力してみるとflagがもらえます.
Pwnこれしか解いてない.俺は無力.
forensics
Renzik’s Case
普通にbinwalkすると出てきます.
Magic Plagueis the Wise
magic numberの先頭1byteだけ改変されたPNGが入ってたので,先頭1byteだけ読み出すとflag出てきます.
jdata
unzipせずにbinwalkするとバイナリが入っていて,そこで呼ばれている関数の名前とunzipした時の画像を組み合わせたらflagになります.
これは@mmmlyがほぼ解いていたのを俺がsubmitしただけです.
misc
ChungusBot v2
Botが使っているのと同じアイコンにするとflagくれます.面倒くせぇ.
RSI 1
OSU!のリプレイっぽいフォーマットのファイルが渡されるので,なんか気合でパースするとflag出てきます.
普通にPythonのライブラリがあったらしい.自作のはバグってそうな雰囲気もあるし無駄な努力した.
#!/usr/bin/env python3.9
import leb128
import time
import sys
import lzma
if len(sys.argv) < 2:
print(f'Usage: {sys.argv[0]} SOMEFILE.osr')
exit(0)
f = open(sys.argv[1], 'rb')
def read_string() -> str:
has = f.read(1)
if has == b'\x0b':
l = leb128.u.decode(f.read(1))
return f.read(l).decode('utf-8', 'ignore')
else:
return ''
def read_long() -> int:
return int.from_bytes(f.read(8), byteorder='little', signed=False)
def read_int() -> int:
return int.from_bytes(f.read(4), byteorder='little', signed=False)
def read_short() -> int:
return int.from_bytes(f.read(2), byteorder='little', signed=False)
def read_byte() -> int:
return int.from_bytes(f.read(1), byteorder='little', signed=False)
gameMode = ['osu! Standard', 'Taiko', 'Catch the Beat', 'osu!mania'][read_byte()]
print(f'Game Mode = {gameMode}')
print(f'Version of the game when the replay was created = {read_int()}')
print(f'osu! beatmap MD5 hash = {read_string()}')
print(f'Player name = {read_string()}')
print(f'osu! replay MD5 hash (includes certain properties of the replay) = {read_string()}')
print(f'Number of 300s = {read_short()}')
print(f'Number of 100s in standard, 150s in Taiko, 100s in CTB, 100s in mania = {read_short()}')
print(f'Number of 50s in standard, small fruit in CTB, 50s in mania = {read_short()}')
print(f'Number of Gekis in standard, Max 300s in mania = {read_short()}')
print(f'Number of Katus in standard, 200s in mania = {read_short()}')
print(f'Number of misses = {read_short()}')
print(f'Total score displayed on the score report = {read_int()}')
print(f'Greatest combo displayed on the score report = {read_short()}')
print(f'Perfect/full combo (1 = no misses and no slider breaks and no early finished sliders) = {read_byte()}')
modsUsed = read_int()
print(f'Mods used. See below for list of mod values. = {modsUsed}')
print(f'Life bar graph = {read_string()}')
print('comma separated pairs u/v, where u is the time in milliseconds into the song and v is a floating point value from 0 - 1 that represents the amount of life you have at the given time (0 = life bar is empty, 1= life bar is full)')
t = int.from_bytes(f.read(8), byteorder='big', signed=False)
print(f'Time stamp = {time.strftime("%Y-%m-%dT%H:%M:%SZ",time.localtime(t))}')
bytelen = read_int()
print(f'Length in bytes of compressed replay data = {bytelen}')
replay_data = lzma.decompress(f.read(bytelen)).strip(b'\x00').decode('utf-8', 'ignore')
print(f'Compressed replay data = {replay_data}')
print(f'Online Score ID = {read_long()}')
print(f'Additional mod information. = {read_long()}')
print('-*-*-*-*-*-*-*-*-*-*-*-')
print(' Mods Used')
print('-*-*-*-*-*-*-*-*-*-*-*-')
def mod_check(n: int) -> bool:
return (modsUsed >> n) & 1
if modsUsed == 0:
print('None mods')
exit(0)
if mod_check(1):
print('NoFail')
if mod_check(2):
print('Easy')
if mod_check(3):
print('TouchDevice')
if mod_check(4):
print('Hidden')
if mod_check(5):
print('HardRock')
if mod_check(6):
print('DoubleTime')
if mod_check(7):
print('Relax')
if mod_check(8):
print('HalfTime')
if mod_check(9):
print('NightCore')
if mod_check(10):
print('Flashlight')
if mod_check(11):
print('Autoplay')
if mod_check(12):
print('SpunOut')
if mod_check(13):
print('Relax2')
if mod_check(14):
print('Perfect')
if mod_check(15):
print('Key4')
if mod_check(16):
print('Key5')
if mod_check(17):
print('Key6')
if mod_check(18):
print('Key7')
if mod_check(19):
print('Key8')
if mod_check(15) and mod_check(16) and mod_check(17) and mod_check(18) and mod_check(19):
print('keyMod')
if mod_check(20):
print('Fadeln')
if mod_check(21):
print('Random')
if mod_check(22):
print('LastMod')
if mod_check(23):
print('TargetPractice')
if mod_check(24):
print('Key9')
if mod_check(25):
print(('Coop'))
if mod_check(26):
print('Key1')
if mod_check(27):
print('Key3')
if mod_check(28):
print('Key2')
if mod_check(29):
print('ScoreV2')
if mod_check(30):
print('Mirror')
Comments