LoginSignup
0
0

More than 1 year has passed since last update.

ksnctf q38 Canned Can Opener

Last updated at Posted at 2022-04-27

ksnctf q38 Canned Can Opener

以下の2ファイルがダウンロードできる。
flag.jpg.enc
flag_canned.jpg

問題文を見ると、flag.jpg.encは以下のコマンドで暗号化されている。
$ openssl enc -e -aes-256-cbc -iter 10000 -in flag.jpg -pass file:flag.jpg -out flag.jpg.enc

ここで-pass file:flag.jpgは、flag.jpgの1行目をパスワードとして使用するという意味のようだ。

flag_canned.jpgを使って同様に暗号化復号化すると、どうもパスワードに使われるのは最初のNull文字までのようで、flag_canned.jpgをバイナリエディタで開くと、「FF D8 FF E1 2A 48 45 78 69 66」までの10バイトがパスワードとして使われるようであった。

ということはflag.jpgの1行目も同じデータかもと思い、試して見ることに。
5バイト目と6バイト目の2A48はAPP1アプリケーションセグメントのデータ長らしいので、ここを変えて探索すれば良いのでは?

下記のようなpythonコードを書き、試してみるとセグメントデータ長が0x3950で当たりとなり、decodeした画像にFLAGが表示された。

test.py
import os
import subprocess
from sys import byteorder

for n in range(8192, 4096*16):
    print(n)
    nlist = [0xFF, 0xD8, 0xFF, 0xE1, 0x2A, 0x48, 0x45, 0x78, 0x69, 0x66]
    nlist[4] = n // 256
    nlist[5] = n % 256
    with open('dummy.bin', 'wb') as fp:
        blist = [n.to_bytes(1, byteorder) for n in nlist]
        fp.writelines(blist)
    cmdline = '/usr/bin/openssl enc -d -aes-256-cbc -iter 10000 -in flag.jpg.enc -pass file:dummy.bin -out fout.jpg'
    proc = subprocess.Popen(cmdline, shell=True, cwd=os.getcwd(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    res = proc.communicate()
    rstr = res[0].decode('utf-8')
    if 'bad decrypt' not in rstr:
        with open ('fout.jpg', 'rb') as fpi:
            data = fpi.read()
            if data[0] == 255 and data[1] == 216:
                print('found', n, rstr)
                break

flag.jpg

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0