Rating:

このような入力が1200個与えられます
`[1267.56, 1130.04, 2588.27, 3338.14, 236.17, 11320.41, 2363.41, 531.25, 1136.72, 1690.02] Romulan Light Fighter`

最終的にこのような数が`Romulan`なのか`Klingons`なのか`Starfleet`なのか当てます.`Starfleet`の時は船を攻撃してはいけないので`N`を,それ以外の時は`Y`を出力します.

`[1250.23, 2817.63, 1820.81, 60.23, 492.89, 44.86, 2013.35, 48.02, 765.08, 6591.08]`

私はまずintelligence reportsからgrepして数列を探索しましたが,そのようなものは存在しませんでした.しかし,intelligence reportsをよく見ると規則性がありそうです.例えば,この辺りを見てみます(一部編集しています)

```txt
[35.05,1941.88,4287.8,2902.9,184.9,2917.93,338.47,2367.21,732.21,4272.74] Klingon
[35.57,2209.72,3959.27,3023.05,134.17,3388.35,880.13,2647.26,460.87,2831.3] Klingon
[35.02,2417.65,1156.22,3055.21,146.49,3348.8,520.05,3973.01,913.65,2746.14] Klingon
[35.13,1575.59,772.11,2883.36,136.16,3894.96,762.43,5266.27,157.02,4019.84] Klingon
[35.32,1770.4,1833.5,4252.28,141.68,2294.74,967.64,2061.43,119.84,5691.19] Klingon
[35.01,1556.79,817.6,2872.76,145.95,3523.56,512.55,4362.45,822.15,5423.58] Klingon
[35.21,1457.47,1882.9,3831.39,154.28,3150.99,646.55,2969.09,276.35,3330.41] Klingon
[35.45,1471.34,4342.47,4768.3,138.08,3532.35,765.62,2374.26,993.36,4643.89] Klingon
[35.18,1790.57,3906.92,4013.17,177.81,2794.02,297.51,2653.02,338.13,4948.36] Klingon
[35.32,1239.93,741.28,3029.71,135.18,2471.76,621.28,3402.43,861.54,5827.88] Klingon
```

Klingonの船の先頭は35が非常に多く見えます.そこで,この問題は数列から特徴量を抽出し,どの船か判別する**機械学習の問題**だと判断しました.私はSVMを使用しました.

```py
from pwn import *
import numpy as np
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC

clf = make_pipeline(StandardScaler(), SVC(gamma="auto"))

io = remote("0.cloud.chals.io", 29511)

X = []
y = []

while True:
line = str(io.recvline())[2:-3]
if line == "=" * 112:
break
if line[0] == "=":
continue
print(line)
line = line.split("]")
ships = line[0]
country = line[1][1:].split(" ")[0]
ships = eval(ships + "]")
X.append(ships)
if country == "Romulan":
y.append(0)
elif country == "Klingon" or country == "Klington":
y.append(1)
elif country == "Starfleet":
y.append(2)

X = np.array(X)
y = np.array(y)

clf.fit(X, y)

while True:
line = str(io.recvline())[2:-3]
print(line)
if line[:9] == "Congrats!":
continue
if line[:20] != "A ship approaches: ":
continue
line = eval(line[20:])
_ = str(io.recv())[2:-1]
payload = "N"
res = clf.predict([line])
if res[0] != 2:
payload = "Y"
print("fire ->", payload)
io.send(payload + "\n")
```

実行してから数秒後,フラグが得られました.

`Congrats, the war is over: shctf{F3Ar-1s-t4E-true-eN3my.-Th3-0nly-en3my}`

`shctf{F3Ar-1s-t4E-true-eN3my.-Th3-0nly-en3my}`

Original writeup (https://github.com/xryuseix/CTF_Writeups/blob/master/SpaceHeroes2022/Writeups.md#frk-war).