しかし、今回の SSD では、これをしようとすると、エラーが出た。エラーの内容は記録するのを忘れてしまったが、コマンドの実行で何かバッファでもあふれているかのような、怪しいエラーメッセージだった。その時ウェブ検索していた内容から見るに、bad/missing sense data といったことが書いてあったようだ。この時開いていた、hard drive – hdparm error: SG_IO: bad/missing sense data – Super User の質問のエラーメッセージ(以下に引用)と同じようだ(数字の羅列が一致するかはわからない)が、状況は違うように思えた。
(追記)音が鳴るようなタイミング(通知音が鳴るようなタイミングや、ブラウザで動画の再生が始まった時)で、たとえスピーカーをミュートにしていてもスピーカーから「カッ」という音がする現象があった。確認できていないが個の挙動としてはそもそも使わない間はスピーカーの電源を切っているのだろうか。Popping sound on speakers when starting 19.3 (Solved) – Linux Mint Forums の記事を見ると省電力設定を解除しているようだ。lsmod を見るとこの端末もこの記事の設定ファイルと同じ snd_hda_intel を呼び出しているようだったので、/etc/modprobe.d/alsa-snd-hda-intel.conf を次の内容で作成して再起動すると直った。
Solo10G については 、 Windows 版のドライバをインストールして使用した。Solo10G ドライバとしてダウンロードしたものが、実際に起動したものは Aquantia のドライバインストーラだった。QNAP QNA-UC5G1 と、 StarTech.com のものは、いずれも Windows 10 では OS 標準か Windows Update かでドライバが入った。
Linux には USB の二機種(QNAP、StarTech.com)を接続したが、いずれも Aquantia 製のコントローラが入っているようで、 aqc111 というドライバが提供されている。ただし、 Linux 5.x には標準に同梱されているが、 Linux 4.x だと入っていないのでそのままでは他のドライバが適用される。また、 Linux 5.x 標準のものと、 AQ_USBDongle_LinuxDriver_1.3.3.0.zip (QNAP のウェブページよりリンクされていた、Marvell のサポートページよりダウンロード)で提供されているものは両方 aqc111 という名称で、かつ後者を解凍して出てくる README にも aqc111 Linux 5.x に同梱されているとの表記があるが、 ethtool で見ることができる項目が若干後者の方が多い(Low Power 5G と Thermal throttling が設定可能になる)など、若干の差があるようだ。
import sys
import math
num=1401111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111222079111111111111111111111111111111111111111111111222079112230890319889030880230880230889200120012002319889030879222080230880230890319887911122318879211992120012999912120013000013000013100892001200119912120012002208920013000011991211991112120012001199211991211991211991211991212001301010000120011991212001209300092001300001199211991111212001200119921199121199121199121199121200130010208012002318879112120929999112120929999121210318889200120011991223089031888919912119912120013000013100791111211992120920919912119921199121200130101111887912220791121299991211991211991212001300001200119911121200120012091992119921299992120013010099991112119911112129999121199121199121200130000120012001200120919922319888919921200120919921301009999111211992120012999912120013000013000013000012001200120012999911112120919912120012091992130100999911121199122308903198890308802308802308892001200119922308903198879212103198890308801199213010099991112119911111111111111111111111111111111111111122207911111111111111111111111111111111111111111111122207911111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111239593
i = 1
while num != 1 and i < 100000:
i += 1
while num % i == 0:
print i
num = num / i
cand_ramaining = -1
for i in range(0, 256):
if (i * ord('}')) % 256 == num % 256:
cand_remaining = i
#print cand_remaining
print num
s = str(num)
for i in range(2,len(s)):
print i
for j in range(1,len(s)):
if s[j] == '9':
sys.stdout.write('#')
else:
sys.stdout.write(' ')
if j % i == 0:
sys.stdout.write('|\n')
a = raw_input()
num2 = 0
while num > 0:
d=0
if num % 10 == 9:
d=1
num2 = num2 * 2 + d
num /= 10
num2 = num2 / 128
a = []
while num2 > 0:
a.insert(0, num2 % 256)
num2 = num2 / 256
#for i in range(0, len(a)):
# sys.stdout.write(chr(a[i]))
exit()
lo = 1
hi = num
while lo < hi:
mid = (lo + hi ) /2
if mid * mid == num:
lo = mid
hi = mid
break
if mid * mid < num:
lo = mid + 1
else:
hi = mid - 1
i = hi + 1
while num != 1:
while num % i == 0:
print i
num = num / i
i -= 1
しかし、このプロセス、一度他のポートで待ち受けている状態になると 25000/tcp では繋がりすらせず、さらに言えば You Lose! のあとも(この時点で逆アセンブリされたコードを読んだ yuta1024 は You Lose! のあとは元に戻るはずと言っていたし、後から Hopper で逆アセンブルした僕が見ても元に戻るはずだと判断したが、この時は何が起こっているかわからなかった)一切応答がなくなって何もできなくなった。再起動はしない、の警告の理由がようやくわかったが、要はどうにもならないのか、とこの時は判断した。しかし、しばらく放置するとなぜか接続が復活した(今から考えればプロセスが再起動されていると判断されることが、これに限らず何度かあったが、条件は謎)。ただ、どういう条件で復活するのかは全くわからなかった。幸い、 25000/tcp が割り当てられたチームに対しては 25000-25999 の udp しかこないことだけはわかった。
とはいえ、偶然の復活に期待して進めていたところ、ある程度自動化して20秒(これが繰り返すと縮まることを、この時はまだ知らない)以内に10回返信すれば、最初に指定したトークンが Defense Flag (5分ごとにチームごとの Defense Flag が特定の場所にあるかチェックされ、特定の場所に含まれていると点数が入る。チェック作業が完了するとチームごとに書き込むべき Flag は変更される。これ自体は参加者全員に対し、全チーム分が公開情報。)として追記される。すなわち、解き方自体は、「自分のチームの Defense Flag を取得し、それを認証トークンとして 25000/tcp に投げたあと、指示されるポートに投げては返信されるポートに追随する」を繰り返すことであることがわかった。ただし、一日目はサーバの状態を見失い、できることがなくなった。
import sys
from Crypto.Cipher import AES
import base64
def encrypt(key, text):
s = ''
for i in range(len(text)):
s += chr((((ord(text[i]) - 0x20) + (ord(key[i % len(key)]) - 0x20)) % (0x7e - 0x20 + 1)) + 0x20)
return s
def decrypt(key, text):
s = ''
for i in range(len(text)):
s += chr((((ord(text[i]) - 0x20) - (ord(key[i % len(key)]) - 0x20) + (0x7e-0x20+1)) % (0x7e - 0x20 + 1)) + 0x20)
return s
key1 = "SECCON"
key2 = "seccon2019"
#text = sys.argv[1]
#enc1 = encrypt(key1, text)
cipher = AES.new(key2 + chr(0x00) * (16 - (len(key2) % 16)), AES.MODE_ECB)
#p = 16 - (len(enc1) % 16)
#enc2 = cipher.encrypt(enc1 + chr(p) * p)
#print(base64.b64encode(enc2).decode('ascii'))
crypted='FyRyZNBO2MG6ncd3hEkC/yeYKUseI/CxYoZiIeV2fe/Jmtwx+WbWmU1gtMX9m905'
crypt_raw=base64.b64decode(crypted)
enc1 = cipher.decrypt(crypt_raw)
enc1 = enc1[:-5]
print decrypt(key1, enc1)
SECCON{Success_Decryption_Yeah_Yeah_SECCON}
Option-Cmd-U
繋ぐと、指定した URL に接続し、取得した HTML を表示してくれる。ソースコードも公開されている。フラグは /flag.php にあるが、こちらは内部ネットワークからしか見れないとのこと。Docker で構成され、 http://nginx/ に繋げばよさそうな雰囲気が漂っているが、 IP アドレス確認で nginx と一致するとはじかれる仕様になっている。
当該ソースコードには、以下のような部分があった。
$url = filter_input(INPUT_GET, 'url');
$parsed_url = parse_url($url);
if($parsed_url["scheme"] !== "http"){
// only http: should be allowed.
echo 'URL should start with http!';
} else if (gethostbyname(idn_to_ascii($parsed_url["host"], 0, INTL_IDNA_VARIANT_UTS46)) === gethostbyname("nginx")) {
// local access to nginx from php-fpm should be blocked.
echo 'Oops, are you a robot or an attacker?';
} else {
// file_get_contents needs idn_to_ascii(): https://stackoverflow.com/questions/40663425/
highlight_string(file_get_contents(idn_to_ascii($url, 0, INTL_IDNA_VARIANT_UTS46),
false,
stream_context_create(array(
'http' => array(
'follow_location' => false,
'timeout' => 2
)
))));
}
なお、ブリッジ側の MAC アドレスは起動するたびにランダムに変わるようで、 DHCP で固定の IP アドレスを配るのに問題があるので、固定した。IP アドレスを static でホスト側で指定するなら不要と思われる。また、 VM で検証しているときはホスト側の仮想スイッチでプロミスキャスモードを禁止しているために通信がうまく行えない罠にはまっていた。
あと、 macvcap でホストの LAN に直接刺せそうな選択肢があるが、これはブリッジではなく NIC をその VM で占有する時に使うもののようなので、 VM とホスト両方、あるいは複数 VM で使うときはブリッジ構成は必要なようだ。
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
version: 2
renderer: networkd
ethernets:
enp1s0:
dhcp4: no
bridges:
br0:
macaddress: XX:XX:XX:XX:XX:XX
dhcp4: yes
interfaces: [enp1s0]
$ sudo brctl show
bridge name bridge id STP enabled interfaces
br0 XXXX.XXXXXXXXXXXX no enp1s0
vnet0
docker0 XXXX.XXXXXXXXXXXX no vethXXXXXXX
vethXXXXXXX
virbr0 XXXX.XXXXXXXXXXXX yes virbr0-nic
みたいな感じで brctl でブリッジが見え、 ifconfig でも DHCP から降ってきた IP アドレスが見れるようになった。