主頁 > 企業開發 > JS逆向之瀏覽器補環境詳解

JS逆向之瀏覽器補環境詳解

2022-12-13 07:22:47 企業開發

JS逆向之瀏覽器補環境詳解

“補瀏覽器環境”是JS逆向者升職加薪的必備技能,也是作業中不可避免的操作,

為了讓大家徹底搞懂 “補瀏覽器環境”的緣由及原理,本文將從以下四個部分進行描述:

  1. 什么是補環境?
  2. 為什么要補環境?
  3. 怎么補環境?
  4. 補環境實戰
  5. 補環境框架成品原始碼

一:什么是 “補瀏覽器環境”?

瀏覽器環境: 是指 JS代碼在瀏覽器中的運行時環境,它包括V8自動構建的物件(即ECMAScript的內容,如Date、Array),瀏覽器(內置)傳遞給V8的操作DOM和BOM的物件(如document、navigator);
Node環境:是基于V8引擎的Js運行時環境,它包括V8與其自己的內置API,如fs,http,path;

Node環境瀏覽器環境 的異同點可以簡單概括如圖:
在這里插入圖片描述

所以我們所說的 “補瀏覽器環境” 其實是補瀏覽器有 而Node沒有的環境,即 補BOM和DOM的物件;

二:為什么要 “補瀏覽器環境”?

對于逆向老手而言,“補環境” 這個詞不會陌生,當我們每次把辛辛苦苦扣出來的 “js加密演算法代碼”,并且放在瀏覽器環境中能正確執行后,就需要將它放到Node環境 中去執行,而由于Node環境瀏覽器環境之間存在差異,會導致部分JS代碼在瀏覽器中運行的結果 與在node中運行得到的結果不一樣,從而影響我們最終逆向成果;eg:

function decrypt() {
    document = false;
    var flag = document?true:false;
    if (flag) {
        return "正確加密"
    } else {
        return "錯誤加密";
    }
}

在瀏覽器環境運行時 flag為true,然后得到正常結果;
在Node環境運行時 flag為false,然后得到錯誤結果;

所以我們需要 “補瀏覽器環境”,使得扣出來的 “js加密演算法代碼”Node環境中運行得到的加密值,與其在 瀏覽器環境中運行得到的加密值一致, 即對于這段 “js加密演算法代碼” 而言,我們補出來的環境與瀏覽器環境一致,

三:怎么 “補瀏覽器環境”?

要想 “補瀏覽器環境”,首先我們得知道 “js加密演算法代碼” 到底使用了哪些瀏覽器環境API,然后再對應去補上這些環境;

那么我們該如何監測 “js加密演算法代碼” 對瀏覽器環境API的使用呢?

毫無爭議:使用Proxy來監測瀏覽器環境API的使用,輔助補瀏覽器環境

Proxy是ES6提供的代理器,用于創建一個物件的代理,從而實作基本操作的攔截和自定義(如屬性查找、賦值、列舉、函式呼叫等), 它可以代理任何型別的物件,包括原生陣列,函式,甚至另一個代理;擁有遞回套娃的能力!!

也就是說 我們代理某個物件后,我們就成了它的中間商,任何JS代碼對它的任何操作都可以被我們所攔截!!

# 對navigator物件進行代理,并設定攔截后的操作
var handler = {set:funcA,get:funcB,deleteProperty:funcC,has:funcD ...};
navigator = new Proxy(navigator,handler);
# 對代理后的navigator進行各種操作都會被攔截并觸發對應處理函式
navigator.userAgent 會被攔截并觸發 get  funcB
navigator.userAgent = "xx" 會被攔截并觸發 set funcA
delete navigator; 會被攔截并觸發 deleteProperty funC
"userAgent" in navigator  會被攔截并觸發 has funD ...
等等... 任何操作都可以被攔截

基于Proxy的特性,衍生了兩種補環境思路:

  1. 遞回嵌套Proxy以此來代理瀏覽器所有的BOM、DOM物件及其屬性,再配合node vm2模塊提供的純凈V8環境,就相當于在node中,對整個瀏覽器環境物件進行了代理,JS代碼使用任何瀏覽器環境 api都能被我們所攔截,然后我們針對攔截到的環境檢測點去補,
  2. 搭建補環境框架,用JS模擬瀏覽器基于原型鏈去偽造實作各個BOM、DOM物件,然后將這些JS組織起來,形成一個純JS丐版瀏覽器環境,我們補的純JS丐版瀏覽器環境越完善,就越接近真實瀏覽器環境,能通殺的js環境檢測就越多,最終完美通殺所有JS環境檢測!!;示例:b站搜 "志遠補環境"

第一種思路雖然實作簡單,主要是對Proxy攔截器的使用 ,但是具備的環境監測能力有限,對較復雜的原型鏈等難以監測,即使是二次開發也上限不高;并且遇到JS使用了很多環境時手補也相當麻煩;
第二種思路雖然實作較為復雜,但是上限極高,且可以完美兼容第一種思路,具備可成長的通殺潛質,

所以業內補環境框架幾乎都是基于第二種思路,先搭建一個補環境框架的骨架,將常見瀏覽器環境BOM、DOM物件補齊,如:window、location、Document、navigator等,等空閑時或作業遇到其他瀏覽器環境BOM、DOM物件,再將它補進來,補的越完善,我們能通殺JS環境檢測越多,

優點:

  • 補的越完善,能通殺JS環境檢測越多,最終完美通殺所有JS環境檢測!!
  • 一鍵運行輸出目標JS中所有環境檢測點;
  • 生成的最終代碼可直接用于生產環境(可直接供nodejs、v8使用);
  • 告別玄學補環境,不再一行行去debugger,極大提高作業效率,
  • 可以在Chrome瀏覽器進行無瀏覽器環境除錯,
  • 新人彎道超車必備
  • .....

四:“補環境框架”實戰

傳統補環境格式:

// 環境頭:
window = global;
navigator= {userAgent:"Mozilla/5.0 (Windows NT 1";}
// 扣出來的JS
........
......

傳統補環境太簡陋,而且不夠通用,代碼組織混亂,我們最好將其組織為一個專案:

補環境框架專案整體結構:
框架結構

那么實作這么一個瀏覽器補環境框架需要哪些步驟哪些考慮呢?

  • 先確定框架運行主流程,即入口檔案 ,
  • 每個BOM、DOM物件的實作都使用一個單獨的js檔案,便于定位及維護,
  • 將這些BOM、DOM檔案按照原型鏈的優先順序進行讀取,拼接成整個瀏覽器環境,
  • 思考如何去實作一個BOM、DOM物件使其和瀏覽器一致;(這個是影響框架上限的重要因素,同時也包含大量重復性人力作業)
  • 事件的處理(對行為驗證碼有幫助)
  • 思考如何保證JS中使用到的所有瀏覽器環境都能被我們所檢測;(這個是影響框架上限的重要因素)
  • 如何設計優化補環境框架專案的可擴展、可維護性;(非常必要)
    ...
    還有一些其他細節思考,我們的目標框架就是 一個易于可擴展與維護、能檢測到JS中所有瀏覽器環境API的使用、實作了常見瀏覽器環境方法等,讓我們在之后補環境中,達到通殺效果,

如果對于原理及實作方向 思考不夠全面、深入,那么實作的框架上限會有限,出現玄學的概率就大了,我也是經歷了很長時間打磨,多次推倒重來、借鑒多個課程,最終實作這個理想的框架,

下面就是一些具體的實作:
以下就是主流程入口骨架:

var  fs = require('fs');
var catvm2 = require('./CatVm2/catvm2.node.js');

const {VM,VMScript} = require('vm2'); //看作純凈V8

var catvm2_code = catvm2.GetCode();  //獲取所有代碼(工具代碼、補的所有BOM、DOM物件)
var web_js_code = fs.readFileSync(`${__dirname}/target/get_b_fz.js`) ; // 獲取目標網站js代碼
var log_code = "\r\ncatvm.print.getAll();debugger;\r\r";
var all_code = catvm2_code+web_js_code+log_code;
fs.writeFileSync(`${__dirname}/debugger_bak.js`,all_code);
const script = new VMScript(all_code,`${__dirname}/debugger.js`); //真實路徑,瀏覽器打開的就是該快取檔案

const vm = new VM(); // new 一個純凈v8環境
debugger
vm.run(script); // 在V8環境中運行除錯
debugger

骨架搭好之后我們就要去補對應的BOM、DOM物件,比如補Navigator
1、先在瀏覽器環境觀察該物件:Navigator
能否進行new Navigator,不能的話則在其建構式定義中拋出例外,能的話不拋;

var dsf_tmp_context = catvm.memory.variable.Navigator = {};
var Navigator = function Navigator() { // 建構式
	throw new TypeError("Illegal constructor");
}; catvm.safefunction(Navigator);//13

2、查看其原型Navigator.prototype 的屬性、方法、原型鏈,
發現Navigator原型屬性、方法不能通過原型呼叫,即
Navigator.appVersion 會拋出例外,
發現 其原型鏈只有一層,即Navigator.prototype.__proto__ === Object.prototype

3、在瀏覽器環境觀察其實體物件:navigator
查看其屬性、方法與 原型上的差異,發現差不多,基本都是繼承原型的,
因此可以簡單補成下面這樣:


Object.defineProperties(Navigator.prototype, {
    [Symbol.toStringTag]: {
		value: "Navigator",
	    configurable: true
	}
});
var navigator = {};
navigator.__proto__ = Navigator.prototype;


Navigator.prototype.plugins = [];
Navigator.prototype.languages = ["zh-CN", "zh"];
Navigator.prototype.userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36';
Navigator.prototype.platform = 'Win32';
Navigator.prototype.maxTouchPoints = 0;
Navigator.prototype.onLine = true;
for (var _prototype in Navigator.prototype) {
    navigator[_prototype] = Navigator.prototype[_prototype];
    if (typeof (Navigator.prototype[_prototype]) != "function") {
        Navigator.prototype.__defineGetter__(_prototype, function () {
            debugger;
            var e = new Error();
            e.name = "TypeError";
            e.message = "Illegal constructor";
            e.stack = "VM988:1 Uncaught TypeError: Illegal invocation \r\n " +
                "at <anonymous>:1:21";
            throw e;
            // throw new TypeError("Illegal constructor");
        });
    }
}

// 加上代理
navigator = catvm.proxy(navigator);


注:上面實體只是一種補環境思路,是基于物件.屬性粒度我個人用的是另一種思路,基于物件.屬性.特性粒度即Object.getOwnPropertyDescriptor 的value,writable..等,雖然需要補代碼更多,但是模擬的效果更完美,理論上限極高,

瀏覽器物件及屬性實在太多了,我們不可能手動補那么物件屬性,因此要想補出一個完美瀏覽器環境,我們需要撰寫瀏覽器環境自吐腳本,即在瀏覽器執行該腳本,它會將某個瀏覽器環境物件的所有屬性與方法,拼接成我們框架所需要的補環境代碼,我們直接粘貼進來,稍微改改即可,

我們可以借助:Reflect.ownKeys(real_obj)來獲取該物件的所有屬性與方法,
然后對其 attr進行各種判斷、處理,最終拼接成我們需要的樣子,

var all_attrs = Reflect.ownKeys(real_obj);
var continue_attrs = ["prototype", "constructor"];
for (let index = 0; index < all_attrs.length; index++) {
    let attr_name = all_attrs[index];
    // 暫時不處理在 continue_attrs 中的屬性
    if (continue_attrs.indexOf(attr_name) != -1) {
        console.log(`遇到 ${attr_name},跳過`);
        continue
    }
        if (attr_name == Symbol.toStringTag) {
            result_code = `Object.defineProperties(${repair_obj}, {
    [Symbol.toStringTag]: {
		value: "${real_obj[Symbol.toStringTag]}",
	    configurable: true
	}
});//23\n`;
            symbol_code_ls.push(result_code);
            continue
        }
    }
    ..........太長,略過(下面框架原始碼中有)

每補完一個瀏覽器物件之后,可以運行起來與真實瀏覽器進行對比,逐步優化,最終達到完美效果,

五:“補環境框架”成品原始碼

補環境框架儼然成為JS逆向人員的大殺器,也是眾多面試官的考察點,我們已經了解了 它的原理及實作步驟,接下來我們可以嘗試自己從頭實作一個完善的補環境框架,但是這會花費很長一段時間來進行開發,而且其中有很多重復性作業比較無聊(復制粘貼對比等),

走快車道:

我在這條路已經走的比較久,補了很多環境,如果你想省下大段時間極大提高效率,直接彎道超車的話,可以 微信聯系我:dengshengfeng666 付費原始碼借鑒;
統一固定價 99,付完直接發原始碼(有readme可直接小白上手),后續有疑問可以直接問我,
或者直接在CSDN私信我,

部分成果展示(以頭條 sign值為例):

監測到的檢測點,做過的靚仔可以看看是不是都有
檢測點列印

與真實瀏覽器對比
與真實瀏覽器對比
彎道超車,從我做起

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/539791.html

標籤:訊息安全

上一篇:JavaScript:this指標

下一篇:JS逆向之瀏覽器補環境詳解

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more