![[ksnctf] Jewel [ksnctf] Jewel](/images/1/1/4/4/6/11446a3aec42c690a8c36b628b83c1c28b37caae-15.png)
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]