JS Reverse - Little Sweet Potato XS環境の分析

序文

比較的厳しいサイトと聞いたので、ここでは深い分析はせず、環境面のポイントをいくつか分析します。詳細については、小紅書 xs の新バージョン (2023 年 5 月 30 日に期限切れ) の
偉人による (プレイはリスク移転です) 分析をご覧ください。

1. 分析

ウェーブカバーを見てください
ここに画像の説明を挿入

暗号化ポイントはここにあります。スキルは必要ありません。フォローアップして確認してください。
ここに画像の説明を挿入

window._webmsxywこれは、js 全体を選択し、環境を構成し、粗さに注意を払うだけです。
lとaはWebページ上でコピーできますが、おそらくこんな感じです。
ここに画像の説明を挿入

最初に彼を通常どおり実行させて、それについて話し合い、結果を実行してみます。安全のため、ノード環境が検出されないように、最初に vm2 を使用して実行します。

const fs = require('fs')
const {
    
     VM, VMScript } = require('vm2');
// console.time('myTimer');
const sandbox = {
    
    
    require: require,
    console: console
};
const codeFile = `${
      
      __dirname}/test.js`;
const vm = new VM({
    
    
    sandbox: sandbox,
    require: {
    
    
        external: true
    }
});
const script = new VMScript(fs.readFileSync(codeFile), `${
      
      __dirname}/我正在调试的代码.js`);
debugger;
result = vm.run(script);
console.log(result)

最初にいくつかの基本的なオブジェクトを作成してから、単純なエージェントを 1 つずつ追加しましょう (独自のチェーン エージェントを使用しないのはどうでしょうか。長すぎるので、退屈です。怠けて全体をランダム化してください)
ここに画像の説明を挿入

次に、構築を開始できます。以下は単純なプロキシです。

better.proxy = function (o, callerName){
    
    
    return new Proxy(o, {
    
    
            set(target, property, value){
    
    
                console.table([{
    
    "类型":"set-->","调用者":callerName,"属性":property,"值":value}]);
                return Reflect.set(...arguments);
            },
            get(target, property, receiver){
    
    
                if (property!=="Math"){
    
    
                    console.table([{
    
    "类型":"get<--","调用者":callerName,"属性":property,"值":target[property]}]);
                }
                return Reflect.get(...arguments);
            },
        }
    );
};

実行すると、Symbol (Symbol.toStringTag) 属性が検出されたことがわかります。
ここに画像の説明を挿入
ブラウザを開いて見てください。この属性には値があるので、それを補うことができます。上記 2 つの属性は取得できません。値、 Symbol(nodejs.util.inspect.custom) このプロパティは、カスタム オブジェクトの文字列表現のために Node.js で使用されるシンボルです。
ここに画像の説明を挿入
そこで、次にこのシンボル (Symbol.toStringTag) を作成し、プロトタイプ チェーンを作成します (これは単純なレイヤーであり、それほど深くはありません。怠け者です)

var Window = function Window(){
    
    
    throw new TypeError("Illegal constructor");
};

Object.defineProperties(Window.prototype, {
    
    
    [Symbol.toStringTag]:{
    
    
        value:"Window",
        configurable:false, // 通常为 false,不允许删除属性并修改其特性。
        writable:true, // 通常为 true,允许重新赋值。
        enumerable:true // 通常为 true,可以出现在 for...in 循环或 Object.keys() 方法中。
    }
});
window.__proto__ = Window.prototype;

上の問題は解決しましたが、下を見ると、これら 3 つが再び不足しています。メイクアップ、ナビゲーター、ウィンドウもメイク方法は同じです。
ここに画像の説明を挿入
ここに細かい詳細ナビゲータがあります。後で表示されますが、最初に通常どおり設定するだけです。残りのメソッドは 2 つあります。直接追加するだけです。もうコードを入力する必要はありません。正直に入力してください。
ここに画像の説明を挿入
後でこのような状況に遭遇した場合、誰もがそれを補う方法を学んだはずなので、次の回ではこの toString を補うつもりはありません。これは、いくつかの toString の後で構成する必要があるパラメーター メソッドです
ここに画像の説明を挿入
。ここで、私たちが遵守するAudioContext原則は、オブジェクトがエージェントの場合は、そのオブジェクトにエージェントを投げるだけです (オブジェクトに関連する次の操作はこの方法で実行する必要があります)、そしてこのステップに到達します
ここに画像の説明を挿入
。多くの人がこのメソッドにさまざまな曖昧さを持っているので、
ここに画像の説明を挿入それを示します。このメソッドは Document のプロトタイプにあり、その機能は要素、つまりオブジェクトを作成することであると理解しています。よく言われるように、すべてはオブジェクトです。オブジェクトの場合は、オブジェクトを返し、それがフェッチされるかどうかを確認するためにプロキシします 値は何でもよいですか? ここでは、このcanvas_objオブジェクトをプロキシするために Canvas を例として取り上げます。(divやspanオブジェクトの場合はどうするか、それを作成し、過去のオブジェクトのオブジェクトを返し、検出プロトタイプがあればプロトタイプを埋めれば完了です。足りないものは補ってください、検出できなかった場合は時間を無駄にしないでください) 上記の
ここに画像の説明を挿入
補足を通じて、環境の考え方、少し補うだけでデータが出てきますこの時点でそれを使用すると絶対に機能しません(試してみました) XYW の後の先頭のアバターが Base64 暗号化のように見えないことに誰もが気づきました。そうであれば、それを使用して復号化します。Base64 復号化された URL が何かを確認してください。このペイロードのみであることがわかり
ここに画像の説明を挿入
ます
ここに画像の説明を挿入
。それがどのようにして来たのかを解明する必要がありますが、他のパラメータはほぼ修正できます。次に、Web ページに戻って、どのように暗号化されたかを確認する必要があります。
ここに画像の説明を挿入

js を最初に置くと、最初のポイントが XS が出てくる場所であることがわかります。2 番目のポイントは戻り値です。最初のポイントでこれに対して_ace_dcca5[0]フック操作を行う必要があります。

_ace_dcca5 = new Proxy(_ace_dcca5,{
    
    
    get: function(target, prop) {
    
    
        return target[prop];
        // 返回属性的值
    },
    set: function(target, prop, value) {
    
    
        // debugger; // 在这里设置断点或执行自定义逻辑
        target[prop] = value;
        // 设置属性的值
        try {
    
    
            if (value['_ace_4de55'] && value['_ace_4de55'].startsWith("XYW")) {
    
    
                debugger ;
            }
        } catch (error) {
    
    
        }
        return true;
    }
});

ここでは楽観的になりましょう。初回はXYWでした。
ここに画像の説明を挿入
2 回目は XYW_、次回は目的の Base64 暗号化のものです。
ここに画像の説明を挿入
ここでは、ステップごとにフォローしていきます。ここをたどっていくと、このbase64が登場していることが分かります。
ここに画像の説明を挿入
フォローアップしましょう_ace_34d1(3, 49)。パラメータを指定することを忘れないでください。
ここに画像の説明を挿入
このステップを実行すると、実際にいくつかの手がかりを見つけることができます。_ace_66私はすでにそれに従っています。その効果は、この値に値を割り当てることです。これは割り当てではないことが_ace_936わかりますが、これは何を意味しますか? これはグローバルです。この中の添字 49 は、必要な Base64 暗号化されたものなので、次にそれをフックします。これはフックコードであり、これを頭のないフックに直接使用しても機能しません。ファローアップ。_ace_66
ここに画像の説明を挿入
ここに画像の説明を挿入

ここに画像の説明を挿入

_ace_66 = new Proxy(_ace_66,{
    
    
    get: function(target, prop) {
    
    
        return target[prop];
        // 返回属性的值
    },
  set: function(target, prop, value) {
    
    
    if (prop === "49") {
    
    
      debugger; // 在第 49 个下标被设置时设置断点或执行自定义逻辑
    }
    console.log(value)
    target[prop] = value; // 设置属性的值
    return true; // 表示设置成功
  }
});

ここに画像の説明を挿入
これは、フックに成功した様子です。このデータはよくご存知です。これは、base64 として使用されたソース データです。
ここに画像の説明を挿入
他には何もせず、フックします。
ここに画像の説明を挿入

_ace_66 = new Proxy(_ace_66,{
    
    
    get: function(target, prop) {
    
    
        return target[prop];
        // 返回属性的值
    },
    set: function(target, prop, value) {
    
    
        try {
    
    
            if (value && value.startsWith("cd")) {
    
    
                debugger ;
            }
        } catch (error) {
    
    }
        if (prop === "49") {
    
    
            debugger ;// 在第 49 个下标被设置时设置断点或执行自定义逻辑
        }
        console.log(value)
        target[prop] = value;
        // 设置属性的值
        return true;
        // 表示设置成功
    }
});

フォローしてみると、またこの _ace_936 で、ここで終わりに来ました。これを見ると、_ace_dcca5全体的な状況です。良い奴、フックを続けます。
ここに画像の説明を挿入
またここを登り続けろよ
ここに画像の説明を挿入
、ボーイ
ここに画像の説明を挿入

実際、再び行き止まりになったことがわかります。その後、このグローバル変数の値を直接フックして出力します。ログを出力すると、合計があることがわかります。これは真実です。この暗号化stackInputに基づいています次に、このパラメータを分解すると、x1、x2、x3、x4 が得られます。x4 は明らかにタイムスタンプです。心配しないでください。x3 は Cookie の a1 です。ドン心配する必要はありません。x1 と x2 だけがそれを取得する方法を知りません。ただし、パニックにならないでください。上記の出力の過程で、誰もが x1、x2、x3、x4 を確認したはずです。つまり、フックするときに、戻って _ace_66 を再度フックして確認します。x1 と x1 の長さは、URL 文字列が表示された後にのみ表示されることがわかります。経験豊富な読者は md5 を思い浮かべてください。確かに、これは URL 文字列の暗号化された md5 です。現在、x1 は解決され、x2 は 1 つだけ残っています。MD5 暗号化アドレス心配しないでください、印刷された情報は x1 だけでなく x2 も含まれています。しかし、上記を見ると、x2 には手がかりがありません。その後、自分の nodejs 環境に戻って、ブラウザとの違いを確認します。stackOutput
x1=f060e018ee22aede6cdd2393dadd54f9;x2=0|0|0|1|0|0|1|0|0|0|1|0|0|0|0;x3=18995b7979bwbgf099rbj41o4mscuki8wn6a4ep3250000419053;x4=1690954928490;
ここに画像の説明を挿入
_ace_66
ここに画像の説明を挿入


ここに画像の説明を挿入

ここに画像の説明を挿入

2、検証

戻って独自のプログラムをフックする必要はありません。フックによると_ace_66、これらはすべてこの関数を通じて生成されていることがわかります。戻ってこの関数を出力できます。
ここに画像の説明を挿入
cmd を使用して情報を読み取ってフィルタリングすることを忘れないでください。そうしないと情報が表示されません。nodejs の
ここに画像の説明を挿入
x2 だけがブラウザと異なることがわかります。情報を調べて出力してみましょう。この x2 を通過するとset->userAgent値は 1 になりますが、これは前述の細かい点ですが、ブラウザではこれを行うことはできません。したがって、それを直接 unacceptable として設定するいくつかの措置を講じてから確認
ここに画像の説明を挿入
する必要があります。set

Object.defineProperty(Navigator.prototype, "userAgent", {
    
    
    value:'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
    writable: false
  });

ほら、これが0になって、ブラウザとは違う1があるので、もう一度調べてみましょう。ブラウザは0|0|0|1|0|0|1|0|0|0|1|0|0|0|0私たちのものです。0|0|0|1|0|0|1|0|0|1|1|0|0|0|0
ここに画像の説明を挿入
見てください、違う 1 はどこですか? ほら、window.Window を呼び出した後、1 になります。問題があるはずです。nodejs の window.Window は次のとおりです。

var Window = function Window(){
    
    
    throw new TypeError("Illegal constructor");
};

ここに画像の説明を挿入
ブラウザはウィンドウです ウィンドウはウィンドウそのものなので軽く操作してwindow.Window=window、今回は善人はブラウザと同じで
ここに画像の説明を挿入
結果をリクエストに送ります。この時点でXiaohongshuのXS環境が完成し、インチキが強制終了します。忘れずにリクエストしdataて暗号化してください一样
ここに画像の説明を挿入

ここに画像の説明を挿入
js環境には約300行ありますが、中には役に立たない行もあります。とても簡単ですので、ご自身で試してみてください。

から学びます

小紅書 xs の新バージョンの分析 (2023-05-30 に期限切れ)

おすすめ

転載: blog.csdn.net/qq_41866988/article/details/132058203