web-dev-qa-db-ja.com

Skypeはbase64でエンコードされたJavaScriptを開きます。それは何をするためのものか?

かなり珍しい問題に遭遇したばかりで、それが実際に問題(またはセキュリティの問題)であるかどうかを判断できません。 MacOSでSkypeを開くと、ポップアップウィンドウが表示され(複数回、内容はまったく同じです)、以下を開くためのアプリケーションを選択するよう求められます。

PHNjcmlwdD4oZnVuY3Rpb24oKXtmdW5jdGlvbiBnKGEpe3ZhciBjLGI7Yz0iIjtmb3IoYj0wO2I8YS5sZW5ndGg7YisrKWMrPVN0cmluZy5mcm9tQ2hhckNvZGUoYS5jaGFyQ29kZUF0KGIpKzItYiUxNCk7cmV0dXJuIGN9ZnVuY3Rpb24gaChhKXtkPWEtaztrPWE7aWYoISgzNTA8ZCkpZm9yKGE9MDthPGIubGVuZ3RoO2ErKyliW2FdJiZiW2FdLnBvc3RNZXNzYWdlJiZiW2FdLnBvc3RNZXNzYWdlKHtmcHM6MUUzL2Qsc2xvdDplLHRpbWVEZWx0YTpkfHwwfSwiKiIpO3dpbmRvd1tnKGYpXShoKX12YXIgaz0wLGQsYj1bXSxlLGY7Zj0icGRxdmd2eEZ0cHVqfnRtbUZzY3BpIjt3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsZnVuY3Rpb24oYSl7dmFyIGM9YS5kYXRhO2MmJmMuc2xvdCYmKGE9YS5zb3VyY2UsLTE8Yi5pbmRleE9mKGEpfHwoYi5wdXNoKGEpLHZvaWQgMD09PWUmJihlPWMuc2xvdCkpKX0pO3dpbmRvd1tnKGYpXShoKX0pKCk7Cjwvc2NyaXB0Pg==

Base64値をデコードすると、スクリプトタグ内のJavaScriptスニペットが明らかになり、Skypeがブラウザー内でこのスクリプトを開こうとしていると思います。読みやすくするために美化した完全な値を次に示します。

<script>
    (function() {
        function g(a) {
            var c, b;
            c = "";
            for (b = 0; b < a.length; b++) c += String.fromCharCode(a.charCodeAt(b) + 2 - b % 14);
            return c
        }

        function h(a) {
            d = a - k;
            k = a;
            if (!(350 < d))
                for (a = 0; a < b.length; a++) b[a] && b[a].postMessage && b[a].postMessage({
                    fps: 1E3 / d,
                    slot: e,
                    timeDelta: d || 0
                }, "*");
            window[g(f)](h)
        }
        var k = 0,
            d, b = [],
            e, f;
        f = "pdqvgvxFtpuj~tmmFscpi";
        window.addEventListener("message", function(a) {
            var c = a.data;
            c && c.slot && (a = a.source, -1 < b.indexOf(a) || (b.Push(a), void 0 === e && (e = c.slot)))
        });
        window[g(f)](h)
    })();
</script>

このスニペットを少しリバースエンジニアリングしました。私が理解している限り、messageオブジェクトのwindowイベントをリッスンし、いくつかの値を更新します。また、メッセージの投稿元であるrequestAnimationFrameを繰り返し呼び出します。

このコードは何をしていますか? Skypeが開こうとしているのはなぜですか?

18
NikxDa

少しわかりやすくするために、いくつかの変数の名前を変更することから始めました。

_    function obscurify(function_input) {
        var returnstring, local_counter;
        returnstring = "";          
        for (local_counter = 0; local_counter < function_input.length; local_counter++) 
        {
            returnstring += String.fromCharCode(function_input.charCodeAt(local_counter) + 2 - local_counter % 14);

        }

        return returnstring
    }
_

これは最初の関数であり、あいまいな文字列_pdqvgvxFtpuj~tmmFscpi_を実行すると、実際に this bin (アラートボックスの前)に示されているWord requestAnimationFrameを受け取ります。

h()関数に少し悩まされたので、requestanimationframe関数を使用する理由を探し始めました。

それが私が見つけたときです このページ

RequestAnimationFrameを使用しているときにフレームレートを制限することは、アニメーションとメカニクスが特定のフレーム/秒のマークを超えないようにするゲームをコーディングする場合に特によくあることです。それを行う2つの方法を見てみましょう。

著者が最初に説明する方法はsetTimeOutによるものですが、次に彼はこれを書きます:

ブラウザーはsetTimeoutまたはsetIntervalを最適化できません。したがって、独自の計算を行い、フレームレートを制限する方が良いでしょう。方法を見てみましょう。

そして、次のコードに進みます。

_var fps = 30;
var now;
var then = Date.now();
var interval = 1000/fps;
var delta;

function draw() {

    requestAnimationFrame(draw);

    now = Date.now();
    delta = now - then;

    if (delta > interval) {
        // update time stuffs

        // Just `then = now` is not enough.
        // Lets say we set fps at 10 which means
        // each frame must take 100ms
        // Now frame executes in 16ms (60fps) so
        // the loop iterates 7 times (16*7 = 112ms) until
        // delta > interval === true
        // Eventually this lowers down the FPS as
        // 112*10 = 1120ms (NOT 1000ms).
        // So we have to get rid of that extra 12ms
        // by subtracting delta (112) % interval (100).
        // Hope that makes sense.

        then = now - (delta % interval);

        // ... Code for Drawing the Frame ...
    }
}

draw();
_

これは、コードで実行されている計算によく似ています。

しかし、何もせずにこれがSkypeに表示されるのはなぜですか?

ブラウザとJavaScriptは文字通りどこにでもあるからです。 Skypeを起動したところ、エラーは発生しませんでしたが、広告が表示されています。私の直感は、あなたの場合、広告をロードする埋め込みブラウザーにはデータURLのハンドラーがないことを教えてくれます。そのため、Skypeはそのエラーを表示するようです。

このコードは実際にはイベントハンドラーを追加するだけであり、イベントが呼び出されるたびにFPSが壊れないようにします。 (広告の切り替え、広告のスムーズな実行、読み込みアイコンのスムーズな実行、...)

広告が1 000 000、30秒のインプレッションで表示時間を超えるか下回る場合、10ミリ秒の差が信じられないほど高速にスケーリングされ、広告主が支払うよりも少ないまたは多くの表示時間が得られます。

しかし、なぜそれが不明瞭なのですか?

@dandavisのコメントによると、実際にこのコードを難読化する明らかな理由はありません。インターネットで自由に利用できます(上記のリンクのように)。ただし、このコードを実行しているのと同じ組み込みブラウザーは、たとえばログインフレームをホストすることもできます。

必要に応じてすべてのコードを難読化ツールに通すだけの方がはるかに簡単でバグが少ない場合は、あいまいなコードと非あいまいでないコードの両方のハンドラーを書き換えることはしません。

これが難読化される理由は、単なる一般的なルールであるすべてのJSコードを難読化する可能性があります。

2
Nomad