Beginners :: Beginner 1
BASE64 decode
Flag: rtcp{youre_very_welcome}
Beginners :: Beginner 2
ASCII conversion
Flag: rtcp{bob_you_suck_at_being_encouraging}
Beginners :: Beginner 3
ASCII conversion (octal)
Flag: rtcp{sue_me_i_didnt_know_what_octal_was_okay?!}
Beginners :: Beginner 4
Caesar cipher, key=13
Flag: rtcp{yall_better_participate}
Beginners :: Beginner 5
Morse code
Flag: rtcp{MANY_BEEPS_AND_BOOPS}
Beginners :: Beginner 6
Alphabet index
Flag: rtcp{zzzzzzzzsleepinginphysics}
Beginners :: Beginner 7
Atbash cipher
Flag: rtcp{unless_they_are_mean}
Beginners :: Beginner 8
Bacon cipher, alphabet=complete
Flag: rtcp{GOEATFOODDONTSTARVE}
Beginners :: Beginner 9
BASE64 decode > hex conversion > morse code > binary conversion > A1Z26 decode > Atbash cipher decode > Caesar cipher decode (key=13)
위 과정을 거치면 "nineornone" 이 나온다. (CyberChef로 ㄱㄱ)
Flag: rtcp{nineornone}
Pwn :: Pie Generator
페이지 소스를 보면, number 외에 timestamp 값을 전달한다. 이 값이 seed로 사용되는 듯 하니 값을 고정해 놓고 number를 보내서 정답 숫자를 확인한 뒤, 그 숫자를 보내줘서 플래그를 딸 수 있다.
Flag: rtcp{w0w_sO_p53uD0}
Reverse Engineering :: Fragile
Java로 역연산하는 코드 만들면 된다.
Flag: rtcp{h3y_1ts_n0t_b4d}
Reverse Engineering :: Breakable
뒷부분의 flags는 볼 필요 없다. 비교 대상 문자열을 14글자씩 반으로 나눠서 역연산하면 된다.
Flag: rtcp{0mg_1m_s0_pr0ud_}
Reverse Engineering :: EZ
Flag: rtcp{tH1s_i5_4_r3aL_fL4g_s0_Do_sUbm1T_1t!}
Reverse Engineering :: PZ
Flag: rtcp{iT5_s1mPlY_1n_tH3_C0d3}
Reverse Engineering :: LEMON
Flag: rtcp{y34H_tHiS_a1nT_sEcuR3}
Reverse Engineering :: SQUEEZY
1
2 3 4 5 6 7 8 9 10 11 12 |
import base64
def xor(s, key) : return bytes([c1^c2 for c1, c2 in zip(s, key)]) if __name__ == '__main__' : s = base64.b64decode(b'HxEMBxUAURg6I0QILT4UVRolMQFRHzokRBcmAygNXhkqWBw=') key = b'meownyameownyameownyameownyameownya' flag = xor(s, key).decode() print(flag) |
Flag: rtcp{y0u_L3fT_y0uR_x0r_K3y_bEh1nD!}
Reverse Engineering :: thedanzman
result에 장난을 쳐놨는데, ROT13을 돌리고 b'' 형식을 빼 준 문자열을 처리해야 한다.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import base64
import codecs def xor(s1, s2) : return bytes([c1^c2 for c1, c2 in zip(s1, s2)]) if __name__ == '__main__' : s = 'ExgNCgkMWhQ3ES1XPDoSVVkxDFwcUDcGLVcEKVYvCwcvKxM=' key = codecs.encode('nyameowpurrpurrnyanyapurrpurrnyanya', 'rot_13') s = base64.b64decode(s.encode()) flag = xor(s, key.encode()).decode() print(flag) |
Flag: rtcp{n0w_tH4T_w45_m0r3_cH4lL3NgiNG}
Reverse Engineering :: Bendy
Java에서 리버싱을 하면 여러모로 불편해서, 문자열의 문자를 정수로 변환하고 python으로 돌렸다.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
if __name__ == '__main__' :
flag = [114, 51, 52, 108, 95, 103, 52, 109, 51, 114, 115, 95, 101, 88, 99, 108, 117, 115, 49, 118, 51] finalflag = [196, 209, 147, 211, 191, 194, 210, 234, 225, 248, 122, 167, 232, 167, 241, 121, 247, 166] theflag = [i-20 for i in finalflag[9:]] + finalflag[:9] index = 0 userinput = [None for _ in range(21)] userinput[0] = 'h' userinput[1] = '0' userinput[7] = 'u' for i in range(0, 7) : userinput[i+8] = chr(theflag[index] - flag[i]) index += 1 for i in range(10, 15) : userinput[i-8] = chr(theflag[index] - flag[i]) index += 1 for i in range(15, 21) : userinput[i] = chr(theflag[index] - flag[i-3]) index += 1 print(''.join(userinput)) |
Flag: rtcp{h0p3_y0ur3_h4v1ng_fun}
Reverse Engineering :: Tough
마찬가지로 python으로 이식했지만, 풀이는 더 복잡해졌다.
userinput에 따라서 substitution table 매핑이 달라지기 때문에, 한 글자씩 브루트포싱하고 결과값을 검증하는 방식으로 플래그를 찾았다.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
from typing import *
FLAGSIZE = 24 def stoi(s:str) -> List[int] : return [ord(c) for c in s] def itos(l:List[int]) -> str : return ''.join([chr(c) for c in l]) def CreateMap(hashmap:dict, s:list, uwu:bool) : realflag = [9, 4, 23, 8, 17, 1, 18, 0, 13, 7, 2, 20, 16, 10, 22, 12, 19, 6, 15, 21, 3, 14, 5, 11] therealflag = [20, 16, 12, 9, 6, 15, 21, 3, 18, 0, 13, 7, 1, 4, 23, 8, 17, 2, 10, 22, 19, 11, 14, 5] for i in range(len(s)) : if uwu : hashmap[realflag[i]] = s[i] else : hashmap[therealflag[i]] = s[i] def FinalFlag(userinput:List[int]) : flag = stoi('ow0_wh4t_4_h4ckr_y0u_4r3') theflags = {} theflags0 = {} theflags1 = {} theflags2 = {} CreateMap(theflags, userinput, True) CreateMap(theflags0, flag, False) CreateMap(theflags1, userinput, False) CreateMap(theflags2, flag, True) theflag = [] thefinalflag = [] i = 0 size = len(userinput) while i < size-3 : theflag.append(theflags[i]) i += 1 while i < size : theflag.append(theflags1[i]) i += 1 for p in range(len(theflag)) : thefinalflag.append(theflags0[p] + theflag[p]) for p in range(len(theflag)) : if thefinalflag[p] > 146 and thefinalflag[p] < 157 : thefinalflag[p] += 10 return thefinalflag def MatchIndex() : finalflag = [157, 157, 236, 168, 160, 162, 171, 162, 165, 199, 169, 169, 160, 194, 235, 207, 227, 210, 157, 203, 227, 104, 212, 202] cindex = {} cinput = [0 for _ in range(FLAGSIZE)] for i in range(FLAGSIZE) : cinput[i] = 1 r1 = FinalFlag(cinput) cinput[i] = 2 r2 = FinalFlag(cinput) for j in range(len(r1)) : if r1[j] != r2[j] : cindex[i] = j break cinput[i] = 0 return cindex if __name__ == '__main__' : userinput = [0 for _ in range(FLAGSIZE)] finalflag = [157, 157, 236, 168, 160, 162, 171, 162, 165, 199, 169, 169, 160, 194, 235, 207, 227, 210, 157, 203, 227, 104, 212, 202] userinput[2] = ord('r') userinput[3] = ord('3') userinput[5] = ord('_') userinput[7] = ord('_') userinput[22] = ord('o') cindex = MatchIndex() for index in range(FLAGSIZE) : if userinput[index] != 0 : continue for i in range(32, 127) : userinput[index] = i result = FinalFlag(userinput) if result[cindex[index]] == finalflag[cindex[index]] : break print(itos(userinput)) |
Flag: flag{h3r3s_4_c0stly_fl4g_4you}
Web :: I don't like needles
/?sauce 로 웹 소스를 볼 수 있다.
id: flagman69 --
Flag: rtcp{y0u-kn0w-1-didn't-mean-it-like-th@t}
Web :: QR Generator
backtick으로 command injection이 통한다. 그런데 결과값의 첫 글자만 QRCode로 나와서 약간의 삽질이 필요하다.
처음에는 손으로 하다가 귀찮아서 python으로 자동화했다. 요지만 간략히 설명하면, wc로 결과 문자열의 글자 개수를 세고 해당 개수만큼 반복문 돌면서 한 글자씩 가져오는 방식이다.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
import argparse
import requests from io import BytesIO from PIL import Image from pyzbar.pyzbar import decode import socket import requests.packages.urllib3.util.connection as urllib3_cn def allowed_gai_family() : family = socket.AF_INET return family urllib3_cn.allowed_gai_family = allowed_gai_family def TranslateQR(qrcode:bytes) : stream = BytesIO(qrcode) f = Image.open(stream) r = decode(f)[0] f.close() stream.close() return r.data def Result(cmd) : URL = 'http://challs.houseplant.riceteacatpanda.wtf:30004' result = [] count = 0 index = 1 # retrieve character counts while True : r = requests.get(URL+'/qr?text=`echo $({}) | wc -m | head -c {} | tail -c 1`'.format(cmd, index)) d = TranslateQR(r.content) if d[0] == 10 : break count *= 10 count += int(d) index += 1 print('[+] Data size = {}'.format(count)) # retrieve result data for index in range(count) : r = requests.get(URL+'/qr?text=`echo -n $({}) | head -c {} | tail -c 1`'.format(cmd, index)) d = TranslateQR(r.content) result.append(d.decode()) print('[.] Retrieved {} bytes ...'.format(index+1).ljust(40, ' '), end='\r') print('[+] Result :'.ljust(40, ' ')) print(''.join(result)) if __name__ == '__main__' : parser = argparse.ArgumentParser() parser.add_argument('cmd', help='target commandline') args = parser.parse_args() Result(args.cmd) |
이거보다 더 쉬운 풀이가 있는지는 잘 모르겠다..
Flag: rtcp{fl4gz_1n_qr_c0d3s???_b1c3fea}
Crypto :: CH₃COOH
딱 봐도 Vigenere 같은데 키가 뭔지 몰라서 헤매다가, vigenere solver 사이트를 발견하고 풀었다. (key=tony)
시간이 된다면 나중에 직접 vigenere solver를 제작해 보는 것도 좋은 경험이 될 것 같다.
Vinegar is an aqueous solution of acetic acid and trace chemicals that may include flavorings.
Vinegar typically contains five to eight percent acetic acid by volume. Usually the acetic acid is produced by the fermentation of ethanol or sugars by acetic acid bacteria. There are many types of vinegar, depending on source materials. Vinegar is now mainly used in the culinary arts: as a flavorful, acidic cooking ingredient, or in pickling. As the most easily manufactured mild acid, it has historically had a wide variety of industrial and domestic uses (such as its use as a household cleaner). While vinegar making may be as old as alcoholic brewing, the first documented evidence of vinegar making and use was by the Ancient Babylonians around 3000 BC. They primarily made vinegar from dates, figs, and beer and used it for both culinary and medicinal purposes. Traces of it also have been found in Egyptian urns. In East Asia, the Chinese began professionalizing vinegar production in the Zhou Dynasty. In the book Zhou Li, it mentions many noble or royal households had a “vinegar maker” as a specialized position. Most vinegar making then was concentrated in what is now Shanxi province near the city Taiyuan which remains a famous vinegar making region today. Many Chinese vinegars and their uses for culinary and medicinal purposes were written down in the agricultural manual Qimin Yaoshu. rtcp{vinegar_on_my_fish_and_chips_please} |
Flag: rtcp{vinegar_on_my_fish_and_chips_please}
Crypto :: "fences are cool unless they're taller than you" - tida
Railfence cipher (rails=3, offset=7)
Flag: rtcp{ask_tida_about_rice_washing}
Crypto :: Returning Stolen Archives
RSA이긴 한데 한 글자씩 암호화를 해서, 가능한 모든 알파벳 글자들을 암호화한 뒤 ciphertext와 대조해서 플래그를 찾을 수 있다.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from binascii import hexlify
from typing import * def encrypt(plaintext:bytes, key:Tuple[int, int]) -> int : e = key[0] N = key[1] plaintext = int.from_bytes(plaintext, 'big') return pow(plaintext, e, N) if __name__ == '__main__' : with open('intercepted.txt', 'r') as f : exec(f.read()) table = {} plaintext = [] for c in range(32, 126) : table[encrypt(bytes([c]), (e, n))] = chr(c) for c in ct : plaintext.append(table[c]) print(''.join(plaintext)) |
Flag: rtcp{cH4r_bY_Ch@R!}
Crypto :: Broken Yolks
약간의 게싱을 바탕으로 진행해야 하는 unscramble 문제다.
먼저 해당 단어를 통째로 검색하면, descrambled, descrambler가 가장 눈에 띈다.
플래그에 "scramble" 이라는 단어가 들어간다는 가정을 하면, 남은 글자는 "doirrefd" 가 된다. 이 단어 역시 통째로 검색해보니 아래와 같은 흥미로운 결과를 발견했다.
문제 설명에 fried라는 단어가 있었으므로 이 단어가 들어간다고 생각해 볼 수 있었다. 이 단어를 포함시키면 남은 글자는 "dor" 가 되는데, scramble에 d를 붙여서 scrambled를 만들면 scrambled, fried, or 세 단어를 얻는다. fried_or_scrambled와 scrambled_or_fried 둘 다 넣어보니 후자를 입력했을 때 correct를 받았다.
Flag: rtcp{scrambled_or_fried}
Crypto :: Rivest Shamir Adleman
factordb에 N을 넣어보니 바로 소인수분해가 되었다. (...)
$$ \begin{align} p = 58754030774905986805754122995310081662217884210168479550129875193424398870745444673926050610118197084042202162420044553461740174815697964254570199939394803548997633592060223756279974260864378745120001533514186672141428133398599326104981445779780014073764199910798520251506148673445046102194538255507437319319 \\ q = 88761620475672281797897005732643499821690688597370440945258776182910533850401433150065043871978311565287949564292158396906865512113015114468175188982916489347656271125993359554057983487741599275948833820107889167078943493772101668339096372868672343763810610724807588466294391846588859523658456534735572626377 \end{align} $$
d를 계산해서 private_key.json을 만들고 decrypt.py를 돌리면 된다.
Flag: rtcp{f1xed_pr*me-0r_low_e?}
Crypto :: Post-Homework Death
단순 행렬곱 문제다.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from sage.all import *
if __name__ == '__main__' : D = Matrix([[1.6, -1.4, 1.8], [2.2, -1.8, 1.6], [-1, 1, -1]]) S = Matrix([[37, 36, -1], [34, 27, -7], [160, 237, 56], [58, 110, 44], [66, 93, 22], [143, 210, 49], [11, 33, 22]]).transpose() P = D*S print(P) for column in P.columns() : for t in column : t = t.round() if t == 0 : print('_', end='') else : print(chr(int(t+96)), end='') print('') |
Flag: rtcp{go_do_your_homework}
Crypto :: Sizzle
.은 0, -은 1로 바꾼 뒤 Bacon cipher decode로 풀면 된다. (문제 설명에 bacon 언급이 되어있어서 눈치가 있으면 바로 풀 수 있다.)
Flag: rtcp{bacon_but_grilled_and_morsified}
Crypto :: Parasite
Morse + SKATS
해독하면 "희망은 진정한 기생충입니다" 이라는 문장이 나온다. (읭?)
영미권 시점으로 생각해서, 해당 문장을 구글 번역기에 돌리고 제출했더니 정답이 떴다. 한국인한테 유리할 것 같지만 한글 자체가 쉬운 문자 체계이기 때문에 한글을 몰라도 쉽게 찾을 수 있을 듯..
Flag: rtcp{hope_is_a_true_parasite}
Crypto :: Rainbow Vomit
암호화 방법은 이미 힌트에 다 나와있고.. decoder를 얼마나 잘 만드느냐가 관건이다. 해독하면 아래의 텍스트가 나온다.
THERE IS SUCH AS THING AS A TOMCAT BUT HAVE YOU EVER HEARD OF A TOMDOG. THIS IS THE MOST IMPORTANT QUESTION OF OUR TIME, AND UNFORTUNATELY ONE THAT MAY NEVER BE ANSWERED BY MODERN SCIENCE. THE DEFINITION OF TOMCAT IS A MALE CAT, YET THE NAME FOR A MALE DOG IS MAX. WAIT NO. THE NAME FOR A MALE DOG IS JUST DOG. REGARDLESS, WHAT WOULD HAPPEN IF WE WERE TO COMBINE A MALE DOG WITH A TOMCAT. PERHAPS WED END UP WITH A DOG THAT VOMITS OUT FLAGS, LIKE THIS ONE RTCP SHOULD,FL5G4,B3,ST1CKY,OR,N0T
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
from PIL import Image
from typing import * BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, GRAY = 0, 1, 2, 3, 4, 5, 6, 7, 8 INVALID = -1 HexahuesTable = {512346 : 'A', 152346 : 'B', 125346 : 'C', 123546 : 'D', 123456 : 'E', 123465 : 'F', 213465 : 'G', 231465 : 'H', 234165 : 'I', 234615 : 'J', 234651 : 'K', 324651 : 'L', 342651 : 'M', 346251 : 'N', 346521 : 'O', 346512 : 'P', 436512 : 'Q', 463512 : 'R', 465312 : 'S', 465132 : 'T', 465123 : 'U', 645123 : 'V', 654123 : 'W', 651423 : 'X', 651243 : 'Y', 651234 : 'Z', 77007 : '.', 700770 : ',', 0 : ' ', 777777 : ' ', 87087 : '0', 807087 : '1', 870087 : '2', 870807 : '3', 870870 : '4', 780870 : '5', 708870 : '6', 708780 : '7', 708708 : '8', 78708 : '9' } def TranslateColor(image:Image) -> List[List[int]] : w = image.width h = image.height r = [] for y in range(h) : l = [] for x in range(w) : px = image.getpixel((x, y)) if px == (0 , 0 , 0 ) : l.append(BLACK) elif px == (255, 0 , 0 ) : l.append(RED) elif px == (0 , 255, 0 ) : l.append(GREEN) elif px == (255, 255, 0 ) : l.append(YELLOW) elif px == (0 , 0 , 255) : l.append(BLUE) elif px == (255, 0 , 255) : l.append(MAGENTA) elif px == (0 , 255, 255) : l.append(CYAN) elif px == (255, 255, 255) : l.append(WHITE) elif px == (128, 128, 128) : l.append(GRAY) else : l.append(INVALID) r.append(l) return r def ConvertCode(data:List[int]) -> str : try : code = int(''.join([str(c) for c in data]), 10) return HexahuesTable[code] except : return None def DecodeHexahue(image:Image) -> str : w = image.width h = image.height data = TranslateColor(image) text = [] for y in range(0, h, 3) : for x in range(0, w, 2) : px = [data[_y][_x] for _y in range(y, y+3) for _x in range(x, x+2)] text.append(ConvertCode(px)) print(''.join(text)) if __name__ == '__main__' : image = Image.open('no-border.png') DecodeHexahue(image) image.close() |
Flag: rtcp{should,fl5g4,b3,st1cky,or,n0t}
OSINT :: The Drummer who Gave all his Daughters the Same Name
https://www.giac.org/paper/gsec/644/malicious-code-vbs-onthefly-anna-kournikova/101208
Flag: Worm made with Vbswg 1.50b
OSINT :: What a Sight to See!
Flag: site:
Misc :: Rules
Flag: rtcp{this_is_not_a_flag_i_think}
Misc :: Spilled Milk
배경을 검은색으로 바꾸면 보인다.
Flag: rtcp{Th4nk$_f0r_h3LP1nG!}
Misc :: Survey
폼을 다 채우면 어떤 문자열이 하나 나온다. BASE85로 디코딩하면 "send Jade (in her DMs) `rice_tea_cat_panda`" 가 된다.
Jade한테 rice_tea_cat_panda를 DM으로 보내면 플래그가 나온다. (이전 대회에 썼던 거랑 똑같은 봇이다.)
Flag: rtcp{awaken_winged_sun_dragon_of_ra}
Misc :: Zip-a-Dee-Doo-Dah
파일을 까면 .tar, .gz, .zip 세 가지 형식 중 하나가 나오며 .zip은 암호가 걸려있다.
처음에는 decompress에서 바로 다음 파일 decompress를 실행했는데 recursion depth 한계치에 걸려서 전역변수로 큐를 만들어서 돌렸다.
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
import gzip
import os import tarfile import zipfile from subprocess import check_output NONE, GZ, TAR, ZIP = -1, 0, 1, 2 TARGET = [] MODE = -1 def check_type(name:str) : if name.endswith('.tar') : return TAR elif name.endswith('.zip') : return ZIP elif name.endswith('.gz') : return GZ else : return -1 def decompress(file, remove=False) : _int_decompress = [decompress_gz, decompress_tar, decompress_zip] filetype = check_type(file) if filetype > NONE : _int_decompress[filetype](file, remove) def decompress_gz(file, remove=False) : with open(file, 'rb') as f : data = f.read() dname = check_output(['gunzip', '-Nlq', file]) dname = dname.decode().strip() dname = dname[dname.find('%')+2:] print('[+] Decompressing {} -> {} ...'.format(file, dname)) with open(dname, 'wb') as f : f.write(gzip.decompress(data)) if remove : os.system('rm {}'.format(file)) TARGET.append(dname) def decompress_tar(file, remove=False) : f_tar = tarfile.open(file) for f in f_tar.getmembers() : dname = f.name print('[+] Decompressing {} -> {} ...'.format(file, dname)) f_tar.extract(f) TARGET.append(dname) f_tar.close() if remove : os.system('rm {}'.format(file)) def decompress_zip(file, remove=False) : global passwords f_zip = zipfile.ZipFile(file, 'r') results = [] password = None for dname in f_zip.namelist() : print('[+] Decompressing {} -> {} ...'.format(file, dname)) if password : f_zip.extract(dname, pwd=password) else : for pw in passwords : try : f_zip.extract(dname, pwd=pw) TARGET.append(dname) password = pw print(' password: {}'.format(pw.decode())) break except : pass if not password : print('[-] Failed to find password in {}.'.format(file)) f_zip.close() if remove : os.system('rm {}'.format(file)) if __name__ == '__main__' : with open('passwords.txt', 'rb') as f : passwords = f.read().replace(b'\r', b'').split(b'\n') TARGET.append('1819.gz') while len(TARGET) != 0 : name = TARGET[0] TARGET = TARGET[1:] decompress(name, True) |
Flag: rtcp{z1pPeD_4_c0uPl3_t00_M4Ny_t1m3s_a1b8c687}
Misc :: Music Lab
무려 6년만에 MIDITrail을 꺼냈다. (https://www.youtube.com/watch?v=ymKsk61gFUc)
플래그를 얻는 것 자체는 그냥 미디 플레이어 돌리면 되는데, resolution이 안 좋아서 애매한 글자를 잘 찍어 맞춰야 한다.
Flag: rtcp{M0z4rt_WOuld_b3_proud}
Misc :: I only see in cubes
NBTExplorer로 세이브 폴더를 통째로 열은 뒤 regions에서 value=book 을 검색하고 책 내용을 전부 합하면 된다.
tag.title = "Book one", tag.pages[0].text = "rtcp{D0n't_d1g
tag.title = "Book two", tag.pages[0].text = "_*str4ight_"
tag.title = "Book three", tag.pages[0].text = "d0wn$}"
Flag: rtcp{D0n't_d1g_*str4ight_d0wn$}
'CTF > CTF Playground' 카테고리의 다른 글
Brixel CTF winter edition (0) | 2021.01.06 |
---|---|
IJCTF 2020 (0) | 2020.04.27 |
TAMUctf 2020 (0) | 2020.03.30 |
Securinets Prequals 2K20 (0) | 2020.03.23 |
riftCTF (0) | 2020.03.21 |