#Crawling Chaos
問題
Crawling Chaos:這いよる混沌
「這いよれ!ニャル子さん」っていうアニメのキャッチフレーズ「いつもニコニコあなたの隣に這いよる混沌、 ニャルラトホテプ、です!」
問題にはunya.htmlのリンクがある。開いてみると、テキストボックスと送信ボタン。ここを突破してflagを入手する。
適当な文字を入力して送信してみても何も起きない。とりあえずソースコードを見てみる。
<html>
<head>
<meta charset="utf-8">
<title>Crawling Chaos</title>
<style>
form { text-align: center; margin-top: 4em; }
input { font-size: x-large; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
(ᒧᆞωᆞ)=(/ᆞωᆞ/),(ᒧᆞωᆞ).ᒧうー=-!!(/ᆞωᆞ/).にゃー...(以下省略)
</script>
</head>
<body>
<form>
<input type="text">
<input type="submit">
</form>
</body>
</html>
javascriptの部分が明らかにおかしい。console.log()を使ってコンソール画面をみてみると何か書いてある。(自分で適当にhtmlファイル作ってunya.htmlコピペして、console.log((ᒧᆞωᆞ)=(/ᆞωᆞ/),(ᒧᆞωᆞ).ᒧうー=-!!(/ᆞωᆞ/).にゃー...(以下省略))に書き換え、そのファイルをブラウザで開いてコンソール画面見てみる)
[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\\…" – "" (15) (a.html, line 19)
function 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
上の方はよくわからないけど、真ん中あたりはjavascriptで書かれていることがわかる。この部分を抜き出して綺麗に書き直す。
$(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; } );
} );
fがfalseにならないような文字列を見つければ良さそう。
入力された文字を数字に変換したもの × その文字の位置+1 を計算して、pの値と等しいければfはfalseにならない。その条件を満たすような文字列をpから求めればいい。具体的には、pのi番目をi+1で割り、その数字を文字に変換する。
charCodeAt:指定した位置にある文字を数字に変換する。
#python
p = (70, 152, 195, 284, 475, 612, 791, 896, 810, 850, 737, 1332, 1469, 1120, 1470, 832, 1785, 2196, 1520, 1480, 1449)
ans = ""
for i in range(len(p)):
ans += chr(int(p[i]/(i+1)))
print(ans)
これでflagが得られる。
chr()は前回のEasy Cipherでも使ったけど、数値を文字に変換するやつ。
#まとめ
JavaScriptを「(」・ω・)」うー!(/・ω・)/にゃー!」にする変換ツールがあるらしい。
javascriptが全角文字を扱えるのは驚いた。