[ksnctf] Jewel

ksnctfにチャレンジ
第15問目です。

※ksnctfは常駐型のCTFサイトです。
※問題のページはコチラです。

Jewel

Androidアプリである apk ファイルが渡されます。
apkは zip アーカイブされているので

$ unzip Jewel.apk -d Jewel

展開できます。
この中の classes.dex が目的のファイルです。
コンパイルされているので dex2jar で jar に戻します。
dex2jarのセットが toolディレクトリにあるとして

$ tool/dex2jar-*/d2j-dex2jar.sh Jewel/classes.dex

これで classes-dex2jar.jar​ という名前で jar まで戻りました。
jar もまた unzip できます。

$ unzip ./classes-dex2jar.jar -d ./Class

これで
Class/info/sweetduet/ksnctf/jewel/JewelActivity.java
が閲覧可能になります。
内容をみると
デバイスIDを取得して、そのIDを鍵にすることで
AESで暗号化された
Jewel/res/raw/jewel_c.png
を復号し表示するという内容です。
FLAGもこの jewel_c.png を開けばわかるはずですが
肝心の デバイスID がわからない (=鍵がわからない)
ので 画像を復号することができません。

ただし、15桁の値であるデバイスIDの上位8桁は
99999991
であり、デバイスIDをSHA256でhash化すると
"356280a58d3c437a45268a0b226d8cccad7b5dd28f5d1b37abf1873cc426a8a5"
ということが、デバイスID判定のコードから読み取れます。

よって下7桁分だけスクリプトで全通り検索して
hash値が一致するものをみつければOKです。

必要なデバイスIDがわかったら
KEY = "!(デバイスID)"
IV = "kLwC29iMc4nRMuE5"
を用いて AES-128-CBC にかけると
もとの画像が復号できます。

画像によると、 pngに含まれるコメントデータにFLAGがあるらしいので

$ strings -n 21 jewel_c_dec.png
FLAG_????????????????

などを実行すればFLAGが取得できました。

以上の流れを
珍しくWrite up風に書くと↓こうなります。

#!/usr/bin/ruby

require 'digest/sha2'
require 'openssl'

target_id = "356280a58d3c437a45268a0b226d8cccad7b5dd28f5d1b37abf1873cc426a8a5"

#Step 1
puts "[+] Step1 "
for i in 0..9999999
    device_id = "99999991%07d"%i
    hashed_id = Digest::SHA256.hexdigest(device_id)
    if( hashed_id == target_id )
        puts " - device id = " + device_id
        break
    end
end

#Step2
puts "[+] Step2 "
puts " - Setup"
enc = File.open("jewel_c.png", "r")
dec = File.open("jewel_c_dec.png", "w")
cip = OpenSSL::Cipher::Cipher.new('AES-128-CBC')

cip.decrypt
cip.key = "!#{device_id}"
cip.iv  = "kLwC29iMc4nRMuE5"
puts " - key = !#{device_id}"
puts " - iv  = kLwC29iMc4nRMuE5"

puts " - Decrypt"
data = ""
data << cip.update(enc.read())
data << cip.final
dec.write(data)
puts " - done!"

#Step3
puts "[+] Step3 "
puts data[/FLAG_(.{16})/,0]

コメントする