# [InterKosenCTF 2019] Hugtto!
###### tags: `InterKosenCTF 2019`, `forensics`
## 概要
`emiru.png`に対してflagを隠す処理をして結果とスクリプトをtar.gzにまとめている。処理の内容は単純で、0〜2の乱数によってr, g, bの下位1ビットにビットを格納している。
乱数のシードを知る必要があるが、tar.gzが生成された時刻に近いのでそれを利用する。
## 解法
tarでタイムスタンプを見てみる。
```
$ tar -t -v --full-time -f hugtto.tar.gz
-rw-rw-r-- ptr/ptr 1346615 2019-08-01 14:07:10 ./steg_emiru.png
-rw-rw-r-- ptr/ptr 1009 2019-08-01 14:06:22 steg.py
```
タイムゾーンや画像処理の方向が縦であることなどに注意してデコーダを書く。
```python
from PIL import Image
import random
import datetime
img = Image.open("steg_emiru.png")
width, height = img.size
bin_prefix = []
for c in "KosenCTF{":
for i in range(8):
bin_prefix.append((ord(c) >> i) & 1)
approx = int(datetime.datetime.strptime(
'2019-08-01 14:00:00', '%Y-%m-%d %H:%M:%S'
).timestamp())
for seed in range(approx, approx + 0x1000):
random.seed(seed)
bin_flag = []
for i in range(len(bin_prefix)):
x, y = i // width, i % width
rnd = random.randint(0, 2)
r, g, b = img.getpixel((x, y))
if rnd == 0: bin_flag.append(r & 1)
if rnd == 1: bin_flag.append(g & 1)
if rnd == 2: bin_flag.append(b & 1)
if bin_flag[i] != bin_prefix[i]:
break
else:
print("[+] Found seed: {}".format(seed))
break
else:
print("[-] Invalid approx")
exit(1)
random.seed(seed)
flag = ""
char = []
for i in range(8 * 128):
x, y = i // width, i % width
rnd = random.randint(0, 2)
r, g, b = img.getpixel((x, y))
if rnd == 0: char.append(r & 1)
if rnd == 1: char.append(g & 1)
if rnd == 2: char.append(b & 1)
if len(char) == 8:
x = 0
for j in range(8):
x |= char[j] << j
flag += chr(x)
char = []
print(flag)
```
はい。
```
KosenCTF{Her_name_is_EMIRU_AISAKI_who_is_appeared_in_Hugtto!PreCure}
```