ksnctf #3 “Crawling Chaos”をPythonで解読する
Problem
下の画像のようにunya.htmlがあるだけです。
ここからFLAG_???を何かしらの方法で得て Flagのところに提出すればクリアです。
Solution
とりあえずunya.htmlをクリックしてみると、入力フォームがある。
試しにabcを送信してみると
Noと言われる。
そこでソースコードを見てみると、
12行目がおかしい!!!
これはJavaScriptの難読化で、(」・ω・)」うー!(/・ω・)/にゃー!encodeというものらしい。
Chromeのデベロッパーツールのconsoleを使って、console.log()で難読化されている部分を出力してみる。
出力結果は
/ᆞωᆞ/ -0 /ᆞωᆞ/ 1 2 3 4 5 6 7 8 9 "" "true" "false" "[object Object]" "undefined" -0 "a" "b" "c" "d" "e" "f" "n" "o" "r" "s" "t" "u" "/\"\"ω\"\"//\\\\ω\\\\/" "\"" "\\" "\\u" "\\u00" "constructor" "return\"\\u0024\\u0028\\u0066\\u0075\\u006e\\u0063\\u0074\\u0069\\u006f\\u006e\\u0028\\u0029\\u007b\\u0024\\u0028\\u0022\\u0066\\u006f\\u0072\\u006d\\u0022\\u0029\\u002e\\u0073\\u0075\\u0062\\u006d\\u0069\\u0074\\u0028\\u0066\\u0075\\u006e\\u0063\\u0074\\u0069\\u006f\\u006e\\u0028\\u0029\\u007b\\u0076\\u0061\\u0072\\u0020\\u0074\\u003d\\u0024\\u0028\\u0027\\u0069\\u006e\\u0070\\u0075\\u0074\\u005b\\u0074\\u0079\\u0070\\u0065\\u003d\\u0022\\u0074\\u0065\\u0078\\u0074\\u0022\\u005d\\u0027\\u0029\\u002e\\u0076\\u0061\\u006c\\u0028\\u0029\\u003b\\u0076\\u0061\\u0072\\u0020\\u0070\\u003d\\u0041\\u0072\\u0072\\u0061\\u0079\\u0028\\u0037\\u0030\\u002c\\u0031\\u0035\\u0032\\u002c\\u0031\\u0039\\u0035\\u002c\\u0032\\u0038\\u0034\\u002c\\u0034\\u0037\\u0035\\u002c\\u0036\\u0031\\u0032\\u002c\\u0037\\u0039\\u0031\\u002c\\u0038\\u0039\\u0036\\u002c\\u0038\\u0031\\u0030\\u002c\\u0038\\u0035\\u0030\\u002c\\u0037\\u0033\\u0037\\u002c\\u0031\\u0033\\u0033\\u0032\\u002c\\u0031\\u0034\\u0036\\u0039\\u002c\\u0031\\u0031\\u0032\\u0030\\u002c\\u0031\\u0034\\u0037\\u0030\\u002c\\u0038\\u0033\\u0032\\u002c\\u0031\\u0037\\u0038\\u0035\\u002c\\u0032\\u0031\\u0039\\u0036\\u002c\\u0031\\u0035\\u0032\\u0030\\u002c\\u0031\\u0034\\u0038\\u0030\\u002c\\u0031\\u0034\\u0034\\u0039\\u0029\\u003b\\u0076\\u0061\\u0072\\u0020\\u0066\\u003d\\u0066\\u0061\\u006c\\u0073\\u0065\\u003b\\u0069\\u0066\\u0028\\u0070\\u002e\\u006c\\u0065\\u006e\\u0067\\u0074\\u0068\\u003d\\u003d\\u0074\\u002e\\u006c\\u0065\\u006e\\u0067\\u0074\\u0068\\u0029\\u007b\\u0066\\u003d\\u0074\\u0072\\u0075\\u0065\\u003b\\u0066\\u006f\\u0072\\u0028\\u0076\\u0061\\u0072\\u0020\\u0069\\u003d\\u0030\\u003b\\u0069\\u003c\\u0070\\u002e\\u006c\\u0065\\u006e\\u0067\\u0074\\u0068\\u003b\\u0069\\u002b\\u002b\\u0029\\u0069\\u0066\\u0028\\u0074\\u002e\\u0063\\u0068\\u0061\\u0072\\u0043\\u006f\\u0064\\u0065\\u0041\\u0074\\u0028\\u0069\\u0029\\u002a\\u0028\\u0069\\u002b\\u0031\\u0029\\u0021\\u003d\\u0070\\u005b\\u0069\\u005d\\u0029\\u0066\\u003d\\u0066\\u0061\\u006c\\u0073\\u0065\\u003b\\u0069\\u0066\\u0028\\u0066\\u0029\\u0061\\u006c\\u0065\\u0072\\u0074\\u0028\\u0022\\u0028\\u300d\\u30fb\\u03c9\\u30fb\\u0029\\u300d\\u3046\\u30fc\\u0021\\u0028\\u002f\\u30fb\\u03c9\\u30fb\\u0029\\u002f\\u306b\\u3083\\u30fc\\u0021\\u0022\\u0029\\u003b\\u007d\\u0069\\u0066\\u0028\\u0021\\u0066\\u0029\\u0061\\u006c\\u0065\\u0072\\u0074\\u0028\\u0022\\u004e\\u006f\\u0022\\u0029\\u003b\\u0072\\u0065\\u0074\\u0075\\u0072\\u006e\\u0020\\u0066\\u0061\\u006c\\u0073\\u0065\\u003b\\u007d\\u0029\\u003b\\u007d\\u0029\\u003b\"" "" ƒ Function() { [native code] } -0 "$(function(){$(\"form\").submit(function(){var t=$('input[type=\"text\"]').val();var p=Array(70,152,195,284,475,612,791,896,810,850,737,1332,1469,1120,1470,832,1785,2196,1520,1480,1449);var f=false;if(p.length==t.length){f=true;for(var i=0;i<p.length;i++)if(t.charCodeAt(i)*(i+1)!=p[i])f=false;if(f)alert(\"(」・ω・)」うー!(/・ω・)/にゃー!\");}if(!f)alert(\"No\");return false;});});" undefined -0 1 2 3 4 5 6 7 8 9 -0
となり、後半のソースコードの部分を抜き出してみる。
ここで全体が“”で囲まれているので\”“の\はエスケープ文字なので削除している。
$(function(){
$("form").submit(function(){
var t = $('input[type=\"text\"]').val();
var p = Array(70,152,195,284,475,612,791,896,810,850,737,1332,1469,1120,1470,832,1785,2196,1520,1480,1449);
var f = false;
if(p.length == t.length){
f = true;
for(var i = 0;i < p.length; i++)
if(t.charCodeAt(i) * (i+1) != p[i])
f = false;
if(f)
alert("(」・ω・)」うー!(/・ω・)/にゃー!");
}
if(!f)
alert("No");
return false;
});
});
入力された値がtに代入され、pとtの長さが同じとき
$$(tのi番目の文字のコードポイント) \times (i+1) = (pのi番目) $$
が成立するならばtrueを返す。
つまりpのi番目の数字をi+1で割ったものがt(Flag)となる。
def main():
p = [70,152,195,284,475,612,791,896,810,850,737,1332,1469,1120,1470,832,1785,2196,1520,1480,1449]
# 解読
decipher(p)
def decipher(p):
for i, n in enumerate(p):
# pのi番目の数字nをi+1で割ったものを出力
print(chr(n // (i + 1)), end = "")
print("")
if __name__ == "__main__":
main()
これでFlagが手に入る。
% python unya_decipher.py
FLAG_************
ちなみにFlagを入力フォームに書いて送信すると
(」・ω・)」うー!(/・ω・)/にゃー!が出てくる。
CTF, セキュリティの参考資料
Udemy
個人的にUdemyが動画で分かりやすいし、値段も安いのでおすすめです。
実践的なものが特に役立ちます。
ホワイトハッカー養成講座(ハッキングツール、Webアプリ攻略、不正侵入検知)
ホワイトハッカー養成講座 (インシデントハンドリング&Windowsアタック編)
書籍
- セキュリティコンテストチャレンジブック CTFで学ぼう!情報を守るための戦い方
- セキュリティコンテストのためのCTF問題集
- デバッガによるx86プログラム解析入門
- リバースエンジニアリングバイブル
- 大熱血アセンブラ入門
- 楽しいバイナリの歩き方
- Reverse Engineering for Beginners
- HACKING: 美しき策謀
- 秘密の国のアリス
- 暗号解読
- 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践 第2版
コメント