UTCTF 2024 Writeup

この大会は2024/3/30 8:00(JST)~2024/4/1 8:00(JST)に開催されました。
今回もチームで参戦。結果は4138点で854チーム中141位でした。
自分で解けた問題をWriteupとして書いておきます。

Beginner: Basic Reversing Problem (Reverse Engineering)

Ghidraでデコンパイルする。

undefined8 main(EVP_PKEY_CTX *param_1,EVP_PKEY *param_2)

{
  keygen(param_1,param_2);
  return 0;
}

int keygen(EVP_PKEY_CTX *ctx,EVP_PKEY *pkey)

{
  long in_FS_OFFSET;
  undefined local_28 [24];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  l1(local_28);
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}

void l1(undefined *param_1)

{
  *param_1 = 0x75;
  l2(param_1 + 1);
  return;
}

void l2(undefined *param_1)

{
  *param_1 = 0x74;
  l3(param_1 + 1);
  return;
}

void l3(undefined *param_1)

{
  *param_1 = 0x66;
  l4(param_1 + 1);
  return;
}

void l4(undefined *param_1)

{
  *param_1 = 0x6c;
  l5(param_1 + 1);
  return;
}

void l5(undefined *param_1)

{
  *param_1 = 0x61;
  l6(param_1 + 1);
  return;
}

void l6(undefined *param_1)

{
  *param_1 = 0x67;
  l7(param_1 + 1);
  return;
}

void l7(undefined *param_1)

{
  *param_1 = 0x7b;
  l8(param_1 + 1);
  return;
}

void l8(undefined *param_1)

{
  *param_1 = 0x69;
  l9(param_1 + 1);
  return;
}

void l9(undefined *param_1)

{
  *param_1 = 0x5f;
  l10(param_1 + 1);
  return;
}

void l10(undefined *param_1)

{
  *param_1 = 99;
  l11(param_1 + 1);
  return;
}

void l11(undefined *param_1)

{
  *param_1 = 0x34;
  l12(param_1 + 1);
  return;
}

void l12(undefined *param_1)

{
  *param_1 = 0x6e;
  l13(param_1 + 1);
  return;
}

void l13(undefined *param_1)

{
  *param_1 = 0x5f;
  l14(param_1 + 1);
  return;
}

void l14(undefined *param_1)

{
  *param_1 = 0x72;
  l15(param_1 + 1);
  return;
}

void l15(undefined *param_1)

{
  *param_1 = 0x33;
  l16(param_1 + 1);
  return;
}

void l16(undefined *param_1)

{
  *param_1 = 0x76;
  l17(param_1 + 1);
  return;
}

void l17(undefined *param_1)

{
  *param_1 = 0x21;
  l18(param_1 + 1);
  return;
}

void l18(undefined *param_1)

{
  *param_1 = 0x7d;
  l19(param_1 + 1);
  return;
}

void l19(undefined *param_1)

{
  *param_1 = 0;
  return;
}

順にコードを文字にしていけばよい。

>>> codes = [0x75, 0x74, 0x66, 0x6c, 0x61, 0x67, 0x7b, 0x69, 0x5f, 99, 0x34, 0x6e, 0x5f, 0x72, 0x33, 0x76, 0x21, 0x7d]
>>> ''.join([chr(code) for code in codes])
'utflag{i_c4n_r3v!}'
utflag{i_c4n_r3v!}

HTMLソースを見ると、以下のスクリプトが書かれている。

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            var count = parseInt(localStorage.getItem('count')) || 0;
            var cookieImage = document.getElementById('cookieImage');
            var display = document.getElementById('clickCount');

            display.textContent = count;

            cookieImage.addEventListener('click', function() {
                count++;
                display.textContent = count;
                localStorage.setItem('count', count);

                if (count >= 10000000) {
                    fetch('/click', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded'
                        },
                        body: 'count=' + count
                    })
                    .then(response => response.json())
                    .then(data => {
                        alert(data.flag);
                    });
                }
            });
        });
    </script>

クリック回数が10000000回以上の場合の処理を実行する。

$ curl http://betta.utctf.live:8138/click -H "Content-Type: application/x-www-form-urlencoded" -d "count=10000000"
{"flag":"Wow, you beat me. Congrats! utflag{y0u_cl1ck_pr3tty_f4st}"}
utflag{y0u_cl1ck_pr3tty_f4st}

Contracts (Forensics)

https://www.extractpdf.com/で画像を抽出すると、フラグが書かれた画像が抽出できた。

utflag{s1mple_w1z4rding_mist4k3s}

RSA-256 (Cryptography)

Nをfactordbで素因数分解する。

N = 1025252665848145091840062845209085931 * 75575216771551332467177108987001026743883

あとは通常通り、RSA暗号の復号をする。

#!/usr/bin/env python3
from Crypto.Util.number import *

with open('vals.txt', 'r') as f:
    params = f.read().splitlines()

N = int(params[0].split(' ')[-1])
e = int(params[1].split(' ')[-1])
c = int(params[2].split(' ')[-1])

p = 1025252665848145091840062845209085931
q = 75575216771551332467177108987001026743883
assert p * q == N

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, N)

flag = long_to_bytes(m).decode()
print(flag)
utflag{just_send_plaintext}

Beginner: Anti-dcode.fr (Cryptography)

シーザー暗号26パターンを実行し、"utflag{"が含まれるものを探し、フラグを抽出する。

#!/usr/bin/env python3
import string
import re

def caesar(s, key):
    d = ''
    for c in s:
        code = ord(c)
        if c in string.ascii_uppercase:
            code = code - key
            if code < ord('A'):
                code += 26
        elif c in string.ascii_lowercase:
            code = code - key
            if code < ord('a'):
                code += 26
        d += chr(code)
    return d

with open('LoooongCaesarCipher.txt', 'r') as f:
    enc = f.read()

for i in range(26):
    dec = caesar(enc, i)
    if 'utflag{' in dec:
        pattern = '(utflag\{[a-z_]+\})'
        m = re.search(pattern, dec)
        flag = m.group(1)
        print(flag)
        break
utflag{rip_dcode}

numbers go brrr (Cryptography)

サーバの処理概要は以下の通り。

・seed: 0以上10**6以下のランダム整数
・以下繰り返し
 ・user_input: 数値入力
 ・user_inputが1の場合、繰り返し終了
 ・message: 入力
 ・encrypt(message.encode())を表示
  ・key = b''
  ・8回以下繰り返し
   ・keyにget_random_number() % (2 ** 16)の2バイト文字を追加
  ・ciphertext: messageをパディングし、AES暗号化
  ・ciphertextを16進数表記で返却
・flag: フラグ
・encrypt(flag.encode())を表示

seedをブルートフォースし、平文と暗号文の組み合わせが合う鍵を探し、フラグを復号する。

#!/usr/bin/env python3
import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import random

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data.decode()
        data += s.recv(1)

def get_random_number():
    global seed
    seed = int(str(seed * seed).zfill(12)[3:9])
    return seed

def encrypt(message):
    key = b''
    for i in range(8):
        key += (get_random_number() % (2 ** 16)).to_bytes(2, 'big')
    cipher = AES.new(key, AES.MODE_ECB)
    ciphertext = cipher.encrypt(pad(message, AES.block_size))
    return ciphertext.hex()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('betta.utctf.live', 7356))

data = recvuntil(s, b'\n').rstrip()
print(data)

try_pt = '1234'

data = recvuntil(s, b'\n').rstrip()
print(data)
print('2')
s.sendall(b'2\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
print(try_pt)
s.sendall(try_pt.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
try_ct_hex = data.split(' ')[-1]

data = recvuntil(s, b'\n').rstrip()
print(data)
print('1')
s.sendall(b'1\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
enc_flag = bytes.fromhex(data.split(' ')[-1])
print()

for seed in range(10 ** 6 + 1):
    ct_hex = encrypt(try_pt.encode())
    if ct_hex == try_ct_hex:
        break

key = b''
for i in range(8):
    key += (get_random_number() % (2 ** 16)).to_bytes(2, 'big')
cipher = AES.new(key, AES.MODE_ECB)
flag = unpad(cipher.decrypt(enc_flag), AES.block_size).decode()
print(flag)

実行結果は以下の通り。

Thanks for using our encryption service! To get the encrypted flag, type 1. To encrypt a message, type 2.
What would you like to do (1 - get encrypted flag, 2 - encrypt a message)?
2
What is your message?
1234
Here is your encrypted message: a8254764914d607479e2a1f3a48fd44c
What would you like to do (1 - get encrypted flag, 2 - encrypt a message)?
1
Here is the encrypted flag: 6f6a9ce8ada3ef9d09a1c953332ec706b0c6a37b57fcd406c4b3e8435c649a2320920190e4656fca057271a8aa2d206f

utflag{deep_seated_and_recurring_self-doubts}
utflag{deep_seated_and_recurring_self-doubts}

bits and pieces (Cryptography)

1つ目のRSA暗号はFermat法でnを素因数分解して復号する。また2つ目と3つ目のRSA暗号は共通する素数をGCDを使用して割り出し、それぞれ素因数分解して復号する。

#!/usr/bin/env python3
from Crypto.Util.number import *

def isqrt(n):
    x = n
    y = (x + n // x) // 2
    while y < x:
        x = y
        y = (x + n // x) // 2
    return x

def fermat(n):
    x = isqrt(n) + 1
    y = isqrt(x * x - n)
    while True:
        w = x * x - n - y * y
        if w == 0:
            break
        elif w > 0:
            y += 1
        else:
            x += 1
    return x - y, x + y

with open('vals.txt', 'r') as f:
    params = f.read().splitlines()

n1 = int(params[0].split(': ')[1])
e1 = int(params[1].split(': ')[1])
c1 = int(params[2].split(': ')[1])

n2 = int(params[4].split(': ')[1])
e2 = int(params[5].split(': ')[1])
c2 = int(params[6].split(': ')[1])

n3 = int(params[8].split(': ')[1])
e3 = int(params[9].split(': ')[1])
c3 = int(params[10].split(': ')[1])

assert e1 == e2 == e3

p, q = fermat(n1)
phi = (p - 1) * (q - 1)
d = inverse(e1, phi)
m = pow(c1, d, n1)
flag1 = long_to_bytes(m).decode()

p = GCD(n2, n3)
assert p != 1

q2 = n2 // p
phi = (p - 1) * (q2 - 1)
d = inverse(e2, phi)
m = pow(c2, d, n2)
flag2 = long_to_bytes(m).decode()

q3 = n3 // p
phi = (p - 1) * (q3 - 1)
d = inverse(e3, phi)
m = pow(c3, d, n3)
flag3 = long_to_bytes(m).decode()

flag = flag1 + flag2 + flag3
print(flag)
utflag{oh_no_it_didnt_work_</3_i_guess_i_can_just_use_standard_libraries_in_the_future}

Cryptordle (Cryptography)

サーバの処理概要は以下の通り。

・wordlist: 単語の配列
・wordlistの各単語wordについて、以下を実行
 ・wordの長さが5であることをチェック
 ・wordの各文字letterが英小文字であることをチェック
・3回以下繰り返し
 ・answer: wordlistから1つ選択
 ・num_guesses = 0
 ・以下繰り返し
  ・num_guesses += 1
  ・guess: 入力
  ・guessがanswerと一致している場合、繰り返し終了
  ・response = 1
  ・5回以下繰り返し(x)
   ・a: guess[x]の英小文字インデックス
   ・b: answer[x]の英小文字インデックス
   ・response = (response * (a-b)) % 31
  ・responseを表示
 ・num_guessesが6より大きい場合終了
・フラグを表示

1箇所変更し、何倍になるかで答えとなる単語を導き出す。

#!/usr/bin/env python3
import socket

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data.decode()
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('betta.utctf.live', 7496))

aj = ord('j') - ord('a')
ak = ord('k') - ord('a')

for attempt in range(3):
    answer = ''

    data = recvuntil(s, b'\n').rstrip()
    print(data)
    guess_base = 'jjjjj'
    print(guess_base)
    s.sendall(guess_base.encode() + b'\n')
    data = recvuntil(s, b'\n').rstrip()
    print(data)
    base = int(data)

    for x in range(4):
        data = recvuntil(s, b'\n').rstrip()
        print(data)
        guess = 'j' * x + 'k' + 'j' * (4 - x)
        print(guess)
        s.sendall(guess.encode() + b'\n')
        data = recvuntil(s, b'\n').rstrip()
        print(data)

        val = int(data)
        for b in range(26):
            if (aj - b) * val % 31 == (ak - b) * base % 31:
                char = chr(ord('a') + b)
                answer += char
                break

    base_response = 1
    for x in range(4):
        a = ord(guess_base[x]) - ord('a')
        b = ord(answer[x]) - ord('a')
        base_response = (base_response * (a - b)) % 31

    for b in range(26):
        response = base_response
        a = ord(guess_base[x]) - ord('a')
        response = (response * (a - b)) % 31
        if response == base:
            char = chr(ord('a') + b)
            answer += char
            break

    data = recvuntil(s, b'\n').rstrip()
    print(data)
    print(answer)
    s.sendall(answer.encode() + b'\n')
    data = recvuntil(s, b'\n').rstrip()
    print(data)

data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)

実行結果は以下の通り。

What's your guess?
jjjjj
5
What's your guess?
kjjjj
17
What's your guess?
jkjjj
16
What's your guess?
jjkjj
10
What's your guess?
jjjkj
24
What's your guess?
grimy
Good job! Onward...
What's your guess?
jjjjj
4
What's your guess?
kjjjj
6
What's your guess?
jkjjj
1
What's your guess?
jjkjj
7
What's your guess?
jjjkj
16
What's your guess?
hasty
Good job! Onward...
What's your guess?
jjjjj
9
What's your guess?
kjjjj
17
What's your guess?
jkjjj
8
What's your guess?
jjkjj
8
What's your guess?
jjjkj
10
What's your guess?
essay
Good job! Onward...
Nice! You got it :) Have a flag:
utflag{sometimes_pure_guessing_is_the_strat}
utflag{sometimes_pure_guessing_is_the_strat}

numbers go brrr 2 (Cryptography)

サーバの処理概要は以下の通り。

・seed: 0以上10**6以下のランダム整数
・以下3回繰り返し
 ・seed: 0以上10**6以下のランダム整数
 ・key = encrypt(b"random text to initalize key")[0]
 ・以下繰り返し
  ・user_input: 数値入力
  ・user_inputが1の場合、繰り返し終了
  ・message: 入力
  ・key, ciphertext = encrypt(message.encode())
  ・ciphertextを表示
 ・found = False
 ・以下250回繰り返し
  ・guess: 入力
  ・guessとkeyが一致している場合
   ・found = True
   ・繰り返し終了
  ・guessとkeyが一致していない場合
   ・該当メッセージを表示
 ・foundがFalseの場合終了
・フラグを表示

seedをブルートフォースし、平文と暗号文の組み合わせが合う鍵を探す。

#!/usr/bin/env python3
import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import random

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data.decode()
        data += s.recv(1)

def get_random_number():
    global seed 
    seed = int(str(seed * seed).zfill(12)[3:9])
    return seed

def encrypt(message):
    key = b''
    for i in range(8):
        key += (get_random_number() % (2 ** 16)).to_bytes(2, 'big')
    cipher = AES.new(key, AES.MODE_ECB)
    ciphertext = cipher.encrypt(pad(message, AES.block_size))
    return key.hex(), ciphertext.hex()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('betta.utctf.live', 2435))

data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)

for i in range(3):
    data = recvuntil(s, b'\n').rstrip()
    print(data)

    try_pt = '1234'

    data = recvuntil(s, b'\n').rstrip()
    print(data)
    print('2')
    s.sendall(b'2\n')
    data = recvuntil(s, b'\n').rstrip()
    print(data)
    print(try_pt)
    s.sendall(try_pt.encode() + b'\n')
    data = recvuntil(s, b'\n').rstrip()
    print(data)
    try_ct_hex = data.split(' ')[-1]

    for seed in range(10 ** 6 + 1):
        key_hex, ct_hex = encrypt(try_pt.encode())
        if ct_hex == try_ct_hex:
            break

    data = recvuntil(s, b'\n').rstrip()
    print(data)
    print('1')
    s.sendall(b'1\n')
    data = recvuntil(s, b'\n').rstrip()
    print(data)

    data = recvuntil(s, b'\n').rstrip()
    print(data)
    print(key_hex)
    s.sendall(key_hex.encode() + b'\n')
    data = recvuntil(s, b'\n').rstrip()
    print(data)

data = recvuntil(s, b'\n').rstrip()
print(data)

実行結果は以下の通り。

Thanks for using our encryption service! To get the start guessing, type 1. To encrypt a message, type 2.
You will need to guess the key (you get 250 guesses for one key). You will do this 3 times!
Find the key 1 of 3!
What would you like to do (1 - guess the key, 2 - encrypt a message)?
2
What is your message?
1234
Here is your encrypted message: c262a1a250dc9c1c3b60940c0c8c4bc5
What would you like to do (1 - guess the key, 2 - encrypt a message)?
1
You have 250 guesses to find the key!
What is your guess (in hex)?
38106fde83a77b6a724ac4ac5ce5a11f
You found the key!
Find the key 2 of 3!
What would you like to do (1 - guess the key, 2 - encrypt a message)?
2
What is your message?
1234
Here is your encrypted message: 5dd809df595f3f7ad9193d84ad104e54
What would you like to do (1 - guess the key, 2 - encrypt a message)?
1
You have 250 guesses to find the key!
What is your guess (in hex)?
a6d9e9fe301ccf6409e3f7616e3d0f67
You found the key!
Find the key 3 of 3!
What would you like to do (1 - guess the key, 2 - encrypt a message)?
2
What is your message?
1234
Here is your encrypted message: 3fc72ed1725ec4597dfb15459aa3b0ff
What would you like to do (1 - guess the key, 2 - encrypt a message)?
1
You have 250 guesses to find the key!
What is your guess (in hex)?
ad9b5968466e0f5f9b6bbb8bb7cfb0a3
You found the key!
Here is the flag: utflag{ok_you_are_either_really_lucky_or_you_solved_it_as_intended_yay}
utflag{ok_you_are_either_really_lucky_or_you_solved_it_as_intended_yay}

simple signature (Cryptography)

$ nc betta.utctf.live 4374
Welcome to the signature generator!
This service generates signatures for nonnegative integer messages.
Today's RSA parameters are: 
n = 21256683315158182129815856331774550219736491659822013777716561403821759106942281553515127548337855434048450386309203634846966770626707737976786578578333663561713725571747549027632868189683318875229850994034558102034412982079423514302939077444742503129302726410235332341952073804606455906118875300358250493598578145242327054365472161513043655796279793521090367257196871638408895409825645953298225120130288671527609928671935379050436498665770230821360288608340575254789593194298367560007619012294850204968087401519447108433848214210445628715721764885069947977533038779890839352843397198704785901489138850520012604735409
e = 65537
Enter a message as an integer (enter 0 to stop): 2
Your signature is: 9008713126753812606011450560795999983628754565781192321534488829838369501952103936146474773001285659513690501893121485196095055975697286303499698153613457741924379705227475544080178997110805379992972098139290290226431777397101866595061818137546060738499225208101502055574688482077678941436271342264447208867798805722791535086091682216242244033815057186892893010980193607422167617166235239381106596853232383017014930464444923074422979433762404293220768415327177933596487826362256186740360846899990120510905871952493666779745057815770355935843560053301001534775647803868595046018020772095448598122540322023235388466469
Enter a message as an integer (enter 0 to stop): 0
Now, come up with your own pair!
Enter a message: 2
Enter a signature: 9008713126753812606011450560795999983628754565781192321534488829838369501952103936146474773001285659513690501893121485196095055975697286303499698153613457741924379705227475544080178997110805379992972098139290290226431777397101866595061818137546060738499225208101502055574688482077678941436271342264447208867798805722791535086091682216242244033815057186892893010980193607422167617166235239381106596853232383017014930464444923074422979433762404293220768415327177933596487826362256186740360846899990120510905871952493666779745057815770355935843560053301001534775647803868595046018020772095448598122540322023235388466469
Cannot enter a message that you already requested.

すでに指定したメッセージは指定できない。
以下のように掛け算で対応する。

sign(2) * sign(3) = sign(2 * 3) = sign(6)

つまり、2のsignatureと3のsignatureを掛け算して、nで割った余りは6のsignatureになる。

#!/usr/bin/env python3
import socket

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data.decode()
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('betta.utctf.live', 4374))

for _ in range(3):
    data = recvuntil(s, b'\n').rstrip()
    print(data)

data = recvuntil(s, b'\n').rstrip()
print(data)
n = int(data.split(' ')[-1])
data = recvuntil(s, b'\n').rstrip()
print(data)
e = int(data.split(' ')[-1])

msg1 = 2
data = recvuntil(s, b': ')
print(data + str(msg1))
s.sendall(str(msg1).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
sign1 = int(data.split(' ')[-1])

msg2 = 3
data = recvuntil(s, b': ')
print(data + str(msg2))
s.sendall(str(msg2).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
sign2 = int(data.split(' ')[-1])

msg = msg1 * msg2
sign = sign1 * sign2 % n
data = recvuntil(s, b': ')
print(data + '0')
s.sendall(b'0\n')
data = recvuntil(s, b': ')
print(data + str(msg))
s.sendall(str(msg).encode() + b'\n')
data = recvuntil(s, b': ')
print(data + str(sign))
s.sendall(str(sign).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)

実行結果は以下の通り。

Welcome to the signature generator!
This service generates signatures for nonnegative integer messages.
Today's RSA parameters are:
n = 22745040857603356094950654119013238723747220178610034852956242041562118237276081614630730515116320707642464350162664776909328033671621035970037099984090401985036500786215882362673949544724701351702912751994243681832886951060143576518069616159575153003220437956455716817271687585305182748114221157079466544219358552743750071158665042390352892225780880626672435090222836535227896004995605606638385751930854647803703207804978831496876933751774423816093334998692863816963960154660924426693605540706759797424401196054144615532821154267469412900552576245981069208807704613152854077917101279909066353977957463864413560023021
e = 65537
Enter a message as an integer (enter 0 to stop): 2
Your signature is: 9771728127420216438291835326570484519213948796085940733565111554302250933329663350576417117750608579719613061331441446546314316153007856956324333962551856613848550753055848284993047255748151261189822986688297942376939191547592466495993733461389396328425724049649199526958459886324852435254646078883654540905122012907094091320955847826798682115946480116758659104870829753562606678981451474118954274496785971392186312570363019066197559892733076246596277730910105487653771365696167538182632442947783322211008677008544608073938497673793908781559416785872041634531173325540113460746309660795478581331374905376345742352104
Enter a message as an integer (enter 0 to stop): 3
Your signature is: 15184926436984207327413599111688835154553124148571788663482988884563402565970130089438457037102287842549020950017784430846786223384555754774570708289943532606790760532829767385581104136340138806851828151461412594086502230267691292199154726841639558992521953053027264432147362707536762715897873598893894463881511315877054246526706413757426178807393768173530208334140095076590954658577489109139787717676418546920303709944283550402937938790112338850053872100781180257764868762894031181040639411839173677256161368277480431358717312962075225713465769247303150138469667451618563103163474871034508347120243927294355269289274
Enter a message as an integer (enter 0 to stop): 0
Now, come up with your own pair!
Enter a message: 6
Enter a signature: 16235471999399052729022938376393109605567026071458583804559271990193467410073795381846501865827643540851419074009527643292839224065809948450423857203043598084832480568186578361637368585968559426397302661365563429713694975808010388433552999440641045697632334380163883415746830091922515758005222043603264915039782423068309087020523916089816408778463170651918121856553919915383102039188993936162422992730214593525338147092972428373731285352025588698703399984020753514983821282995427516251661888455604952762268026558670747724249577969128422578136151189780316619099973132967922260109552080743844094221685368487561433642384
Congrats! Here is the flag: utflag{a1m05t_t3xtb00k_3x3rc153}
utflag{a1m05t_t3xtb00k_3x3rc153}

Survey (Misc)

アンケートに答えたら、以下のようなメッセージが表示された。

thank yoU for filling ouT our Feedback form!  pLeAse rate the ctf on ctftime when you Get a chance. rememBer that we will accept Your writEups for forTy-eigHt hours After the competitioN for writeup prizes. hooK em hornS!

大文字を並べる。

UTFLAGBYETHANKS
utflag{byethanks}