st98 の日記帳


[ctf] Pwn2Win CTF 2017 の write-up

チーム Harekaze で Pwn2Win CTF 2017 に参加しました。最終的にチームで 988 点を獲得し、順位は得点 207 チーム中 40 位でした。うち、私は 7 問を解いて 988 点を入れました。

以下、解いた問題の write-up です。

[Reversing 303] Achievement Unlocked

achievementunlocked_088a2d785c35acaed6cdf64afff1ecceb649690d9a4175ae6e6a7645bd1f3bbf という 1.09 MB ほどのサイズのファイルが与えられました。file に投げてどのようなファイルか確認しましょう。

$ file ./achievementunlocked_088a2d785c35acaed6cdf64afff1ecceb649690d9a4175ae6e6a7645bd1f3bbf
./achievementunlocked_088a2d785c35acaed6cdf64afff1ecceb649690d9a4175ae6e6a7645bd1f3bbf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped

stripped かつ statically linked な x86_64 の ELF のようです。実行してみましょう。

$ ./achievementunlocked_088a2d785c35acaed6cdf64afff1ecceb649690d9a4175ae6e6a7645bd1f3bbf
Flag: hoge
Wrong!

フラグの入力を求められました。Wrong! の位置を調べておいて、バイナリ中で参照されている部分を探してみましょう。

$ python
Python 2.7.9 (default, Mar  1 2015, 12:57:24) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> with open('./achievementunlocked_088a2d785c35acaed6cdf64afff1ecceb649690d9a4175ae6e6a7645bd1f3bbf', 'rb') as f:
...   print hex(f.read().index('Wrong!'))
... 
0xb2e91
$ objdump -d -M intel ./achievementunlocked_088a2d785c35acaed6cdf64afff1ecceb649690d9a4175ae6e6a7645bd1f3bbf
...
  4851f6:	48 8b 44 24 18       	mov    rax,QWORD PTR [rsp+0x18]
  4851fb:	48 8b 4c 24 10       	mov    rcx,QWORD PTR [rsp+0x10]
  485200:	48 89 0c 24          	mov    QWORD PTR [rsp],rcx
  485204:	48 89 44 24 08       	mov    QWORD PTR [rsp+0x8],rax
  485209:	e8 b2 f7 ff ff       	call   0x4849c0
  48520e:	48 8b 44 24 18       	mov    rax,QWORD PTR [rsp+0x18]
  485213:	48 8b 4c 24 10       	mov    rcx,QWORD PTR [rsp+0x10]
  485218:	48 83 f8 1e          	cmp    rax,0x1e
  48521c:	0f 84 9d 00 00 00    	je     0x4852bf
  485222:	48 8d 05 68 dc 02 00 	lea    rax,[rip+0x2dc68]        # 0x4b2e91 ("Wrong!")
  485229:	48 89 84 24 80 00 00 	mov    QWORD PTR [rsp+0x80],rax
  485230:	00 
  485231:	48 c7 84 24 88 00 00 	mov    QWORD PTR [rsp+0x88],0x6
  485238:	00 06 00 00 00 
  48523d:	48 c7 84 24 90 00 00 	mov    QWORD PTR [rsp+0x90],0x0
  485244:	00 00 00 00 00 
  485249:	48 c7 84 24 98 00 00 	mov    QWORD PTR [rsp+0x98],0x0
  485250:	00 00 00 00 00 
  485255:	48 8d 05 64 00 01 00 	lea    rax,[rip+0x10064]        # 0x4952c0
  48525c:	48 89 04 24          	mov    QWORD PTR [rsp],rax
  485260:	48 8d 84 24 80 00 00 	lea    rax,[rsp+0x80]
  485267:	00 
  485268:	48 89 44 24 08       	mov    QWORD PTR [rsp+0x8],rax
  48526d:	e8 fe 66 f8 ff       	call   0x40b970
...

gdb で 0x485218 にブレークポイントを設定して実行し、hoge を入力すると rax の値は 4 になっていました。また、hogege を入力すると rax の値は 6 になっていました。どうやらフラグの文字数は 30 文字のようです。

入力した文字数が 30 文字だった場合の処理を見ていきましょう。

  4852bf:	48 89 0c 24          	mov    QWORD PTR [rsp],rcx
  4852c3:	48 89 44 24 08       	mov    QWORD PTR [rsp+0x8],rax
  4852c8:	e8 13 f9 ff ff       	call   0x484be0
  4852cd:	0f b6 44 24 10       	movzx  eax,BYTE PTR [rsp+0x10]
  4852d2:	84 c0                	test   al,al
  4852d4:	74 7a                	je     0x485350
  4852d6:	48 8d 05 ff fd 02 00 	lea    rax,[rip+0x2fdff]        # 0x4b50dc ("Achievement Unlocked!")
  4852dd:	48 89 44 24 60       	mov    QWORD PTR [rsp+0x60],rax
  4852e2:	48 c7 44 24 68 15 00 	mov    QWORD PTR [rsp+0x68],0x15
  4852e9:	00 00 
  4852eb:	48 c7 44 24 70 00 00 	mov    QWORD PTR [rsp+0x70],0x0
  4852f2:	00 00 
  4852f4:	48 c7 44 24 78 00 00 	mov    QWORD PTR [rsp+0x78],0x0
  4852fb:	00 00 
  4852fd:	48 8d 05 bc ff 00 00 	lea    rax,[rip+0xffbc]        # 0x4952c0
  485304:	48 89 04 24          	mov    QWORD PTR [rsp],rax
  485308:	48 8d 44 24 60       	lea    rax,[rsp+0x60]
  48530d:	48 89 44 24 08       	mov    QWORD PTR [rsp+0x8],rax
  485312:	e8 59 66 f8 ff       	call   0x40b970
  485317:	48 8b 44 24 10       	mov    rax,QWORD PTR [rsp+0x10]
  48531c:	48 8b 4c 24 18       	mov    rcx,QWORD PTR [rsp+0x18]
  485321:	48 89 44 24 70       	mov    QWORD PTR [rsp+0x70],rax
  485326:	48 89 4c 24 78       	mov    QWORD PTR [rsp+0x78],rcx
  48532b:	48 8d 44 24 70       	lea    rax,[rsp+0x70]
  485330:	48 89 04 24          	mov    QWORD PTR [rsp],rax
  485334:	48 c7 44 24 08 01 00 	mov    QWORD PTR [rsp+0x8],0x1
  48533b:	00 00 
  48533d:	48 c7 44 24 10 01 00 	mov    QWORD PTR [rsp+0x10],0x1
  485344:	00 00 
  485346:	e8 65 81 ff ff       	call   0x47d4b0
  48534b:	e9 5f ff ff ff       	jmp    0x4852af
  485350:	48 8d 05 3a db 02 00 	lea    rax,[rip+0x2db3a]        # 0x4b2e91 ("Wrong!")
  485357:	48 89 44 24 40       	mov    QWORD PTR [rsp+0x40],rax
  48535c:	48 c7 44 24 48 06 00 	mov    QWORD PTR [rsp+0x48],0x6
  485363:	00 00 
  485365:	48 c7 44 24 50 00 00 	mov    QWORD PTR [rsp+0x50],0x0
  48536c:	00 00 
  48536e:	48 c7 44 24 58 00 00 	mov    QWORD PTR [rsp+0x58],0x0
  485375:	00 00 
  485377:	48 8d 05 42 ff 00 00 	lea    rax,[rip+0xff42]        # 0x4952c0
  48537e:	48 89 04 24          	mov    QWORD PTR [rsp],rax
  485382:	48 8d 44 24 40       	lea    rax,[rsp+0x40]
  485387:	48 89 44 24 08       	mov    QWORD PTR [rsp+0x8],rax
  48538c:	e8 df 65 f8 ff       	call   0x40b970
...

0x484be0 を呼んだ結果が 0 であれば Wrong! を、そうでなければ Achievement Unlocked! を出力しています。0x484be0 を見ていきましょう。

  484be0:	64 48 8b 0c 25 f8 ff 	mov    rcx,QWORD PTR fs:0xfffffffffffffff8
  484be7:	ff ff 
  484be9:	48 8d 84 24 e0 fe ff 	lea    rax,[rsp-0x120]
  484bf0:	ff 
  484bf1:	48 3b 41 10          	cmp    rax,QWORD PTR [rcx+0x10]
  484bf5:	0f 86 9d 04 00 00    	jbe    0x485098
  484bfb:	48 81 ec a0 01 00 00 	sub    rsp,0x1a0
  484c02:	48 89 ac 24 98 01 00 	mov    QWORD PTR [rsp+0x198],rbp
  484c09:	00 
  484c0a:	48 8d ac 24 98 01 00 	lea    rbp,[rsp+0x198]
  484c11:	00 
  484c12:	48 8d 05 e7 fb 00 00 	lea    rax,[rip+0xfbe7]        # 0x494800
  484c19:	48 89 04 24          	mov    QWORD PTR [rsp],rax
  484c1d:	48 c7 44 24 08 00 00 	mov    QWORD PTR [rsp+0x8],0x0
  484c24:	00 00 
  484c26:	e8 f5 e7 f7 ff       	call   0x403420
...
  484d30:	48 8b 6d 00          	mov    rbp,QWORD PTR [rbp+0x0]
  484d34:	31 c9                	xor    ecx,ecx
  484d36:	ba 01 00 00 00       	mov    edx,0x1
  484d3b:	48 89 4c 24 40       	mov    QWORD PTR [rsp+0x40],rcx
  484d40:	88 54 24 35          	mov    BYTE PTR [rsp+0x35],dl
  484d44:	48 8b 9c 24 b0 01 00 	mov    rbx,QWORD PTR [rsp+0x1b0]
  484d4b:	00 
  484d4c:	48 39 d9             	cmp    rcx,rbx
  484d4f:	0f 8d 2c 03 00 00    	jge    0x485081
  484d55:	48 8b b4 24 a8 01 00 	mov    rsi,QWORD PTR [rsp+0x1a8]
  484d5c:	00 
  484d5d:	0f b6 3c 0e          	movzx  edi,BYTE PTR [rsi+rcx*1]
  484d61:	40 88 7c 24 37       	mov    BYTE PTR [rsp+0x37],dil
  484d66:	48 8b bc 24 50 01 00 	mov    rdi,QWORD PTR [rsp+0x150]
  484d6d:	00 
  484d6e:	48 89 7c 24 08       	mov    QWORD PTR [rsp+0x8],rdi
  484d73:	48 8d 3d 86 fa 00 00 	lea    rdi,[rip+0xfa86]        # 0x494800
  484d7a:	48 89 3c 24          	mov    QWORD PTR [rsp],rdi
  484d7e:	4c 8d 44 24 37       	lea    r8,[rsp+0x37]
  484d83:	4c 89 44 24 10       	mov    QWORD PTR [rsp+0x10],r8
  484d88:	e8 43 e9 f7 ff       	call   0x4036d0
  484d8d:	31 c0                	xor    eax,eax
  484d8f:	48 89 44 24 38       	mov    QWORD PTR [rsp+0x38],rax
  484d94:	48 83 f8 08          	cmp    rax,0x8
  484d98:	7d 50                	jge    0x484dea
  484d9a:	48 8b 4c 24 40       	mov    rcx,QWORD PTR [rsp+0x40]
  484d9f:	48 8d 14 c8          	lea    rdx,[rax+rcx*8]
  484da3:	48 81 fa f0 00 00 00 	cmp    rdx,0xf0
  484daa:	0f 83 ca 02 00 00    	jae    0x48507a
  484db0:	48 8d 54 14 58       	lea    rdx,[rsp+rdx*1+0x58]
  484db5:	48 89 54 24 10       	mov    QWORD PTR [rsp+0x10],rdx
  484dba:	48 8d 15 3f fa 00 00 	lea    rdx,[rip+0xfa3f]        # 0x494800
  484dc1:	48 89 14 24          	mov    QWORD PTR [rsp],rdx
  484dc5:	48 8b 9c 24 48 01 00 	mov    rbx,QWORD PTR [rsp+0x148]
  484dcc:	00 
  484dcd:	48 89 5c 24 08       	mov    QWORD PTR [rsp+0x8],rbx
  484dd2:	e8 f9 e8 f7 ff       	call   0x4036d0
  484dd7:	48 8b 44 24 38       	mov    rax,QWORD PTR [rsp+0x38]
  484ddc:	48 ff c0             	inc    rax
  484ddf:	48 89 44 24 38       	mov    QWORD PTR [rsp+0x38],rax
  484de4:	48 83 f8 08          	cmp    rax,0x8
  484de8:	7c b0                	jl     0x484d9a
  484dea:	c6 44 24 36 00       	mov    BYTE PTR [rsp+0x36],0x0
  484def:	48 8b 84 24 90 01 00 	mov    rax,QWORD PTR [rsp+0x190]
  484df6:	00 
  484df7:	48 89 44 24 08       	mov    QWORD PTR [rsp+0x8],rax
  484dfc:	48 8d 05 fd f9 00 00 	lea    rax,[rip+0xf9fd]        # 0x494800
  484e03:	48 89 04 24          	mov    QWORD PTR [rsp],rax
  484e07:	48 8d 4c 24 36       	lea    rcx,[rsp+0x36]
  484e0c:	48 89 4c 24 10       	mov    QWORD PTR [rsp+0x10],rcx
  484e11:	e8 5a f8 f7 ff       	call   0x404670
  484e16:	0f b6 44 24 36       	movzx  eax,BYTE PTR [rsp+0x36]
  484e1b:	48 8b 4c 24 40       	mov    rcx,QWORD PTR [rsp+0x40]
  484e20:	48 85 c9             	test   rcx,rcx
  484e23:	75 1c                	jne    0x484e41
  484e25:	48 3d d0 00 00 00    	cmp    rax,0xd0
  484e2b:	74 14                	je     0x484e41
  484e2d:	31 c0                	xor    eax,eax
  484e2f:	48 ff c1             	inc    rcx
  484e32:	89 c2                	mov    edx,eax
  484e34:	48 8b 84 24 48 01 00 	mov    rax,QWORD PTR [rsp+0x148]
  484e3b:	00 
  484e3c:	e9 fa fe ff ff       	jmp    0x484d3b
  484e41:	48 83 f9 01          	cmp    rcx,0x1
  484e45:	75 0a                	jne    0x484e51
  484e47:	48 83 f8 71          	cmp    rax,0x71
  484e4b:	74 04                	je     0x484e51
  484e4d:	31 c0                	xor    eax,eax
  484e4f:	eb de                	jmp    0x484e2f
  484e51:	48 83 f9 02          	cmp    rcx,0x2
  484e55:	75 0c                	jne    0x484e63
  484e57:	48 3d e6 00 00 00    	cmp    rax,0xe6
  484e5d:	74 04                	je     0x484e63
  484e5f:	31 c0                	xor    eax,eax
  484e61:	eb cc                	jmp    0x484e2f
  484e63:	48 83 f9 03          	cmp    rcx,0x3
  484e67:	75 0a                	jne    0x484e73
  484e69:	48 83 f8 32          	cmp    rax,0x32
  484e6d:	74 04                	je     0x484e73
  484e6f:	31 c0                	xor    eax,eax
  484e71:	eb bc                	jmp    0x484e2f
...

入力した文字列を何かしてから、ループのカウンターが 1 であれば何かされた文字と 0x71 と比較、2 であれば 0xe6 と比較、3 であれば 0x32 と比較 … ということを繰り返しています。

以下のようなスクリプトを key.py として保存して実行してみます。

plaintext = 'A' * 30
encrypted = ''

def xor(s, t):
  return ''.join(chr(ord(c) ^ ord(d)) for c, d in zip(s, t))

class MyBreakpoint(gdb.Breakpoint):
  def stop(self):
    global encrypted
    encrypted += chr(gdb.parse_and_eval('$rax'))
    return False

with open('input', 'w') as f:
  f.write(plaintext)

MyBreakpoint('*0x484e41')
gdb.execute('r < input')
print repr(xor(plaintext, encrypted))
gdb.execute('q')
$ gdb -n -x key.py ./achievementunlocked_088a2d785c35acaed6cdf64afff1ecceb649690d9a4175ae6e6a7645bd1f3bbf
Reading symbols from ./achievementunlocked_088a2d785c35acaed6cdf64afff1ecceb649690d9a4175ae6e6a7645bd1f3bbf...(no debugging symbols found)...done.
Breakpoint 1 at 0x484e41
Flag: Wrong!
[Inferior 1 (process 4256) exited normally]
'%\xa0\x1fMhry\x90\x90\xf5:\x81\xfc6-\x06\xf7|\xe6\x83F/\x9e@\x05\xb1\xb0\xea-'

plaintext = 'A' * 30plaintext = 'B' * 30 に変えてみても同じ結果が得られました。どうやら xor を使っているようです。

比較されている値を集めて xor してみましょう。

def xor(s, t):
  return ''.join(chr(ord(c) ^ ord(d)) for c, d in zip(s, t))

print xor('\x71\xe6\x32\x0f\x3a\x09\x2e\xf8\xa1\xb6\x52\xde\xcd\x65\x72\x52\x9f\x4f\xb9\xf4\x72\x76\xc1\x34\x35\xee\xf7\xda\x50', '%\xa0\x1fMhry\x90\x90\xf5:\x81\xfc6-\x06\xf7|\xe6\x83F/\x9e@\x05\xb1\xb0\xea-')
$ python solve.py
TF-BR{Wh1Ch_1S_Th3_w4Y_t0_G0}

最初の 1 文字が消えてしまっていますがフラグが得られました。

CTF-BR{Wh1Ch_1S_Th3_w4Y_t0_G0}

[Crypto 173] Differential Privacy

問題サーバの接続情報が与えられました。接続してみましょう。

$ nc 200.136.213.143 9999
Hello, chose an option:
[1] Info
[2] Query the flag (in ASCII)
[3] Quit
1
You can query the flag, but the characters are private (indistinguishable).
Differential privacy mechanism: Laplace
Sensitivity: ||125 - 45|| = 80
Epsilon: 6.5

Hello, chose an option:
[1] Info
[2] Query the flag (in ASCII)
[3] Quit
2
[59, 95, 79, 45, 77, 88, 134, 36, 93, 95, 127, 85, 97, 122, 101, 104, 118, 111, 106, 109, 93, 97, 86, 115, 118, 101, 111, 112, 95, 101, 97, 112, 115, 106, 125, 85, 117]
Hello, chose an option:
[1] Info
[2] Query the flag (in ASCII)
[3] Quit
3

何度か接続し直してみましょう。

[59, 107, 97, 46, 61, 77, 172, 77, 96, 97, 96, 99, 107, 109, 127, 124, 88, 146, 119, 101, 117, 98, 95, 106, 100, 105, 130, 139, 114, 95, 89, 118, 90, 105, 106, 105, 102]
[62, 83, 49, 23, 35, 60, 143, 43, 78, 149, 124, 79, 88, 103, 141, 113, 98, 74, 106, 125, 146, 94, 123, 109, 86, 104, 105, 106, 118, 82, 115, 124, 58, 98, 110, 89, 126]
[73, 91, 92, 37, 55, 137, 116, 71, 93, 91, 80, 71, 100, 135, 79, 120, 71, 87, 98, 77, 120, 110, 117, 100, 132, 82, 93, 121, 105, 88, 111, 80, 114, 111, 99, 98, 116]
[72, 64, 56, 43, 50, 79, 122, 61, 109, 91, 119, 89, 87, 93, 110, 109, 110, 112, 97, 73, 119, 95, 96, 134, 121, 93, 99, 116, 81, 84, 70, 111, 109, 90, 116, 107, 102]
[87, 49, 92, 35, 87, 89, 124, 44, 88, 88, 74, 95, 101, 135, 141, 138, 102, 98, 96, 109, 140, 101, 134, 102, 101, 94, 93, 100, 97, 111, 102, 124, 93, 104, 103, 95, 139]

毎回返ってくる結果が変わっています。これを集めて中央値を調べてみましょう。

import numpy as np
from pwn import *

res = []
for _ in range(500):
  s = remote('200.136.213.143', 9999)
  s.recvuntil('[3] Quit\n')
  s.sendline('2')
  res.append(eval(s.recvline()))
  s.sendline('3')
  s.close()

print ''.join(chr(int(np.median([a[i] for a in res]))) for i in range(len(res[0])))
$ python solve.py
...
BUE-BR{I`bm_juss_filueriog`the_noise~

それっぽい文字列が出てきました。意味が通るように少し直してみるとフラグが得られました。

CTF-BR{I_am_just_filtering_the_noise}

[Bonus 84] g00d b0y

Now prove you were a good kid and show you learned the most basic lesson in CTFs!!

という問題文が与えられました。

CTF の紹介ページを眺めていると、ルールページの下部に以下のような文章が表示されていました。

For the first time, these tiny letters on the bottom of the screen are not a prank. \o/ if you got to this point, means that you probably read all our informations and instructions. And for that, we will award your team with extra points in the competition, after all, reading is FUNDAMENTAL for a competition like this. Use the flag “CTF-BR{RTFM_1s_4_g00d_3xpr3ss10n_v3.0}” on the challenge “Bonus” during the day of the event and guarantee your extra score! ;)

CTF-BR{RTFM_1s_4_g00d_3xpr3ss10n_v3.0}

[Story 193] Great Cybernetic Revolution (Read first)

大変に長い問題文が与えられました。ぼーっと眺めていると最終行に以下のような文章がありました。

Answer with ‘CTF-BR{mission_accepted}’ if you wish to help us!

CTF-BR{mission_accepted}

[Exploitation 82] Hidden Program (Warmup)

以下のようなソースコードが与えられました。

#include <stdio.h>
#include <limits.h>
#include <string.h>

typedef struct
{
    char flag[SHRT_MAX+1];
    char in[SHRT_MAX+1];
    char sub[SHRT_MAX+1];
    int n;
} player;

player p1;

void main()
{    
    FILE *fp = fopen("/home/hidden-program/flag","r");
    memset(p1.flag,0,sizeof(p1.flag));
    fscanf(fp,"%[^\n]",p1.flag);
    fclose(fp);
    while(1)
    {
        printf("Insert a short integer: ");
        fflush(stdout);
        scanf(" %d", &p1.n);
        if(p1.n>SHRT_MAX)
            printf("Invalid number\n\n");
        else break;
    }
    p1.n = (short)abs((short)p1.n);
    printf("Insert a string: ");
    fflush(stdout);
    scanf("%10000s",p1.in);
    printf("Insert another string: ");
    fflush(stdout);
    scanf("%10000s",p1.sub);
    if(strcmp(&p1.in[p1.n],p1.sub)==0) printf("Congratulations!! YOU WIN!!\n");
    else
        printf("\tYou lost!!!\n\
        In the string %s the substring in the position %d is %s\n\
        Try again...\n", p1.in, p1.n, &p1.in[p1.n]);
    fflush(stdout);
}

Insert a short integer-32768 を入力するとフラグが得られました。

$ nc 200.136.213.126 1988
Insert a short integer: -32768
Insert a string: hoge
Insert another string: fuga
        You lost!!!
        In the string hoge the substring in the position -32768 is CTF-BR{Th1s_1S_4_50_5Imp13_C_exp1017_}
        Try again...
CTF-BR{Th1s_1S_4_50_5Imp13_C_exp1017_}

[PPC-M 63] Sum (Hello World Platform)

与えられたソースコードを実行するとフラグが得られました。

CTF-BR{Congrats!_you_know_how_to_sum!}

[Electronics 223] Top Secret

Message.txt というテキストファイルと StrangeCircuit.jpg という画像が与えられました。

with open('Message.txt') as f:
  s = f.read().replace('\n\n', '').splitlines()[1:]

for i, line in enumerate(s):
  s[i] = [int(x) for x in line.replace(' ', '')]

res = [''] * 8
for i, line in enumerate(filter(lambda line: line[0] == 1, s)):
  res[i % 8] += str(line[1] ^ 1) + str(line[2]) + str(line[3]) + str(line[4] ^ 1) + str(line[5] ^ 1) + str(line[6] ^ 1) + str(line[7]) + str(line[8])

print '\n'.join(res).replace('1', '#').replace('0', ' ')
$ python solve.py
                                                                                                                                                                                                                                
 ######  ######  #####           #####   ####      ##    #         ##    ######    ##    ######  #####             ##    #    #  ####            #   #   ######  #       #               ####    #####   #     #  #####    ##   
 #         ##    #               #    #  #   #    #      #        #  #   #        #  #     ##    #                #  #   ##   #  #   #           #  #      ##    #       #               #   #   #       ##   ## #           #  
 #         ##    #        ####   #    #  #   #    #      #       #    #  #       #    #    ##    #               #    #  # #  #  #    #          # #       ##    #       #               #   #   #       # # # # #           #  
 #         ##    #####    ####   #####   ####    #       #       #    #  #       #    #    ##    #####           #    #  #  # #  #    #          ##        ##    #       #               ####    #####   #  #  #  ####        # 
 #         ##    #               #    #  ##       #      #        #  #   #       ######    ##    #               ######  #   ##  #   #           # #       ##    #       #               ##      #       #     #      #      #  
 ######    ##    #               #    #  # #      #      ######    ##    ######  #    #    ##    #               #    #  #    #  ####            #  #    ######  ######  ######          # #     #       #     #      #      #  
                 #               #####   #  #      ##                            #    #          #####    ####   #    #                   ####   #   #                            ####   #  #    #####            #####    ##   

フラグが得られました。

CTF-BR{LOCATE_AND_KILL_REMS}
このエントリーをはてなブックマークに追加
st98.github.io / st98 の日記帳