JSFuck

6種類の文字によって構成されるJavaScriptを完全に書き換えることが可能な難解プログラミング言語 ウィキペディアから

JSFuckJavaScriptのサブセットとして考案された難解プログラミング言語[]()!+の6文字のみコードを書く。

JavaScriptの様々な言語仕様を利用することで、非常に冗長なコードになってしまうものの上記6文字だけでJavaScriptの全機能を使用できる[1]

名前はBrainfuckに由来するが、独自のコンパイラインタプリタを必要とするBrainfuckとは異なり、JSFuckはあくまでもJavaScriptの言語仕様に基づいているためJavaScriptの処理系(WebブラウザJavaScriptエンジン)で動作する。

歴史

2009年7月にHasegawa YosukeがJavaScriptを[]()!+,\"$.:;_{}~=の18文字に変換するWebアプリケーションを作った[2][3]

2010年1月には、sla.ckers.orgというWebアプリケーションセキュリティサイトの「Obfuscation」フォーラムで非公式の競争が開催され、文字数を当時必要最小限だと思われていた8文字([]()!+,/)に抑える方法が考案された。その後、どうにか ,/ を使わないようにできないか模索され[4]、同年3月にはJS-NoAlnumと呼ばれる現在の6文字で表現されるエンコーダーができた[5]。同年11月にハセガワはJSF*ckと呼ばれる6文字で表現されるエンコーダーを完成させた[6][7]2012年には、Martin Kleppe が"jsfuck"と名前をつけたプロジェクトをGitHub上で公開した[8]。そしてJSFuck.comというサイトでエンコーダーの実装を公開している[9]

JSFuckはマルウェアウェブサイトクロスサイトスクリプティング (XSS)等によって埋め込むことにも使われたことがある[10]。他の潜在的な使用方法としては、難読化がある。よく使われるJavaScriptライブラリであるjQueryも、6文字で完全に置き換えられたことがある[11]

変換の手順

要約
視点

JSFuckは非常に冗長である。JavaScriptではalert("Hello World!")としてポップアップを開くであろうコードは21字である。しかし、同じことをJSFuckでしようとすると22948字にもなる。いくつかの文字はJSFuckで表現しようとすると1000文字を超える。この節はどうやって文字を生成することができるのか説明する。

数字

0は+[]によって作られる。ここで、[]は空の配列であり、+単項プラス英語版である。ここに型変換が働いて、[]は0とみなされる[12]

1は+!![]+!+[]で、論理値true (JSFuckでは!![]!+[]として表現される)が数字の1に変換されたものである[13]

2から9については、!![](前述の通り1)をその回数だけ繰り返し、それを+で連結すれば良い。これを踏まえると2は!![]+!![]!+[]+!+[]と書くことができる。

2桁以上の場合は、1桁ずつ数字として配列に詰めたあと、それを1要素連結すればよい。例として"10"[1] + [0]と書き換えることができる。前述の0と1の作り方を適用すると、これは[+!+[]]+[+[]]となる。数値を返したい場合は、頭に+をつける(この例では10 = +([+!+[]]+[+[]]))

文字

JSFuckではいくつかの文字は論理値や"NaN"、"undefined"から添字付き(角括弧の中に数字が入ったもの)で取り出すことになる。他の文字を生成するためにさらなるトリックが存在する。"1e1000"を数字に型変換すると、Infinityとなり、yを簡単に取り出すことができるようになる[14]。下に記したのは最もシンプルにプリミティブな値を作るコードである。

(ただし、幾つかのコンパイラでは!+[]が警告されるため!![]に統一している。)

さらに見る 値 ...
JSFuck
false![]
true!![]
NaN+[![]]
undefined[][[]]
Infinity+(+!![]+(!![]+[])[!![]+!![]+!![]]+[+!![]]+[+[]]+[+[]]+[+[]])
閉じる

例:"a"の生成

  • "a": 文字列"false"から取ることにする。"false"の2文字目は"a"である。これは
  • "false"[1]としてアクセスできる。"false"false+[]から作ることができる。すなわち、falseと空の配列を足すことになる。
  • (false+[])[1]: falseは![]から生成できるので(論理否定を空の配列に適用する)
  • (![]+[])[1]: 1は数字であるので、これを+trueで置き換えると
  • (![]+[])[+true]: そしてfalseは![]でtrueは!![]なので
  • (![]+[])[+!![]] - これで"a"を返す。

JavaScriptで実際に試してみると、alert((![]+[])[+!![]])alert("a")は同じ出力である[15]

他の生成

FunctionコンストラクタはJavaScriptとして有効なコードを実行することができるので、alert(1)Function("alert(1)")()と同じである。Functionのコンストラクタは、[]["at"] (Array.prototype.at) のように標準の関数のconstructorプロパティから取り出すことができる。このことを踏まえると、alert(1)[]["at"]["constructor"]("alert(1)")()と書き換えることができる。

文字表

文字を作ることができる一番短いコードを下に記した。他の文字も生成できるがおそらくもっと長くなるだろう。

(ただし、幾つかのコンパイラでは!+[]が警告されるため!![]に統一している。)

さらに見る 文字 ...
文字JSFuck
+(+(+!![]+(!![]+[])[!![]+!![]+!![]]+[+!![]]+[+[]]+[+[]])+[])[!![]+!![]]
.(+(+!![]+[+!![]]+(!![]+[])[!![]+!![]+!![]]+[!![]+!![]]+[+[]])+[])[+!![]]
0+[]
1+!![]
2!![]+!![]
3!![]+!![]+!![]
4!![]+!![]+!![]+!![]
5!![]+!![]+!![]+!![]+!![]
6!![]+!![]+!![]+!![]+!![]+!![]
7!![]+!![]+!![]+!![]+!![]+!![]+!![]
8!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]
9!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]
a(![]+[])[+!![]]
d([][[]]+[])[!![]+!![]]
e(!![]+[])[!![]+!![]+!![]]
f(![]+[])[+[]]
i([![]]+[][[]])[+!![]+[+[]]]
I (i)(+(+!![]+(!![]+[])[!![]+!![]+!![]]+(+!![])+(+[])+(+[])+(+[]))+[])[+[]]
l (L)(![]+[])[!![]+!![]]
N(+[![]]+[])[+[]]
n([][[]]+[])[+!![]]
r(!![]+[])[+!![]]
s(![]+[])[!![]+!![]+!![]]
t(!![]+[])[+[]]
u([][[]]+[])[+[]]
y(+[![]]+[+(+!![]+(!![]+[])[!![]+!![]+!![]]+[+!![]]+[+[]]+[+[]]+[+[]])])[+!![]+[+[]]]
閉じる

コード表

組み合わせることができる一番短いコードを下に記した。

これらを組み合わせ、コードを単純化することができるだろう。

さらに見る 出力, 型 ...
JSFuck 出力
[] [] object
+[] 0 number
![] false boolean
[[]] [[]] object
!![] true boolean
[]+[] "" string
[+[]] [0] object
[![]] [false] object
+!![] 1 number
[[[]]] [[[]]] object
[][[]] undefined undefined
[]+![] "false" string
[!![]] [true] object
+[]+[] "0" string
+[![]] NaN number
[[]+[]] [""] object
[[+[]]] [[0]] object
[[![]]] [[false]] object
[]+!![] "true" string
[[[[]]]] [[[[]]]] object
[+!![]] [1] object
[[][[]]] [undefined] object
[[]+![]] ["false"] object
[[!![]]] [[true]] object
[+[]+[]] ["0"] object
[+[![]]] [NaN] object
+!![]+[] "1" string
閉じる

セキュリティ

JSFuckのような難読化技術は、「通常の」JavaScriptに備わる"クラッキング防止システム"が存在しない[16]ため、eBayのオークションのページにJSFuckで書かれたスクリプトを埋め込むことができた[17]

脚注

外部リンク

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.