Zuck3r’s Study

エンジニアではありません

Google CTF : Beginner Quest : JS SAFE

前回と同じ前置きになるが、間違っているところや改善点があったらコメントして欲しい。

環境:VMware,DebianベースのLinuxを使っている

解説

今回は、"Google CTF : Beginner Quest : JS SAFE"を解いていく。"Attachment"から問題ファイルをダウンロードする。zipファイルなので解凍する。出てきたhtmlファイルの中からフラッグを見つけろという問題だ。

f:id:Zuck3r:20181228190816p:plain

js_safe_1.htmlが出てくる。これを開いてみると、こんなページが出てくる。そして、ソースコードを見てみると以下のようにパスワードは"CTF{・・・}"形式になっていて、カッコ内の文字列が合ってるか、間違っているかで鍵を開けるか判断しているようだ。恐らく、これがフラッグなのだろう。

f:id:Zuck3r:20181228191229p:plain

js_safe_1.html

f:id:Zuck3r:20181228192725p:plain

ソースコード

次に、"console.log"を使って"i,env[lhs],env[fn],arg1,env[arg1],arg2,env[arg2]"のログを表示する。

for (var i = 0; i < code.length; i += 4) {
var [lhs, fn, arg1, arg2] = code.substr(i, 4);
try {
env[lhs] = env[fn](env[arg1], env[arg2]);
} catch(e) {
env[lhs] = new env[fn](env[arg1], env[arg2]);
}
if (env[lhs] instanceof Promise) env[lhs] = await env[lhs];
console.log("#" , i, env[lhs], env[fn], "(" +arg1+"="+env[arg1], arg2+"="+env[arg2]+")");
console.log("-----------------------")
}
return !env.h;
}

自分は"CTF{1234}"と入力した。結果として出てきたのは以下で、SHA-256でハッシュ生成されているという事が分かった。更に、1234の部分が"3,172,103,66,22,243,225,92,118,30,225,165,226,85,240,103,149,54,35,
200,179,136,180,69,158,19,249,120,215,200,70,244"になったという事もわかる。
次に1234をSHA-256で生成すると、"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4"。そして、"3,172,103,・・・200,70,244"この数列をそれぞれpythonのhex(x)を使って調べていく。出てきた、"0x??"の下二桁を拾えばいいようだ。これを順に並べると、1234をSHA-256で生成したものと同じという事が分かる。

f:id:Zuck3r:20181229034251p:plain

SHA-256

f:id:Zuck3r:20181229034628p:plain

3, 172, 103,・・・200, 70, 244

f:id:Zuck3r:20181229034914j:plain

hexを使い下二桁を拾う

上記の事が分かったので今度は正しいパスワードの時、どんな数列になるのか調べる。以下の様にコードを入力する。コンソールに出てきた数列の数字一つ一つにhex()をかけ、0x以外の値を並べる。最後にこのハッシュを復号する。復号にはこのサイトを使った。

let cursor = 964;
let output =[]
for (var i = 0; i < code.length; i += 4) {
var [lhs, fn, arg1, arg2] = code.substr(i, 4);
try {
env[lhs] = env[fn](env[arg1], env[arg2]);
} catch(e) {
env[lhs] = new env[fn](env[arg1], env[arg2]);
}
if (env[lhs] instanceof Promise) env[lhs] = await env[lhs];
if (i == cursor){
cursor += 20 ;
output.push(env[arg2]);
}    }
console.log(output);
return !env.h;
}

f:id:Zuck3r:20181229175212p:plain

新しく書き換えてコンソールに出したパスワードの数列

上の数列からhex()をかけ、下二桁とった値 "e66860546f18cdbbcd86b35e18b525bffc67f772c650cedfe3ff7a0026fa1dee"
最後にこれを復号した結果が今回のフラッグだ。

終わりに

今回の問題は英語のwrite upを参考にしながら解いたが、私には難しかった。javascriptに対する知識がまだ浅いので調べながらになった。勉強したいと思う。
参考にしたサイト 

気になったら調べておくといいかもなワード

  • SHA
  • コンソール(使いこなせるとかなり便利そう)