본문으로 바로가기

Houseplant CTF

category CTF/CTF Playground 2020. 4. 27. 01:02

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(skey) :
    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(s1s2) :
    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 = [11451521089510352109511141159510188991081171154911851]
    finalflag = [196209147211191194210234225248122167232167241121247166]

    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(07) :
        userinput[i+8] = chr(theflag[index] - flag[i])
        index += 1

    for i in range(1015) :
        userinput[i-8] = chr(theflag[index] - flag[i])
        index += 1

    for i in range(1521) :
        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:dicts:listuwu:bool) :
    realflag = [94238171180137220161022121961521314511]
    therealflag = [20161296152131801371423817210221911145]

    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 = [157157236168160162171162165199169169160194235207227210157203227104212202]
    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 = [157157236168160162171162165199169169160194235207227210157203227104212202]
    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(32127) :
            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:byteskey:Tuple[intint]) -> 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(32126) :
        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.41.8], [2.2, -1.81.6], [-11, -1]])
    S = Matrix([[3736, -1], [3427, -7], [16023756], [5811044], [669322], [14321049], [113322]]).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 = 012345678
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 == (2550  , 0  ) : l.append(RED)
            elif px == (0  , 2550  ) : l.append(GREEN)
            elif px == (2552550  ) : l.append(YELLOW)
            elif px == (0  , 0  , 255) : l.append(BLUE)
            elif px == (2550  , 255) : l.append(MAGENTA)
            elif px == (0  , 255255) : l.append(CYAN)
            elif px == (255255255) : l.append(WHITE)
            elif px == (128128128) : 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+3for _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 = -1012
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(fileremove=False) :
    _int_decompress = [decompress_gz, decompress_tar, decompress_zip]
    filetype = check_type(file)

    if filetype > NONE :
        _int_decompress[filetype](file, remove)

def decompress_gz(fileremove=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(fileremove=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(fileremove=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