フラグを食べる grep 作ってみた【おいしい】
EXAMPLE_FILE = "/usr/share/dict/words"
FLAG_EATER = open("/dev/null", "w")
DUMMY_EATER = open("/dev/null", "w")
while True:
file = input(f"File (Default: {EXAMPLE_FILE}, Flag: flag.txt): ")
pattern = input("Pattern: ")
content = open(file or EXAMPLE_FILE).read(0x10000)
for line in content.splitlines():
if pattern in line:
print(line, file=FLAG_EATER if "Alpaca" in line else None)
else:
print(line, file=DUMMY_EATER) # dummy write to avoid timing attacks :)
概要
ファイル選択→pattern入力で一致行を出力するgrep風のプログラム
ただし、Alpacaを含む行はFLAG_EATER = open("/dev/null", "w")に出力される。
一致しない行はDUMMY_EATER = open("/dev/null", "w")に出力される。
どこに注目するか?
コメントにある通りタイミング攻撃は対策していて難しそう。
任意のパスが読めるので/proc/self配下で何か使えないか探す。
すると/proc/self/io で値が色々と増加していることに気づく。
File (Default: /usr/share/dict/words, Flag: flag.txt): /proc/self/io
Pattern:
rchar: 33802
wchar: 64
syscr: 30
syscw: 2
read_bytes: 6262784
write_bytes: 0
cancelled_write_bytes: 0
File (Default: /usr/share/dict/words, Flag: flag.txt): /proc/self/io
Pattern:
rchar: 33919
wchar: 230
syscr: 34
syscw: 4
read_bytes: 6496256
write_bytes: 0
cancelled_write_bytes: 0
File (Default: /usr/share/dict/words, Flag: flag.txt): /proc/self/io
Pattern:
rchar: 34037
wchar: 397
syscr: 38
syscw: 6
read_bytes: 6496256
write_bytes: 0
cancelled_write_bytes: 0
rchar:read()などでユーザー空間に渡されたバイト数
wchar:write()などでユーザー空間から受け取ったバイト数
syscw/syscr :write/read系 syscall を呼んだ回数
read_bytes/write_bytes :実際に読んだ/書いたとみなされたバイト数
また、read_bytesの初期値は接続ごとに変わっていた。