チーム omakase として参加した。最終的に獲得できたポイントは 626 点でチーム順位は 13 位だった。
rand (javascript 200), args (javascript 200), gradius (binary 100), monochrome bar (steganography 100) の 4 問を解いた。
rand は 3 番目に正解したので 6 点、args は最初に正解したので 20 点のボーナスポイントがあった。
- まずグローバルオブジェクトのプロパティを確認する。
Object.keys(this) // => ["print", "quit", "version", "arguments", "g"]
- String#split と String#join を this を返す関数にする。これで getFlag にアクセスできる。
- getFlag + "" で getFlag の中身が読める。
String.prototype.split = String.prototype.join = function () { return String(this); };
g('print(getFlag + "")'); // => '…FLAG{7f94427ec6f49f70642d41c675b98832}'
flag: 7f94427ec6f49f70642d41c675b98832`
kkjjhlhlba
と入力するとFLAG{!!D4GG3R!!}
と出る。
flag: !!D4GG3R!!
- 幅が 72900px、高さ 1px の png ファイルが渡される。
Math.sqrt(72900) === 270
なので、元の画像を 270px ずつ切って縦に並べる。
import sys
from PIL import Image
def main(name='monochrome_bar.png', width=270, *_):
orig = Image.open(name)
img = Image.new('RGB', (width, 72900 // width), (128, 128, 128))
for y in range(72900 // width):
cut = orig.crop((y * width, 0, (y + 1) * width, 1))
img.paste(cut, (0, y))
img.save('output.png')
return 0
if __name__ == '__main__':
sys.exit(main(*sys.argv[1:]))
- QR コードが出てくるので、画像を少しいじってスキャンすると
RkxBR3tDaDF0M2sxazBrMXNoMW4tbTRufQ==
が出てくる。 - Base64 でエンコードされているのでデコードすると
FLAG{Ch1t3k1k0k1sh1n-m4n}
が出てくる。
flag: Ch1t3k1k0k1sh1n-m4n
- f の中に
this.args = arguments;
と書かれている部分がある。 - その後の
f.bind(null, false);
からその this がグローバルオブジェクトになることが分かる。 - つまり一度 g を呼び出せばグローバル変数の args にその時の arguments が入る。
args.callee
から f が取り出せるので、true になる引数を与えて呼び出すとフラッグが手に入る。
g();
args.callee(true); // => 'FLAG{3d2dba5b774814fa8fe87798898b7b30}'
flag: 3d2dba5b774814fa8fe87798898b7b30
- あみだくじ。base64 でエンコードされた画像をデコードして表示し、人力で解いて入力するプログラムを書いた。
- ステージ 5 で諦めた。
import base64
import io
import re
import socket
import sys
import uuid
from PIL import Image
def main(host='203.178.132.117', port=42719, *_):
s = socket.create_connection((host, port), 3)
s.settimeout(3)
print('[*]', s.recv(0x1000))
while True:
for x in range(50):
print('[*] ', x)
f = ''
while True:
r = s.recv(0x1000)
f += re.findall(r'(?:#\d+\n)?(.+)(?:\nAnswer\?\n)?', r.decode('ascii'))[0]
if b'\nAnswer?\n' in r:
break
Image.open(io.BytesIO(base64.b64decode(f))).show()
s.send(input('> ').encode() + b'\n\n')
print('[*]', s.recv(0x1000))
if input() == 'q':
break
else:
continue
s.close()
return 0
if __name__ == '__main__':
sys.exit(main(*sys.argv[1:]))